struct xfs_trans;
struct xfs_mount;
struct xfs_inode_log_item;
+struct inode;
/*
* These are not actually used, they are only for userspace build
#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)
/*
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)
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 */
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 */
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)
{
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)
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 *,
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 **);