aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-04-03 01:11:24 -0400
committerBen Myers <bpm@sgi.com>2013-04-27 13:24:32 -0400
commit6b2647a12a00bdad431ac1e9049c5e8579aa7869 (patch)
treea2e9a94af4d27297e7ef7f147137e6c4fa099513 /fs/xfs
parent24df33b45ecf5ca413ef1530e0aca5506d9be2cc (diff)
xfs: shortform directory offsets change for dir3 format
Because the header size for the CRC enabled directory blocks is larger, the offset of the first entry into a directory block is different to the dir2 format. The shortform directory stores the dirent's offset so that it doesn't change when moving from shortform to block form and back again, and hence it needs to take into account the different header sizes to maintain the correct offsets. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Ben Myers <bpm@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_dir2_format.h25
-rw-r--r--fs/xfs/xfs_dir2_sf.c10
2 files changed, 19 insertions, 16 deletions
diff --git a/fs/xfs/xfs_dir2_format.h b/fs/xfs/xfs_dir2_format.h
index 7b986d334b33..a3b1bd841a80 100644
--- a/fs/xfs/xfs_dir2_format.h
+++ b/fs/xfs/xfs_dir2_format.h
@@ -228,16 +228,6 @@ xfs_dir2_sf_nextentry(struct xfs_dir2_sf_hdr *hdr,
228 xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET) 228 xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET)
229 229
230/* 230/*
231 * Offsets of . and .. in data space (always block 0)
232 */
233#define XFS_DIR2_DATA_DOT_OFFSET \
234 ((xfs_dir2_data_aoff_t)sizeof(struct xfs_dir2_data_hdr))
235#define XFS_DIR2_DATA_DOTDOT_OFFSET \
236 (XFS_DIR2_DATA_DOT_OFFSET + xfs_dir2_data_entsize(1))
237#define XFS_DIR2_DATA_FIRST_OFFSET \
238 (XFS_DIR2_DATA_DOTDOT_OFFSET + xfs_dir2_data_entsize(2))
239
240/*
241 * Describe a free area in the data block. 231 * Describe a free area in the data block.
242 * 232 *
243 * The freespace will be formatted as a xfs_dir2_data_unused_t. 233 * The freespace will be formatted as a xfs_dir2_data_unused_t.
@@ -378,7 +368,20 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
378 368
379/* 369/*
380 * Offsets of . and .. in data space (always block 0) 370 * Offsets of . and .. in data space (always block 0)
381 */ 371 *
372 * The macros are used for shortform directories as they have no headers to read
373 * the magic number out of. Shortform directories need to know the size of the
374 * data block header because the sfe embeds the block offset of the entry into
375 * it so that it doesn't change when format conversion occurs. Bad Things Happen
376 * if we don't follow this rule.
377 */
378#define XFS_DIR3_DATA_DOT_OFFSET(mp) \
379 xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&(mp)->m_sb))
380#define XFS_DIR3_DATA_DOTDOT_OFFSET(mp) \
381 (XFS_DIR3_DATA_DOT_OFFSET(mp) + xfs_dir2_data_entsize(1))
382#define XFS_DIR3_DATA_FIRST_OFFSET(mp) \
383 (XFS_DIR3_DATA_DOTDOT_OFFSET(mp) + xfs_dir2_data_entsize(2))
384
382static inline xfs_dir2_data_aoff_t 385static inline xfs_dir2_data_aoff_t
383xfs_dir3_data_dot_offset(struct xfs_dir2_data_hdr *hdr) 386xfs_dir3_data_dot_offset(struct xfs_dir2_data_hdr *hdr)
384{ 387{
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index b9756228e9c0..6157424dbf8f 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -535,7 +535,7 @@ xfs_dir2_sf_addname_hard(
535 * to insert the new entry. 535 * to insert the new entry.
536 * If it's going to end up at the end then oldsfep will point there. 536 * If it's going to end up at the end then oldsfep will point there.
537 */ 537 */
538 for (offset = XFS_DIR2_DATA_FIRST_OFFSET, 538 for (offset = XFS_DIR3_DATA_FIRST_OFFSET(dp->i_mount),
539 oldsfep = xfs_dir2_sf_firstentry(oldsfp), 539 oldsfep = xfs_dir2_sf_firstentry(oldsfp),
540 add_datasize = xfs_dir2_data_entsize(args->namelen), 540 add_datasize = xfs_dir2_data_entsize(args->namelen),
541 eof = (char *)oldsfep == &buf[old_isize]; 541 eof = (char *)oldsfep == &buf[old_isize];
@@ -617,7 +617,7 @@ xfs_dir2_sf_addname_pick(
617 617
618 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; 618 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
619 size = xfs_dir2_data_entsize(args->namelen); 619 size = xfs_dir2_data_entsize(args->namelen);
620 offset = XFS_DIR2_DATA_FIRST_OFFSET; 620 offset = XFS_DIR3_DATA_FIRST_OFFSET(mp);
621 sfep = xfs_dir2_sf_firstentry(sfp); 621 sfep = xfs_dir2_sf_firstentry(sfp);
622 holefit = 0; 622 holefit = 0;
623 /* 623 /*
@@ -688,7 +688,7 @@ xfs_dir2_sf_check(
688 dp = args->dp; 688 dp = args->dp;
689 689
690 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; 690 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
691 offset = XFS_DIR2_DATA_FIRST_OFFSET; 691 offset = XFS_DIR3_DATA_FIRST_OFFSET(dp->i_mount);
692 ino = xfs_dir2_sf_get_parent_ino(sfp); 692 ino = xfs_dir2_sf_get_parent_ino(sfp);
693 i8count = ino > XFS_DIR2_MAX_SHORT_INUM; 693 i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
694 694
@@ -812,9 +812,9 @@ xfs_dir2_sf_getdents(
812 * mp->m_dirdatablk. 812 * mp->m_dirdatablk.
813 */ 813 */
814 dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 814 dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
815 XFS_DIR2_DATA_DOT_OFFSET); 815 XFS_DIR3_DATA_DOT_OFFSET(mp));
816 dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 816 dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
817 XFS_DIR2_DATA_DOTDOT_OFFSET); 817 XFS_DIR3_DATA_DOTDOT_OFFSET(mp));
818 818
819 /* 819 /*
820 * Put . entry unless we're starting past it. 820 * Put . entry unless we're starting past it.