diff mbox

[v2,17/20] fsnotify: add super block object type

Message ID 1522934301-6520-18-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
Add the infrastructure to attach a mark to a super_block struct
and detach all attached marks when super block is destroyed.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/notify/fsnotify.c             |  8 +++++++-
 fs/notify/fsnotify.h             | 10 ++++++++++
 fs/notify/mark.c                 |  4 ++++
 fs/super.c                       |  2 +-
 include/linux/fs.h               |  4 ++++
 include/linux/fsnotify.h         |  8 ++++++++
 include/linux/fsnotify_backend.h | 15 ++++++++++++---
 7 files changed, 46 insertions(+), 5 deletions(-)

Comments

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

I love your patch! Yet something to improve:

[auto build test ERROR 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
config: i386-tinyconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   In file included from fs//attr.c:15:0:
   include/linux/fsnotify.h: In function 'fsnotify_sb_delete':
>> include/linux/fsnotify.h:122:2: error: implicit declaration of function '__fsnotify_sb_delete'; did you mean 'fsnotify_sb_delete'? [-Werror=implicit-function-declaration]
     __fsnotify_sb_delete(sb);
     ^~~~~~~~~~~~~~~~~~~~
     fsnotify_sb_delete
   cc1: some warnings being treated as errors

vim +122 include/linux/fsnotify.h

   116	
   117	/*
   118	 * fsnotify_sb_delete - a super block is being destroyed, clean up is needed
   119	 */
   120	static inline void fsnotify_sb_delete(struct super_block *sb)
   121	{
 > 122		__fsnotify_sb_delete(sb);
   123	}
   124	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Amir Goldstein April 6, 2018, 11:04 a.m. UTC | #2
On Fri, Apr 6, 2018 at 9:01 AM, kbuild test robot <lkp@intel.com> wrote:
> Hi Amir,
>
> I love your patch! Yet something to improve:

Thank you robot :)

>
> [auto build test ERROR 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
> config: i386-tinyconfig (attached as .config)
> compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
> reproduce:
>         # save the attached .config to linux build tree
>         make ARCH=i386
>
> All errors (new ones prefixed by >>):
>
>    In file included from fs//attr.c:15:0:
>    include/linux/fsnotify.h: In function 'fsnotify_sb_delete':
>>> include/linux/fsnotify.h:122:2: error: implicit declaration of function '__fsnotify_sb_delete'; did you mean 'fsnotify_sb_delete'? [-Werror=implicit-function-declaration]
>      __fsnotify_sb_delete(sb);
>      ^~~~~~~~~~~~~~~~~~~~
>      fsnotify_sb_delete
>    cc1: some warnings being treated as errors
>
> vim +122 include/linux/fsnotify.h
>
>    116
>    117  /*
>    118   * fsnotify_sb_delete - a super block is being destroyed, clean up is needed
>    119   */
>    120  static inline void fsnotify_sb_delete(struct super_block *sb)
>    121  {
>  > 122          __fsnotify_sb_delete(sb);
>    123  }
>    124
>

Jan,

What do you think about ifdefing away everything in fsnotify.h
for CONFIG_FSNOTIFY=n?

Seems like the right thing to do anyway and then we won't need
those __fsnotify_XXX_delete() noops in fsnotify_backend.h

Thanks,
Amir.
Jan Kara April 19, 2018, 12:39 p.m. UTC | #3
On Thu 05-04-18 16:18:18, Amir Goldstein wrote:
> @@ -98,6 +98,12 @@ void fsnotify_unmount_inodes(struct super_block *sb)
>  		iput(iput_inode);
>  }
>  
> +void __fsnotify_sb_delete(struct super_block *sb)
> +{
> +	fsnotify_unmount_inodes(sb);
> +	fsnotify_clear_marks_by_sb(sb);
> +}
> +

I think it is pointless to have fsnotify_sb_delete() and
__fsnotify_sb_delete(). I know some other fsnotify API is like that and I'm
slowly trying to get rid of that overabstraction. Just make this
fsnotify_sb_delete() directly.

								Honza
Jan Kara April 19, 2018, 12:41 p.m. UTC | #4
On Fri 06-04-18 14:04:23, Amir Goldstein wrote:
> On Fri, Apr 6, 2018 at 9:01 AM, kbuild test robot <lkp@intel.com> wrote:
> > Hi Amir,
> >
> > I love your patch! Yet something to improve:
> 
> Thank you robot :)
> 
> >
> > [auto build test ERROR 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
> > config: i386-tinyconfig (attached as .config)
> > compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
> > reproduce:
> >         # save the attached .config to linux build tree
> >         make ARCH=i386
> >
> > All errors (new ones prefixed by >>):
> >
> >    In file included from fs//attr.c:15:0:
> >    include/linux/fsnotify.h: In function 'fsnotify_sb_delete':
> >>> include/linux/fsnotify.h:122:2: error: implicit declaration of function '__fsnotify_sb_delete'; did you mean 'fsnotify_sb_delete'? [-Werror=implicit-function-declaration]
> >      __fsnotify_sb_delete(sb);
> >      ^~~~~~~~~~~~~~~~~~~~
> >      fsnotify_sb_delete
> >    cc1: some warnings being treated as errors
> >
> > vim +122 include/linux/fsnotify.h
> >
> >    116
> >    117  /*
> >    118   * fsnotify_sb_delete - a super block is being destroyed, clean up is needed
> >    119   */
> >    120  static inline void fsnotify_sb_delete(struct super_block *sb)
> >    121  {
> >  > 122          __fsnotify_sb_delete(sb);
> >    123  }
> >    124
> >
> 
> Jan,
> 
> What do you think about ifdefing away everything in fsnotify.h
> for CONFIG_FSNOTIFY=n?

I'm fine with that but I suspect you'll then have to define empty stubs for
the stuff defined in fsnotify.h when CONFIG_FSNOTIFY=n, won't you?

								Honza
Amir Goldstein April 19, 2018, 2:27 p.m. UTC | #5
On Thu, Apr 19, 2018 at 3:41 PM, Jan Kara <jack@suse.cz> wrote:
> On Fri 06-04-18 14:04:23, Amir Goldstein wrote:
>> On Fri, Apr 6, 2018 at 9:01 AM, kbuild test robot <lkp@intel.com> wrote:
>> > Hi Amir,
>> >
>> > I love your patch! Yet something to improve:
>>
>> Thank you robot :)
>>
>> >
>> > [auto build test ERROR 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
>> > config: i386-tinyconfig (attached as .config)
>> > compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
>> > reproduce:
>> >         # save the attached .config to linux build tree
>> >         make ARCH=i386
>> >
>> > All errors (new ones prefixed by >>):
>> >
>> >    In file included from fs//attr.c:15:0:
>> >    include/linux/fsnotify.h: In function 'fsnotify_sb_delete':
>> >>> include/linux/fsnotify.h:122:2: error: implicit declaration of function '__fsnotify_sb_delete'; did you mean 'fsnotify_sb_delete'? [-Werror=implicit-function-declaration]
>> >      __fsnotify_sb_delete(sb);
>> >      ^~~~~~~~~~~~~~~~~~~~
>> >      fsnotify_sb_delete
>> >    cc1: some warnings being treated as errors
>> >
>> > vim +122 include/linux/fsnotify.h
>> >
>> >    116
>> >    117  /*
>> >    118   * fsnotify_sb_delete - a super block is being destroyed, clean up is needed
>> >    119   */
>> >    120  static inline void fsnotify_sb_delete(struct super_block *sb)
>> >    121  {
>> >  > 122          __fsnotify_sb_delete(sb);
>> >    123  }
>> >    124
>> >
>>
>> Jan,
>>
>> What do you think about ifdefing away everything in fsnotify.h
>> for CONFIG_FSNOTIFY=n?
>
> I'm fine with that but I suspect you'll then have to define empty stubs for
> the stuff defined in fsnotify.h when CONFIG_FSNOTIFY=n, won't you?
>

Yes, I though that will be cleaner - zero footprint of fsnotify for
CONFIG_FSNOTIFY=n,
but now I realize that audit_inode_child() piggy backs on the
fsnotify_ hooks and
CONFIG_AUDIT is independent of  CONFIG_FSNOTIFY, so I will just get rid of
__fsnotify_sb_delete() as you suggested.

Thanks,
Amir.
diff mbox

Patch

diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 6a235091d2e4..2ef97bc27e20 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -48,7 +48,7 @@  void __fsnotify_vfsmount_delete(struct vfsmount *mnt)
  * Called during unmount with no locks held, so needs to be safe against
  * concurrent modifiers. We temporarily drop sb->s_inode_list_lock and CAN block.
  */
-void fsnotify_unmount_inodes(struct super_block *sb)
+static void fsnotify_unmount_inodes(struct super_block *sb)
 {
 	struct inode *inode, *iput_inode = NULL;
 
@@ -98,6 +98,12 @@  void fsnotify_unmount_inodes(struct super_block *sb)
 		iput(iput_inode);
 }
 
+void __fsnotify_sb_delete(struct super_block *sb)
+{
+	fsnotify_unmount_inodes(sb);
+	fsnotify_clear_marks_by_sb(sb);
+}
+
 /*
  * Given an inode, first check if we care what happens to our children.  Inotify
  * and dnotify both tell their parents about events.  If we care about any event
diff --git a/fs/notify/fsnotify.h b/fs/notify/fsnotify.h
index e70d39aed9d8..2ef9f6e9084f 100644
--- a/fs/notify/fsnotify.h
+++ b/fs/notify/fsnotify.h
@@ -31,6 +31,11 @@  static inline void fsnotify_clear_marks_by_mount(struct vfsmount *mnt)
 {
 	fsnotify_destroy_marks(&real_mount(mnt)->mnt_fsnotify);
 }
+/* run the list of all marks associated with sb and destroy them */
+static inline void fsnotify_clear_marks_by_sb(struct super_block *sb)
+{
+	fsnotify_destroy_marks(&sb->s_fsnotify);
+}
 /* Wait until all marks queued for destruction are destroyed */
 extern void fsnotify_wait_marks_destroyed(void);
 
@@ -54,4 +59,9 @@  static inline struct vfsmount *fsnotify_vfsmount(struct fsnotify_obj *obj)
 	return &(container_of(obj, struct mount, mnt_fsnotify))->mnt;
 }
 
+static inline struct super_block *fsnotify_sb(struct fsnotify_obj *obj)
+{
+	return container_of(obj, struct super_block, s_fsnotify);
+}
+
 #endif	/* __FS_NOTIFY_FSNOTIFY_H_ */
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index 3b19ed700ac3..994f6131d307 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -132,6 +132,8 @@  static struct fsnotify_obj *fsnotify_connector_obj(
 		return &conn->inode->i_fsnotify;
 	else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT)
 		return &real_mount(conn->mnt)->mnt_fsnotify;
+	else if (conn->type == FSNOTIFY_OBJ_TYPE_SB)
+		return &conn->sb->s_fsnotify;
 	else
 		return NULL;
 }
@@ -460,6 +462,8 @@  static int fsnotify_attach_connector_to_object(struct fsnotify_obj *obj,
 		inode = conn->inode = igrab(fsnotify_inode(obj));
 	else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT)
 		conn->mnt = fsnotify_vfsmount(obj);
+	else if (conn->type == FSNOTIFY_OBJ_TYPE_SB)
+		conn->sb = fsnotify_sb(obj);
 	/*
 	 * cmpxchg() provides the barrier so that readers of obj->marks can see
 	 * only initialized structure
diff --git a/fs/super.c b/fs/super.c
index 672538ca9831..875c5ed9a29c 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -425,7 +425,7 @@  void generic_shutdown_super(struct super_block *sb)
 		sync_filesystem(sb);
 		sb->s_flags &= ~SB_ACTIVE;
 
-		fsnotify_unmount_inodes(sb);
+		fsnotify_sb_delete(sb);
 		cgroup_writeback_umount();
 
 		evict_inodes(sb);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 144a488fb74b..1c13b2d901f5 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1445,6 +1445,10 @@  struct super_block {
 
 	spinlock_t		s_inode_wblist_lock;
 	struct list_head	s_inodes_wb;	/* writeback inodes */
+
+#ifdef CONFIG_FSNOTIFY
+	struct fsnotify_obj	s_fsnotify;
+#endif
 } __randomize_layout;
 
 /* Helper functions so that in most cases filesystems will
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index bdaf22582f6e..7d70bdc8af04 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -115,6 +115,14 @@  static inline void fsnotify_vfsmount_delete(struct vfsmount *mnt)
 }
 
 /*
+ * fsnotify_sb_delete - a super block is being destroyed, clean up is needed
+ */
+static inline void fsnotify_sb_delete(struct super_block *sb)
+{
+	__fsnotify_sb_delete(sb);
+}
+
+/*
  * fsnotify_nameremove - a filename was removed from a directory
  */
 static inline void fsnotify_nameremove(struct dentry *dentry, int isdir)
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index abbd7311077f..3c1cc6ee5b49 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -203,12 +203,14 @@  struct fsnotify_group {
 enum fsnotify_obj_type {
 	FSNOTIFY_OBJ_TYPE_INODE,
 	FSNOTIFY_OBJ_TYPE_VFSMOUNT,
+	FSNOTIFY_OBJ_TYPE_SB,
 	FSNOTIFY_OBJ_TYPE_MAX,
 	FSNOTIFY_OBJ_TYPE_DETACHED = FSNOTIFY_OBJ_TYPE_MAX
 };
 
 #define FSNOTIFY_OBJ_TYPE_INODE_FL	(1U << FSNOTIFY_OBJ_TYPE_INODE)
 #define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL	(1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT)
+#define FSNOTIFY_OBJ_TYPE_SB_FL		(1U << FSNOTIFY_OBJ_TYPE_SB)
 #define FSNOTIFY_OBJ_ALL_TYPES_MASK	((1U << FSNOTIFY_OBJ_TYPE_MAX) - 1)
 
 static inline bool fsnotify_valid_obj_type(unsigned int type)
@@ -256,6 +258,7 @@  static inline void fsnotify_iter_set_##name##_mark( \
 
 FSNOTIFY_ITER_FUNCS(inode, INODE)
 FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT)
+FSNOTIFY_ITER_FUNCS(sb, SB)
 
 #define fsnotify_foreach_obj_type(type) \
 	for (type = 0; type < FSNOTIFY_OBJ_TYPE_MAX; type++)
@@ -266,8 +269,8 @@  FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT)
 	     type++, mark = fsnotify_iter_type_mark(iter, type)) \
 
 /*
- * Inode / vfsmount point to this structure which tracks all marks attached to
- * the inode / vfsmount. The reference to inode / vfsmount is held by this
+ * Inode/vfsmount/sb point to this structure which tracks all marks attached to
+ * the inode/vfsmount/sb. The reference to inode/vfsmount/sb is held by this
  * structure. We destroy this structure when there are no more marks attached
  * to it. The structure is protected by fsnotify_mark_srcu.
  */
@@ -278,6 +281,7 @@  struct fsnotify_mark_connector {
 		void *object;
 		struct inode *inode;
 		struct vfsmount *mnt;
+		struct super_block *sb;
 	};
 	union {
 		struct hlist_head list;
@@ -337,6 +341,7 @@  extern int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int dat
 extern int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask);
 extern void __fsnotify_inode_delete(struct inode *inode);
 extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt);
+extern void __fsnotify_sb_delete(struct super_block *sb);
 extern u32 fsnotify_get_cookie(void);
 
 static inline int fsnotify_inode_watches_children(struct inode *inode)
@@ -449,9 +454,13 @@  static inline void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *gr
 {
 	fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_INODE_FL);
 }
+/* run all the marks in a group, and clear all of the sn marks */
+static inline void fsnotify_clear_sb_marks_by_group(struct fsnotify_group *group)
+{
+	fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_SB_FL);
+}
 extern void fsnotify_get_mark(struct fsnotify_mark *mark);
 extern void fsnotify_put_mark(struct fsnotify_mark *mark);
-extern void fsnotify_unmount_inodes(struct super_block *sb);
 extern void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info);
 extern bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info);