OSDN Git Service

mm, vmacache: hash addresses based on pmd
[uclinux-h8/linux.git] / include / linux / fsnotify_backend.h
index e64c029..a0c4790 100644 (file)
@@ -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.
@@ -98,8 +100,6 @@ struct fsnotify_iter_info;
 struct fsnotify_ops {
        int (*handle_event)(struct fsnotify_group *group,
                            struct inode *inode,
-                           struct fsnotify_mark *inode_mark,
-                           struct fsnotify_mark *vfsmount_mark,
                            u32 mask, const void *data, int data_type,
                            const unsigned char *file_name, u32 cookie,
                            struct fsnotify_iter_info *iter_info);
@@ -129,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.
@@ -139,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 */
@@ -162,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 */
@@ -169,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 {
@@ -201,6 +203,57 @@ struct fsnotify_group {
 #define FSNOTIFY_EVENT_PATH    1
 #define FSNOTIFY_EVENT_INODE   2
 
+enum fsnotify_obj_type {
+       FSNOTIFY_OBJ_TYPE_INODE,
+       FSNOTIFY_OBJ_TYPE_VFSMOUNT,
+       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_ALL_TYPES_MASK    ((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1)
+
+struct fsnotify_iter_info {
+       struct fsnotify_mark *marks[FSNOTIFY_OBJ_TYPE_COUNT];
+       unsigned int report_mask;
+       int srcu_idx;
+};
+
+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);
+}
+
+#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) ? \
+               iter_info->marks[FSNOTIFY_OBJ_TYPE_##NAME] : NULL; \
+}
+
+FSNOTIFY_ITER_FUNCS(inode, INODE)
+FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT)
+
+#define fsnotify_foreach_obj_type(type) \
+       for (type = 0; type < FSNOTIFY_OBJ_TYPE_COUNT; type++)
+
 /*
  * Inode / vfsmount point to this structure which tracks all marks attached to
  * the inode / vfsmount. The reference to inode / vfsmount is held by this
@@ -209,11 +262,7 @@ struct fsnotify_group {
  */
 struct fsnotify_mark_connector {
        spinlock_t lock;
-#define FSNOTIFY_OBJ_TYPE_INODE                0x01
-#define FSNOTIFY_OBJ_TYPE_VFSMOUNT     0x02
-#define FSNOTIFY_OBJ_ALL_TYPES         (FSNOTIFY_OBJ_TYPE_INODE | \
-                                        FSNOTIFY_OBJ_TYPE_VFSMOUNT)
-       unsigned int flags;     /* Type of object [lock] */
+       unsigned int type;      /* Type of object [lock] */
        union { /* Object pointer [lock] */
                struct inode *inode;
                struct vfsmount *mnt;
@@ -356,7 +405,21 @@ extern struct fsnotify_mark *fsnotify_find_mark(
 extern int fsnotify_add_mark(struct fsnotify_mark *mark, struct inode *inode,
                             struct vfsmount *mnt, int allow_dups);
 extern int fsnotify_add_mark_locked(struct fsnotify_mark *mark,
-                                   struct inode *inode, struct vfsmount *mnt, int allow_dups);
+                                   struct inode *inode, struct vfsmount *mnt,
+                                   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);
+}
+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);
+}
 /* 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);
@@ -369,12 +432,12 @@ extern void fsnotify_clear_marks_by_group(struct fsnotify_group *group, unsigned
 /* 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)
 {
-       fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_VFSMOUNT);
+       fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL);
 }
 /* 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)
 {
-       fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_INODE);
+       fsnotify_clear_marks_by_group(group, FSNOTIFY_OBJ_TYPE_INODE_FL);
 }
 extern void fsnotify_get_mark(struct fsnotify_mark *mark);
 extern void fsnotify_put_mark(struct fsnotify_mark *mark);