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; | |||
| 84 | struct fsnotify_fname; | 84 | struct fsnotify_fname; |
| 85 | struct fsnotify_iter_info; | 85 | struct fsnotify_iter_info; |
| 86 | 86 | ||
| 87 | struct mem_cgroup; | ||
| 88 | |||
| 87 | /* | 89 | /* |
| 88 | * Each group much define these ops. The fsnotify infrastructure will call | 90 | * Each group much define these ops. The fsnotify infrastructure will call |
| 89 | * these operations for each relevant group. | 91 | * these operations for each relevant group. |
| @@ -127,6 +129,8 @@ struct fsnotify_event { | |||
| 127 | * everything will be cleaned up. | 129 | * everything will be cleaned up. |
| 128 | */ | 130 | */ |
| 129 | struct fsnotify_group { | 131 | struct fsnotify_group { |
| 132 | const struct fsnotify_ops *ops; /* how this group handles things */ | ||
| 133 | |||
| 130 | /* | 134 | /* |
| 131 | * How the refcnt is used is up to each group. When the refcnt hits 0 | 135 | * How the refcnt is used is up to each group. When the refcnt hits 0 |
| 132 | * fsnotify will clean up all of the resources associated with this group. | 136 | * fsnotify will clean up all of the resources associated with this group. |
| @@ -137,8 +141,6 @@ struct fsnotify_group { | |||
| 137 | */ | 141 | */ |
| 138 | refcount_t refcnt; /* things with interest in this group */ | 142 | refcount_t refcnt; /* things with interest in this group */ |
| 139 | 143 | ||
| 140 | const struct fsnotify_ops *ops; /* how this group handles things */ | ||
| 141 | |||
| 142 | /* needed to send notification to userspace */ | 144 | /* needed to send notification to userspace */ |
| 143 | spinlock_t notification_lock; /* protect the notification_list */ | 145 | spinlock_t notification_lock; /* protect the notification_list */ |
| 144 | struct list_head notification_list; /* list of event_holder this group needs to send to userspace */ | 146 | struct list_head notification_list; /* list of event_holder this group needs to send to userspace */ |
| @@ -160,6 +162,8 @@ struct fsnotify_group { | |||
| 160 | atomic_t num_marks; /* 1 for each mark and 1 for not being | 162 | atomic_t num_marks; /* 1 for each mark and 1 for not being |
| 161 | * past the point of no return when freeing | 163 | * past the point of no return when freeing |
| 162 | * a group */ | 164 | * a group */ |
| 165 | atomic_t user_waits; /* Number of tasks waiting for user | ||
| 166 | * response */ | ||
| 163 | struct list_head marks_list; /* all inode marks for this group */ | 167 | struct list_head marks_list; /* all inode marks for this group */ |
| 164 | 168 | ||
| 165 | struct fasync_struct *fsn_fa; /* async notification */ | 169 | struct fasync_struct *fsn_fa; /* async notification */ |
| @@ -167,8 +171,8 @@ struct fsnotify_group { | |||
| 167 | struct fsnotify_event *overflow_event; /* Event we queue when the | 171 | struct fsnotify_event *overflow_event; /* Event we queue when the |
| 168 | * notification list is too | 172 | * notification list is too |
| 169 | * full */ | 173 | * full */ |
| 170 | atomic_t user_waits; /* Number of tasks waiting for user | 174 | |
| 171 | * response */ | 175 | struct mem_cgroup *memcg; /* memcg to charge allocations */ |
| 172 | 176 | ||
| 173 | /* groups can define private fields here or use the void *private */ | 177 | /* groups can define private fields here or use the void *private */ |
| 174 | union { | 178 | union { |
| @@ -210,6 +214,11 @@ enum fsnotify_obj_type { | |||
| 210 | #define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL (1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT) | 214 | #define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL (1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT) |
| 211 | #define FSNOTIFY_OBJ_ALL_TYPES_MASK ((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1) | 215 | #define FSNOTIFY_OBJ_ALL_TYPES_MASK ((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1) |
| 212 | 216 | ||
| 217 | static inline bool fsnotify_valid_obj_type(unsigned int type) | ||
| 218 | { | ||
| 219 | return (type < FSNOTIFY_OBJ_TYPE_COUNT); | ||
| 220 | } | ||
| 221 | |||
| 213 | struct fsnotify_iter_info { | 222 | struct fsnotify_iter_info { |
| 214 | struct fsnotify_mark *marks[FSNOTIFY_OBJ_TYPE_COUNT]; | 223 | struct fsnotify_mark *marks[FSNOTIFY_OBJ_TYPE_COUNT]; |
| 215 | unsigned int report_mask; | 224 | unsigned int report_mask; |
| @@ -251,6 +260,13 @@ FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT) | |||
| 251 | for (type = 0; type < FSNOTIFY_OBJ_TYPE_COUNT; type++) | 260 | for (type = 0; type < FSNOTIFY_OBJ_TYPE_COUNT; type++) |
| 252 | 261 | ||
| 253 | /* | 262 | /* |
| 263 | * fsnotify_connp_t is what we embed in objects which connector can be attached | ||
| 264 | * to. fsnotify_connp_t * is how we refer from connector back to object. | ||
| 265 | */ | ||
| 266 | struct fsnotify_mark_connector; | ||
| 267 | typedef struct fsnotify_mark_connector __rcu *fsnotify_connp_t; | ||
| 268 | |||
| 269 | /* | ||
| 254 | * Inode / vfsmount point to this structure which tracks all marks attached to | 270 | * Inode / vfsmount point to this structure which tracks all marks attached to |
| 255 | * the inode / vfsmount. The reference to inode / vfsmount is held by this | 271 | * the inode / vfsmount. The reference to inode / vfsmount is held by this |
| 256 | * structure. We destroy this structure when there are no more marks attached | 272 | * structure. We destroy this structure when there are no more marks attached |
| @@ -259,9 +275,9 @@ FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT) | |||
| 259 | struct fsnotify_mark_connector { | 275 | struct fsnotify_mark_connector { |
| 260 | spinlock_t lock; | 276 | spinlock_t lock; |
| 261 | unsigned int type; /* Type of object [lock] */ | 277 | unsigned int type; /* Type of object [lock] */ |
| 262 | union { /* Object pointer [lock] */ | 278 | union { |
| 263 | struct inode *inode; | 279 | /* Object pointer [lock] */ |
| 264 | struct vfsmount *mnt; | 280 | fsnotify_connp_t *obj; |
| 265 | /* Used listing heads to free after srcu period expires */ | 281 | /* Used listing heads to free after srcu period expires */ |
| 266 | struct fsnotify_mark_connector *destroy_next; | 282 | struct fsnotify_mark_connector *destroy_next; |
| 267 | }; | 283 | }; |
| @@ -389,32 +405,36 @@ extern struct fsnotify_event *fsnotify_remove_first_event(struct fsnotify_group | |||
| 389 | 405 | ||
| 390 | /* functions used to manipulate the marks attached to inodes */ | 406 | /* functions used to manipulate the marks attached to inodes */ |
| 391 | 407 | ||
| 408 | /* Get mask of events for a list of marks */ | ||
| 409 | extern __u32 fsnotify_conn_mask(struct fsnotify_mark_connector *conn); | ||
| 392 | /* Calculate mask of events for a list of marks */ | 410 | /* Calculate mask of events for a list of marks */ |
| 393 | extern void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn); | 411 | extern void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn); |
| 394 | extern void fsnotify_init_mark(struct fsnotify_mark *mark, | 412 | extern void fsnotify_init_mark(struct fsnotify_mark *mark, |
| 395 | struct fsnotify_group *group); | 413 | struct fsnotify_group *group); |
| 396 | /* Find mark belonging to given group in the list of marks */ | 414 | /* Find mark belonging to given group in the list of marks */ |
| 397 | extern struct fsnotify_mark *fsnotify_find_mark( | 415 | extern struct fsnotify_mark *fsnotify_find_mark(fsnotify_connp_t *connp, |
| 398 | struct fsnotify_mark_connector __rcu **connp, | 416 | struct fsnotify_group *group); |
| 399 | struct fsnotify_group *group); | 417 | /* attach the mark to the object */ |
| 400 | /* attach the mark to the inode or vfsmount */ | 418 | extern int fsnotify_add_mark(struct fsnotify_mark *mark, |
| 401 | extern int fsnotify_add_mark(struct fsnotify_mark *mark, struct inode *inode, | 419 | fsnotify_connp_t *connp, unsigned int type, |
| 402 | struct vfsmount *mnt, int allow_dups); | 420 | int allow_dups); |
| 403 | extern int fsnotify_add_mark_locked(struct fsnotify_mark *mark, | 421 | extern int fsnotify_add_mark_locked(struct fsnotify_mark *mark, |
| 404 | struct inode *inode, struct vfsmount *mnt, | 422 | fsnotify_connp_t *connp, unsigned int type, |
| 405 | int allow_dups); | 423 | int allow_dups); |
| 406 | /* attach the mark to the inode */ | 424 | /* attach the mark to the inode */ |
| 407 | static inline int fsnotify_add_inode_mark(struct fsnotify_mark *mark, | 425 | static inline int fsnotify_add_inode_mark(struct fsnotify_mark *mark, |
| 408 | struct inode *inode, | 426 | struct inode *inode, |
| 409 | int allow_dups) | 427 | int allow_dups) |
| 410 | { | 428 | { |
| 411 | return fsnotify_add_mark(mark, inode, NULL, allow_dups); | 429 | return fsnotify_add_mark(mark, &inode->i_fsnotify_marks, |
| 430 | FSNOTIFY_OBJ_TYPE_INODE, allow_dups); | ||
| 412 | } | 431 | } |
| 413 | static inline int fsnotify_add_inode_mark_locked(struct fsnotify_mark *mark, | 432 | static inline int fsnotify_add_inode_mark_locked(struct fsnotify_mark *mark, |
| 414 | struct inode *inode, | 433 | struct inode *inode, |
| 415 | int allow_dups) | 434 | int allow_dups) |
| 416 | { | 435 | { |
| 417 | return fsnotify_add_mark_locked(mark, inode, NULL, allow_dups); | 436 | return fsnotify_add_mark_locked(mark, &inode->i_fsnotify_marks, |
| 437 | FSNOTIFY_OBJ_TYPE_INODE, allow_dups); | ||
| 418 | } | 438 | } |
| 419 | /* given a group and a mark, flag mark to be freed when all references are dropped */ | 439 | /* given a group and a mark, flag mark to be freed when all references are dropped */ |
| 420 | extern void fsnotify_destroy_mark(struct fsnotify_mark *mark, | 440 | extern void fsnotify_destroy_mark(struct fsnotify_mark *mark, |
