diff mbox

[v2,15/20] fsnotify: make fsnotify_recalc_mask() unaware of object type

Message ID 1522934301-6520-16-git-send-email-amir73il@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Amir Goldstein April 5, 2018, 1:18 p.m. UTC
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(-)

Comments

kernel test robot April 6, 2018, 9:03 a.m. UTC | #1
Hi Amir,

I love your patch! Perhaps something to improve:

[auto build test WARNING on v4.16]
[cannot apply to linus/master next-20180405]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Amir-Goldstein/fanotify-super-block-mark/20180406-132931
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

   fs/notify/mark.c:94:19: sparse: symbol 'fsnotify_mark_connector_cachep' was not declared. Should it be static?
>> fs/notify/mark.c:114:51: sparse: incorrect type in initializer (different address spaces) @@    expected struct fsnotify_mark_connector *conn @@    got struct fsnotify_mstruct fsnotify_mark_connector *conn @@
   fs/notify/mark.c:114:51:    expected struct fsnotify_mark_connector *conn
   fs/notify/mark.c:114:51:    got struct fsnotify_mark_connector [noderef] <asn:4>*marks
   fs/notify/mark.c:147:51: sparse: incorrect type in initializer (different address spaces) @@    expected struct fsnotify_mark_connector *conn @@    got struct fsnotify_mstruct fsnotify_mark_connector *conn @@
   fs/notify/mark.c:147:51:    expected struct fsnotify_mark_connector *conn
   fs/notify/mark.c:147:51:    got struct fsnotify_mark_connector [noderef] <asn:4>*marks
   fs/notify/mark.c:472:13: sparse: incorrect type in initializer (different address spaces) @@    expected struct fsnotify_mark_connector [noderef] <asn:4>*__new @@    got  fsnotify_mark_connector [noderef] <asn:4>*__new @@
   fs/notify/mark.c:472:13:    expected struct fsnotify_mark_connector [noderef] <asn:4>*__new
   fs/notify/mark.c:472:13:    got struct fsnotify_mark_connector *[assigned] conn
   fs/notify/mark.c:237:9: sparse: context imbalance in 'fsnotify_put_mark' - unexpected unlock
   fs/notify/mark.c:323:25: sparse: context imbalance in 'fsnotify_prepare_user_wait' - unexpected unlock
   fs/notify/mark.c:338:9: sparse: context imbalance in 'fsnotify_finish_user_wait' - wrong count at exit
   fs/notify/mark.c:488:39: sparse: context imbalance in 'fsnotify_grab_connector' - different lock contexts for basic block
   fs/notify/mark.c:567:20: sparse: context imbalance in 'fsnotify_add_mark_list' - unexpected unlock
   fs/notify/mark.c:649:25: sparse: context imbalance in 'fsnotify_find_mark' - unexpected unlock
   fs/notify/mark.c:721:17: sparse: context imbalance in 'fsnotify_destroy_marks' - unexpected unlock

vim +114 fs/notify/mark.c

    92	
    93	struct srcu_struct fsnotify_mark_srcu;
  > 94	struct kmem_cache *fsnotify_mark_connector_cachep;
    95	
    96	static DEFINE_SPINLOCK(destroy_lock);
    97	static LIST_HEAD(destroy_list);
    98	static struct fsnotify_mark_connector *connector_destroy_list;
    99	
   100	static void fsnotify_mark_destroy_workfn(struct work_struct *work);
   101	static DECLARE_DELAYED_WORK(reaper_work, fsnotify_mark_destroy_workfn);
   102	
   103	static void fsnotify_connector_destroy_workfn(struct work_struct *work);
   104	static DECLARE_WORK(connector_reaper_work, fsnotify_connector_destroy_workfn);
   105	
   106	void fsnotify_get_mark(struct fsnotify_mark *mark)
   107	{
   108		WARN_ON_ONCE(!refcount_read(&mark->refcnt));
   109		refcount_inc(&mark->refcnt);
   110	}
   111	
   112	static void __fsnotify_recalc_mask(struct fsnotify_obj *obj)
   113	{
 > 114		struct fsnotify_mark_connector *conn = obj->marks;
   115		u32 new_mask = 0;
   116		struct fsnotify_mark *mark;
   117	
   118		assert_spin_locked(&conn->lock);
   119		hlist_for_each_entry(mark, &conn->list, obj_list) {
   120			if (mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)
   121				new_mask |= mark->mask;
   122		}
   123		obj->mask = new_mask;
   124	}
   125	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox

Patch

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 */