Blame view
include/linux/fsnotify_backend.h
22.8 KB
b24413180 License cleanup: ... |
1 |
/* SPDX-License-Identifier: GPL-2.0 */ |
90586523e fsnotify: unified... |
2 3 4 5 6 7 8 9 10 11 |
/* * Filesystem access notification for Linux * * Copyright (C) 2008 Red Hat, Inc., Eric Paris <eparis@redhat.com> */ #ifndef __LINUX_FSNOTIFY_BACKEND_H #define __LINUX_FSNOTIFY_BACKEND_H #ifdef __KERNEL__ |
63c882a05 inotify: reimplem... |
12 |
#include <linux/idr.h> /* inotify uses this */ |
90586523e fsnotify: unified... |
13 14 15 16 17 |
#include <linux/fs.h> /* struct inode */ #include <linux/list.h> #include <linux/path.h> /* struct path */ #include <linux/spinlock.h> #include <linux/types.h> |
60063497a atomic: use <linu... |
18 |
#include <linux/atomic.h> |
1cce1eea0 inotify: Convert ... |
19 |
#include <linux/user_namespace.h> |
7761daa6a fsnotify: convert... |
20 |
#include <linux/refcount.h> |
90586523e fsnotify: unified... |
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
/* * IN_* from inotfy.h lines up EXACTLY with FS_*, this is so we can easily * convert between them. dnotify only needs conversion at watch creation * so no perf loss there. fanotify isn't defined yet, so it can use the * wholes if it needs more events. */ #define FS_ACCESS 0x00000001 /* File was accessed */ #define FS_MODIFY 0x00000002 /* File was modified */ #define FS_ATTRIB 0x00000004 /* Metadata changed */ #define FS_CLOSE_WRITE 0x00000008 /* Writtable file was closed */ #define FS_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */ #define FS_OPEN 0x00000020 /* File was opened */ #define FS_MOVED_FROM 0x00000040 /* File was moved from X */ #define FS_MOVED_TO 0x00000080 /* File was moved to Y */ #define FS_CREATE 0x00000100 /* Subfile was created */ #define FS_DELETE 0x00000200 /* Subfile was deleted */ #define FS_DELETE_SELF 0x00000400 /* Self was deleted */ #define FS_MOVE_SELF 0x00000800 /* Self was moved */ |
9b076f1c0 fanotify: introdu... |
40 |
#define FS_OPEN_EXEC 0x00001000 /* File was opened for exec */ |
90586523e fsnotify: unified... |
41 42 43 44 |
#define FS_UNMOUNT 0x00002000 /* inode on umount fs */ #define FS_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ #define FS_IN_IGNORED 0x00008000 /* last inotify event here */ |
c4ec54b40 fsnotify: new fsn... |
45 46 |
#define FS_OPEN_PERM 0x00010000 /* open event in an permission hook */ #define FS_ACCESS_PERM 0x00020000 /* access event in a permissions hook */ |
66917a313 fanotify: introdu... |
47 |
#define FS_OPEN_EXEC_PERM 0x00040000 /* open/exec event in a permission hook */ |
c4ec54b40 fsnotify: new fsn... |
48 |
|
8c1934c8d inotify: allow us... |
49 |
#define FS_EXCL_UNLINK 0x04000000 /* do not send events if object is unlinked */ |
9b93f3310 fsnotify: send ev... |
50 51 52 53 54 |
/* * Set on inode mark that cares about things that happen to its children. * Always set for dnotify and inotify. * Set on inode/sb/mount marks that care about parent/name info. */ |
c28f7e56e fsnotify: parent ... |
55 |
#define FS_EVENT_ON_CHILD 0x08000000 |
6473ea760 fsnotify: tidy up... |
56 57 58 59 |
#define FS_DN_RENAME 0x10000000 /* file renamed */ #define FS_DN_MULTISHOT 0x20000000 /* dnotify multishot */ #define FS_ISDIR 0x40000000 /* event occurred against dir */ #define FS_IN_ONESHOT 0x80000000 /* only send event once */ |
e9fd702a5 audit: convert au... |
60 |
#define FS_MOVE (FS_MOVED_FROM | FS_MOVED_TO) |
e220140ff fsnotify: remove ... |
61 62 63 64 65 66 |
/* * Directory entry modification events - reported only to directory * where entry is modified and not to a watching parent. * The watching parent may get an FS_ATTRIB|FS_EVENT_ON_CHILD event * when a directory entry inside a child subdir changes. */ |
08b95c338 fanotify: remove ... |
67 |
#define ALL_FSNOTIFY_DIRENT_EVENTS (FS_CREATE | FS_DELETE | FS_MOVE) |
e220140ff fsnotify: remove ... |
68 |
|
66917a313 fanotify: introdu... |
69 70 |
#define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM | \ FS_OPEN_EXEC_PERM) |
ff8bcbd03 fsnotify: correct... |
71 |
|
e220140ff fsnotify: remove ... |
72 |
/* |
9b93f3310 fsnotify: send ev... |
73 74 |
* This is a list of all events that may get sent to a parent that is watching * with flag FS_EVENT_ON_CHILD based on fs event on a child of that directory. |
e220140ff fsnotify: remove ... |
75 76 77 78 79 |
*/ #define FS_EVENTS_POSS_ON_CHILD (ALL_FSNOTIFY_PERM_EVENTS | \ FS_ACCESS | FS_MODIFY | FS_ATTRIB | \ FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | \ FS_OPEN | FS_OPEN_EXEC) |
9b93f3310 fsnotify: send ev... |
80 81 82 83 84 85 86 |
/* * This is a list of all events that may get sent with the parent inode as the * @to_tell argument of fsnotify(). * It may include events that can be sent to an inode/sb/mount mark, but cannot * be sent to a parent watching children. */ #define FS_EVENTS_POSS_TO_PARENT (FS_EVENTS_POSS_ON_CHILD) |
007d1e839 fsnotify: general... |
87 |
/* Events that can be reported to backends */ |
e220140ff fsnotify: remove ... |
88 89 90 91 |
#define ALL_FSNOTIFY_EVENTS (ALL_FSNOTIFY_DIRENT_EVENTS | \ FS_EVENTS_POSS_ON_CHILD | \ FS_DELETE_SELF | FS_MOVE_SELF | FS_DN_RENAME | \ FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED) |
007d1e839 fsnotify: general... |
92 93 94 |
/* Extra flags that may be reported with event or control handling of events */ #define ALL_FSNOTIFY_FLAGS (FS_EXCL_UNLINK | FS_ISDIR | FS_IN_ONESHOT | \ |
20dee624c fsnotify: check t... |
95 |
FS_DN_MULTISHOT | FS_EVENT_ON_CHILD) |
007d1e839 fsnotify: general... |
96 |
#define ALL_FSNOTIFY_BITS (ALL_FSNOTIFY_EVENTS | ALL_FSNOTIFY_FLAGS) |
90586523e fsnotify: unified... |
97 98 |
struct fsnotify_group; struct fsnotify_event; |
e61ce8673 fsnotify: rename ... |
99 |
struct fsnotify_mark; |
e4aff1173 fsnotify: allow g... |
100 |
struct fsnotify_event_private_data; |
7053aee26 fsnotify: do not ... |
101 |
struct fsnotify_fname; |
abc77577a fsnotify: Provide... |
102 |
struct fsnotify_iter_info; |
90586523e fsnotify: unified... |
103 |
|
d46eb14b7 fs: fsnotify: acc... |
104 |
struct mem_cgroup; |
90586523e fsnotify: unified... |
105 106 107 108 109 |
/* * Each group much define these ops. The fsnotify infrastructure will call * these operations for each relevant group. * * handle_event - main call for a group to handle an fs event |
b54cecf5e fsnotify: pass di... |
110 111 112 113 114 115 116 117 118 119 120 |
* @group: group to notify * @mask: event type and flags * @data: object that event happened on * @data_type: type of object for fanotify_data_XXX() accessors * @dir: optional directory associated with event - * if @file_name is not NULL, this is the directory that * @file_name is relative to * @file_name: optional file name associated with event * @cookie: inotify rename cookie * @iter_info: array of marks from this group that are interested in the event * |
b9a1b9772 fsnotify: create ... |
121 122 123 124 125 126 127 128 129 |
* handle_inode_event - simple variant of handle_event() for groups that only * have inode marks and don't have ignore mask * @mark: mark to notify * @mask: event type and flags * @inode: inode that event happened on * @dir: optional directory associated with event - * if @file_name is not NULL, this is the directory that * @file_name is relative to. * @file_name: optional file name associated with event |
c9be99c86 fsnotify: general... |
130 |
* @cookie: inotify rename cookie |
b9a1b9772 fsnotify: create ... |
131 |
* |
90586523e fsnotify: unified... |
132 |
* free_group_priv - called when a group refcnt hits 0 to clean up the private union |
6960b0d90 fsnotify: change ... |
133 |
* freeing_mark - called when a mark is being destroyed for some reason. The group |
b9a1b9772 fsnotify: create ... |
134 135 136 |
* MUST be holding a reference on each mark and that reference must be * dropped in this function. inotify uses this function to send * userspace messages that marks have been removed. |
90586523e fsnotify: unified... |
137 138 |
*/ struct fsnotify_ops { |
b54cecf5e fsnotify: pass di... |
139 140 |
int (*handle_event)(struct fsnotify_group *group, u32 mask, const void *data, int data_type, struct inode *dir, |
e43e9c339 fsnotify: switch ... |
141 |
const struct qstr *file_name, u32 cookie, |
9385a84d7 fsnotify: Pass fs... |
142 |
struct fsnotify_iter_info *iter_info); |
b9a1b9772 fsnotify: create ... |
143 144 |
int (*handle_inode_event)(struct fsnotify_mark *mark, u32 mask, struct inode *inode, struct inode *dir, |
c9be99c86 fsnotify: general... |
145 |
const struct qstr *file_name, u32 cookie); |
90586523e fsnotify: unified... |
146 |
void (*free_group_priv)(struct fsnotify_group *group); |
841bdc10f fsnotify: rename ... |
147 |
void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group); |
7053aee26 fsnotify: do not ... |
148 |
void (*free_event)(struct fsnotify_event *event); |
054c636e5 fsnotify: Move ->... |
149 150 |
/* called on final put+free to free memory */ void (*free_mark)(struct fsnotify_mark *mark); |
7053aee26 fsnotify: do not ... |
151 152 153 154 155 156 157 158 159 |
}; /* * all of the information about the original object we want to now send to * a group. If you want to carry more info from the accessing task to the * listener this structure is where you need to be adding fields. */ struct fsnotify_event { struct list_head list; |
dfc2d2594 fsnotify: replace... |
160 |
unsigned long objectid; /* identifier for queue merges */ |
90586523e fsnotify: unified... |
161 162 163 164 165 166 167 168 169 |
}; /* * A group is a "thing" that wants to receive notification about filesystem * events. The mask holds the subset of event types this group cares about. * refcnt on a group is up to the implementor and at any moment if it goes 0 * everything will be cleaned up. */ struct fsnotify_group { |
d46eb14b7 fs: fsnotify: acc... |
170 |
const struct fsnotify_ops *ops; /* how this group handles things */ |
90586523e fsnotify: unified... |
171 |
/* |
90586523e fsnotify: unified... |
172 173 174 175 176 177 178 |
* 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. * As an example, the dnotify group will always have a refcnt=1 and that * will never change. Inotify, on the other hand, has a group per * inotify_init() and the refcnt will hit 0 only when that fd has been * closed. */ |
7761daa6a fsnotify: convert... |
179 |
refcount_t refcnt; /* things with interest in this group */ |
90586523e fsnotify: unified... |
180 |
|
a2d8bc6cb fsnotify: generic... |
181 |
/* needed to send notification to userspace */ |
c21dbe20f fsnotify: convert... |
182 |
spinlock_t notification_lock; /* protect the notification_list */ |
a2d8bc6cb fsnotify: generic... |
183 184 185 186 |
struct list_head notification_list; /* list of event_holder this group needs to send to userspace */ wait_queue_head_t notification_waitq; /* read() on the notification file blocks on this waitq */ unsigned int q_len; /* events on the queue */ unsigned int max_events; /* maximum events allowed on the list */ |
6ad2d4e3e fsnotify: impleme... |
187 188 189 190 191 192 193 194 |
/* * Valid fsnotify group priorities. Events are send in order from highest * priority to lowest priority. We default to the lowest priority. */ #define FS_PRIO_0 0 /* normal notifiers, no permissions */ #define FS_PRIO_1 1 /* fanotify content based access control */ #define FS_PRIO_2 2 /* fanotify pre-content access */ unsigned int priority; |
12703dbfe fsnotify: add a w... |
195 |
bool shutdown; /* group is being shut down, don't queue more events */ |
a2d8bc6cb fsnotify: generic... |
196 |
|
e61ce8673 fsnotify: rename ... |
197 |
/* stores all fastpath marks assoc with this group so they can be cleaned on unregister */ |
986ab0980 fsnotify: use a m... |
198 |
struct mutex mark_mutex; /* protect marks_list */ |
841bdc10f fsnotify: rename ... |
199 |
atomic_t num_marks; /* 1 for each mark and 1 for not being |
3be25f49b fsnotify: add mar... |
200 201 |
* past the point of no return when freeing * a group */ |
d46eb14b7 fs: fsnotify: acc... |
202 203 |
atomic_t user_waits; /* Number of tasks waiting for user * response */ |
e61ce8673 fsnotify: rename ... |
204 |
struct list_head marks_list; /* all inode marks for this group */ |
3be25f49b fsnotify: add mar... |
205 |
|
7053aee26 fsnotify: do not ... |
206 |
struct fasync_struct *fsn_fa; /* async notification */ |
ff57cd586 fsnotify: Allocat... |
207 |
struct fsnotify_event *overflow_event; /* Event we queue when the |
7053aee26 fsnotify: do not ... |
208 209 |
* notification list is too * full */ |
d46eb14b7 fs: fsnotify: acc... |
210 211 |
struct mem_cgroup *memcg; /* memcg to charge allocations */ |
0a6b6bd59 fsnotify: make fa... |
212 |
|
90586523e fsnotify: unified... |
213 214 215 |
/* groups can define private fields here or use the void *private */ union { void *private; |
63c882a05 inotify: reimplem... |
216 217 218 219 |
#ifdef CONFIG_INOTIFY_USER struct inotify_group_private_data { spinlock_t idr_lock; struct idr idr; |
1cce1eea0 inotify: Convert ... |
220 |
struct ucounts *ucounts; |
63c882a05 inotify: reimplem... |
221 222 |
} inotify_data; #endif |
80af25886 fanotify: groups ... |
223 |
#ifdef CONFIG_FANOTIFY |
9e66e4233 fanotify: permiss... |
224 225 |
struct fanotify_group_private_data { /* allows a group to block waiting for a userspace response */ |
9e66e4233 fanotify: permiss... |
226 227 |
struct list_head access_list; wait_queue_head_t access_waitq; |
96a71f21e fanotify: store f... |
228 229 |
int flags; /* flags from fanotify_init() */ int f_flags; /* event_f_flags from fanotify_init() */ |
e7099d8a5 fanotify: limit t... |
230 |
unsigned int max_marks; |
4afeff850 fanotify: limit n... |
231 |
struct user_struct *user; |
9e66e4233 fanotify: permiss... |
232 |
} fanotify_data; |
80af25886 fanotify: groups ... |
233 |
#endif /* CONFIG_FANOTIFY */ |
90586523e fsnotify: unified... |
234 235 |
}; }; |
aa93bdc55 fsnotify: use hel... |
236 237 238 239 240 241 |
/* When calling fsnotify tell it if the data is a path or inode */ enum fsnotify_data_type { FSNOTIFY_EVENT_NONE, FSNOTIFY_EVENT_PATH, FSNOTIFY_EVENT_INODE, }; |
cbcf47adc fsnotify: return ... |
242 |
static inline struct inode *fsnotify_data_inode(const void *data, int data_type) |
aa93bdc55 fsnotify: use hel... |
243 244 245 |
{ switch (data_type) { case FSNOTIFY_EVENT_INODE: |
cbcf47adc fsnotify: return ... |
246 |
return (struct inode *)data; |
aa93bdc55 fsnotify: use hel... |
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
case FSNOTIFY_EVENT_PATH: return d_inode(((const struct path *)data)->dentry); default: return NULL; } } static inline const struct path *fsnotify_data_path(const void *data, int data_type) { switch (data_type) { case FSNOTIFY_EVENT_PATH: return data; default: return NULL; } } |
90586523e fsnotify: unified... |
264 |
|
d6f7b98bc fsnotify: use typ... |
265 266 |
enum fsnotify_obj_type { FSNOTIFY_OBJ_TYPE_INODE, |
41bf5eed8 fsnotify: fix eve... |
267 |
FSNOTIFY_OBJ_TYPE_PARENT, |
d6f7b98bc fsnotify: use typ... |
268 |
FSNOTIFY_OBJ_TYPE_VFSMOUNT, |
1e6cb7239 fsnotify: add sup... |
269 |
FSNOTIFY_OBJ_TYPE_SB, |
d6f7b98bc fsnotify: use typ... |
270 271 272 273 274 |
FSNOTIFY_OBJ_TYPE_COUNT, FSNOTIFY_OBJ_TYPE_DETACHED = FSNOTIFY_OBJ_TYPE_COUNT }; #define FSNOTIFY_OBJ_TYPE_INODE_FL (1U << FSNOTIFY_OBJ_TYPE_INODE) |
41bf5eed8 fsnotify: fix eve... |
275 |
#define FSNOTIFY_OBJ_TYPE_PARENT_FL (1U << FSNOTIFY_OBJ_TYPE_PARENT) |
d6f7b98bc fsnotify: use typ... |
276 |
#define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL (1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT) |
1e6cb7239 fsnotify: add sup... |
277 |
#define FSNOTIFY_OBJ_TYPE_SB_FL (1U << FSNOTIFY_OBJ_TYPE_SB) |
d6f7b98bc fsnotify: use typ... |
278 |
#define FSNOTIFY_OBJ_ALL_TYPES_MASK ((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1) |
b812a9f58 fsnotify: pass co... |
279 280 281 282 |
static inline bool fsnotify_valid_obj_type(unsigned int type) { return (type < FSNOTIFY_OBJ_TYPE_COUNT); } |
5b0457ad0 fsnotify: remove ... |
283 |
struct fsnotify_iter_info { |
47d9c7cc4 fsnotify: general... |
284 |
struct fsnotify_mark *marks[FSNOTIFY_OBJ_TYPE_COUNT]; |
5b0457ad0 fsnotify: remove ... |
285 286 287 |
unsigned int report_mask; int srcu_idx; }; |
47d9c7cc4 fsnotify: general... |
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 |
static inline bool fsnotify_iter_should_report_type( struct fsnotify_iter_info *iter_info, int type) { return (iter_info->report_mask & (1U << type)); } static inline void fsnotify_iter_set_report_type( struct fsnotify_iter_info *iter_info, int type) { iter_info->report_mask |= (1U << type); } static inline void fsnotify_iter_set_report_type_mark( struct fsnotify_iter_info *iter_info, int type, struct fsnotify_mark *mark) { iter_info->marks[type] = mark; iter_info->report_mask |= (1U << type); } |
5b0457ad0 fsnotify: remove ... |
307 308 309 310 311 |
#define FSNOTIFY_ITER_FUNCS(name, NAME) \ static inline struct fsnotify_mark *fsnotify_iter_##name##_mark( \ struct fsnotify_iter_info *iter_info) \ { \ return (iter_info->report_mask & FSNOTIFY_OBJ_TYPE_##NAME##_FL) ? \ |
47d9c7cc4 fsnotify: general... |
312 |
iter_info->marks[FSNOTIFY_OBJ_TYPE_##NAME] : NULL; \ |
5b0457ad0 fsnotify: remove ... |
313 314 315 |
} FSNOTIFY_ITER_FUNCS(inode, INODE) |
41bf5eed8 fsnotify: fix eve... |
316 |
FSNOTIFY_ITER_FUNCS(parent, PARENT) |
5b0457ad0 fsnotify: remove ... |
317 |
FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT) |
1e6cb7239 fsnotify: add sup... |
318 |
FSNOTIFY_ITER_FUNCS(sb, SB) |
5b0457ad0 fsnotify: remove ... |
319 |
|
47d9c7cc4 fsnotify: general... |
320 321 |
#define fsnotify_foreach_obj_type(type) \ for (type = 0; type < FSNOTIFY_OBJ_TYPE_COUNT; type++) |
3be25f49b fsnotify: add mar... |
322 |
/* |
36f10f55f fsnotify: let con... |
323 324 325 326 327 328 329 |
* 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; /* |
1e6cb7239 fsnotify: add sup... |
330 331 |
* 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 |
08991e83b fsnotify: Free fs... |
332 333 |
* structure. We destroy this structure when there are no more marks attached * to it. The structure is protected by fsnotify_mark_srcu. |
9dd813c15 fsnotify: Move ma... |
334 335 |
*/ struct fsnotify_mark_connector { |
04662cab5 fsnotify: Lock ob... |
336 |
spinlock_t lock; |
c285a2f01 fanotify: update ... |
337 338 339 |
unsigned short type; /* Type of object [lock] */ #define FSNOTIFY_CONN_FLAG_HAS_FSID 0x01 unsigned short flags; /* flags [lock] */ |
77115225a fanotify: cache f... |
340 |
__kernel_fsid_t fsid; /* fsid of filesystem containing object */ |
36f10f55f fsnotify: let con... |
341 342 343 |
union { /* Object pointer [lock] */ fsnotify_connp_t *obj; |
08991e83b fsnotify: Free fs... |
344 345 346 |
/* Used listing heads to free after srcu period expires */ struct fsnotify_mark_connector *destroy_next; }; |
d90a10e24 fsnotify: Fix fsn... |
347 |
struct hlist_head list; |
9dd813c15 fsnotify: Move ma... |
348 349 350 |
}; /* |
1e39fc018 fsnotify: documen... |
351 |
* A mark is simply an object attached to an in core inode which allows an |
3be25f49b fsnotify: add mar... |
352 353 354 |
* fsnotify listener to indicate they are either no longer interested in events * of a type matching mask or only interested in those events. * |
1e39fc018 fsnotify: documen... |
355 356 357 358 359 360 361 362 |
* These are flushed when an inode is evicted from core and may be flushed * when the inode is modified (as seen by fsnotify_access). Some fsnotify * users (such as dnotify) will flush these when the open fd is closed and not * at inode eviction or modification. * * Text in brackets is showing the lock(s) protecting modifications of a * particular entry. obj_lock means either inode->i_lock or * mnt->mnt_root->d_lock depending on the mark type. |
3be25f49b fsnotify: add mar... |
363 |
*/ |
e61ce8673 fsnotify: rename ... |
364 |
struct fsnotify_mark { |
1e39fc018 fsnotify: documen... |
365 366 367 |
/* Mask this mark is for [mark->lock, group->mark_mutex] */ __u32 mask; /* We hold one for presence in g_list. Also one ref for each 'thing' |
3be25f49b fsnotify: add mar... |
368 |
* in kernel that found and may be using this mark. */ |
ab97f8732 fsnotify: convert... |
369 |
refcount_t refcnt; |
1e39fc018 fsnotify: documen... |
370 371 372 |
/* Group this mark is for. Set on mark creation, stable until last ref * is dropped */ struct fsnotify_group *group; |
8e984f866 fsnotify: fix typ... |
373 |
/* List of marks by group->marks_list. Also reused for queueing |
1e39fc018 fsnotify: documen... |
374 375 |
* mark into destroy_list when it's waiting for the end of SRCU period * before it can be freed. [group->mark_mutex] */ |
13d34ac6e Revert "fsnotify:... |
376 |
struct list_head g_list; |
1e39fc018 fsnotify: documen... |
377 378 |
/* Protects inode / mnt pointers, flags, masks */ spinlock_t lock; |
6b3f05d24 fsnotify: Detach ... |
379 |
/* List of marks for inode / vfsmount [connector->lock, mark ref] */ |
1e39fc018 fsnotify: documen... |
380 |
struct hlist_node obj_list; |
6b3f05d24 fsnotify: Detach ... |
381 |
/* Head of list of marks for an object [mark ref] */ |
86ffe245c fsnotify: Move ob... |
382 |
struct fsnotify_mark_connector *connector; |
1e39fc018 fsnotify: documen... |
383 384 |
/* Events types to ignore [mark->lock, group->mark_mutex] */ __u32 ignored_mask; |
e911d8af8 fsnotify: Make fs... |
385 386 387 |
#define FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY 0x01 #define FSNOTIFY_MARK_FLAG_ALIVE 0x02 #define FSNOTIFY_MARK_FLAG_ATTACHED 0x04 |
1e39fc018 fsnotify: documen... |
388 |
unsigned int flags; /* flags [mark->lock] */ |
3be25f49b fsnotify: add mar... |
389 |
}; |
90586523e fsnotify: unified... |
390 391 392 393 394 |
#ifdef CONFIG_FSNOTIFY /* called from the vfs helpers */ /* main fsnotify call to send events */ |
40a100d3a fsnotify: pass di... |
395 396 397 |
extern int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir, const struct qstr *name, struct inode *inode, u32 cookie); |
71d734103 fsnotify: Rearran... |
398 |
extern int __fsnotify_parent(struct dentry *dentry, __u32 mask, const void *data, |
017de65fe fsnotify: simplif... |
399 |
int data_type); |
3be25f49b fsnotify: add mar... |
400 |
extern void __fsnotify_inode_delete(struct inode *inode); |
ca9c726ee fsnotify: Infrast... |
401 |
extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt); |
1e6cb7239 fsnotify: add sup... |
402 |
extern void fsnotify_sb_delete(struct super_block *sb); |
47882c6f5 fsnotify: add cor... |
403 |
extern u32 fsnotify_get_cookie(void); |
90586523e fsnotify: unified... |
404 |
|
9b93f3310 fsnotify: send ev... |
405 406 407 408 409 410 411 412 413 414 415 416 |
static inline __u32 fsnotify_parent_needed_mask(__u32 mask) { /* FS_EVENT_ON_CHILD is set on marks that want parent/name info */ if (!(mask & FS_EVENT_ON_CHILD)) return 0; /* * This object might be watched by a mark that cares about parent/name * info, does it care about the specific set of events that can be * reported with parent/name info? */ return mask & FS_EVENTS_POSS_TO_PARENT; } |
c28f7e56e fsnotify: parent ... |
417 418 419 420 421 422 423 424 425 426 427 428 429 430 |
static inline int fsnotify_inode_watches_children(struct inode *inode) { /* FS_EVENT_ON_CHILD is set if the inode may care */ if (!(inode->i_fsnotify_mask & FS_EVENT_ON_CHILD)) return 0; /* this inode might care about child events, does it care about the * specific set of events that can happen on a child? */ return inode->i_fsnotify_mask & FS_EVENTS_POSS_ON_CHILD; } /* * Update the dentry with a flag indicating the interest of its parent to receive * filesystem events when those events happens to this dentry->d_inode. */ |
affda4841 trim fsnotify hoo... |
431 |
static inline void fsnotify_update_flags(struct dentry *dentry) |
c28f7e56e fsnotify: parent ... |
432 |
{ |
c28f7e56e fsnotify: parent ... |
433 |
assert_spin_locked(&dentry->d_lock); |
b5c84bf6f fs: dcache remove... |
434 435 436 437 438 439 440 |
/* * Serialisation of setting PARENT_WATCHED on the dentries is provided * by d_lock. If inotify_inode_watched changes after we have taken * d_lock, the following __fsnotify_update_child_dentry_flags call will * find our entry, so it will spin until we complete here, and update * us with the new state. */ |
affda4841 trim fsnotify hoo... |
441 |
if (fsnotify_inode_watches_children(dentry->d_parent->d_inode)) |
c28f7e56e fsnotify: parent ... |
442 443 444 445 |
dentry->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED; else dentry->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED; } |
90586523e fsnotify: unified... |
446 |
/* called from fsnotify listeners, such as fanotify or dnotify */ |
986129520 fsnotify: introdu... |
447 |
/* create a new group */ |
0d2e2a1d0 fsnotify: drop ma... |
448 |
extern struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops); |
986129520 fsnotify: introdu... |
449 450 |
/* get reference to a group */ extern void fsnotify_get_group(struct fsnotify_group *group); |
ffab83402 fsnotify: fsnotif... |
451 |
/* drop reference on a group from fsnotify_alloc_group */ |
90586523e fsnotify: unified... |
452 |
extern void fsnotify_put_group(struct fsnotify_group *group); |
12703dbfe fsnotify: add a w... |
453 454 |
/* group destruction begins, stop queuing new events */ extern void fsnotify_group_stop_queueing(struct fsnotify_group *group); |
d8153d4d8 inotify, fanotify... |
455 456 |
/* destroy group */ extern void fsnotify_destroy_group(struct fsnotify_group *group); |
0a6b6bd59 fsnotify: make fa... |
457 458 |
/* fasync handler function */ extern int fsnotify_fasync(int fd, struct file *file, int on); |
7053aee26 fsnotify: do not ... |
459 460 461 |
/* Free event from memory */ extern void fsnotify_destroy_event(struct fsnotify_group *group, struct fsnotify_event *event); |
a2d8bc6cb fsnotify: generic... |
462 |
/* attach the event to the group notification queue */ |
8ba8fa917 fsnotify: rename ... |
463 464 465 466 |
extern int fsnotify_add_event(struct fsnotify_group *group, struct fsnotify_event *event, int (*merge)(struct list_head *, struct fsnotify_event *)); |
7b1f64177 fsnotify: Let use... |
467 468 469 470 471 |
/* Queue overflow event to a notification group */ static inline void fsnotify_queue_overflow(struct fsnotify_group *group) { fsnotify_add_event(group, group->overflow_event, NULL); } |
a2d8bc6cb fsnotify: generic... |
472 473 474 |
/* true if the group notification queue is empty */ extern bool fsnotify_notify_queue_is_empty(struct fsnotify_group *group); /* return, but do not dequeue the first event on the notification queue */ |
8ba8fa917 fsnotify: rename ... |
475 |
extern struct fsnotify_event *fsnotify_peek_first_event(struct fsnotify_group *group); |
e4aff1173 fsnotify: allow g... |
476 |
/* return AND dequeue the first event on the notification queue */ |
8ba8fa917 fsnotify: rename ... |
477 |
extern struct fsnotify_event *fsnotify_remove_first_event(struct fsnotify_group *group); |
f7db89acc fsnotify: Create ... |
478 479 480 |
/* Remove event queued in the notification list */ extern void fsnotify_remove_queued_event(struct fsnotify_group *group, struct fsnotify_event *event); |
a2d8bc6cb fsnotify: generic... |
481 |
|
3be25f49b fsnotify: add mar... |
482 |
/* functions used to manipulate the marks attached to inodes */ |
3ac70bfcd fsnotify: add hel... |
483 484 |
/* Get mask of events for a list of marks */ extern __u32 fsnotify_conn_mask(struct fsnotify_mark_connector *conn); |
a242677bb fsnotify: Move lo... |
485 486 |
/* Calculate mask of events for a list of marks */ extern void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn); |
7b1293234 fsnotify: Add gro... |
487 |
extern void fsnotify_init_mark(struct fsnotify_mark *mark, |
054c636e5 fsnotify: Move ->... |
488 |
struct fsnotify_group *group); |
b1362edfe fsnotify: Remove ... |
489 |
/* Find mark belonging to given group in the list of marks */ |
9b6e54345 fsnotify: use typ... |
490 491 |
extern struct fsnotify_mark *fsnotify_find_mark(fsnotify_connp_t *connp, struct fsnotify_group *group); |
77115225a fanotify: cache f... |
492 493 494 |
/* Get cached fsid of filesystem containing object */ extern int fsnotify_get_conn_fsid(const struct fsnotify_mark_connector *conn, __kernel_fsid_t *fsid); |
b812a9f58 fsnotify: pass co... |
495 496 497 |
/* attach the mark to the object */ extern int fsnotify_add_mark(struct fsnotify_mark *mark, fsnotify_connp_t *connp, unsigned int type, |
77115225a fanotify: cache f... |
498 |
int allow_dups, __kernel_fsid_t *fsid); |
7b1293234 fsnotify: Add gro... |
499 |
extern int fsnotify_add_mark_locked(struct fsnotify_mark *mark, |
77115225a fanotify: cache f... |
500 501 502 |
fsnotify_connp_t *connp, unsigned int type, int allow_dups, __kernel_fsid_t *fsid); |
b249f5be6 fsnotify: add fsn... |
503 504 505 506 507 |
/* attach the mark to the inode */ static inline int fsnotify_add_inode_mark(struct fsnotify_mark *mark, struct inode *inode, int allow_dups) { |
b812a9f58 fsnotify: pass co... |
508 |
return fsnotify_add_mark(mark, &inode->i_fsnotify_marks, |
77115225a fanotify: cache f... |
509 |
FSNOTIFY_OBJ_TYPE_INODE, allow_dups, NULL); |
b249f5be6 fsnotify: add fsn... |
510 511 512 513 514 |
} static inline int fsnotify_add_inode_mark_locked(struct fsnotify_mark *mark, struct inode *inode, int allow_dups) { |
b812a9f58 fsnotify: pass co... |
515 |
return fsnotify_add_mark_locked(mark, &inode->i_fsnotify_marks, |
77115225a fanotify: cache f... |
516 517 |
FSNOTIFY_OBJ_TYPE_INODE, allow_dups, NULL); |
b249f5be6 fsnotify: add fsn... |
518 |
} |
77115225a fanotify: cache f... |
519 |
|
e2a29943e fsnotify: pass gr... |
520 521 522 |
/* 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, struct fsnotify_group *group); |
4712e722f fsnotify: get rid... |
523 524 525 526 |
/* detach mark from inode / mount list, group list, drop inode reference */ extern void fsnotify_detach_mark(struct fsnotify_mark *mark); /* free mark */ extern void fsnotify_free_mark(struct fsnotify_mark *mark); |
b72679ee8 notify: export sy... |
527 528 |
/* Wait until all marks queued for destruction are destroyed */ extern void fsnotify_wait_marks_destroyed(void); |
86ffe245c fsnotify: Move ob... |
529 |
/* run all the marks in a group, and clear all of the marks attached to given object type */ |
18f2e0d3a fsnotify: Rename ... |
530 |
extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group, unsigned int type); |
416bcdbcb fsnotify: Inline ... |
531 532 533 |
/* run all the marks in a group, and clear all of the vfsmount marks */ static inline void fsnotify_clear_vfsmount_marks_by_group(struct fsnotify_group *group) { |
d6f7b98bc fsnotify: use typ... |
534 |
fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL); |
416bcdbcb fsnotify: Inline ... |
535 536 537 538 |
} /* run all the marks in a group, and clear all of the inode marks */ static inline void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *group) { |
d6f7b98bc fsnotify: use typ... |
539 |
fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_INODE_FL); |
416bcdbcb fsnotify: Inline ... |
540 |
} |
1e6cb7239 fsnotify: add sup... |
541 542 543 544 545 |
/* 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); } |
841bdc10f fsnotify: rename ... |
546 547 |
extern void fsnotify_get_mark(struct fsnotify_mark *mark); extern void fsnotify_put_mark(struct fsnotify_mark *mark); |
abc77577a fsnotify: Provide... |
548 549 |
extern void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info); extern bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info); |
3be25f49b fsnotify: add mar... |
550 |
|
a0a92d261 fsnotify: move ma... |
551 |
static inline void fsnotify_init_event(struct fsnotify_event *event, |
dfc2d2594 fsnotify: replace... |
552 |
unsigned long objectid) |
a0a92d261 fsnotify: move ma... |
553 554 |
{ INIT_LIST_HEAD(&event->list); |
dfc2d2594 fsnotify: replace... |
555 |
event->objectid = objectid; |
a0a92d261 fsnotify: move ma... |
556 |
} |
b4e4e1407 fsnotify: clone e... |
557 |
|
90586523e fsnotify: unified... |
558 |
#else |
40a100d3a fsnotify: pass di... |
559 560 561 |
static inline int fsnotify(__u32 mask, const void *data, int data_type, struct inode *dir, const struct qstr *name, struct inode *inode, u32 cookie) |
c4ec54b40 fsnotify: new fsn... |
562 563 564 |
{ return 0; } |
3be25f49b fsnotify: add mar... |
565 |
|
71d734103 fsnotify: Rearran... |
566 |
static inline int __fsnotify_parent(struct dentry *dentry, __u32 mask, |
017de65fe fsnotify: simplif... |
567 |
const void *data, int data_type) |
52420392c fsnotify: call fs... |
568 569 570 |
{ return 0; } |
c28f7e56e fsnotify: parent ... |
571 |
|
3be25f49b fsnotify: add mar... |
572 573 |
static inline void __fsnotify_inode_delete(struct inode *inode) {} |
ca9c726ee fsnotify: Infrast... |
574 575 |
static inline void __fsnotify_vfsmount_delete(struct vfsmount *mnt) {} |
1e6cb7239 fsnotify: add sup... |
576 577 |
static inline void fsnotify_sb_delete(struct super_block *sb) {} |
affda4841 trim fsnotify hoo... |
578 |
static inline void fsnotify_update_flags(struct dentry *dentry) |
c28f7e56e fsnotify: parent ... |
579 |
{} |
47882c6f5 fsnotify: add cor... |
580 581 582 583 |
static inline u32 fsnotify_get_cookie(void) { return 0; } |
74278da9f inode: convert in... |
584 |
static inline void fsnotify_unmount_inodes(struct super_block *sb) |
164bc6195 fsnotify: handle ... |
585 |
{} |
90586523e fsnotify: unified... |
586 587 588 589 590 |
#endif /* CONFIG_FSNOTIFY */ #endif /* __KERNEL __ */ #endif /* __LINUX_FSNOTIFY_BACKEND_H */ |