diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 5f038f4..0696d46 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -653,6 +653,7 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
 }
 
 static int fanotify_add_inode_mark(struct fsnotify_group *group,
+				   struct vfsmount *mnt,
 				   struct inode *inode, __u32 mask,
 				   unsigned int flags)
 {
@@ -674,7 +675,7 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 	mutex_lock(&group->mark_mutex);
 	fsn_mark = fsnotify_find_inode_mark(group, inode);
 	if (!fsn_mark) {
-		fsn_mark = fanotify_add_new_mark(group, inode, NULL);
+		fsn_mark = fanotify_add_new_mark(group, inode, mnt);
 		if (IS_ERR(fsn_mark)) {
 			mutex_unlock(&group->mark_mutex);
 			return PTR_ERR(fsn_mark);
@@ -891,7 +892,14 @@ SYSCALL_DEFINE5(fanotify_mark, int, fanotify_fd, unsigned int, flags,
 	/* inode held in place by reference to path; group by fget on fd */
 	if (!(flags & FAN_MARK_MOUNT))
 		inode = path.dentry->d_inode;
-	else
+
+	/*
+	 * Store the mount point from which the watch was added also for
+	 * inode marks. This mount point may be used to report dentry events,
+	 * even if the events happened on another mount point.
+	 */
+	if ((flags & FAN_MARK_MOUNT) ||
+	    group->fanotify_data.flags & FAN_EVENT_INFO_PARENT)
 		mnt = path.mnt;
 
 	/* create/update an inode mark */
@@ -900,7 +908,7 @@ SYSCALL_DEFINE5(fanotify_mark, int, fanotify_fd, unsigned int, flags,
 		if (flags & FAN_MARK_MOUNT)
 			ret = fanotify_add_vfsmount_mark(group, mnt, mask, flags);
 		else
-			ret = fanotify_add_inode_mark(group, inode, mask, flags);
+			ret = fanotify_add_inode_mark(group, mnt, inode, mask, flags);
 		break;
 	case FAN_MARK_REMOVE:
 		if (flags & FAN_MARK_MOUNT)
diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c
index fd98e51..6dd776b 100644
--- a/fs/notify/fdinfo.c
+++ b/fs/notify/fdinfo.c
@@ -119,7 +119,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
 	if (mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY)
 		mflags |= FAN_MARK_IGNORED_SURV_MODIFY;
 
-	if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) {
+	if (FSNOTIFY_IS_INODE_MARK(mark)) {
 		inode = igrab(mark->inode);
 		if (!inode)
 			return;
@@ -129,7 +129,7 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
 		show_mark_fhandle(m, inode);
 		seq_putc(m, '\n');
 		iput(inode);
-	} else if (mark->flags & FSNOTIFY_MARK_FLAG_VFSMOUNT) {
+	} else if (FSNOTIFY_IS_VFSMOUNT_MARK(mark)) {
 		struct mount *mnt = real_mount(mark->mnt);
 
 		seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n",
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
index 741077d..2471229 100644
--- a/fs/notify/inode_mark.c
+++ b/fs/notify/inode_mark.c
@@ -54,6 +54,7 @@ void fsnotify_destroy_inode_mark(struct fsnotify_mark *mark)
 
 	hlist_del_init_rcu(&mark->obj_list);
 	mark->inode = NULL;
+	mark->mnt = NULL;
 
 	/*
 	 * this mark is now off the inode->i_fsnotify_marks list and we
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index d3fea0b..2ebabb4 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -148,10 +148,10 @@ void fsnotify_detach_mark(struct fsnotify_mark *mark)
 
 	mark->flags &= ~FSNOTIFY_MARK_FLAG_ATTACHED;
 
-	if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) {
+	if (FSNOTIFY_IS_INODE_MARK(mark)) {
 		inode = mark->inode;
 		fsnotify_destroy_inode_mark(mark);
-	} else if (mark->flags & FSNOTIFY_MARK_FLAG_VFSMOUNT)
+	} else if (FSNOTIFY_IS_VFSMOUNT_MARK(mark))
 		fsnotify_destroy_vfsmount_mark(mark);
 	else
 		BUG();
@@ -352,6 +352,11 @@ int fsnotify_add_mark_list(struct hlist_head *head, struct fsnotify_mark *mark,
  * Attach an initialized mark to a given group and fs object.
  * These marks may be used for the fsnotify backend to determine which
  * event types should be delivered to which group.
+ *
+ * Either @inode or @mnt MUST be non NULL.
+ * @inode may be NULL implying this is a mount watch.
+ * @inode and @mnt both non NULL imply this is an inode watch
+ * and @mnt is the mount point from which the watch was added.
  */
 int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
 			     struct fsnotify_group *group, struct inode *inode,
@@ -359,7 +364,6 @@ int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
 {
 	int ret = 0;
 
-	BUG_ON(inode && mnt);
 	BUG_ON(!inode && !mnt);
 	BUG_ON(!mutex_is_locked(&group->mark_mutex));
 
@@ -382,6 +386,11 @@ int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
 		ret = fsnotify_add_inode_mark(mark, group, inode, allow_dups);
 		if (ret)
 			goto err;
+		/* Store the mount point from which the inode watch was added */
+		if (mnt) {
+			mark->mnt = mnt;
+			mark->flags |= FSNOTIFY_MARK_FLAG_VFSMOUNT;
+		}
 	} else if (mnt) {
 		ret = fsnotify_add_vfsmount_mark(mark, group, mnt, allow_dups);
 		if (ret)
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 5722e4f..c36e8e5 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -227,10 +227,9 @@ struct fsnotify_mark {
 	spinlock_t lock;
 	/* List of marks for inode / vfsmount [obj_lock] */
 	struct hlist_node obj_list;
-	union {	/* Object pointer [mark->lock, group->mark_mutex] */
-		struct inode *inode;	/* inode this mark is associated with */
-		struct vfsmount *mnt;	/* vfsmount this mark is associated with */
-	};
+	/* Object pointer [mark->lock, group->mark_mutex] */
+	struct inode *inode;	/* inode this mark is associated with */
+	struct vfsmount *mnt;	/* vfsmount this mark is associated with */
 	/* Events types to ignore [mark->lock, group->mark_mutex] */
 	__u32 ignored_mask;
 #define FSNOTIFY_MARK_FLAG_INODE		0x01
@@ -243,6 +242,17 @@ struct fsnotify_mark {
 	void (*free_mark)(struct fsnotify_mark *mark); /* called on final put+free */
 };
 
+/*
+ * A mark may have a reference to both an inode and a vfsmount,
+ * indicating that this is an inode mark with a reference to
+ * the mount point from which that inode mark was added
+ */
+#define FSNOTIFY_MARK_HAS_INODE(m)    ((m)->flags & FSNOTIFY_MARK_FLAG_INODE)
+#define FSNOTIFY_MARK_HAS_VFSMOUNT(m) ((m)->flags & FSNOTIFY_MARK_FLAG_VFSMOUNT)
+#define FSNOTIFY_IS_INODE_MARK(m)     (FSNOTIFY_MARK_HAS_INODE(m))
+#define FSNOTIFY_IS_VFSMOUNT_MARK(m)  (!FSNOTIFY_MARK_HAS_INODE(m) && \
+					FSNOTIFY_MARK_HAS_VFSMOUNT(m))
+
 #ifdef CONFIG_FSNOTIFY
 
 /* called from the vfs helpers */
