]> 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 ef9700677f1a3c5ab043b37f6af32295bcef30ea..a351bb0d9040f155591faf163156cdd1efc4f593 100644 (file)
@@ -14,6 +14,7 @@
 struct xfs_trans;
 struct xfs_mount;
 struct xfs_inode_log_item;
+struct inode;
 
 /*
  * These are not actually used, they are only for userspace build
@@ -22,7 +23,7 @@ struct xfs_inode_log_item;
 #define I_DIRTY_TIME           0
 #define I_DIRTY_TIME_EXPIRED   0
 
-#define IS_I_VERSION(inode)                    (0)
+static inline bool IS_I_VERSION(const struct inode *inode) { return false; }
 #define inode_maybe_inc_iversion(inode,flags)  (0)
 
 /*
@@ -40,9 +41,10 @@ struct inode {
        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;
+       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)
@@ -67,15 +69,107 @@ 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_ifork        i_af;           /* attribute fork */
        struct xfs_inode_log_item *i_itemp;     /* logging information */
        unsigned int            i_delayed_blks; /* count of delay alloc blks */
        xfs_fsize_t             i_disk_size;    /* number of bytes in file */
@@ -88,7 +182,12 @@ typedef struct xfs_inode {
                uint16_t        i_flushiter;    /* incremented on flush */
        };
        uint8_t                 i_forkoff;      /* attr fork offset >> 3 */
-       struct xfs_icdinode     i_d;            /* most of ondisk inode */
+       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 */
@@ -97,6 +196,66 @@ typedef struct xfs_inode {
        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)
 {
@@ -139,7 +298,7 @@ static inline xfs_fsize_t XFS_ISIZE(struct xfs_inode *ip)
                return ip->i_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)
@@ -153,18 +312,26 @@ static inline void inc_nlink(struct inode *inode)
 
 static inline bool xfs_is_reflink_inode(struct xfs_inode *ip)
 {
-       return ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK;
+       return ip->i_diflags2 & XFS_DIFLAG2_REFLINK;
 }
 
 static inline bool xfs_inode_has_bigtime(struct xfs_inode *ip)
 {
-       return ip->i_d.di_flags2 & XFS_DIFLAG2_BIGTIME;
+       return ip->i_diflags2 & XFS_DIFLAG2_BIGTIME;
 }
 
-typedef struct cred {
-       uid_t   cr_uid;
-       gid_t   cr_gid;
-} cred_t;
+static inline bool xfs_inode_has_large_extent_counts(struct xfs_inode *ip)
+{
+       return ip->i_diflags2 & XFS_DIFLAG2_NREXT64;
+}
+
+/* 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_dir_ialloc (struct xfs_trans **, struct xfs_inode *,
                                mode_t, nlink_t, xfs_dev_t, struct cred *,
@@ -176,8 +343,6 @@ extern void libxfs_trans_ichgtime(struct xfs_trans *,
                                struct xfs_inode *, int);
 extern int     libxfs_iflush_int (struct xfs_inode *, struct xfs_buf *);
 
-extern struct timespec64 current_time(struct inode *inode);
-
 /* Inode Cache Interfaces */
 extern int     libxfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
                                uint, struct xfs_inode **);