@@ -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);
@@ -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);
@@ -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_ */
@@ -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);
}
@@ -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:
@@ -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 */
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@gmail.com> --- 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(-)