From: Eric Sandeen <sandeen@sandeen.net>
To: Dave Chinner <david@fromorbit.com>
Cc: xfs@oss.sgi.com
Subject: Re: [PATCH 07/32] xfs: dirent dtype presence is dependent on directory magic numbers
Date: Tue, 08 Oct 2013 18:30:43 -0500 [thread overview]
Message-ID: <525495A3.30607@sandeen.net> (raw)
In-Reply-To: <1380510944-8571-8-git-send-email-david@fromorbit.com>
On 9/29/13 10:15 PM, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
>
> The determination of whether a directory entry contains a dtype
> field originally was dependent on the filesystem having CRCs
> enabled. This meant that the format for dtype beign enabled could be
> determined by checking the directory block magic number rather than
> doing a feature bit check. This was useful in that it meant that we
> didn't need to pass a struct xfs_mount around to functions that
> were already supplied with a directory block header.
>
> Unfortunately, the introduction of dtype fields into the v4
> structure via a feature bit meant this "use the directory block
> magic number" method of discriminating the dirent entry sizes is
> broken. Hence we need to convert the places that use magic number
> checks to use feature bit checks so that they work correctly and not
> by chance.
>
> The current code works on v4 filesystems only because the dirent
> size roundup covers the extra byte needed by the dtype field in the
> places where this problem occurs.
Looks right to me. Nitpicks & questions though:
FWIW, I find it confusing that we call xfs_dir3_*()
functions from dir2 code or to find out whether the
dir is in fact dir2 or dir3.
i.e.:
return xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&mp->m_sb));
that just seems like an odd name to calculate the header size for
dir2 vs. dir3 directories.
Also -
Is there any pro or con to defining the 3 offsets recursively:
static inline xfs_dir2_data_aoff_t
xfs_dir3_data_dot_offset(struct xfs_mount *mp)
{
return xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&mp->m_sb));
}
static inline xfs_dir2_data_aoff_t
xfs_dir3_data_dotdot_offset(struct xfs_mount *mp)
{
return xfs_dir3_data_dot_offset(mp) +
xfs_dir3_data_entsize(mp, 1);
}
static inline xfs_dir2_data_aoff_t
xfs_dir3_data_first_offset(struct xfs_mount *mp)
{
return xfs_dir3_data_dotdot_offset(mp) +
xfs_dir3_data_entsize(mp, 2);
}
vs directly, i.e.:
static inline xfs_dir2_data_aoff_t
xfs_dir3_data_first_offset(struct xfs_mount *mp)
{
return xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&mp->m_sb)) +
xfs_dir3_data_entsize(mp, 1); /* Dot */
xfs_dir3_data_entsize(mp, 2); /* Dotdot */
}
?
Looks technically correct though, so:
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
-Eric
> Signed-off-by: Dave Chinner <dchinner@redhat.com>
> ---
> db/check.c | 2 +-
> include/xfs_dir2_format.h | 51 +++++++++++++++++++----------------------------
> libxfs/xfs_dir2_block.c | 6 +++---
> libxfs/xfs_dir2_sf.c | 6 +++---
> repair/dir2.c | 4 ++--
> 5 files changed, 29 insertions(+), 40 deletions(-)
>
> diff --git a/db/check.c b/db/check.c
> index 2d4718d..4867698 100644
> --- a/db/check.c
> +++ b/db/check.c
> @@ -3434,7 +3434,7 @@ process_sf_dir_v2(
> dbprintf(_("dir %lld entry . %lld\n"), id->ino, id->ino);
> (*dot)++;
> sfe = xfs_dir2_sf_firstentry(sf);
> - offset = XFS_DIR3_DATA_FIRST_OFFSET(mp);
> + offset = xfs_dir3_data_first_offset(mp);
> for (i = sf->count - 1, i8 = 0; i >= 0; i--) {
> if ((__psint_t)sfe + xfs_dir3_sf_entsize(mp, sf, sfe->namelen) -
> (__psint_t)sf > be64_to_cpu(dip->di_size)) {
> diff --git a/include/xfs_dir2_format.h b/include/xfs_dir2_format.h
> index a0961a6..9cf6738 100644
> --- a/include/xfs_dir2_format.h
> +++ b/include/xfs_dir2_format.h
> @@ -497,69 +497,58 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
> /*
> * 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.
> - *
> * XXX: there is scope for significant optimisation of the logic here. Right
> * now we are checking for "dir3 format" over and over again. Ideally we should
> * only do it once for each operation.
> */
> -#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_dir3_data_entsize(mp, 1))
> -#define XFS_DIR3_DATA_FIRST_OFFSET(mp) \
> - (XFS_DIR3_DATA_DOTDOT_OFFSET(mp) + xfs_dir3_data_entsize(mp, 2))
> -
> static inline xfs_dir2_data_aoff_t
> -xfs_dir3_data_dot_offset(struct xfs_dir2_data_hdr *hdr)
> +xfs_dir3_data_dot_offset(struct xfs_mount *mp)
> {
> - return xfs_dir3_data_entry_offset(hdr);
> + return xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&mp->m_sb));
> }
>
> static inline xfs_dir2_data_aoff_t
> -xfs_dir3_data_dotdot_offset(struct xfs_dir2_data_hdr *hdr)
> +xfs_dir3_data_dotdot_offset(struct xfs_mount *mp)
> {
> - bool dir3 = hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
> - hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC);
> - return xfs_dir3_data_dot_offset(hdr) +
> - __xfs_dir3_data_entsize(dir3, 1);
> + return xfs_dir3_data_dot_offset(mp) +
> + xfs_dir3_data_entsize(mp, 1);
> }
>
> static inline xfs_dir2_data_aoff_t
> -xfs_dir3_data_first_offset(struct xfs_dir2_data_hdr *hdr)
> +xfs_dir3_data_first_offset(struct xfs_mount *mp)
> {
> - bool dir3 = hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
> - hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC);
> - return xfs_dir3_data_dotdot_offset(hdr) +
> - __xfs_dir3_data_entsize(dir3, 2);
> + return xfs_dir3_data_dotdot_offset(mp) +
> + xfs_dir3_data_entsize(mp, 2);
> }
>
> /*
> * location of . and .. in data space (always block 0)
> */
> static inline struct xfs_dir2_data_entry *
> -xfs_dir3_data_dot_entry_p(struct xfs_dir2_data_hdr *hdr)
> +xfs_dir3_data_dot_entry_p(
> + struct xfs_mount *mp,
> + struct xfs_dir2_data_hdr *hdr)
> {
> return (struct xfs_dir2_data_entry *)
> - ((char *)hdr + xfs_dir3_data_dot_offset(hdr));
> + ((char *)hdr + xfs_dir3_data_dot_offset(mp));
> }
>
> static inline struct xfs_dir2_data_entry *
> -xfs_dir3_data_dotdot_entry_p(struct xfs_dir2_data_hdr *hdr)
> +xfs_dir3_data_dotdot_entry_p(
> + struct xfs_mount *mp,
> + struct xfs_dir2_data_hdr *hdr)
> {
> return (struct xfs_dir2_data_entry *)
> - ((char *)hdr + xfs_dir3_data_dotdot_offset(hdr));
> + ((char *)hdr + xfs_dir3_data_dotdot_offset(mp));
> }
>
> static inline struct xfs_dir2_data_entry *
> -xfs_dir3_data_first_entry_p(struct xfs_dir2_data_hdr *hdr)
> +xfs_dir3_data_first_entry_p(
> + struct xfs_mount *mp,
> + struct xfs_dir2_data_hdr *hdr)
> {
> return (struct xfs_dir2_data_entry *)
> - ((char *)hdr + xfs_dir3_data_first_offset(hdr));
> + ((char *)hdr + xfs_dir3_data_first_offset(mp));
> }
>
> /*
> diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c
> index 3e4bc53..1d8f598 100644
> --- a/libxfs/xfs_dir2_block.c
> +++ b/libxfs/xfs_dir2_block.c
> @@ -1139,7 +1139,7 @@ xfs_dir2_sf_to_block(
> /*
> * Create entry for .
> */
> - dep = xfs_dir3_data_dot_entry_p(hdr);
> + dep = xfs_dir3_data_dot_entry_p(mp, hdr);
> dep->inumber = cpu_to_be64(dp->i_ino);
> dep->namelen = 1;
> dep->name[0] = '.';
> @@ -1153,7 +1153,7 @@ xfs_dir2_sf_to_block(
> /*
> * Create entry for ..
> */
> - dep = xfs_dir3_data_dotdot_entry_p(hdr);
> + dep = xfs_dir3_data_dotdot_entry_p(mp, hdr);
> dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp));
> dep->namelen = 2;
> dep->name[0] = dep->name[1] = '.';
> @@ -1164,7 +1164,7 @@ xfs_dir2_sf_to_block(
> blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
> blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp,
> (char *)dep - (char *)hdr));
> - offset = xfs_dir3_data_first_offset(hdr);
> + offset = xfs_dir3_data_first_offset(mp);
> /*
> * Loop over existing entries, stuff them in.
> */
> diff --git a/libxfs/xfs_dir2_sf.c b/libxfs/xfs_dir2_sf.c
> index 740cab0..7580333 100644
> --- a/libxfs/xfs_dir2_sf.c
> +++ b/libxfs/xfs_dir2_sf.c
> @@ -540,7 +540,7 @@ xfs_dir2_sf_addname_hard(
> * to insert the new entry.
> * If it's going to end up at the end then oldsfep will point there.
> */
> - for (offset = XFS_DIR3_DATA_FIRST_OFFSET(mp),
> + for (offset = xfs_dir3_data_first_offset(mp),
> oldsfep = xfs_dir2_sf_firstentry(oldsfp),
> add_datasize = xfs_dir3_data_entsize(mp, args->namelen),
> eof = (char *)oldsfep == &buf[old_isize];
> @@ -623,7 +623,7 @@ xfs_dir2_sf_addname_pick(
>
> sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
> size = xfs_dir3_data_entsize(mp, args->namelen);
> - offset = XFS_DIR3_DATA_FIRST_OFFSET(mp);
> + offset = xfs_dir3_data_first_offset(mp);
> sfep = xfs_dir2_sf_firstentry(sfp);
> holefit = 0;
> /*
> @@ -696,7 +696,7 @@ xfs_dir2_sf_check(
> mp = dp->i_mount;
>
> sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
> - offset = XFS_DIR3_DATA_FIRST_OFFSET(mp);
> + offset = xfs_dir3_data_first_offset(mp);
> ino = xfs_dir2_sf_get_parent_ino(sfp);
> i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
>
> diff --git a/repair/dir2.c b/repair/dir2.c
> index a856631..d931d1d 100644
> --- a/repair/dir2.c
> +++ b/repair/dir2.c
> @@ -705,7 +705,7 @@ process_sf_dir2_fixoff(
>
> sfp = (struct xfs_dir2_sf_hdr *)XFS_DFORK_DPTR(dip);
> sfep = xfs_dir2_sf_firstentry(sfp);
> - offset = XFS_DIR3_DATA_FIRST_OFFSET(mp);
> + offset = xfs_dir3_data_first_offset(mp);
>
> for (i = 0; i < sfp->count; i++) {
> xfs_dir2_sf_put_offset(sfep, offset);
> @@ -759,7 +759,7 @@ process_sf_dir2(
> max_size = XFS_DFORK_DSIZE(dip, mp);
> num_entries = sfp->count;
> ino_dir_size = be64_to_cpu(dip->di_size);
> - offset = XFS_DIR3_DATA_FIRST_OFFSET(mp);
> + offset = xfs_dir3_data_first_offset(mp);
> bad_offset = *repair = 0;
>
> ASSERT(ino_dir_size <= max_size);
>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2013-10-08 23:30 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1380510944-8571-1-git-send-email-david@fromorbit.com>
2013-09-30 3:15 ` [PATCH 01/32] xfsprogs: fix automatic dependency generation Dave Chinner
2013-10-08 23:00 ` Eric Sandeen
2013-09-30 3:15 ` [PATCH 02/32] libxfs: fix missing filetype updates to xfs_dir2.c Dave Chinner
2013-10-08 22:53 ` Eric Sandeen
2013-10-09 20:41 ` Dave Chinner
2013-10-18 16:45 ` Rich Johnston
2013-09-30 3:15 ` [PATCH 03/32] xfs: fix some minor sparse warnings Dave Chinner
2013-10-08 22:56 ` Eric Sandeen
2013-10-09 20:43 ` Dave Chinner
2013-09-30 3:15 ` [PATCH 04/32] xfs: check magic numbers in dir3 leaf verifier first Dave Chinner
2013-10-08 23:03 ` Eric Sandeen
2013-10-09 20:45 ` Dave Chinner
2013-10-09 20:50 ` Eric Sandeen
2013-09-30 3:15 ` [PATCH 05/32] xfs: ensure we copy buffer type in da btree root splits Dave Chinner
2013-10-08 23:06 ` Eric Sandeen
2013-10-18 16:49 ` Rich Johnston
2013-09-30 3:15 ` [PATCH 06/32] xfs: don't assert fail on bad inode numbers Dave Chinner
2013-10-08 23:09 ` Eric Sandeen
2013-09-30 3:15 ` [PATCH 07/32] xfs: dirent dtype presence is dependent on directory magic numbers Dave Chinner
2013-10-08 23:30 ` Eric Sandeen [this message]
2013-10-09 20:51 ` Dave Chinner
2013-10-09 20:57 ` Eric Sandeen
2013-10-18 22:38 ` Rich Johnston
2013-09-30 3:15 ` [PATCH 08/32] xfs: create a shared header file for format-related information Dave Chinner
2013-10-08 23:37 ` Eric Sandeen
2013-10-18 16:59 ` Rich Johnston
2013-10-18 22:40 ` Dave Chinner
2013-10-18 22:43 ` Rich Johnston
2013-10-22 18:07 ` Rich Johnston
2013-09-30 3:15 ` [PATCH 09/32] xfs: unify directory/attribute format definitions Dave Chinner
2013-10-14 20:44 ` Eric Sandeen
2013-10-18 20:32 ` Rich Johnston
2013-10-22 22:25 ` Dave Chinner
2013-09-30 3:15 ` [PATCH 10/32] xfs: split dquot buffer operations out Dave Chinner
2013-09-30 3:15 ` [PATCH 11/32] xfs: decouple inode and bmap btree header files Dave Chinner
2013-09-30 3:15 ` [PATCH 12/32] libxfs: unify xfs_btree.c with kernel code Dave Chinner
2013-09-30 3:15 ` [PATCH 13/32] libxfs: bmap btree owner swap support Dave Chinner
2013-09-30 3:15 ` [PATCH 14/32] libxfs: xfs_rtalloc.c becomes xfs_rtbitmap.c Dave Chinner
2013-09-30 3:15 ` [PATCH 15/32] libxfs: bring across inode buffer readahead verifier changes Dave Chinner
2013-09-30 3:15 ` [PATCH 16/32] libxfs: Minor cleanup and bug fix sync Dave Chinner
2013-09-30 3:15 ` [PATCH 17/32] db: separate out straight buffer IO from map based IO Dave Chinner
2013-09-30 3:15 ` [PATCH 18/32] db: rewrite bbmap to use xfs_buf_map Dave Chinner
2013-09-30 3:15 ` [PATCH 19/32] db: rewrite IO engine to use libxfs Dave Chinner
2013-09-30 3:15 ` [PATCH 20/32] db: introduce verifier support into set_cur Dave Chinner
2013-09-30 3:15 ` [PATCH 21/32] db: indicate if the CRC on a buffer is correct or not Dave Chinner
2013-09-30 3:15 ` [PATCH 22/32] db: verify and calculate inode CRCs Dave Chinner
2013-09-30 3:15 ` [PATCH 23/32] db: verify and calculate dquot CRCs Dave Chinner
2013-09-30 3:15 ` [PATCH 24/32] db: add a special directory buffer verifier Dave Chinner
2013-09-30 3:15 ` [PATCH 25/32] db: add a special attribute " Dave Chinner
2013-09-30 3:15 ` [PATCH 26/32] db: re-enable write support for v5 filesystems Dave Chinner
2013-09-30 3:15 ` [PATCH 27/32] libxfs: fix root inode handling inconsistencies Dave Chinner
2013-09-30 3:15 ` [PATCH 28/32] xfs_db: avoid libxfs buffer lookup warnings Dave Chinner
2013-09-30 3:15 ` [PATCH 29/32] libxfs: work around do_div() not handling 32 bit numerators Dave Chinner
2013-09-30 3:15 ` [PATCH 30/32] db: enable metadump on CRC filesystems Dave Chinner
2013-09-30 3:15 ` [PATCH 31/32] xfs: support larger inode clusters on v5 filesystems Dave Chinner
2013-09-30 3:15 ` [PATCH 32/32] xfsprogs: kill experimental warnings for " Dave Chinner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=525495A3.30607@sandeen.net \
--to=sandeen@sandeen.net \
--cc=david@fromorbit.com \
--cc=xfs@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox