Pass an abstract fsnotify_obj to fsnotify_recalc_mask() and factor out the object type dependent code to a helper fsnotify_connector_obj(), which is called only from fsnotify_put_mark(). Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx> --- fs/notify/dnotify/dnotify.c | 11 ++++++----- fs/notify/fanotify/fanotify_user.c | 8 ++++---- fs/notify/fsnotify.h | 1 - fs/notify/inotify/inotify_user.c | 2 +- fs/notify/mark.c | 27 ++++++++++++++++++++------- include/linux/fsnotify_backend.h | 4 ++-- 6 files changed, 33 insertions(+), 20 deletions(-) diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index c7a74ee4b7a3..bdffdd29e182 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c @@ -50,7 +50,8 @@ struct dnotify_mark { * it calls the fsnotify function so it can update the set of all events relevant * to this inode. */ -static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark) +static void dnotify_recalc_inode_mask(struct inode *inode, + struct fsnotify_mark *fsn_mark) { __u32 new_mask = 0; struct dnotify_struct *dn; @@ -66,7 +67,7 @@ static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark) return; fsn_mark->mask = new_mask; - fsnotify_recalc_mask(fsn_mark->connector); + fsnotify_recalc_mask(&inode->i_fsnotify); } /* @@ -113,7 +114,7 @@ static int dnotify_handle_event(struct fsnotify_group *group, else { *prev = dn->dn_next; kmem_cache_free(dnotify_struct_cache, dn); - dnotify_recalc_inode_mask(inode_mark); + dnotify_recalc_inode_mask(inode, inode_mark); } } @@ -171,7 +172,7 @@ void dnotify_flush(struct file *filp, fl_owner_t id) if ((dn->dn_owner == id) && (dn->dn_filp == filp)) { *prev = dn->dn_next; kmem_cache_free(dnotify_struct_cache, dn); - dnotify_recalc_inode_mask(fsn_mark); + dnotify_recalc_inode_mask(inode, fsn_mark); break; } prev = &dn->dn_next; @@ -364,7 +365,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) else if (error == -EEXIST) error = 0; - dnotify_recalc_inode_mask(fsn_mark); + dnotify_recalc_inode_mask(inode, fsn_mark); out: spin_unlock(&fsn_mark->lock); diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index ecd3539587cc..9f2e7e2c33b3 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -542,7 +542,7 @@ static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group, removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags, &destroy_mark); if (removed & real_mount(mnt)->mnt_fsnotify.mask) - fsnotify_recalc_mask(real_mount(mnt)->mnt_fsnotify.marks); + fsnotify_recalc_mask(&real_mount(mnt)->mnt_fsnotify); if (destroy_mark) fsnotify_detach_mark(fsn_mark); mutex_unlock(&group->mark_mutex); @@ -571,7 +571,7 @@ static int fanotify_remove_inode_mark(struct fsnotify_group *group, removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags, &destroy_mark); if (removed & inode->i_fsnotify.mask) - fsnotify_recalc_mask(inode->i_fsnotify.marks); + fsnotify_recalc_mask(&inode->i_fsnotify); if (destroy_mark) fsnotify_detach_mark(fsn_mark); mutex_unlock(&group->mark_mutex); @@ -657,7 +657,7 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group, } added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); if (added & ~real_mount(mnt)->mnt_fsnotify.mask) - fsnotify_recalc_mask(real_mount(mnt)->mnt_fsnotify.marks); + fsnotify_recalc_mask(&real_mount(mnt)->mnt_fsnotify); mutex_unlock(&group->mark_mutex); fsnotify_put_mark(fsn_mark); @@ -695,7 +695,7 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group, } added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); if (added & ~inode->i_fsnotify.mask) - fsnotify_recalc_mask(inode->i_fsnotify.marks); + fsnotify_recalc_mask(&inode->i_fsnotify); mutex_unlock(&group->mark_mutex); fsnotify_put_mark(fsn_mark); diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h index 2a3fe62e2bf6..e70d39aed9d8 100644 --- a/fs/notify/fsnotify.h +++ b/fs/notify/fsnotify.h @@ -54,5 +54,4 @@ static inline struct vfsmount *fsnotify_vfsmount(struct fsnotify_obj *obj) return &(container_of(obj, struct mount, mnt_fsnotify))->mnt; } - #endif /* __FS_NOTIFY_FSNOTIFY_H_ */ diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index a563d053cc79..49be6fb9432b 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -521,7 +521,7 @@ static int inotify_update_existing_watch(struct fsnotify_group *group, /* update the inode with this new fsn_mark */ if (dropped || do_inode) - fsnotify_recalc_mask(inode->i_fsnotify.marks); + fsnotify_recalc_mask(&inode->i_fsnotify); } diff --git a/fs/notify/mark.c b/fs/notify/mark.c index ea6d97f5fc3b..53bacbce1145 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -109,8 +109,9 @@ void fsnotify_get_mark(struct fsnotify_mark *mark) refcount_inc(&mark->refcnt); } -static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) +static void __fsnotify_recalc_mask(struct fsnotify_obj *obj) { + struct fsnotify_mark_connector *conn = obj->marks; u32 new_mask = 0; struct fsnotify_mark *mark; @@ -119,10 +120,20 @@ static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED) new_mask |= mark->mask; } + obj->mask = new_mask; +} + +static struct fsnotify_obj *fsnotify_connector_obj( + struct fsnotify_mark_connector *conn) +{ + assert_spin_locked(&conn->lock); + if (conn->type == FSNOTIFY_OBJ_TYPE_INODE) - conn->inode->i_fsnotify.mask = new_mask; + return &conn->inode->i_fsnotify; else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) - real_mount(conn->mnt)->mnt_fsnotify.mask = new_mask; + return &real_mount(conn->mnt)->mnt_fsnotify; + else + return NULL; } /* @@ -131,13 +142,15 @@ static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) * this by holding a mark->lock or mark->group->mark_mutex for a mark on this * list. */ -void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) +void fsnotify_recalc_mask(struct fsnotify_obj *obj) { + struct fsnotify_mark_connector *conn = obj->marks; + if (!conn) return; spin_lock(&conn->lock); - __fsnotify_recalc_mask(conn); + __fsnotify_recalc_mask(obj); spin_unlock(&conn->lock); if (conn->type == FSNOTIFY_OBJ_TYPE_INODE) __fsnotify_update_child_dentry_flags(conn->inode); @@ -219,7 +232,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark) inode = fsnotify_detach_connector_from_object(conn); free_conn = true; } else { - __fsnotify_recalc_mask(conn); + __fsnotify_recalc_mask(fsnotify_connector_obj(conn)); } mark->connector = NULL; spin_unlock(&conn->lock); @@ -589,7 +602,7 @@ int fsnotify_add_mark_locked(struct fsnotify_mark *mark, goto err; if (mark->mask) - fsnotify_recalc_mask(mark->connector); + fsnotify_recalc_mask(obj); return ret; err: diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 4a034e6832ea..9a908b96909e 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -400,8 +400,8 @@ extern struct fsnotify_event *fsnotify_remove_first_event(struct fsnotify_group /* functions used to manipulate the marks attached to inodes */ -/* Calculate mask of events for a list of marks */ -extern void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn); +/* Calculate mask of events for a list of object marks */ +extern void fsnotify_recalc_mask(struct fsnotify_obj *obj); extern void fsnotify_init_mark(struct fsnotify_mark *mark, struct fsnotify_group *group); /* Find mark belonging to given group in the list of object marks */ -- 2.7.4