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
* 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)
{
{
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)
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 *,
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__ */