Skip to contentSkip to conversation

kill xfs_dinode_core_t

PATCH In review Christoph Hellwig 2 participants 3 messages Oct 7, 2008 – Oct 8, 2008 XFS filesystem

lore
Share & tools
lore
#0 lore raw

PATCH 3/3 kill xfs_dinode_core_t

No that we have a separate xfs_icdinode_t for the in-core inode that get's logged there's absolutely no reason for the xfs_dinode vs xfs_dinode_core split - the fact that part of the structure gets logged through the inode log item and a small part not can better be described in a comment. The few places that uses sizeof() on the dinode_core are replaced with macros that also prepare for the variable size inode core we'll need for adding checksums to the inodes.

Removing the data and attribute fork unions also has the advantage that xfs_dinode.h doesn't need to pull in every header under the sun.

While we're at it also add some more comments describing the dinode structure.

fs/xfs/dmapi/xfs_dm.c +9 -11
Index: linux-2.6-xfs/fs/xfs/dmapi/xfs_dm.c
===================================================================
@@ -303,7 +303,7 @@ STATIC uint
 xfs_dic2dmflags(
 	xfs_dinode_t	*dip)
 {
-	return _xfs_dic2dmflags(be16_to_cpu(dip->di_core.di_flags)) |
+	return _xfs_dic2dmflags(be16_to_cpu(dip->di_flags)) |
 			(XFS_DFORK_Q(dip) ? DM_XFLAG_HASATTR : 0);
 }
 
@@ -317,11 +317,9 @@ STATIC void
 xfs_dip_to_stat(
 	xfs_mount_t		*mp,
 	xfs_ino_t		ino,
-	xfs_dinode_t		*dip,
+	xfs_dinode_t		*dic,
 	dm_stat_t		*buf)
 {
-	xfs_dinode_core_t	*dic = &dip->di_core;
-
 	/*
 	 * The inode format changed when we moved the link count and
 	 * made it 32 bits long.  If this is an old format inode,
@@ -349,7 +347,7 @@ xfs_dip_to_stat(
 	buf->dt_atime = be32_to_cpu(dic->di_atime.t_sec);
 	buf->dt_mtime = be32_to_cpu(dic->di_mtime.t_sec);
 	buf->dt_ctime = be32_to_cpu(dic->di_ctime.t_sec);
-	buf->dt_xfs_xflags = xfs_dic2dmflags(dip);
+	buf->dt_xfs_xflags = xfs_dic2dmflags(dic);
 	buf->dt_xfs_extsize =
 		be32_to_cpu(dic->di_extsize) << mp->m_sb.sb_blocklog;
 	buf->dt_xfs_extents = be32_to_cpu(dic->di_nextents);
@@ -359,7 +357,7 @@ xfs_dip_to_stat(
 
 	switch (dic->di_format) {
 	case XFS_DINODE_FMT_DEV:
-		buf->dt_rdev = be32_to_cpu(dip->di_u.di_dev);
+		buf->dt_rdev = be32_to_cpu(*(__be32 *)XFS_DFORK_DPTR(mp, dic));
 		buf->dt_blksize = BLKDEV_IOSIZE;
 		buf->dt_blocks = 0;
 		break;
@@ -543,14 +541,14 @@ xfs_dm_inline_attr(
 	caddr_t		attr_buf,
 	int		*value_lenp)
 {
-	if (dip->di_core.di_aformat == XFS_DINODE_FMT_LOCAL) {
+	if (dip->di_aformat == XFS_DINODE_FMT_LOCAL) {
 		xfs_attr_shortform_t	*sf;
 		xfs_attr_sf_entry_t	*sfe;
 		unsigned int		namelen = strlen(attr_name);
 		unsigned int		valuelen = *value_lenp;
 		int			i;
 
-		sf = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip);
+		sf = (xfs_attr_shortform_t *)XFS_DFORK_APTR(mp, dip);
 		sfe = &sf->list[0];
 		for (i = 0; i < sf->hdr.count;
 				sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
@@ -585,7 +583,7 @@ dm_dip_to_handle(
 	fid.dm_fid_len = sizeof(struct dm_fid) - sizeof(fid.dm_fid_len);
 	fid.dm_fid_pad = 0;
 	fid.dm_fid_ino = ino;
-	fid.dm_fid_gen = be32_to_cpu(dip->di_core.di_gen);
+	fid.dm_fid_gen = be32_to_cpu(dip->di_gen);
 
 	memcpy(&handlep->ha_fsid, fsid, sizeof(*fsid));
 	memcpy(&handlep->ha_fid, &fid, fid.dm_fid_len + sizeof(fid.dm_fid_len));
@@ -610,7 +608,7 @@ xfs_dm_bulkall_inline_one(
 	int		value_len = *value_lenp;
 	int		error;
 
-	if (dip->di_core.di_mode == 0)
+	if (dip->di_mode == 0)
 		return ENOENT;
 
 	xfs_dip_to_stat(mp, ino, dip, &xbuf->dx_statinfo);
@@ -782,7 +780,7 @@ xfs_dm_bulkattr_inline_one(
 {
 	dm_handle_t	handle;
 
-	if (dip->di_core.di_mode == 0)
+	if (dip->di_mode == 0)
 		return ENOENT;
 	xfs_dip_to_stat(mp, ino, dip, sbuf);
 	dm_dip_to_handle(ino, dip, fsid, &handle);
fs/xfs/xfs_dinode.h +45 -54

154 lines not on this page · raw message

fs/xfs/xfs_inode.c +54 -49

280 lines not on this page · raw message

fs/xfs/xfs_log_recover.c +18 -16
Index: linux-2.6-xfs/fs/xfs/xfs_log_recover.c
===================================================================
@@ -2316,7 +2316,7 @@ xlog_recover_do_inode_trans(
 	 * Make sure the place we're flushing out to really looks
 	 * like an inode!
 	 */
-	if (unlikely(be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC)) {
+	if (unlikely(be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC)) {
 		xfs_buf_relse(bp);
 		xfs_fs_cmn_err(CE_ALERT, mp,
 			"xfs_inode_recover: Bad inode magic number, dino ptr = 0x%p, dino bp = 0x%p, ino = %Ld",
@@ -2339,12 +2339,12 @@ xlog_recover_do_inode_trans(
 	}
 
 	/* Skip replay when the on disk inode is newer than the log one */
-	if (dicp->di_flushiter < be16_to_cpu(dip->di_core.di_flushiter)) {
+	if (dicp->di_flushiter < be16_to_cpu(dip->di_flushiter)) {
 		/*
 		 * Deal with the wrap case, DI_MAX_FLUSH is less
 		 * than smaller numbers
 		 */
-		if (be16_to_cpu(dip->di_core.di_flushiter) == DI_MAX_FLUSH &&
+		if (be16_to_cpu(dip->di_flushiter) == DI_MAX_FLUSH &&
 		    dicp->di_flushiter < (DI_MAX_FLUSH >> 1)) {
 			/* do nothing */
 		} else {
@@ -2404,7 +2404,7 @@ xlog_recover_do_inode_trans(
 		error = EFSCORRUPTED;
 		goto error;
 	}
-	if (unlikely(item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t))) {
+	if (unlikely(item->ri_buf[1].i_len > XFS_DINODE_CORE_SIZE(mp))) {
 		XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)",
 				     XFS_ERRLEVEL_LOW, mp, dicp);
 		xfs_buf_relse(bp);
@@ -2416,23 +2416,25 @@ xlog_recover_do_inode_trans(
 	}
 
 	/* The core is in in-core format */
-	xfs_dinode_to_disk(&dip->di_core,
-		(xfs_icdinode_t *)item->ri_buf[1].i_addr);
+	xfs_dinode_to_disk(dip, (xfs_icdinode_t *)item->ri_buf[1].i_addr);
 
 	/* the rest is in on-disk format */
-	if (item->ri_buf[1].i_len > sizeof(xfs_dinode_core_t)) {
-		memcpy((xfs_caddr_t) dip + sizeof(xfs_dinode_core_t),
-			item->ri_buf[1].i_addr + sizeof(xfs_dinode_core_t),
-			item->ri_buf[1].i_len  - sizeof(xfs_dinode_core_t));
+	if (item->ri_buf[1].i_len > XFS_DINODE_CORE_SIZE(mp)) {
+		memcpy((xfs_caddr_t) dip + XFS_DINODE_CORE_SIZE(mp),
+			item->ri_buf[1].i_addr + XFS_DINODE_CORE_SIZE(mp),
+			item->ri_buf[1].i_len  - XFS_DINODE_CORE_SIZE(mp));
 	}
 
 	fields = in_f->ilf_fields;
 	switch (fields & (XFS_ILOG_DEV | XFS_ILOG_UUID)) {
 	case XFS_ILOG_DEV:
-		dip->di_u.di_dev = cpu_to_be32(in_f->ilf_u.ilfu_rdev);
+		*(__u32 *)XFS_DFORK_DPTR(mp, dip) =
+			cpu_to_be32(in_f->ilf_u.ilfu_rdev);
 		break;
 	case XFS_ILOG_UUID:
-		dip->di_u.di_muuid = in_f->ilf_u.ilfu_uuid;
+		memcpy(XFS_DFORK_DPTR(mp, dip),
+		       &in_f->ilf_u.ilfu_uuid,
+		       sizeof(uuid_t));
 		break;
 	}
 
@@ -2448,12 +2450,12 @@ xlog_recover_do_inode_trans(
 	switch (fields & XFS_ILOG_DFORK) {
 	case XFS_ILOG_DDATA:
 	case XFS_ILOG_DEXT:
-		memcpy(&dip->di_u, src, len);
+		memcpy(XFS_DFORK_DPTR(mp, dip), src, len);
 		break;
 
 	case XFS_ILOG_DBROOT:
 		xfs_bmbt_to_bmdr(mp, (struct xfs_btree_block *)src, len,
-				 &dip->di_u.di_bmbt,
+				 (xfs_bmdr_block_t *)XFS_DFORK_DPTR(mp, dip),
 				 XFS_DFORK_DSIZE(dip, mp));
 		break;
 
@@ -2483,13 +2485,13 @@ xlog_recover_do_inode_trans(
 		switch (in_f->ilf_fields & XFS_ILOG_AFORK) {
 		case XFS_ILOG_ADATA:
 		case XFS_ILOG_AEXT:
-			dest = XFS_DFORK_APTR(dip);
+			dest = XFS_DFORK_APTR(mp, dip);
 			ASSERT(len <= XFS_DFORK_ASIZE(dip, mp));
 			memcpy(dest, src, len);
 			break;
 
 		case XFS_ILOG_ABROOT:
-			dest = XFS_DFORK_APTR(dip);
+			dest = XFS_DFORK_APTR(mp, dip);
 			xfs_bmbt_to_bmdr(mp, (struct xfs_btree_block *)src,
 					 len, (xfs_bmdr_block_t*)dest,
 					 XFS_DFORK_ASIZE(dip, mp));
fs/xfs/xfs_inode.h +3 -4
Index: linux-2.6-xfs/fs/xfs/xfs_inode.h
===================================================================
@@ -19,7 +19,6 @@
 #define	__XFS_INODE_H__
 
 struct xfs_dinode;
-struct xfs_dinode_core;
 struct xfs_inode;
 
 /*
@@ -112,7 +111,7 @@ typedef struct xfs_ictimestamp {
 } xfs_ictimestamp_t;
 
 /*
- * NOTE:  This structure must be kept identical to struct xfs_dinode_core
+ * NOTE:  This structure must be kept identical to struct xfs_dinode
  * 	  in xfs_dinode.h except for the endianess annotations.
  */
 typedef struct xfs_icdinode {
@@ -539,8 +538,8 @@ int		xfs_itobp(struct xfs_mount *, struc
 			  struct xfs_inode *, struct xfs_dinode **,
 			  struct xfs_buf **, xfs_daddr_t, uint, uint);
 void		xfs_dinode_from_disk(struct xfs_icdinode *,
-				     struct xfs_dinode_core *);
-void		xfs_dinode_to_disk(struct xfs_dinode_core *,
+				     struct xfs_dinode *);
+void		xfs_dinode_to_disk(struct xfs_dinode *,
 				   struct xfs_icdinode *);
 void		xfs_idestroy_fork(struct xfs_inode *, int);
 void		xfs_idata_realloc(struct xfs_inode *, int, int);
fs/xfs/xfs_itable.c +8 -12
Index: linux-2.6-xfs/fs/xfs/xfs_itable.c
===================================================================
@@ -125,13 +125,9 @@ STATIC void
 xfs_bulkstat_one_dinode(
 	xfs_mount_t	*mp,		/* mount point for filesystem */
 	xfs_ino_t	ino,		/* inode number to get data for */
-	xfs_dinode_t	*dip,		/* dinode inode pointer */
+	xfs_dinode_t	*dic,		/* dinode inode pointer */
 	xfs_bstat_t	*buf)		/* return buffer */
 {
-	xfs_dinode_core_t *dic;		/* dinode core info pointer */
-
-	dic = &dip->di_core;
-
 	/*
 	 * The inode format changed when we moved the link count and
 	 * made it 32 bits long.  If this is an old format inode,
@@ -162,7 +158,7 @@ xfs_bulkstat_one_dinode(
 	buf->bs_mtime.tv_nsec = be32_to_cpu(dic->di_mtime.t_nsec);
 	buf->bs_ctime.tv_sec = be32_to_cpu(dic->di_ctime.t_sec);
 	buf->bs_ctime.tv_nsec = be32_to_cpu(dic->di_ctime.t_nsec);
-	buf->bs_xflags = xfs_dic2xflags(dip);
+	buf->bs_xflags = xfs_dic2xflags(dic);
 	buf->bs_extsize = be32_to_cpu(dic->di_extsize) << mp->m_sb.sb_blocklog;
 	buf->bs_extents = be32_to_cpu(dic->di_nextents);
 	buf->bs_gen = be32_to_cpu(dic->di_gen);
@@ -173,7 +169,7 @@ xfs_bulkstat_one_dinode(
 
 	switch (dic->di_format) {
 	case XFS_DINODE_FMT_DEV:
-		buf->bs_rdev = be32_to_cpu(dip->di_u.di_dev);
+		buf->bs_rdev = be32_to_cpu(*(__be32 *)XFS_DFORK_DPTR(mp, dic));
 		buf->bs_blksize = BLKDEV_IOSIZE;
 		buf->bs_blocks = 0;
 		break;
@@ -287,19 +283,19 @@ xfs_bulkstat_use_dinode(
 	 * to disk yet. This is a temporary hack that would require a proper
 	 * fix in the future.
 	 */
-	if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC ||
-	    !XFS_DINODE_GOOD_VERSION(dip->di_core.di_version) ||
-	    !dip->di_core.di_mode)
+	if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC ||
+	    !XFS_DINODE_GOOD_VERSION(dip->di_version) ||
+	    !dip->di_mode)
 		return 0;
 	if (flags & BULKSTAT_FG_QUICK) {
 		*dipp = dip;
 		return 1;
 	}
 	/* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */
-	aformat = dip->di_core.di_aformat;
+	aformat = dip->di_aformat;
 	if ((XFS_DFORK_Q(dip) == 0) ||
 	    (aformat == XFS_DINODE_FMT_LOCAL) ||
-	    (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_core.di_anextents)) {
+	    (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_anextents)) {
 		*dipp = dip;
 		return 1;
 	}
fs/xfs/xfs_dir2_sf.h +0 -7
Index: linux-2.6-xfs/fs/xfs/xfs_dir2_sf.h
===================================================================
@@ -34,13 +34,6 @@ struct xfs_mount;
 struct xfs_trans;
 
 /*
- * Maximum size of a shortform directory.
- */
-#define	XFS_DIR2_SF_MAX_SIZE	\
-	(XFS_DINODE_MAX_SIZE - (uint)sizeof(xfs_dinode_core_t) - \
-	 (uint)sizeof(xfs_agino_t))
-
-/*
  * Inode number stored as 8 8-bit values.
  */
 typedef	struct { __uint8_t i[8]; } xfs_dir2_ino8_t;
fs/xfs/xfs_ialloc.c +4 -4
Index: linux-2.6-xfs/fs/xfs/xfs_ialloc.c
===================================================================
@@ -355,12 +355,12 @@ xfs_ialloc_ag_alloc(
 		xfs_biozero(fbuf, 0, ninodes << args.mp->m_sb.sb_inodelog);
 		for (i = 0; i < ninodes; i++) {
 			int	ioffset = i << args.mp->m_sb.sb_inodelog;
-			uint	isize = sizeof(xfs_dinode_t) + sizeof(__be32);
+			uint	isize = XFS_DINODE_SIZE(mp);
 
 			free = XFS_MAKE_IPTR(args.mp, fbuf, i);
-			free->di_core.di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
-			free->di_core.di_version = version;
-			free->di_core.di_gen = cpu_to_be32(gen);
+			free->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
+			free->di_version = version;
+			free->di_gen = cpu_to_be32(gen);
 			free->di_next_unlinked = cpu_to_be32(NULLAGINO);
 			xfs_trans_log_buf(tp, fbuf, ioffset, ioffset + isize - 1);
 		}
fs/xfs/xfs_inode_item.c +3 -2
Index: linux-2.6-xfs/fs/xfs/xfs_inode_item.c
===================================================================
@@ -280,8 +280,10 @@ xfs_inode_item_format(
 	 */
 	xfs_mark_inode_dirty_sync(ip);
 
+	mp = ip->i_mount;
+
 	vecp->i_addr = (xfs_caddr_t)&ip->i_d;
-	vecp->i_len  = sizeof(xfs_dinode_core_t);
+	vecp->i_len  = XFS_DINODE_CORE_SIZE(ip->i_mount);
 	XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ICORE);
 	vecp++;
 	nvecs++;
@@ -295,7 +297,6 @@ xfs_inode_item_format(
 	 * the old inode version number is there.  If the superblock already
 	 * has a new version number, then we don't bother converting back.
 	 */
-	mp = ip->i_mount;
 	ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1 ||
 	       xfs_sb_version_hasnlink(&mp->m_sb));
 	if (ip->i_d.di_version == XFS_DINODE_VERSION_1) {
fs/xfs/xfs_mount.c +1 -2
Index: linux-2.6-xfs/fs/xfs/xfs_mount.c
===================================================================
@@ -575,8 +575,7 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb
 	mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
 	mp->m_agno_log = xfs_highbit32(sbp->sb_agcount - 1) + 1;
 	mp->m_agino_log = sbp->sb_inopblog + sbp->sb_agblklog;
-	mp->m_litino = sbp->sb_inodesize -
-		((uint)sizeof(xfs_dinode_core_t) + (uint)sizeof(xfs_agino_t));
+	mp->m_litino = sbp->sb_inodesize - XFS_DINODE_SIZE(mp);
 	mp->m_blockmask = sbp->sb_blocksize - 1;
 	mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
 	mp->m_blockwmask = mp->m_blockwsize - 1;
fs/xfs/xfsidbg.c +6 -3
Index: linux-2.6-xfs/fs/xfs/xfsidbg.c
===================================================================
@@ -3625,19 +3625,22 @@ xfs_qoff_item_print(xfs_qoff_logitem_t *
 static void
 xfs_inodebuf(xfs_buf_t *bp)
 {
+	struct xfs_mount *mp;
 	xfs_dinode_t *di;
 	xfs_icdinode_t dic;
 	int n, i;
 
+	mp = XFS_BUF_FSPRIVATE3(bp, xfs_mount_t *);
 	n = XFS_BUF_COUNT(bp) >> 8;
 	for (i = 0; i < n; i++) {
 		di = (xfs_dinode_t *)xfs_buf_offset(bp,
 					i * 256);
 
-		xfs_dinode_from_disk(&dic, &di->di_core);
+		xfs_dinode_from_disk(&dic, di);
 		xfs_prdinode_incore(&dic);
 		kdb_printf("next_unlinked 0x%x u@0x%p\n",
-			   be32_to_cpu(di->di_next_unlinked), &di->di_u);
+			   be32_to_cpu(di->di_next_unlinked),
+			   XFS_DFORK_DPTR(mp, di));
 	}
 }
 
@@ -4846,7 +4849,7 @@ xfsidbg_xbuf_real(xfs_buf_t *bp, int sum
 			kdb_printf("buf 0x%p dir/attr node 0x%p\n", bp, node);
 			xfsidbg_xdanode(node);
 		}
-	} else if (be16_to_cpu((di = d)->di_core.di_magic) == XFS_DINODE_MAGIC) {
+	} else if (be16_to_cpu((di = d)->di_magic) == XFS_DINODE_MAGIC) {
 		if (summary) {
 			kdb_printf("Disk Inode (at 0x%p)\n", di);
 		} else {
#1 lore raw
Quoted 8 lines · Christoph Hellwig

No that we have a separate xfs_icdinode_t for the in-core inode that get's logged there's absolutely no reason for the xfs_dinode vs xfs_dinode_core split - the fact that part of the structure gets logged through the inode log item and a small part not can better be described in a comment. The few places that uses sizeof() on the dinode_core are replaced with macros that also prepare for the variable size inode core we'll need for adding checksums to the inodes.

Quoted 5 lines

Removing the data and attribute fork unions also has the advantage that xfs_dinode.h doesn't need to pull in every header under the sun.

While we're at it also add some more comments describing the dinode structure.

Nice. I haven't reviewed this fully yet, but a couple of things stand out:

fs/xfs/dmapi/xfs_dm.c xfs_dip_to_stat( · line 360

Quoted 6 lines
fs/xfs/dmapi/xfs_dm.c +1 -1
@@ -359,7 +357,7 @@ xfs_dip_to_stat(
 
 	switch (dic->di_format) {
 	case XFS_DINODE_FMT_DEV:
-		buf->dt_rdev = be32_to_cpu(dip->di_u.di_dev);
+		buf->dt_rdev = be32_to_cpu(*(__be32 *)XFS_DFORK_DPTR(mp, dic));

That's not particularly obvious where the rdev value is stored. Perhaps a comment indicating that it's a direct dereference out of the start of the data area in the inode?

fs/xfs/xfs_dinode.h line 39

Quoted 11 lines
fs/xfs/xfs_dinode.h +7 -3
 /*
- * Note: Coordinate changes to this structure with the XFS_DI_* #defines
- * below, the offsets table in xfs_ialloc_log_di() and struct xfs_icdinode
- * in xfs_inode.h.
+ * 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 macro:

macros

fs/xfs/xfs_dinode.h typedef struct xfs_dinode_core { · line 78

Quoted 2 lines
fs/xfs/xfs_dinode.h +2 -0
+#define XFS_DINODE_CORE_SIZE(mp)	(96)
+#define XFS_DINODE_SIZE(mp)		(96 + sizeof(__be32))

probably shouldn't hard-code the second "96" there. Perhaps the XFS_DINODE_SIZE() macro should be a sizeof(xfs_dinode_t)?

That's as far as I've looked....

Cheers,

Dave.

Signature · 2 lines
Dave Chinner
[email protected]
#2 lore raw
Quoted 8 lines · Dave Chinner

fs/xfs/dmapi/xfs_dm.c xfs_dip_to_stat( · line 360

Quoted 4 lines
fs/xfs/dmapi/xfs_dm.c +1 -1
 	switch (dic->di_format) {
 	case XFS_DINODE_FMT_DEV:
-		buf->dt_rdev = be32_to_cpu(dip->di_u.di_dev);
+		buf->dt_rdev = be32_to_cpu(*(__be32 *)XFS_DFORK_DPTR(mp, dic));

That's not particularly obvious where the rdev value is stored. Perhaps a comment indicating that it's a direct dereference out of the start of the data area in the inode?

Yeah. Or maybe I should add a nice accessor that does the casting and endianess conversion.

Quoted 5 lines

fs/xfs/xfs_dinode.h typedef struct xfs_dinode_core { · line 78

Quoted 2 lines
fs/xfs/xfs_dinode.h +2 -0
+#define XFS_DINODE_CORE_SIZE(mp)	(96)
+#define XFS_DINODE_SIZE(mp)		(96 + sizeof(__be32))

probably shouldn't hard-code the second "96" there. Perhaps the XFS_DINODE_SIZE() macro should be a sizeof(xfs_dinode_t)?

Well, that will change once xfs_dinode grows. But we could do it for now and then use offsetoff of the first new member for the old one.

I'll see if I can find a way to make this a little more clear.