root/fs/notify/fanotify/fanotify.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. fanotify_fid_fh
  2. fanotify_fid_equal
  3. fanotify_event_has_path
  4. fanotify_event_has_fid
  5. fanotify_event_has_ext_fh
  6. fanotify_event_fh
  7. FANOTIFY_PE
  8. fanotify_is_perm_event
  9. FANOTIFY_E

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 #include <linux/fsnotify_backend.h>
   3 #include <linux/path.h>
   4 #include <linux/slab.h>
   5 #include <linux/exportfs.h>
   6 
   7 extern struct kmem_cache *fanotify_mark_cache;
   8 extern struct kmem_cache *fanotify_event_cachep;
   9 extern struct kmem_cache *fanotify_perm_event_cachep;
  10 
  11 /* Possible states of the permission event */
  12 enum {
  13         FAN_EVENT_INIT,
  14         FAN_EVENT_REPORTED,
  15         FAN_EVENT_ANSWERED,
  16         FAN_EVENT_CANCELED,
  17 };
  18 
  19 /*
  20  * 3 dwords are sufficient for most local fs (64bit ino, 32bit generation).
  21  * For 32bit arch, fid increases the size of fanotify_event by 12 bytes and
  22  * fh_* fields increase the size of fanotify_event by another 4 bytes.
  23  * For 64bit arch, fid increases the size of fanotify_fid by 8 bytes and
  24  * fh_* fields are packed in a hole after mask.
  25  */
  26 #if BITS_PER_LONG == 32
  27 #define FANOTIFY_INLINE_FH_LEN  (3 << 2)
  28 #else
  29 #define FANOTIFY_INLINE_FH_LEN  (4 << 2)
  30 #endif
  31 
  32 struct fanotify_fid {
  33         __kernel_fsid_t fsid;
  34         union {
  35                 unsigned char fh[FANOTIFY_INLINE_FH_LEN];
  36                 unsigned char *ext_fh;
  37         };
  38 };
  39 
  40 static inline void *fanotify_fid_fh(struct fanotify_fid *fid,
  41                                     unsigned int fh_len)
  42 {
  43         return fh_len <= FANOTIFY_INLINE_FH_LEN ? fid->fh : fid->ext_fh;
  44 }
  45 
  46 static inline bool fanotify_fid_equal(struct fanotify_fid *fid1,
  47                                       struct fanotify_fid *fid2,
  48                                       unsigned int fh_len)
  49 {
  50         return fid1->fsid.val[0] == fid2->fsid.val[0] &&
  51                 fid1->fsid.val[1] == fid2->fsid.val[1] &&
  52                 !memcmp(fanotify_fid_fh(fid1, fh_len),
  53                         fanotify_fid_fh(fid2, fh_len), fh_len);
  54 }
  55 
  56 /*
  57  * Structure for normal fanotify events. It gets allocated in
  58  * fanotify_handle_event() and freed when the information is retrieved by
  59  * userspace
  60  */
  61 struct fanotify_event {
  62         struct fsnotify_event fse;
  63         u32 mask;
  64         /*
  65          * Those fields are outside fanotify_fid to pack fanotify_event nicely
  66          * on 64bit arch and to use fh_type as an indication of whether path
  67          * or fid are used in the union:
  68          * FILEID_ROOT (0) for path, > 0 for fid, FILEID_INVALID for neither.
  69          */
  70         u8 fh_type;
  71         u8 fh_len;
  72         u16 pad;
  73         union {
  74                 /*
  75                  * We hold ref to this path so it may be dereferenced at any
  76                  * point during this object's lifetime
  77                  */
  78                 struct path path;
  79                 /*
  80                  * With FAN_REPORT_FID, we do not hold any reference on the
  81                  * victim object. Instead we store its NFS file handle and its
  82                  * filesystem's fsid as a unique identifier.
  83                  */
  84                 struct fanotify_fid fid;
  85         };
  86         struct pid *pid;
  87 };
  88 
  89 static inline bool fanotify_event_has_path(struct fanotify_event *event)
  90 {
  91         return event->fh_type == FILEID_ROOT;
  92 }
  93 
  94 static inline bool fanotify_event_has_fid(struct fanotify_event *event)
  95 {
  96         return event->fh_type != FILEID_ROOT &&
  97                 event->fh_type != FILEID_INVALID;
  98 }
  99 
 100 static inline bool fanotify_event_has_ext_fh(struct fanotify_event *event)
 101 {
 102         return fanotify_event_has_fid(event) &&
 103                 event->fh_len > FANOTIFY_INLINE_FH_LEN;
 104 }
 105 
 106 static inline void *fanotify_event_fh(struct fanotify_event *event)
 107 {
 108         return fanotify_fid_fh(&event->fid, event->fh_len);
 109 }
 110 
 111 /*
 112  * Structure for permission fanotify events. It gets allocated and freed in
 113  * fanotify_handle_event() since we wait there for user response. When the
 114  * information is retrieved by userspace the structure is moved from
 115  * group->notification_list to group->fanotify_data.access_list to wait for
 116  * user response.
 117  */
 118 struct fanotify_perm_event {
 119         struct fanotify_event fae;
 120         unsigned short response;        /* userspace answer to the event */
 121         unsigned short state;           /* state of the event */
 122         int fd;         /* fd we passed to userspace for this event */
 123 };
 124 
 125 static inline struct fanotify_perm_event *
 126 FANOTIFY_PE(struct fsnotify_event *fse)
 127 {
 128         return container_of(fse, struct fanotify_perm_event, fae.fse);
 129 }
 130 
 131 static inline bool fanotify_is_perm_event(u32 mask)
 132 {
 133         return IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS) &&
 134                 mask & FANOTIFY_PERM_EVENTS;
 135 }
 136 
 137 static inline struct fanotify_event *FANOTIFY_E(struct fsnotify_event *fse)
 138 {
 139         return container_of(fse, struct fanotify_event, fse);
 140 }
 141 
 142 struct fanotify_event *fanotify_alloc_event(struct fsnotify_group *group,
 143                                             struct inode *inode, u32 mask,
 144                                             const void *data, int data_type,
 145                                             __kernel_fsid_t *fsid);

/* [<][>][^][v][top][bottom][index][help] */