]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - include/linux/fsnotify_backend.h
fanotify: use both marks when possible
[net-next-2.6.git] / include / linux / fsnotify_backend.h
index a46355db1e47e5d111645ae97657b3aae1f38c9f..9bbfd7204b04aff0fe6a06b34734df452b12b773 100644 (file)
@@ -92,9 +92,13 @@ struct fsnotify_event_private_data;
  */
 struct fsnotify_ops {
        bool (*should_send_event)(struct fsnotify_group *group, struct inode *inode,
-                                 struct vfsmount *mnt, __u32 mask, void *data,
-                                 int data_type);
-       int (*handle_event)(struct fsnotify_group *group, struct fsnotify_event *event);
+                                 struct fsnotify_mark *inode_mark,
+                                 struct fsnotify_mark *vfsmount_mark,
+                                 __u32 mask, void *data, int data_type);
+       int (*handle_event)(struct fsnotify_group *group,
+                           struct fsnotify_mark *inode_mark,
+                           struct fsnotify_mark *vfsmount_mark,
+                           struct fsnotify_event *event);
        void (*free_group_priv)(struct fsnotify_group *group);
        void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group);
        void (*free_event_priv)(struct fsnotify_event_private_data *priv);
@@ -107,26 +111,6 @@ struct fsnotify_ops {
  * everything will be cleaned up.
  */
 struct fsnotify_group {
-       /*
-        * global list of all groups receiving events from fsnotify.
-        * anchored by fsnotify_inode_groups and protected by either fsnotify_grp_mutex
-        * or fsnotify_grp_srcu depending on write vs read.
-        */
-       struct list_head inode_group_list;
-       /*
-        * same as above except anchored by fsnotify_vfsmount_groups
-        */
-       struct list_head vfsmount_group_list;
-
-       /*
-        * Defines all of the event types in which this group is interested.
-        * This mask is a bitwise OR of the FS_* events from above.  Each time
-        * this mask changes for a group (if it changes) the correct functions
-        * must be called to update the global structures which indicate global
-        * interest in event types.
-        */
-       __u32 mask;
-
        /*
         * 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.
@@ -153,10 +137,6 @@ struct fsnotify_group {
                                         * a group */
        struct list_head marks_list;    /* all inode marks for this group */
 
-       /* prevents double list_del of group_list.  protected by global fsnotify_grp_mutex */
-       bool on_inode_group_list;
-       bool on_vfsmount_group_list;
-
        /* groups can define private fields here or use the void *private */
        union {
                void *private;
@@ -169,14 +149,17 @@ struct fsnotify_group {
                        struct user_struct      *user;
                } inotify_data;
 #endif
-#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
+#ifdef CONFIG_FANOTIFY
                struct fanotify_group_private_data {
+#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
                        /* allows a group to block waiting for a userspace response */
                        struct mutex access_mutex;
                        struct list_head access_list;
                        wait_queue_head_t access_waitq;
+#endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */
+                       int f_flags;
                } fanotify_data;
-#endif
+#endif /* CONFIG_FANOTIFY */
        };
 };
 
@@ -220,20 +203,20 @@ struct fsnotify_event {
        /* to_tell may ONLY be dereferenced during handle_event(). */
        struct inode *to_tell;  /* either the inode the event happened to or its parent */
        /*
-        * depending on the event type we should have either a path or inode
-        * We hold a reference on path, but NOT on inode.  Since we have the ref on
-        * the path, it may be dereferenced at any point during this object's
+        * depending on the event type we should have either a file or inode
+        * We hold a reference on file, but NOT on inode.  Since we have the ref on
+        * the file, it may be dereferenced at any point during this object's
         * lifetime.  That reference is dropped when this object's refcnt hits
-        * 0.  If this event contains an inode instead of a path, the inode may
+        * 0.  If this event contains an inode instead of a file, the inode may
         * ONLY be used during handle_event().
         */
        union {
-               struct path path;
+               struct file *file;
                struct inode *inode;
        };
 /* when calling fsnotify tell it if the data is a path or inode */
 #define FSNOTIFY_EVENT_NONE    0
-#define FSNOTIFY_EVENT_PATH    1
+#define FSNOTIFY_EVENT_FILE    1
 #define FSNOTIFY_EVENT_INODE   2
        int data_type;          /* which of the above union we have */
        atomic_t refcnt;        /* how many groups still are using/need to send this event */
@@ -297,7 +280,9 @@ struct fsnotify_mark {
 #define FSNOTIFY_MARK_FLAG_VFSMOUNT            0x02
 #define FSNOTIFY_MARK_FLAG_OBJECT_PINNED       0x04
 #define FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY 0x08
+#define FSNOTIFY_MARK_FLAG_ALIVE               0x10
        unsigned int flags;             /* vfsmount or inode mark? */
+       struct list_head destroy_list;
        void (*free_mark)(struct fsnotify_mark *mark); /* called on final put+free */
 };
 
@@ -308,7 +293,7 @@ struct fsnotify_mark {
 /* main fsnotify call to send events */
 extern int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
                    const unsigned char *name, u32 cookie);
-extern void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask);
+extern void __fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask);
 extern void __fsnotify_inode_delete(struct inode *inode);
 extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt);
 extern u32 fsnotify_get_cookie(void);
@@ -359,12 +344,8 @@ static inline void __fsnotify_d_instantiate(struct dentry *dentry, struct inode
 
 /* called from fsnotify listeners, such as fanotify or dnotify */
 
-/* must call when a group changes its ->mask */
-extern void fsnotify_recalc_global_mask(void);
 /* get a reference to an existing or create a new group */
 extern struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops);
-/* run all marks associated with this group and update group->mask */
-extern void fsnotify_recalc_group_mask(struct fsnotify_group *group);
 /* drop reference on a group from fsnotify_alloc_group */
 extern void fsnotify_put_group(struct fsnotify_group *group);
 
@@ -376,13 +357,11 @@ extern struct fsnotify_event_private_data *fsnotify_remove_priv_from_event(struc
                                                                           struct fsnotify_event *event);
 
 /* attach the event to the group notification queue */
-extern int fsnotify_add_notify_event(struct fsnotify_group *group,
-                                    struct fsnotify_event *event,
-                                    struct fsnotify_event_private_data *priv,
-                                    int (*merge)(struct list_head *,
-                                                 struct fsnotify_event *,
-                                                 void **),
-                                    void **arg);
+extern struct fsnotify_event *fsnotify_add_notify_event(struct fsnotify_group *group,
+                                                       struct fsnotify_event *event,
+                                                       struct fsnotify_event_private_data *priv,
+                                                       struct fsnotify_event *(*merge)(struct list_head *,
+                                                                                       struct fsnotify_event *));
 /* 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 */
@@ -443,7 +422,7 @@ static inline int fsnotify(struct inode *to_tell, __u32 mask, void *data, int da
        return 0;
 }
 
-static inline void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask)
+static inline void __fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask)
 {}
 
 static inline void __fsnotify_inode_delete(struct inode *inode)