diff options
Diffstat (limited to 'include/linux/fsnotify_backend.h')
| -rw-r--r-- | include/linux/fsnotify_backend.h | 52 | 
1 files changed, 36 insertions, 16 deletions
| diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index b38964a7a521..b8f4182f42f1 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -84,6 +84,8 @@ struct fsnotify_event_private_data;  struct fsnotify_fname;  struct fsnotify_iter_info; +struct mem_cgroup; +  /*   * Each group much define these ops.  The fsnotify infrastructure will call   * these operations for each relevant group. @@ -127,6 +129,8 @@ struct fsnotify_event {   * everything will be cleaned up.   */  struct fsnotify_group { +	const struct fsnotify_ops *ops;	/* how this group handles things */ +  	/*  	 * How the refcnt is used is up to each group.  When the refcnt hits 0  	 * fsnotify will clean up all of the resources associated with this group. @@ -137,8 +141,6 @@ struct fsnotify_group {  	 */  	refcount_t refcnt;		/* things with interest in this group */ -	const struct fsnotify_ops *ops;	/* how this group handles things */ -  	/* needed to send notification to userspace */  	spinlock_t notification_lock;		/* protect the notification_list */  	struct list_head notification_list;	/* list of event_holder this group needs to send to userspace */ @@ -160,6 +162,8 @@ struct fsnotify_group {  	atomic_t num_marks;		/* 1 for each mark and 1 for not being  					 * past the point of no return when freeing  					 * a group */ +	atomic_t user_waits;		/* Number of tasks waiting for user +					 * response */  	struct list_head marks_list;	/* all inode marks for this group */  	struct fasync_struct *fsn_fa;    /* async notification */ @@ -167,8 +171,8 @@ struct fsnotify_group {  	struct fsnotify_event *overflow_event;	/* Event we queue when the  						 * notification list is too  						 * full */ -	atomic_t user_waits;		/* Number of tasks waiting for user -					 * response */ + +	struct mem_cgroup *memcg;	/* memcg to charge allocations */  	/* groups can define private fields here or use the void *private */  	union { @@ -210,6 +214,11 @@ enum fsnotify_obj_type {  #define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL	(1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT)  #define FSNOTIFY_OBJ_ALL_TYPES_MASK	((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1) +static inline bool fsnotify_valid_obj_type(unsigned int type) +{ +	return (type < FSNOTIFY_OBJ_TYPE_COUNT); +} +  struct fsnotify_iter_info {  	struct fsnotify_mark *marks[FSNOTIFY_OBJ_TYPE_COUNT];  	unsigned int report_mask; @@ -251,6 +260,13 @@ FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT)  	for (type = 0; type < FSNOTIFY_OBJ_TYPE_COUNT; type++)  /* + * fsnotify_connp_t is what we embed in objects which connector can be attached + * to. fsnotify_connp_t * is how we refer from connector back to object. + */ +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   * structure. We destroy this structure when there are no more marks attached @@ -259,9 +275,9 @@ FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT)  struct fsnotify_mark_connector {  	spinlock_t lock;  	unsigned int type;	/* Type of object [lock] */ -	union {	/* Object pointer [lock] */ -		struct inode *inode; -		struct vfsmount *mnt; +	union { +		/* Object pointer [lock] */ +		fsnotify_connp_t *obj;  		/* Used listing heads to free after srcu period expires */  		struct fsnotify_mark_connector *destroy_next;  	}; @@ -389,32 +405,36 @@ extern struct fsnotify_event *fsnotify_remove_first_event(struct fsnotify_group  /* functions used to manipulate the marks attached to inodes */ +/* Get mask of events for a list of marks */ +extern __u32 fsnotify_conn_mask(struct fsnotify_mark_connector *conn);  /* Calculate mask of events for a list of marks */  extern void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn);  extern void fsnotify_init_mark(struct fsnotify_mark *mark,  			       struct fsnotify_group *group);  /* Find mark belonging to given group in the list of marks */ -extern struct fsnotify_mark *fsnotify_find_mark( -				struct fsnotify_mark_connector __rcu **connp, -				struct fsnotify_group *group); -/* attach the mark to the inode or vfsmount */ -extern int fsnotify_add_mark(struct fsnotify_mark *mark, struct inode *inode, -			     struct vfsmount *mnt, int allow_dups); +extern struct fsnotify_mark *fsnotify_find_mark(fsnotify_connp_t *connp, +						struct fsnotify_group *group); +/* attach the mark to the object */ +extern int fsnotify_add_mark(struct fsnotify_mark *mark, +			     fsnotify_connp_t *connp, unsigned int type, +			     int allow_dups);  extern int fsnotify_add_mark_locked(struct fsnotify_mark *mark, -				    struct inode *inode, struct vfsmount *mnt, +				    fsnotify_connp_t *connp, unsigned int type,  				    int allow_dups);  /* attach the mark to the inode */  static inline int fsnotify_add_inode_mark(struct fsnotify_mark *mark,  					  struct inode *inode,  					  int allow_dups)  { -	return fsnotify_add_mark(mark, inode, NULL, allow_dups); +	return fsnotify_add_mark(mark, &inode->i_fsnotify_marks, +				 FSNOTIFY_OBJ_TYPE_INODE, allow_dups);  }  static inline int fsnotify_add_inode_mark_locked(struct fsnotify_mark *mark,  						 struct inode *inode,  						 int allow_dups)  { -	return fsnotify_add_mark_locked(mark, inode, NULL, allow_dups); +	return fsnotify_add_mark_locked(mark, &inode->i_fsnotify_marks, +					FSNOTIFY_OBJ_TYPE_INODE, allow_dups);  }  /* given a group and a mark, flag mark to be freed when all references are dropped */  extern void fsnotify_destroy_mark(struct fsnotify_mark *mark, |