]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - include/xfs_inode.h
configure: don't check for fadvise
[thirdparty/xfsprogs-dev.git] / include / xfs_inode.h
index f573f23bf4f4b25a3d935f9d7229d855a4889757..a351bb0d9040f155591faf163156cdd1efc4f593 100644 (file)
 struct xfs_trans;
 struct xfs_mount;
 struct xfs_inode_log_item;
-struct xfs_dir_ops;
+struct inode;
+
+/*
+ * These are not actually used, they are only for userspace build
+ * compatibility in code that looks at i_state
+ */
+#define I_DIRTY_TIME           0
+#define I_DIRTY_TIME_EXPIRED   0
+
+static inline bool IS_I_VERSION(const struct inode *inode) { return false; }
+#define inode_maybe_inc_iversion(inode,flags)  (0)
 
 /*
  * Inode interface. This fakes up a "VFS inode" to make the xfs_inode appear
@@ -22,38 +32,230 @@ struct xfs_dir_ops;
  * metadata.
  */
 struct inode {
-       mode_t          i_mode;
-       uint32_t        i_nlink;
-       xfs_dev_t       i_rdev;         /* This actually holds xfs_dev_t */
-       uint32_t        i_generation;
-       uint64_t        i_version;
-       struct timespec i_atime;
-       struct timespec i_mtime;
-       struct timespec i_ctime;
+       mode_t                  i_mode;
+       uint32_t                i_uid;
+       uint32_t                i_gid;
+       uint32_t                i_nlink;
+       xfs_dev_t               i_rdev;  /* This actually holds xfs_dev_t */
+       unsigned int            i_count;
+       unsigned long           i_state; /* Not actually used in userspace */
+       uint32_t                i_generation;
+       uint64_t                i_version;
+       struct timespec64       __i_atime;
+       struct timespec64       __i_mtime;
+       struct timespec64       __i_ctime; /* use inode_*_ctime accessors! */
+       spinlock_t              i_lock;
 };
 
+static inline uint32_t i_uid_read(struct inode *inode)
+{
+       return inode->i_uid;
+}
+static inline uint32_t i_gid_read(struct inode *inode)
+{
+       return inode->i_gid;
+}
+static inline void i_uid_write(struct inode *inode, uint32_t uid)
+{
+       inode->i_uid = uid;
+}
+static inline void i_gid_write(struct inode *inode, uint32_t gid)
+{
+       inode->i_gid = gid;
+}
+
+static inline void ihold(struct inode *inode)
+{
+       inode->i_count++;
+}
+
+static inline time64_t inode_get_atime_sec(const struct inode *inode)
+{
+       return inode->__i_atime.tv_sec;
+}
+
+static inline long inode_get_atime_nsec(const struct inode *inode)
+{
+       return inode->__i_atime.tv_nsec;
+}
+
+static inline struct timespec64 inode_get_atime(const struct inode *inode)
+{
+       return inode->__i_atime;
+}
+
+static inline struct timespec64 inode_set_atime_to_ts(struct inode *inode,
+                                                     struct timespec64 ts)
+{
+       inode->__i_atime = ts;
+       return ts;
+}
+
+static inline struct timespec64 inode_set_atime(struct inode *inode,
+                                               time64_t sec, long nsec)
+{
+       struct timespec64 ts = { .tv_sec = sec,
+                                .tv_nsec = nsec };
+       return inode_set_atime_to_ts(inode, ts);
+}
+
+static inline time64_t inode_get_mtime_sec(const struct inode *inode)
+{
+       return inode->__i_mtime.tv_sec;
+}
+
+static inline long inode_get_mtime_nsec(const struct inode *inode)
+{
+       return inode->__i_mtime.tv_nsec;
+}
+
+static inline struct timespec64 inode_get_mtime(const struct inode *inode)
+{
+       return inode->__i_mtime;
+}
+
+static inline struct timespec64 inode_set_mtime_to_ts(struct inode *inode,
+                                                     struct timespec64 ts)
+{
+       inode->__i_mtime = ts;
+       return ts;
+}
+
+static inline struct timespec64 inode_set_mtime(struct inode *inode,
+                                               time64_t sec, long nsec)
+{
+       struct timespec64 ts = { .tv_sec = sec,
+                                .tv_nsec = nsec };
+       return inode_set_mtime_to_ts(inode, ts);
+}
+
+static inline time64_t inode_get_ctime_sec(const struct inode *inode)
+{
+       return inode->__i_ctime.tv_sec;
+}
+
+static inline long inode_get_ctime_nsec(const struct inode *inode)
+{
+       return inode->__i_ctime.tv_nsec;
+}
+
+static inline struct timespec64 inode_get_ctime(const struct inode *inode)
+{
+       return inode->__i_ctime;
+}
+
+static inline struct timespec64 inode_set_ctime_to_ts(struct inode *inode,
+                                                    struct timespec64 ts)
+{
+       inode->__i_ctime = ts;
+       return ts;
+}
+
+extern struct timespec64 current_time(struct inode *inode);
+
+static inline struct timespec64 inode_set_ctime_current(struct inode *inode)
+{
+       struct timespec64 now = current_time(inode);
+
+       inode_set_ctime_to_ts(inode, now);
+       return now;
+}
+
 typedef struct xfs_inode {
        struct cache_node       i_node;
        struct xfs_mount        *i_mount;       /* fs mount struct ptr */
        xfs_ino_t               i_ino;          /* inode number (agno/agino) */
        struct xfs_imap         i_imap;         /* location for xfs_imap() */
        struct xfs_buftarg      i_dev;          /* dev for this inode */
-       struct xfs_ifork        *i_afp;         /* attribute fork pointer */
        struct xfs_ifork        *i_cowfp;       /* copy on write extents */
        struct xfs_ifork        i_df;           /* data fork */
-       struct xfs_trans        *i_transp;      /* ptr to owning transaction */
+       struct xfs_ifork        i_af;           /* attribute fork */
        struct xfs_inode_log_item *i_itemp;     /* logging information */
        unsigned int            i_delayed_blks; /* count of delay alloc blks */
-       struct xfs_icdinode     i_d;            /* most of ondisk inode */
+       xfs_fsize_t             i_disk_size;    /* number of bytes in file */
+       xfs_rfsblock_t          i_nblocks;      /* # of direct & btree blocks */
+       prid_t                  i_projid;       /* owner's project id */
+       xfs_extlen_t            i_extsize;      /* basic/minimum extent size */
+       /* cowextsize is only used for v3 inodes, flushiter for v1/2 */
+       union {
+               xfs_extlen_t    i_cowextsize;   /* basic cow extent size */
+               uint16_t        i_flushiter;    /* incremented on flush */
+       };
+       uint8_t                 i_forkoff;      /* attr fork offset >> 3 */
+       uint16_t                i_diflags;      /* XFS_DIFLAG_... */
+       uint64_t                i_diflags2;     /* XFS_DIFLAG2_... */
+       struct timespec64       i_crtime;       /* time created */
+
+       /* unlinked list pointers */
+       xfs_agino_t             i_next_unlinked;
 
        xfs_extnum_t            i_cnextents;    /* # of extents in cow fork */
        unsigned int            i_cformat;      /* format of cow fork */
 
        xfs_fsize_t             i_size;         /* in-memory size */
-       const struct xfs_dir_ops *d_ops;        /* directory ops vector */
        struct inode            i_vnode;
 } xfs_inode_t;
 
+static inline bool xfs_inode_has_attr_fork(struct xfs_inode *ip)
+{
+       return ip->i_forkoff > 0;
+}
+
+static inline struct xfs_ifork *
+xfs_ifork_ptr(
+       struct xfs_inode        *ip,
+       int                     whichfork)
+{
+       switch (whichfork) {
+       case XFS_DATA_FORK:
+               return &ip->i_df;
+       case XFS_ATTR_FORK:
+               if (!xfs_inode_has_attr_fork(ip))
+                       return NULL;
+               return &ip->i_af;
+       case XFS_COW_FORK:
+               return ip->i_cowfp;
+       default:
+               ASSERT(0);
+               return NULL;
+       }
+}
+
+static inline unsigned int xfs_inode_fork_boff(struct xfs_inode *ip)
+{
+       return ip->i_forkoff << 3;
+}
+
+static inline unsigned int xfs_inode_data_fork_size(struct xfs_inode *ip)
+{
+       if (xfs_inode_has_attr_fork(ip))
+               return xfs_inode_fork_boff(ip);
+
+       return XFS_LITINO(ip->i_mount);
+}
+
+static inline unsigned int xfs_inode_attr_fork_size(struct xfs_inode *ip)
+{
+       if (xfs_inode_has_attr_fork(ip))
+               return XFS_LITINO(ip->i_mount) - xfs_inode_fork_boff(ip);
+       return 0;
+}
+
+static inline unsigned int
+xfs_inode_fork_size(
+       struct xfs_inode        *ip,
+       int                     whichfork)
+{
+       switch (whichfork) {
+       case XFS_DATA_FORK:
+               return xfs_inode_data_fork_size(ip);
+       case XFS_ATTR_FORK:
+               return xfs_inode_attr_fork_size(ip);
+       default:
+               return 0;
+       }
+}
+
 /* Convert from vfs inode to xfs inode */
 static inline struct xfs_inode *XFS_I(struct inode *inode)
 {
@@ -94,9 +296,9 @@ static inline xfs_fsize_t XFS_ISIZE(struct xfs_inode *ip)
 {
        if (XFS_ISREG(ip))
                return ip->i_size;
-       return ip->i_d.di_size;
+       return ip->i_disk_size;
 }
-#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME)
+#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_diflags & XFS_DIFLAG_REALTIME)
 
 /* inode link counts */
 static inline void set_nlink(struct inode *inode, uint32_t nlink)
@@ -108,38 +310,30 @@ static inline void inc_nlink(struct inode *inode)
        inode->i_nlink++;
 }
 
-/*
- * Project quota id helpers (previously projid was 16bit only and using two
- * 16bit values to hold new 32bit projid was chosen to retain compatibility with
- * "old" filesystems).
- *
- * Copied here from xfs_inode.h because it has to be defined after the struct
- * xfs_inode...
- */
-static inline prid_t
-xfs_get_projid(struct xfs_icdinode *id)
+static inline bool xfs_is_reflink_inode(struct xfs_inode *ip)
 {
-       return (prid_t)id->di_projid_hi << 16 | id->di_projid_lo;
+       return ip->i_diflags2 & XFS_DIFLAG2_REFLINK;
 }
 
-static inline void
-xfs_set_projid(struct xfs_icdinode *id, prid_t projid)
+static inline bool xfs_inode_has_bigtime(struct xfs_inode *ip)
 {
-       id->di_projid_hi = (uint16_t) (projid >> 16);
-       id->di_projid_lo = (uint16_t) (projid & 0xffff);
+       return ip->i_diflags2 & XFS_DIFLAG2_BIGTIME;
 }
 
-static inline bool xfs_is_reflink_inode(struct xfs_inode *ip)
+static inline bool xfs_inode_has_large_extent_counts(struct xfs_inode *ip)
 {
-       return ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK;
+       return ip->i_diflags2 & XFS_DIFLAG2_NREXT64;
 }
 
-typedef struct cred {
-       uid_t   cr_uid;
-       gid_t   cr_gid;
-} cred_t;
+/* Always set the child's GID to this value, even if the parent is setgid. */
+#define CRED_FORCE_GID (1U << 0)
+struct cred {
+       uid_t           cr_uid;
+       gid_t           cr_gid;
+       unsigned int    cr_flags;
+};
 
-extern int     libxfs_inode_alloc (struct xfs_trans **, struct xfs_inode *,
+extern int     libxfs_dir_ialloc (struct xfs_trans **, struct xfs_inode *,
                                mode_t, nlink_t, xfs_dev_t, struct cred *,
                                struct fsxattr *, struct xfs_inode **);
 extern void    libxfs_trans_inode_alloc_buf (struct xfs_trans *,
@@ -150,13 +344,8 @@ extern void        libxfs_trans_ichgtime(struct xfs_trans *,
 extern int     libxfs_iflush_int (struct xfs_inode *, struct xfs_buf *);
 
 /* Inode Cache Interfaces */
-extern bool    libxfs_inode_verify_forks(struct xfs_inode *ip,
-                               struct xfs_ifork_ops *);
 extern int     libxfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
-                               uint, struct xfs_inode **,
-                               struct xfs_ifork_ops *);
-extern void    libxfs_iput(struct xfs_inode *);
-
-#define IRELE(ip) libxfs_iput(ip)
+                               uint, struct xfs_inode **);
+extern void    libxfs_irele(struct xfs_inode *ip);
 
 #endif /* __XFS_INODE_H__ */