dbprintf(_("dir %lld entry . %lld\n"), id->ino, id->ino);
(*dot)++;
sfe = xfs_dir2_sf_firstentry(&sf->hdr);
- offset = XFS_DIR2_DATA_FIRST_OFFSET;
+ offset = XFS_DIR3_DATA_FIRST_OFFSET(mp);
for (i = sf->hdr.count - 1, i8 = 0; i >= 0; i--) {
if ((__psint_t)sfe + xfs_dir2_sf_entsize(&sf->hdr,sfe->namelen) -
(__psint_t)sf > be64_to_cpu(dip->di_size)) {
#define XFS_DIR2_DATA_FIRSTDB(mp) \
xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET)
-/*
- * Offsets of . and .. in data space (always block 0)
- */
-#define XFS_DIR2_DATA_DOT_OFFSET \
- ((xfs_dir2_data_aoff_t)sizeof(struct xfs_dir2_data_hdr))
-#define XFS_DIR2_DATA_DOTDOT_OFFSET \
- (XFS_DIR2_DATA_DOT_OFFSET + xfs_dir2_data_entsize(1))
-#define XFS_DIR2_DATA_FIRST_OFFSET \
- (XFS_DIR2_DATA_DOTDOT_OFFSET + xfs_dir2_data_entsize(2))
-
/*
* Describe a free area in the data block.
*
/*
* Offsets of . and .. in data space (always block 0)
- */
+ *
+ * The macros are used for shortform directories as they have no headers to read
+ * the magic number out of. Shortform directories need to know the size of the
+ * data block header because the sfe embeds the block offset of the entry into
+ * it so that it doesn't change when format conversion occurs. Bad Things Happen
+ * if we don't follow this rule.
+ */
+#define XFS_DIR3_DATA_DOT_OFFSET(mp) \
+ xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&(mp)->m_sb))
+#define XFS_DIR3_DATA_DOTDOT_OFFSET(mp) \
+ (XFS_DIR3_DATA_DOT_OFFSET(mp) + xfs_dir2_data_entsize(1))
+#define XFS_DIR3_DATA_FIRST_OFFSET(mp) \
+ (XFS_DIR3_DATA_DOTDOT_OFFSET(mp) + xfs_dir2_data_entsize(2))
+
static inline xfs_dir2_data_aoff_t
xfs_dir3_data_dot_offset(struct xfs_dir2_data_hdr *hdr)
{
* to insert the new entry.
* If it's going to end up at the end then oldsfep will point there.
*/
- for (offset = XFS_DIR2_DATA_FIRST_OFFSET,
+ for (offset = XFS_DIR3_DATA_FIRST_OFFSET(dp->i_mount),
oldsfep = xfs_dir2_sf_firstentry(oldsfp),
add_datasize = xfs_dir2_data_entsize(args->namelen),
eof = (char *)oldsfep == &buf[old_isize];
sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
size = xfs_dir2_data_entsize(args->namelen);
- offset = XFS_DIR2_DATA_FIRST_OFFSET;
+ offset = XFS_DIR3_DATA_FIRST_OFFSET(mp);
sfep = xfs_dir2_sf_firstentry(sfp);
holefit = 0;
/*
dp = args->dp;
sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
- offset = XFS_DIR2_DATA_FIRST_OFFSET;
+ offset = XFS_DIR3_DATA_FIRST_OFFSET(dp->i_mount);
ino = xfs_dir2_sf_get_parent_ino(sfp);
i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
*/
static void
process_sf_dir2_fixoff(
+ xfs_mount_t *mp,
xfs_dinode_t *dip)
{
int i;
sfp = (xfs_dir2_sf_t *)XFS_DFORK_DPTR(dip);
sfep = xfs_dir2_sf_firstentry(&sfp->hdr);
- offset = XFS_DIR2_DATA_FIRST_OFFSET;
+ offset = XFS_DIR3_DATA_FIRST_OFFSET(mp);
for (i = 0; i < sfp->hdr.count; i++) {
xfs_dir2_sf_put_offset(sfep, offset);
max_size = XFS_DFORK_DSIZE(dip, mp);
num_entries = sfp->hdr.count;
ino_dir_size = be64_to_cpu(dip->di_size);
- offset = XFS_DIR2_DATA_FIRST_OFFSET;
+ offset = XFS_DIR3_DATA_FIRST_OFFSET(mp);
bad_offset = *repair = 0;
ASSERT(ino_dir_size <= max_size);
do_warn(
_("corrected entry offsets in directory %" PRIu64 "\n"),
ino);
- process_sf_dir2_fixoff(dip);
+ process_sf_dir2_fixoff(mp, dip);
*dino_dirty = 1;
*repair = 1;
}