Commit 32720aca authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'fsnotify_for_v6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs

Pull fsnotify updates from Jan Kara:
 "fanotify changes allowing use of fanotify directory events even for
  filesystems such as FUSE which don't report proper fsid"

* tag 'fsnotify_for_v6.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
  fanotify: allow "weak" fsid when watching a single filesystem
  fanotify: store fsid in mark instead of in connector
parents 9963327f 30ad1938
...@@ -29,12 +29,6 @@ static unsigned int fanotify_hash_path(const struct path *path) ...@@ -29,12 +29,6 @@ static unsigned int fanotify_hash_path(const struct path *path)
hash_ptr(path->mnt, FANOTIFY_EVENT_HASH_BITS); 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) static unsigned int fanotify_hash_fsid(__kernel_fsid_t *fsid)
{ {
return hash_32(fsid->val[0], FANOTIFY_EVENT_HASH_BITS) ^ return hash_32(fsid->val[0], FANOTIFY_EVENT_HASH_BITS) ^
...@@ -838,9 +832,8 @@ static struct fanotify_event *fanotify_alloc_event( ...@@ -838,9 +832,8 @@ static struct fanotify_event *fanotify_alloc_event(
} }
/* /*
* Get cached fsid of the filesystem containing the object from any connector. * Get cached fsid of the filesystem containing the object from any mark.
* All connectors are supposed to have the same fsid, but we do not verify that * All marks are supposed to have the same fsid, but we do not verify that here.
* here.
*/ */
static __kernel_fsid_t fanotify_get_fsid(struct fsnotify_iter_info *iter_info) static __kernel_fsid_t fanotify_get_fsid(struct fsnotify_iter_info *iter_info)
{ {
...@@ -849,18 +842,11 @@ static __kernel_fsid_t fanotify_get_fsid(struct fsnotify_iter_info *iter_info) ...@@ -849,18 +842,11 @@ static __kernel_fsid_t fanotify_get_fsid(struct fsnotify_iter_info *iter_info)
__kernel_fsid_t fsid = {}; __kernel_fsid_t fsid = {};
fsnotify_foreach_iter_mark_type(iter_info, mark, type) { fsnotify_foreach_iter_mark_type(iter_info, mark, type) {
struct fsnotify_mark_connector *conn; if (!(mark->flags & FSNOTIFY_MARK_FLAG_HAS_FSID))
conn = READ_ONCE(mark->connector);
/* Mark is just getting destroyed or created? */
if (!conn)
continue; continue;
if (!(conn->flags & FSNOTIFY_CONN_FLAG_HAS_FSID)) fsid = FANOTIFY_MARK(mark)->fsid;
continue; if (!(mark->flags & FSNOTIFY_MARK_FLAG_WEAK_FSID) &&
/* Pairs with smp_wmb() in fsnotify_add_mark_list() */ WARN_ON_ONCE(!fsid.val[0] && !fsid.val[1]))
smp_rmb();
fsid = conn->fsid;
if (WARN_ON_ONCE(!fsid.val[0] && !fsid.val[1]))
continue; continue;
return fsid; return fsid;
} }
...@@ -942,12 +928,8 @@ static int fanotify_handle_event(struct fsnotify_group *group, u32 mask, ...@@ -942,12 +928,8 @@ static int fanotify_handle_event(struct fsnotify_group *group, u32 mask,
return 0; return 0;
} }
if (FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS)) { if (FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS))
fsid = fanotify_get_fsid(iter_info); 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, event = fanotify_alloc_event(group, mask, data, data_type, dir,
file_name, &fsid, match_mask); file_name, &fsid, match_mask);
...@@ -1068,7 +1050,7 @@ static void fanotify_freeing_mark(struct fsnotify_mark *mark, ...@@ -1068,7 +1050,7 @@ static void fanotify_freeing_mark(struct fsnotify_mark *mark,
static void fanotify_free_mark(struct fsnotify_mark *fsn_mark) static void fanotify_free_mark(struct fsnotify_mark *fsn_mark)
{ {
kmem_cache_free(fanotify_mark_cache, fsn_mark); kmem_cache_free(fanotify_mark_cache, FANOTIFY_MARK(fsn_mark));
} }
const struct fsnotify_ops fanotify_fsnotify_ops = { const struct fsnotify_ops fanotify_fsnotify_ops = {
......
...@@ -489,6 +489,22 @@ static inline unsigned int fanotify_event_hash_bucket( ...@@ -489,6 +489,22 @@ static inline unsigned int fanotify_event_hash_bucket(
return event->hash & FANOTIFY_HTABLE_MASK; return event->hash & FANOTIFY_HTABLE_MASK;
} }
struct fanotify_mark {
struct fsnotify_mark fsn_mark;
__kernel_fsid_t fsid;
};
static inline struct fanotify_mark *FANOTIFY_MARK(struct fsnotify_mark *mark)
{
return container_of(mark, struct fanotify_mark, fsn_mark);
}
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 inline unsigned int fanotify_mark_user_flags(struct fsnotify_mark *mark) static inline unsigned int fanotify_mark_user_flags(struct fsnotify_mark *mark)
{ {
unsigned int mflags = 0; unsigned int mflags = 0;
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include <asm/ioctls.h> #include <asm/ioctls.h>
#include "../../mount.h" #include "../fsnotify.h"
#include "../fdinfo.h" #include "../fdinfo.h"
#include "fanotify.h" #include "fanotify.h"
...@@ -1192,13 +1192,71 @@ static bool fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark, ...@@ -1192,13 +1192,71 @@ static bool fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark,
return recalc; return recalc;
} }
struct fan_fsid {
struct super_block *sb;
__kernel_fsid_t id;
bool weak;
};
static int fanotify_set_mark_fsid(struct fsnotify_group *group,
struct fsnotify_mark *mark,
struct fan_fsid *fsid)
{
struct fsnotify_mark_connector *conn;
struct fsnotify_mark *old;
struct super_block *old_sb = NULL;
FANOTIFY_MARK(mark)->fsid = fsid->id;
mark->flags |= FSNOTIFY_MARK_FLAG_HAS_FSID;
if (fsid->weak)
mark->flags |= FSNOTIFY_MARK_FLAG_WEAK_FSID;
/* First mark added will determine if group is single or multi fsid */
if (list_empty(&group->marks_list))
return 0;
/* Find sb of an existing mark */
list_for_each_entry(old, &group->marks_list, g_list) {
conn = READ_ONCE(old->connector);
if (!conn)
continue;
old_sb = fsnotify_connector_sb(conn);
if (old_sb)
break;
}
/* Only detached marks left? */
if (!old_sb)
return 0;
/* Do not allow mixing of marks with weak and strong fsid */
if ((mark->flags ^ old->flags) & FSNOTIFY_MARK_FLAG_WEAK_FSID)
return -EXDEV;
/* Allow mixing of marks with strong fsid from different fs */
if (!fsid->weak)
return 0;
/* Do not allow mixing marks with weak fsid from different fs */
if (old_sb != fsid->sb)
return -EXDEV;
/* Do not allow mixing marks from different btrfs sub-volumes */
if (!fanotify_fsid_equal(&FANOTIFY_MARK(old)->fsid,
&FANOTIFY_MARK(mark)->fsid))
return -EXDEV;
return 0;
}
static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group, static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group,
fsnotify_connp_t *connp, fsnotify_connp_t *connp,
unsigned int obj_type, unsigned int obj_type,
unsigned int fan_flags, unsigned int fan_flags,
__kernel_fsid_t *fsid) struct fan_fsid *fsid)
{ {
struct ucounts *ucounts = group->fanotify_data.ucounts; struct ucounts *ucounts = group->fanotify_data.ucounts;
struct fanotify_mark *fan_mark;
struct fsnotify_mark *mark; struct fsnotify_mark *mark;
int ret; int ret;
...@@ -1211,24 +1269,34 @@ static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group, ...@@ -1211,24 +1269,34 @@ static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group,
!inc_ucount(ucounts->ns, ucounts->uid, UCOUNT_FANOTIFY_MARKS)) !inc_ucount(ucounts->ns, ucounts->uid, UCOUNT_FANOTIFY_MARKS))
return ERR_PTR(-ENOSPC); return ERR_PTR(-ENOSPC);
mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL); fan_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL);
if (!mark) { if (!fan_mark) {
ret = -ENOMEM; ret = -ENOMEM;
goto out_dec_ucounts; goto out_dec_ucounts;
} }
mark = &fan_mark->fsn_mark;
fsnotify_init_mark(mark, group); fsnotify_init_mark(mark, group);
if (fan_flags & FAN_MARK_EVICTABLE) if (fan_flags & FAN_MARK_EVICTABLE)
mark->flags |= FSNOTIFY_MARK_FLAG_NO_IREF; mark->flags |= FSNOTIFY_MARK_FLAG_NO_IREF;
ret = fsnotify_add_mark_locked(mark, connp, obj_type, 0, fsid); /* Cache fsid of filesystem containing the marked object */
if (ret) { if (fsid) {
fsnotify_put_mark(mark); ret = fanotify_set_mark_fsid(group, mark, fsid);
goto out_dec_ucounts; if (ret)
goto out_put_mark;
} else {
fan_mark->fsid.val[0] = fan_mark->fsid.val[1] = 0;
} }
ret = fsnotify_add_mark_locked(mark, connp, obj_type, 0);
if (ret)
goto out_put_mark;
return mark; return mark;
out_put_mark:
fsnotify_put_mark(mark);
out_dec_ucounts: out_dec_ucounts:
if (!FAN_GROUP_FLAG(group, FAN_UNLIMITED_MARKS)) if (!FAN_GROUP_FLAG(group, FAN_UNLIMITED_MARKS))
dec_ucount(ucounts, UCOUNT_FANOTIFY_MARKS); dec_ucount(ucounts, UCOUNT_FANOTIFY_MARKS);
...@@ -1279,7 +1347,7 @@ static int fanotify_may_update_existing_mark(struct fsnotify_mark *fsn_mark, ...@@ -1279,7 +1347,7 @@ static int fanotify_may_update_existing_mark(struct fsnotify_mark *fsn_mark,
static int fanotify_add_mark(struct fsnotify_group *group, static int fanotify_add_mark(struct fsnotify_group *group,
fsnotify_connp_t *connp, unsigned int obj_type, fsnotify_connp_t *connp, unsigned int obj_type,
__u32 mask, unsigned int fan_flags, __u32 mask, unsigned int fan_flags,
__kernel_fsid_t *fsid) struct fan_fsid *fsid)
{ {
struct fsnotify_mark *fsn_mark; struct fsnotify_mark *fsn_mark;
bool recalc; bool recalc;
...@@ -1327,7 +1395,7 @@ static int fanotify_add_mark(struct fsnotify_group *group, ...@@ -1327,7 +1395,7 @@ static int fanotify_add_mark(struct fsnotify_group *group,
static int fanotify_add_vfsmount_mark(struct fsnotify_group *group, static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
struct vfsmount *mnt, __u32 mask, struct vfsmount *mnt, __u32 mask,
unsigned int flags, __kernel_fsid_t *fsid) unsigned int flags, struct fan_fsid *fsid)
{ {
return fanotify_add_mark(group, &real_mount(mnt)->mnt_fsnotify_marks, return fanotify_add_mark(group, &real_mount(mnt)->mnt_fsnotify_marks,
FSNOTIFY_OBJ_TYPE_VFSMOUNT, mask, flags, fsid); FSNOTIFY_OBJ_TYPE_VFSMOUNT, mask, flags, fsid);
...@@ -1335,7 +1403,7 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group, ...@@ -1335,7 +1403,7 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
static int fanotify_add_sb_mark(struct fsnotify_group *group, static int fanotify_add_sb_mark(struct fsnotify_group *group,
struct super_block *sb, __u32 mask, struct super_block *sb, __u32 mask,
unsigned int flags, __kernel_fsid_t *fsid) unsigned int flags, struct fan_fsid *fsid)
{ {
return fanotify_add_mark(group, &sb->s_fsnotify_marks, return fanotify_add_mark(group, &sb->s_fsnotify_marks,
FSNOTIFY_OBJ_TYPE_SB, mask, flags, fsid); FSNOTIFY_OBJ_TYPE_SB, mask, flags, fsid);
...@@ -1343,7 +1411,7 @@ static int fanotify_add_sb_mark(struct fsnotify_group *group, ...@@ -1343,7 +1411,7 @@ static int fanotify_add_sb_mark(struct fsnotify_group *group,
static int fanotify_add_inode_mark(struct fsnotify_group *group, static int fanotify_add_inode_mark(struct fsnotify_group *group,
struct inode *inode, __u32 mask, struct inode *inode, __u32 mask,
unsigned int flags, __kernel_fsid_t *fsid) unsigned int flags, struct fan_fsid *fsid)
{ {
pr_debug("%s: group=%p inode=%p\n", __func__, group, inode); pr_debug("%s: group=%p inode=%p\n", __func__, group, inode);
...@@ -1554,20 +1622,25 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) ...@@ -1554,20 +1622,25 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
return fd; return fd;
} }
static int fanotify_test_fsid(struct dentry *dentry, __kernel_fsid_t *fsid) static int fanotify_test_fsid(struct dentry *dentry, unsigned int flags,
struct fan_fsid *fsid)
{ {
unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS;
__kernel_fsid_t root_fsid; __kernel_fsid_t root_fsid;
int err; int err;
/* /*
* Make sure dentry is not of a filesystem with zero fsid (e.g. fuse). * Make sure dentry is not of a filesystem with zero fsid (e.g. fuse).
*/ */
err = vfs_get_fsid(dentry, fsid); err = vfs_get_fsid(dentry, &fsid->id);
if (err) if (err)
return err; return err;
if (!fsid->val[0] && !fsid->val[1]) fsid->sb = dentry->d_sb;
return -ENODEV; if (!fsid->id.val[0] && !fsid->id.val[1]) {
err = -ENODEV;
goto weak;
}
/* /*
* Make sure dentry is not of a filesystem subvolume (e.g. btrfs) * Make sure dentry is not of a filesystem subvolume (e.g. btrfs)
...@@ -1577,11 +1650,18 @@ static int fanotify_test_fsid(struct dentry *dentry, __kernel_fsid_t *fsid) ...@@ -1577,11 +1650,18 @@ static int fanotify_test_fsid(struct dentry *dentry, __kernel_fsid_t *fsid)
if (err) if (err)
return err; return err;
if (root_fsid.val[0] != fsid->val[0] || if (!fanotify_fsid_equal(&root_fsid, &fsid->id)) {
root_fsid.val[1] != fsid->val[1]) err = -EXDEV;
return -EXDEV; goto weak;
}
fsid->weak = false;
return 0; return 0;
weak:
/* Allow weak fsid when marking inodes */
fsid->weak = true;
return (mark_type == FAN_MARK_INODE) ? 0 : err;
} }
/* Check if filesystem can encode a unique fid */ /* Check if filesystem can encode a unique fid */
...@@ -1665,7 +1745,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, ...@@ -1665,7 +1745,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
struct fsnotify_group *group; struct fsnotify_group *group;
struct fd f; struct fd f;
struct path path; struct path path;
__kernel_fsid_t __fsid, *fsid = NULL; struct fan_fsid __fsid, *fsid = NULL;
u32 valid_mask = FANOTIFY_EVENTS | FANOTIFY_EVENT_FLAGS; u32 valid_mask = FANOTIFY_EVENTS | FANOTIFY_EVENT_FLAGS;
unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS; unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS;
unsigned int mark_cmd = flags & FANOTIFY_MARK_CMD_BITS; unsigned int mark_cmd = flags & FANOTIFY_MARK_CMD_BITS;
...@@ -1817,7 +1897,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask, ...@@ -1817,7 +1897,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
} }
if (fid_mode) { if (fid_mode) {
ret = fanotify_test_fsid(path.dentry, &__fsid); ret = fanotify_test_fsid(path.dentry, flags, &__fsid);
if (ret) if (ret)
goto path_put_and_out; goto path_put_and_out;
...@@ -1935,7 +2015,7 @@ static int __init fanotify_user_setup(void) ...@@ -1935,7 +2015,7 @@ static int __init fanotify_user_setup(void)
BUILD_BUG_ON(HWEIGHT32(FANOTIFY_INIT_FLAGS) != 12); BUILD_BUG_ON(HWEIGHT32(FANOTIFY_INIT_FLAGS) != 12);
BUILD_BUG_ON(HWEIGHT32(FANOTIFY_MARK_FLAGS) != 11); BUILD_BUG_ON(HWEIGHT32(FANOTIFY_MARK_FLAGS) != 11);
fanotify_mark_cache = KMEM_CACHE(fsnotify_mark, fanotify_mark_cache = KMEM_CACHE(fanotify_mark,
SLAB_PANIC|SLAB_ACCOUNT); SLAB_PANIC|SLAB_ACCOUNT);
fanotify_fid_event_cachep = KMEM_CACHE(fanotify_fid_event, fanotify_fid_event_cachep = KMEM_CACHE(fanotify_fid_event,
SLAB_PANIC); SLAB_PANIC);
......
...@@ -537,8 +537,7 @@ int fsnotify_compare_groups(struct fsnotify_group *a, struct fsnotify_group *b) ...@@ -537,8 +537,7 @@ int fsnotify_compare_groups(struct fsnotify_group *a, struct fsnotify_group *b)
} }
static int fsnotify_attach_connector_to_object(fsnotify_connp_t *connp, static int fsnotify_attach_connector_to_object(fsnotify_connp_t *connp,
unsigned int obj_type, unsigned int obj_type)
__kernel_fsid_t *fsid)
{ {
struct fsnotify_mark_connector *conn; struct fsnotify_mark_connector *conn;
...@@ -550,14 +549,7 @@ static int fsnotify_attach_connector_to_object(fsnotify_connp_t *connp, ...@@ -550,14 +549,7 @@ static int fsnotify_attach_connector_to_object(fsnotify_connp_t *connp,
conn->flags = 0; conn->flags = 0;
conn->type = obj_type; conn->type = obj_type;
conn->obj = connp; conn->obj = connp;
/* Cache fsid of filesystem containing the object */ conn->flags = 0;
if (fsid) {
conn->fsid = *fsid;
conn->flags = FSNOTIFY_CONN_FLAG_HAS_FSID;
} else {
conn->fsid.val[0] = conn->fsid.val[1] = 0;
conn->flags = 0;
}
fsnotify_get_sb_connectors(conn); fsnotify_get_sb_connectors(conn);
/* /*
...@@ -608,8 +600,7 @@ static struct fsnotify_mark_connector *fsnotify_grab_connector( ...@@ -608,8 +600,7 @@ static struct fsnotify_mark_connector *fsnotify_grab_connector(
*/ */
static int fsnotify_add_mark_list(struct fsnotify_mark *mark, static int fsnotify_add_mark_list(struct fsnotify_mark *mark,
fsnotify_connp_t *connp, fsnotify_connp_t *connp,
unsigned int obj_type, unsigned int obj_type, int add_flags)
int add_flags, __kernel_fsid_t *fsid)
{ {
struct fsnotify_mark *lmark, *last = NULL; struct fsnotify_mark *lmark, *last = NULL;
struct fsnotify_mark_connector *conn; struct fsnotify_mark_connector *conn;
...@@ -619,41 +610,15 @@ static int fsnotify_add_mark_list(struct fsnotify_mark *mark, ...@@ -619,41 +610,15 @@ static int fsnotify_add_mark_list(struct fsnotify_mark *mark,
if (WARN_ON(!fsnotify_valid_obj_type(obj_type))) if (WARN_ON(!fsnotify_valid_obj_type(obj_type)))
return -EINVAL; return -EINVAL;
/* Backend is expected to check for zero fsid (e.g. tmpfs) */
if (fsid && WARN_ON_ONCE(!fsid->val[0] && !fsid->val[1]))
return -ENODEV;
restart: restart:
spin_lock(&mark->lock); spin_lock(&mark->lock);
conn = fsnotify_grab_connector(connp); conn = fsnotify_grab_connector(connp);
if (!conn) { if (!conn) {
spin_unlock(&mark->lock); spin_unlock(&mark->lock);
err = fsnotify_attach_connector_to_object(connp, obj_type, err = fsnotify_attach_connector_to_object(connp, obj_type);
fsid);
if (err) if (err)
return err; return err;
goto restart; goto restart;
} else if (fsid && !(conn->flags & FSNOTIFY_CONN_FLAG_HAS_FSID)) {
conn->fsid = *fsid;
/* Pairs with smp_rmb() in fanotify_get_fsid() */
smp_wmb();
conn->flags |= FSNOTIFY_CONN_FLAG_HAS_FSID;
} else if (fsid && (conn->flags & FSNOTIFY_CONN_FLAG_HAS_FSID) &&
(fsid->val[0] != conn->fsid.val[0] ||
fsid->val[1] != conn->fsid.val[1])) {
/*
* Backend is expected to check for non uniform fsid
* (e.g. btrfs), but maybe we missed something?
* Only allow setting conn->fsid once to non zero fsid.
* inotify and non-fid fanotify groups do not set nor test
* conn->fsid.
*/
pr_warn_ratelimited("%s: fsid mismatch on object of type %u: "
"%x.%x != %x.%x\n", __func__, conn->type,
fsid->val[0], fsid->val[1],
conn->fsid.val[0], conn->fsid.val[1]);
err = -EXDEV;
goto out_err;
} }
/* is mark the first mark? */ /* is mark the first mark? */
...@@ -703,7 +668,7 @@ static int fsnotify_add_mark_list(struct fsnotify_mark *mark, ...@@ -703,7 +668,7 @@ static int fsnotify_add_mark_list(struct fsnotify_mark *mark,
*/ */
int fsnotify_add_mark_locked(struct fsnotify_mark *mark, int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
fsnotify_connp_t *connp, unsigned int obj_type, fsnotify_connp_t *connp, unsigned int obj_type,
int add_flags, __kernel_fsid_t *fsid) int add_flags)
{ {
struct fsnotify_group *group = mark->group; struct fsnotify_group *group = mark->group;
int ret = 0; int ret = 0;
...@@ -723,7 +688,7 @@ int fsnotify_add_mark_locked(struct fsnotify_mark *mark, ...@@ -723,7 +688,7 @@ int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
fsnotify_get_mark(mark); /* for g_list */ fsnotify_get_mark(mark); /* for g_list */
spin_unlock(&mark->lock); spin_unlock(&mark->lock);
ret = fsnotify_add_mark_list(mark, connp, obj_type, add_flags, fsid); ret = fsnotify_add_mark_list(mark, connp, obj_type, add_flags);
if (ret) if (ret)
goto err; goto err;
...@@ -742,14 +707,13 @@ int fsnotify_add_mark_locked(struct fsnotify_mark *mark, ...@@ -742,14 +707,13 @@ int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
} }
int fsnotify_add_mark(struct fsnotify_mark *mark, fsnotify_connp_t *connp, int fsnotify_add_mark(struct fsnotify_mark *mark, fsnotify_connp_t *connp,
unsigned int obj_type, int add_flags, unsigned int obj_type, int add_flags)
__kernel_fsid_t *fsid)
{ {
int ret; int ret;
struct fsnotify_group *group = mark->group; struct fsnotify_group *group = mark->group;
fsnotify_group_lock(group); fsnotify_group_lock(group);
ret = fsnotify_add_mark_locked(mark, connp, obj_type, add_flags, fsid); ret = fsnotify_add_mark_locked(mark, connp, obj_type, add_flags);
fsnotify_group_unlock(group); fsnotify_group_unlock(group);
return ret; return ret;
} }
......
...@@ -472,10 +472,8 @@ typedef struct fsnotify_mark_connector __rcu *fsnotify_connp_t; ...@@ -472,10 +472,8 @@ typedef struct fsnotify_mark_connector __rcu *fsnotify_connp_t;
struct fsnotify_mark_connector { struct fsnotify_mark_connector {
spinlock_t lock; spinlock_t lock;
unsigned short type; /* Type of object [lock] */ unsigned short type; /* Type of object [lock] */
#define FSNOTIFY_CONN_FLAG_HAS_FSID 0x01
#define FSNOTIFY_CONN_FLAG_HAS_IREF 0x02 #define FSNOTIFY_CONN_FLAG_HAS_IREF 0x02
unsigned short flags; /* flags [lock] */ unsigned short flags; /* flags [lock] */
__kernel_fsid_t fsid; /* fsid of filesystem containing object */
union { union {
/* Object pointer [lock] */ /* Object pointer [lock] */
fsnotify_connp_t *obj; fsnotify_connp_t *obj;
...@@ -530,6 +528,8 @@ struct fsnotify_mark { ...@@ -530,6 +528,8 @@ struct fsnotify_mark {
#define FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY 0x0100 #define FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY 0x0100
#define FSNOTIFY_MARK_FLAG_NO_IREF 0x0200 #define FSNOTIFY_MARK_FLAG_NO_IREF 0x0200
#define FSNOTIFY_MARK_FLAG_HAS_IGNORE_FLAGS 0x0400 #define FSNOTIFY_MARK_FLAG_HAS_IGNORE_FLAGS 0x0400
#define FSNOTIFY_MARK_FLAG_HAS_FSID 0x0800
#define FSNOTIFY_MARK_FLAG_WEAK_FSID 0x1000
unsigned int flags; /* flags [mark->lock] */ unsigned int flags; /* flags [mark->lock] */
}; };
...@@ -763,11 +763,10 @@ extern struct fsnotify_mark *fsnotify_find_mark(fsnotify_connp_t *connp, ...@@ -763,11 +763,10 @@ extern struct fsnotify_mark *fsnotify_find_mark(fsnotify_connp_t *connp,
/* attach the mark to the object */ /* attach the mark to the object */
extern int fsnotify_add_mark(struct fsnotify_mark *mark, extern int fsnotify_add_mark(struct fsnotify_mark *mark,
fsnotify_connp_t *connp, unsigned int obj_type, fsnotify_connp_t *connp, unsigned int obj_type,
int add_flags, __kernel_fsid_t *fsid); int add_flags);
extern int fsnotify_add_mark_locked(struct fsnotify_mark *mark, extern int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
fsnotify_connp_t *connp, fsnotify_connp_t *connp,
unsigned int obj_type, int add_flags, unsigned int obj_type, int add_flags);
__kernel_fsid_t *fsid);
/* attach the mark to the inode */ /* attach the mark to the inode */
static inline int fsnotify_add_inode_mark(struct fsnotify_mark *mark, static inline int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
...@@ -775,15 +774,14 @@ static inline int fsnotify_add_inode_mark(struct fsnotify_mark *mark, ...@@ -775,15 +774,14 @@ static inline int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
int add_flags) int add_flags)
{ {
return fsnotify_add_mark(mark, &inode->i_fsnotify_marks, return fsnotify_add_mark(mark, &inode->i_fsnotify_marks,
FSNOTIFY_OBJ_TYPE_INODE, add_flags, NULL); FSNOTIFY_OBJ_TYPE_INODE, add_flags);
} }
static inline int fsnotify_add_inode_mark_locked(struct fsnotify_mark *mark, static inline int fsnotify_add_inode_mark_locked(struct fsnotify_mark *mark,
struct inode *inode, struct inode *inode,
int add_flags) int add_flags)
{ {
return fsnotify_add_mark_locked(mark, &inode->i_fsnotify_marks, return fsnotify_add_mark_locked(mark, &inode->i_fsnotify_marks,
FSNOTIFY_OBJ_TYPE_INODE, add_flags, FSNOTIFY_OBJ_TYPE_INODE, add_flags);
NULL);
} }
/* given a group and a mark, flag mark to be freed when all references are dropped */ /* given a group and a mark, flag mark to be freed when all references are dropped */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment