Re: [PATCH v3 1/3] fsnotify: add super block object type

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu 30-08-18 18:15:49, Amir Goldstein wrote:
> Add the infrastructure to attach a mark to a super_block struct
> and detach all attached marks when super block is destroyed.
> 
> This is going to be used by fanotify backend to setup super block
> marks.
> 
> Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx>

This patch looks OK to me.

								Honza

> ---
>  fs/notify/fdinfo.c               |  5 +++++
>  fs/notify/fsnotify.c             |  8 +++++++-
>  fs/notify/fsnotify.h             | 11 +++++++++++
>  fs/notify/mark.c                 |  4 ++++
>  fs/super.c                       |  2 +-
>  include/linux/fs.h               |  5 +++++
>  include/linux/fsnotify_backend.h | 17 ++++++++++++++---
>  7 files changed, 47 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c
> index 86fcf5814279..25385e336ac7 100644
> --- a/fs/notify/fdinfo.c
> +++ b/fs/notify/fdinfo.c
> @@ -131,6 +131,11 @@ static void fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
>  
>  		seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x\n",
>  			   mnt->mnt_id, mflags, mark->mask, mark->ignored_mask);
> +	} else if (mark->connector->type == FSNOTIFY_OBJ_TYPE_SB) {
> +		struct super_block *sb = fsnotify_conn_sb(mark->connector);
> +
> +		seq_printf(m, "fanotify sdev:%x mflags:%x mask:%x ignored_mask:%x\n",
> +			   sb->s_dev, mflags, mark->mask, mark->ignored_mask);
>  	}
>  }
>  
> diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
> index f174397b63a0..775e731d3016 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 7902653dd577..5a00121fb219 100644
> --- a/fs/notify/fsnotify.h
> +++ b/fs/notify/fsnotify.h
> @@ -21,6 +21,12 @@ static inline struct mount *fsnotify_conn_mount(
>  	return container_of(conn->obj, struct mount, mnt_fsnotify_marks);
>  }
>  
> +static inline struct super_block *fsnotify_conn_sb(
> +				struct fsnotify_mark_connector *conn)
> +{
> +	return container_of(conn->obj, struct super_block, s_fsnotify_marks);
> +}
> +
>  /* destroy all events sitting in this groups notification queue */
>  extern void fsnotify_flush_notify(struct fsnotify_group *group);
>  
> @@ -43,6 +49,11 @@ static inline void fsnotify_clear_marks_by_mount(struct vfsmount *mnt)
>  {
>  	fsnotify_destroy_marks(&real_mount(mnt)->mnt_fsnotify_marks);
>  }
> +/* 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_marks);
> +}
>  /* Wait until all marks queued for destruction are destroyed */
>  extern void fsnotify_wait_marks_destroyed(void);
>  
> diff --git a/fs/notify/mark.c b/fs/notify/mark.c
> index 59cdb27826de..b5172ccb2e60 100644
> --- a/fs/notify/mark.c
> +++ b/fs/notify/mark.c
> @@ -115,6 +115,8 @@ static __u32 *fsnotify_conn_mask_p(struct fsnotify_mark_connector *conn)
>  		return &fsnotify_conn_inode(conn)->i_fsnotify_mask;
>  	else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT)
>  		return &fsnotify_conn_mount(conn)->mnt_fsnotify_mask;
> +	else if (conn->type == FSNOTIFY_OBJ_TYPE_SB)
> +		return &fsnotify_conn_sb(conn)->s_fsnotify_mask;
>  	return NULL;
>  }
>  
> @@ -192,6 +194,8 @@ static struct inode *fsnotify_detach_connector_from_object(
>  		inode->i_fsnotify_mask = 0;
>  	} else if (conn->type == FSNOTIFY_OBJ_TYPE_VFSMOUNT) {
>  		fsnotify_conn_mount(conn)->mnt_fsnotify_mask = 0;
> +	} else if (conn->type == FSNOTIFY_OBJ_TYPE_SB) {
> +		fsnotify_conn_sb(conn)->s_fsnotify_mask = 0;
>  	}
>  
>  	rcu_assign_pointer(*(conn->obj), NULL);
> diff --git a/fs/super.c b/fs/super.c
> index f3a8c008e164..ca53a08497ed 100644
> --- a/fs/super.c
> +++ b/fs/super.c
> @@ -442,7 +442,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 6c0b4a1c22ff..4f0a11d0d296 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1464,6 +1464,11 @@ struct super_block {
>  
>  	spinlock_t		s_inode_wblist_lock;
>  	struct list_head	s_inodes_wb;	/* writeback inodes */
> +
> +#ifdef CONFIG_FSNOTIFY
> +	__u32			s_fsnotify_mask;
> +	struct fsnotify_mark_connector __rcu	*s_fsnotify_marks;
> +#endif
>  } __randomize_layout;
>  
>  /* Helper functions so that in most cases filesystems will
> diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
> index b8f4182f42f1..81b88fc9df31 100644
> --- a/include/linux/fsnotify_backend.h
> +++ b/include/linux/fsnotify_backend.h
> @@ -206,12 +206,14 @@ struct fsnotify_group {
>  enum fsnotify_obj_type {
>  	FSNOTIFY_OBJ_TYPE_INODE,
>  	FSNOTIFY_OBJ_TYPE_VFSMOUNT,
> +	FSNOTIFY_OBJ_TYPE_SB,
>  	FSNOTIFY_OBJ_TYPE_COUNT,
>  	FSNOTIFY_OBJ_TYPE_DETACHED = FSNOTIFY_OBJ_TYPE_COUNT
>  };
>  
>  #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_COUNT) - 1)
>  
>  static inline bool fsnotify_valid_obj_type(unsigned int type)
> @@ -255,6 +257,7 @@ static inline struct fsnotify_mark *fsnotify_iter_##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_COUNT; type++)
> @@ -267,8 +270,8 @@ struct fsnotify_mark_connector;
>  typedef struct fsnotify_mark_connector __rcu *fsnotify_connp_t;
>  
>  /*
> - * 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.
>   */
> @@ -335,6 +338,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)
> @@ -455,9 +459,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);
>  
> @@ -484,6 +492,9 @@ static inline void __fsnotify_inode_delete(struct inode *inode)
>  static inline void __fsnotify_vfsmount_delete(struct vfsmount *mnt)
>  {}
>  
> +static inline void fsnotify_sb_delete(struct super_block *sb)
> +{}
> +
>  static inline void fsnotify_update_flags(struct dentry *dentry)
>  {}
>  
> -- 
> 2.7.4
> 
-- 
Jan Kara <jack@xxxxxxxx>
SUSE Labs, CR



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux