summaryrefslogtreecommitdiff
path: root/fs/notify/fanotify/fanotify.c
diff options
context:
space:
mode:
authorAmir Goldstein <amir73il@gmail.com>2023-11-30 18:56:19 +0200
committerJan Kara <jack@suse.cz>2023-12-01 10:55:21 +0100
commit30ad1938326bf9303ca38090339d948975a626f5 (patch)
tree984c77da4696ad4e46cbae8ff859223e5fb6fc37 /fs/notify/fanotify/fanotify.c
parent7232522e6cafdf466ed7649c14546fd07ccc1978 (diff)
fanotify: allow "weak" fsid when watching a single filesystem
So far, fanotify returns -ENODEV or -EXDEV when trying to set a mark on a filesystem with a "weak" fsid, namely, zero fsid (e.g. fuse), or non-uniform fsid (e.g. btrfs non-root subvol). When group is watching inodes all from the same filesystem (or subvol), allow adding inode marks with "weak" fsid, because there is no ambiguity regarding which filesystem reports the event. The first mark added to a group determines if this group is single or multi filesystem, depending on the fsid at the path of the added mark. If the first mark added has a "strong" fsid, marks with "weak" fsid cannot be added and vice versa. If the first mark added has a "weak" fsid, following marks must have the same "weak" fsid and the same sb as the first mark. Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Jan Kara <jack@suse.cz> Message-Id: <20231130165619.3386452-3-amir73il@gmail.com>
Diffstat (limited to 'fs/notify/fanotify/fanotify.c')
-rw-r--r--fs/notify/fanotify/fanotify.c15
1 files changed, 3 insertions, 12 deletions
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index aff1ab3c32aa..1e4def21811e 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -29,12 +29,6 @@ static unsigned int fanotify_hash_path(const struct path *path)
hash_ptr(path->mnt, FANOTIFY_EVENT_HASH_BITS);
}
-static inline bool fanotify_fsid_equal(__kernel_fsid_t *fsid1,
- __kernel_fsid_t *fsid2)
-{
- return fsid1->val[0] == fsid2->val[0] && fsid1->val[1] == fsid2->val[1];
-}
-
static unsigned int fanotify_hash_fsid(__kernel_fsid_t *fsid)
{
return hash_32(fsid->val[0], FANOTIFY_EVENT_HASH_BITS) ^
@@ -851,7 +845,8 @@ static __kernel_fsid_t fanotify_get_fsid(struct fsnotify_iter_info *iter_info)
if (!(mark->flags & FSNOTIFY_MARK_FLAG_HAS_FSID))
continue;
fsid = FANOTIFY_MARK(mark)->fsid;
- if (WARN_ON_ONCE(!fsid.val[0] && !fsid.val[1]))
+ if (!(mark->flags & FSNOTIFY_MARK_FLAG_WEAK_FSID) &&
+ WARN_ON_ONCE(!fsid.val[0] && !fsid.val[1]))
continue;
return fsid;
}
@@ -933,12 +928,8 @@ static int fanotify_handle_event(struct fsnotify_group *group, u32 mask,
return 0;
}
- if (FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS)) {
+ if (FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS))
fsid = fanotify_get_fsid(iter_info);
- /* Racing with mark destruction or creation? */
- if (!fsid.val[0] && !fsid.val[1])
- return 0;
- }
event = fanotify_alloc_event(group, mask, data, data_type, dir,
file_name, &fsid, match_mask);