#ifndef __XFS_DINODE_H__
#define __XFS_DINODE_H__
-struct xfs_buf;
-struct xfs_mount;
+#define XFS_DINODE_MAGIC 0x494e /* 'IN' */
+#define XFS_DINODE_GOOD_VERSION(v) (((v) == 1 || (v) == 2))
-#define XFS_DINODE_VERSION_1 1
-#define XFS_DINODE_VERSION_2 2
-#define XFS_DINODE_GOOD_VERSION(v) \
- (((v) == XFS_DINODE_VERSION_1 || (v) == XFS_DINODE_VERSION_2))
-#define XFS_DINODE_MAGIC 0x494e /* 'IN' */
-
-/*
- * Disk inode structure.
- * This is just the header; the inode is expanded to fill a variable size
- * with the last field expanding. It is split into the core and "other"
- * because we only need the core part in the in-core inode.
- */
typedef struct xfs_timestamp {
- __int32_t t_sec; /* timestamp seconds */
- __int32_t t_nsec; /* timestamp nanoseconds */
+ __be32 t_sec; /* timestamp seconds */
+ __be32 t_nsec; /* timestamp nanoseconds */
} xfs_timestamp_t;
/*
- * Note: Coordinate changes to this structure with the XFS_DI_* #defines
- * below and the offsets table in xfs_ialloc_log_di().
+ * On-disk inode structure.
+ *
+ * This is just the header or "dinode core", the inode is expanded to fill a
+ * variable size the leftover area split into a data and an attribute fork.
+ * The format of the data and attribute fork depends on the format of the
+ * inode as indicated by di_format and di_aformat. To access the data and
+ * attribute use the XFS_DFORK_PTR, XFS_DFORK_DPTR, and XFS_DFORK_PTR macros
+ * below.
+ *
+ * There is a very similar struct icdinode in xfs_inode which matches the
+ * layout of the first 96 bytes of this structure, but is kept in native
+ * format instead of big endian.
*/
-typedef struct xfs_dinode_core
-{
- __uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */
- __uint16_t di_mode; /* mode and type of file */
- __int8_t di_version; /* inode version */
- __int8_t di_format; /* format of di_c data */
- __uint16_t di_onlink; /* old number of links to file */
- __uint32_t di_uid; /* owner's user id */
- __uint32_t di_gid; /* owner's group id */
- __uint32_t di_nlink; /* number of links to file */
- __uint16_t di_projid; /* owner's project id */
- __uint8_t di_pad[8]; /* unused, zeroed space */
- __uint16_t di_flushiter; /* incremented on flush */
+typedef struct xfs_dinode {
+ __be16 di_magic; /* inode magic # = XFS_DINODE_MAGIC */
+ __be16 di_mode; /* mode and type of file */
+ __u8 di_version; /* inode version */
+ __u8 di_format; /* format of di_c data */
+ __be16 di_onlink; /* old number of links to file */
+ __be32 di_uid; /* owner's user id */
+ __be32 di_gid; /* owner's group id */
+ __be32 di_nlink; /* number of links to file */
+ __be16 di_projid; /* owner's project id */
+ __u8 di_pad[8]; /* unused, zeroed space */
+ __be16 di_flushiter; /* incremented on flush */
xfs_timestamp_t di_atime; /* time last accessed */
xfs_timestamp_t di_mtime; /* time last modified */
xfs_timestamp_t di_ctime; /* time created/inode modified */
- xfs_fsize_t di_size; /* number of bytes in file */
- xfs_drfsbno_t di_nblocks; /* # of direct & btree blocks used */
- xfs_extlen_t di_extsize; /* basic/minimum extent size for file */
- xfs_extnum_t di_nextents; /* number of extents in data fork */
- xfs_aextnum_t di_anextents; /* number of extents in attribute fork*/
- __uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */
- __int8_t di_aformat; /* format of attr fork's data */
- __uint32_t di_dmevmask; /* DMIG event mask */
- __uint16_t di_dmstate; /* DMIG state info */
- __uint16_t di_flags; /* random flags, XFS_DIFLAG_... */
- __uint32_t di_gen; /* generation number */
-} xfs_dinode_core_t;
+ __be64 di_size; /* number of bytes in file */
+ __be64 di_nblocks; /* # of direct & btree blocks used */
+ __be32 di_extsize; /* basic/minimum extent size for file */
+ __be32 di_nextents; /* number of extents in data fork */
+ __be16 di_anextents; /* number of extents in attribute fork*/
+ __u8 di_forkoff; /* attr fork offs, <<3 for 64b align */
+ __s8 di_aformat; /* format of attr fork's data */
+ __be32 di_dmevmask; /* DMIG event mask */
+ __be16 di_dmstate; /* DMIG state info */
+ __be16 di_flags; /* random flags, XFS_DIFLAG_... */
+ __be32 di_gen; /* generation number */
+
+ /* di_next_unlinked is the only non-core field in the old dinode */
+ __be32 di_next_unlinked;/* agi unlinked list ptr */
+} __attribute__((packed)) xfs_dinode_t;
#define DI_MAX_FLUSH 0xffff
-typedef struct xfs_dinode
-{
- xfs_dinode_core_t di_core;
- /*
- * In adding anything between the core and the union, be
- * sure to update the macros like XFS_LITINO below and
- * XFS_BMAP_RBLOCK_DSIZE in xfs_bmap_btree.h.
- */
- xfs_agino_t di_next_unlinked;/* agi unlinked list ptr */
- union {
- xfs_bmdr_block_t di_bmbt; /* btree root block */
- xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */
- xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */
- char di_c[1]; /* local contents */
- xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */
- uuid_t di_muuid; /* mount point value */
- char di_symlink[1]; /* local symbolic link */
- } di_u;
- union {
- xfs_bmdr_block_t di_abmbt; /* btree root block */
- xfs_bmbt_rec_32_t di_abmx[1]; /* extent list */
- xfs_attr_shortform_t di_attrsf; /* shortform attribute list */
- } di_a;
-} xfs_dinode_t;
-
/*
* The 32 bit link count in the inode theoretically maxes out at UINT_MAX.
* Since the pathconf interface is signed, we use 2^31 - 1 instead.
#define XFS_MAXLINK ((1U << 31) - 1U)
#define XFS_MAXLINK_1 65535U
-/*
- * Bit names for logging disk inodes only
- */
-#define XFS_DI_MAGIC 0x0000001
-#define XFS_DI_MODE 0x0000002
-#define XFS_DI_VERSION 0x0000004
-#define XFS_DI_FORMAT 0x0000008
-#define XFS_DI_ONLINK 0x0000010
-#define XFS_DI_UID 0x0000020
-#define XFS_DI_GID 0x0000040
-#define XFS_DI_NLINK 0x0000080
-#define XFS_DI_PROJID 0x0000100
-#define XFS_DI_PAD 0x0000200
-#define XFS_DI_ATIME 0x0000400
-#define XFS_DI_MTIME 0x0000800
-#define XFS_DI_CTIME 0x0001000
-#define XFS_DI_SIZE 0x0002000
-#define XFS_DI_NBLOCKS 0x0004000
-#define XFS_DI_EXTSIZE 0x0008000
-#define XFS_DI_NEXTENTS 0x0010000
-#define XFS_DI_NAEXTENTS 0x0020000
-#define XFS_DI_FORKOFF 0x0040000
-#define XFS_DI_AFORMAT 0x0080000
-#define XFS_DI_DMEVMASK 0x0100000
-#define XFS_DI_DMSTATE 0x0200000
-#define XFS_DI_FLAGS 0x0400000
-#define XFS_DI_GEN 0x0800000
-#define XFS_DI_NEXT_UNLINKED 0x1000000
-#define XFS_DI_U 0x2000000
-#define XFS_DI_A 0x4000000
-#define XFS_DI_NUM_BITS 27
-#define XFS_DI_ALL_BITS ((1 << XFS_DI_NUM_BITS) - 1)
-#define XFS_DI_CORE_BITS (XFS_DI_ALL_BITS & ~(XFS_DI_U|XFS_DI_A))
-
/*
* Values for di_format
*/
-typedef enum xfs_dinode_fmt
-{
- XFS_DINODE_FMT_DEV, /* CHR, BLK: di_dev */
- XFS_DINODE_FMT_LOCAL, /* DIR, REG: di_c */
- /* LNK: di_symlink */
- XFS_DINODE_FMT_EXTENTS, /* DIR, REG, LNK: di_bmx */
- XFS_DINODE_FMT_BTREE, /* DIR, REG, LNK: di_bmbt */
- XFS_DINODE_FMT_UUID /* MNT: di_uuid */
+typedef enum xfs_dinode_fmt {
+ XFS_DINODE_FMT_DEV, /* xfs_dev_t */
+ XFS_DINODE_FMT_LOCAL, /* bulk data */
+ XFS_DINODE_FMT_EXTENTS, /* struct xfs_bmbt_rec */
+ XFS_DINODE_FMT_BTREE, /* struct xfs_bmdr_block */
+ XFS_DINODE_FMT_UUID /* uuid_t */
} xfs_dinode_fmt_t;
/*
*/
#define XFS_LITINO(mp) ((mp)->m_litino)
#define XFS_BROOT_SIZE_ADJ \
- (sizeof(xfs_bmbt_block_t) - sizeof(xfs_bmdr_block_t))
+ (XFS_BTREE_LBLOCK_LEN - sizeof(xfs_bmdr_block_t))
/*
* Inode data & attribute fork sizes, per inode.
*/
-#define XFS_CFORK_Q(dcp) ((dcp)->di_forkoff != 0)
-#define XFS_CFORK_Q_DISK(dcp) ((dcp)->di_forkoff != 0)
-
-#define XFS_CFORK_BOFF(dcp) ((int)((dcp)->di_forkoff << 3))
-#define XFS_CFORK_BOFF_DISK(dcp) \
- ((int)(INT_GET((dcp)->di_forkoff, ARCH_CONVERT) << 3))
-
-#define XFS_CFORK_DSIZE_DISK(dcp,mp) \
- (XFS_CFORK_Q_DISK(dcp) ? XFS_CFORK_BOFF_DISK(dcp) : XFS_LITINO(mp))
-#define XFS_CFORK_DSIZE(dcp,mp) \
- (XFS_CFORK_Q(dcp) ? XFS_CFORK_BOFF(dcp) : XFS_LITINO(mp))
-
-#define XFS_CFORK_ASIZE_DISK(dcp,mp) \
- (XFS_CFORK_Q_DISK(dcp) ? XFS_LITINO(mp) - XFS_CFORK_BOFF_DISK(dcp) : 0)
-#define XFS_CFORK_ASIZE(dcp,mp) \
- (XFS_CFORK_Q(dcp) ? XFS_LITINO(mp) - XFS_CFORK_BOFF(dcp) : 0)
-
-#define XFS_CFORK_SIZE_DISK(dcp,mp,w) \
- ((w) == XFS_DATA_FORK ? \
- XFS_CFORK_DSIZE_DISK(dcp, mp) : \
- XFS_CFORK_ASIZE_DISK(dcp, mp))
-#define XFS_CFORK_SIZE(dcp,mp,w) \
- ((w) == XFS_DATA_FORK ? \
- XFS_CFORK_DSIZE(dcp, mp) : XFS_CFORK_ASIZE(dcp, mp))
+#define XFS_DFORK_Q(dip) ((dip)->di_forkoff != 0)
+#define XFS_DFORK_BOFF(dip) ((int)((dip)->di_forkoff << 3))
#define XFS_DFORK_DSIZE(dip,mp) \
- XFS_CFORK_DSIZE_DISK(&(dip)->di_core, mp)
-#define XFS_DFORK_DSIZE_HOST(dip,mp) \
- XFS_CFORK_DSIZE(&(dip)->di_core, mp)
+ (XFS_DFORK_Q(dip) ? \
+ XFS_DFORK_BOFF(dip) : \
+ XFS_LITINO(mp))
#define XFS_DFORK_ASIZE(dip,mp) \
- XFS_CFORK_ASIZE_DISK(&(dip)->di_core, mp)
-#define XFS_DFORK_ASIZE_HOST(dip,mp) \
- XFS_CFORK_ASIZE(&(dip)->di_core, mp)
-#define XFS_DFORK_SIZE(dip,mp,w) \
- XFS_CFORK_SIZE_DISK(&(dip)->di_core, mp, w)
-#define XFS_DFORK_SIZE_HOST(dip,mp,w) \
- XFS_CFORK_SIZE(&(dip)->di_core, mp, w)
+ (XFS_DFORK_Q(dip) ? \
+ XFS_LITINO(mp) - XFS_DFORK_BOFF(dip) : \
+ 0)
+#define XFS_DFORK_SIZE(dip,mp,w) \
+ ((w) == XFS_DATA_FORK ? \
+ XFS_DFORK_DSIZE(dip, mp) : \
+ XFS_DFORK_ASIZE(dip, mp))
-#define XFS_DFORK_Q(dip) XFS_CFORK_Q_DISK(&(dip)->di_core)
-#define XFS_DFORK_BOFF(dip) XFS_CFORK_BOFF_DISK(&(dip)->di_core)
-#define XFS_DFORK_DPTR(dip) ((dip)->di_u.di_c)
-#define XFS_DFORK_APTR(dip) \
- ((dip)->di_u.di_c + XFS_DFORK_BOFF(dip))
-#define XFS_DFORK_PTR(dip,w) \
+/*
+ * Return pointers to the data or attribute forks.
+ */
+#define XFS_DFORK_DPTR(dip) \
+ ((char *)(dip) + sizeof(struct xfs_dinode))
+#define XFS_DFORK_APTR(dip) \
+ (XFS_DFORK_DPTR(dip) + XFS_DFORK_BOFF(dip))
+#define XFS_DFORK_PTR(dip,w) \
((w) == XFS_DATA_FORK ? XFS_DFORK_DPTR(dip) : XFS_DFORK_APTR(dip))
-#define XFS_CFORK_FORMAT(dcp,w) \
- ((w) == XFS_DATA_FORK ? (dcp)->di_format : (dcp)->di_aformat)
-#define XFS_CFORK_FMT_SET(dcp,w,n) \
- ((w) == XFS_DATA_FORK ? \
- ((dcp)->di_format = (n)) : ((dcp)->di_aformat = (n)))
-#define XFS_DFORK_FORMAT(dip,w) XFS_CFORK_FORMAT(&(dip)->di_core, w)
-#define XFS_CFORK_NEXTENTS_DISK(dcp,w) \
+#define XFS_DFORK_FORMAT(dip,w) \
((w) == XFS_DATA_FORK ? \
- INT_GET((dcp)->di_nextents, ARCH_CONVERT) : \
- INT_GET((dcp)->di_anextents, ARCH_CONVERT))
-#define XFS_CFORK_NEXTENTS(dcp,w) \
- ((w) == XFS_DATA_FORK ? (dcp)->di_nextents : (dcp)->di_anextents)
-#define XFS_DFORK_NEXTENTS(dip,w) XFS_CFORK_NEXTENTS_DISK(&(dip)->di_core, w)
-#define XFS_DFORK_NEXTENTS_HOST(dip,w) XFS_CFORK_NEXTENTS(&(dip)->di_core, w)
-
-#define XFS_CFORK_NEXT_SET(dcp,w,n) \
+ (dip)->di_format : \
+ (dip)->di_aformat)
+#define XFS_DFORK_NEXTENTS(dip,w) \
((w) == XFS_DATA_FORK ? \
- ((dcp)->di_nextents = (n)) : ((dcp)->di_anextents = (n)))
+ be32_to_cpu((dip)->di_nextents) : \
+ be16_to_cpu((dip)->di_anextents))
#define XFS_BUF_TO_DINODE(bp) ((xfs_dinode_t *)XFS_BUF_PTR(bp))
+/*
+ * For block and character special files the 32bit dev_t is stored at the
+ * beginning of the data fork.
+ */
+static inline xfs_dev_t xfs_dinode_get_rdev(struct xfs_dinode *dip)
+{
+ return be32_to_cpu(*(__be32 *)XFS_DFORK_DPTR(dip));
+}
+
+static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev)
+{
+ *(__be32 *)XFS_DFORK_DPTR(dip) = cpu_to_be32(rdev);
+}
+
/*
* Values for di_flags
* There should be a one-to-one correspondence between these flags and the
#define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT)
#define XFS_DIFLAG_FILESTREAM (1 << XFS_DIFLAG_FILESTREAM_BIT)
+#ifdef CONFIG_XFS_RT
+#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME)
+#else
+#define XFS_IS_REALTIME_INODE(ip) (0)
+#endif
+
#define XFS_DIFLAG_ANY \
(XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \