All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Chinner <dgc@sgi.com>
To: Barry Naujok <bnaujok@sgi.com>
Cc: xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH 1/7] XFS: Name operation vector for hash and compare
Date: Thu, 3 Apr 2008 11:29:12 +1000	[thread overview]
Message-ID: <20080403012912.GO103491721@sgi.com> (raw)
In-Reply-To: <20080402062707.797672682@chook.melbourne.sgi.com>

On Wed, Apr 02, 2008 at 04:25:09PM +1000, Barry Naujok wrote:
> Adds two pieces of functionality for the basis of case-insensitive
> support in XFS:
> 
> 1.  A comparison result enumerated type: xfs_dacmp_t. It represents an
>     exact match, case-insensitive match or no match at all. This patch
>     only implements different and exact results.
> 
> 2.  xfs_nameops vector for specifying how to perform the hash generation
>     of filenames and comparision methods. In this patch the hash vector
>     points to the existing xfs_da_hashname function and the comparison
>     method does a length compare, and if the same, does a memcmp and
>     return the xfs_dacmp_t result.
> 
> All filename functions that use the hash (create, lookup remove, rename,
> etc) now use the xfs_nameops.hashname function and all directory lookup
> functions also use the xfs_nameops.compname function.

Ok, so internally I see this is not the case. I'll comment on that
inline.

> The lookup functions also handle case-insensitive results even though
> the default comparison function cannot return that. And important
> aspect of the lookup functions is that an exact match always has
> precedence over a case-insensitive. So while a case-insensitive match
> is found, we have to keep looking just in case there is an exact
> match. In the meantime, the info for the first case-insensitive match
> is retained if no exact match is found.
> 
> Signed-off-by: Barry Naujok <bnaujok@sgi.com>
......
>  }
>  
> +xfs_dacmp_t
> +xfs_da_compname(const uchar_t *name1, int len1, const uchar_t *name2, int len2)
> +{
> +	return (len1 == len2 && memcmp(name1, name2, len1) == 0) ?
> +			XFS_CMP_EXACT : XFS_CMP_DIFFERENT;
> +}
> +
> +struct xfs_nameops xfs_default_nameops = {

const.

>  #ifdef __KERNEL__
>  /*========================================================================
> @@ -248,7 +271,12 @@ xfs_daddr_t	xfs_da_reada_buf(struct xfs_
>  int	xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
>  					  xfs_dabuf_t *dead_buf);
>  
> +extern struct xfs_nameops xfs_default_nameops;

Does this need global visibility? It's only needed in xfs_dir_mount(),
right?

> Index: kern_ci/fs/xfs/xfs_dir2.h
> ===================================================================
> --- kern_ci.orig/fs/xfs/xfs_dir2.h
> +++ kern_ci/fs/xfs/xfs_dir2.h
> @@ -85,6 +85,12 @@ extern int xfs_dir_canenter(struct xfs_t
>  				char *name, int namelen);
>  extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
>  
> +#define xfs_dir_hashname(dp, n, l) \
> +		((dp)->i_mount->m_dirnameops->hashname((n), (l)))
> +
> +#define xfs_dir_compname(dp, n1, l1, n2, l2) \
> +		((dp)->i_mount->m_dirnameops->compname((n1), (l1), (n2), (l2)))
> +

Static inline functions, please.

>  /*
>   * Utility routines for v2 directories.
>   */
> Index: kern_ci/fs/xfs/xfs_dir2_block.c
> ===================================================================
> --- kern_ci.orig/fs/xfs/xfs_dir2_block.c
> +++ kern_ci/fs/xfs/xfs_dir2_block.c
> @@ -643,6 +643,7 @@ xfs_dir2_block_lookup_int(
>  	int			mid;		/* binary search current idx */
>  	xfs_mount_t		*mp;		/* filesystem mount point */
>  	xfs_trans_t		*tp;		/* transaction pointer */
> +	xfs_dacmp_t		cmp;		/* comparison result */
>  
>  	dp = args->dp;
>  	tp = args->trans;
> @@ -698,19 +699,33 @@ xfs_dir2_block_lookup_int(
>  			((char *)block + xfs_dir2_dataptr_to_off(mp, addr));
>  		/*
>  		 * Compare, if it's right give back buffer & entry number.
> +		 *
> +		 * lookup case - use nameops;
> +		 *
> +		 * replace/remove case - as lookup has been already been
> +		 * performed, look for an exact match using the fast method
>  		 */
> -		if (dep->namelen == args->namelen &&
> -		    dep->name[0] == args->name[0] &&
> -		    memcmp(dep->name, args->name, args->namelen) == 0) {
> +		cmp = args->oknoent ?
> +			xfs_dir_compname(dp, dep->name, dep->namelen,
> +						args->name, args->namelen) :
> +			xfs_da_compname(dep->name, dep->namelen,
> +						args->name, args->namelen);

Why add this "fast path"? All you're saving here is a few
instructions but making the code much harder to follow.

		cmp = xfs_dir_compname(dp, dep->name, dep->namelen,
						args->name, args->namelen);

Will do exactly the same thing and I'd much prefer readable code
over prematurely optimised code any day of the week....

> +		if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
> +			args->cmpresult = cmp;
>  			*bpp = bp;
>  			*entno = mid;
> -			return 0;
> +			if (cmp == XFS_CMP_EXACT)
> +				return 0;
>  		}
> -	} while (++mid < be32_to_cpu(btp->count) && be32_to_cpu(blp[mid].hashval) == hash);
> +	} while (++mid < be32_to_cpu(btp->count) &&
> +			be32_to_cpu(blp[mid].hashval) == hash);
> +
> +	ASSERT(args->oknoent);
> +	if (args->cmpresult == XFS_CMP_CASE)
> +		return 0;

So if we find multiple case matches, we'll take the last we find?

>  	/*
>  	 * No match, release the buffer and return ENOENT.
>  	 */
> -	ASSERT(args->oknoent);
>  	xfs_da_brelse(tp, bp);
>  	return XFS_ERROR(ENOENT);

Should we really be promoting that assert to before we return a successful
case match?

> @@ -1391,19 +1394,49 @@ xfs_dir2_leaf_lookup_int(
>  		       xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)));
>  		/*
>  		 * If it matches then return it.
> +		 *
> +		 * lookup case - use nameops;
> +		 *
> +		 * replace/remove case - as lookup has been already been
> +		 * performed, look for an exact match using the fast method
>  		 */
> -		if (dep->namelen == args->namelen &&
> -		    dep->name[0] == args->name[0] &&
> -		    memcmp(dep->name, args->name, args->namelen) == 0) {
> -			*dbpp = dbp;
> +		cmp = args->oknoent ?
> +			xfs_dir_compname(dp, dep->name, dep->namelen,
> +						args->name, args->namelen) :
> +			xfs_da_compname(dep->name, dep->namelen,
> +						args->name, args->namelen);

Same again.

> +		if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
> +			args->cmpresult = cmp;
>  			*indexp = index;
> -			return 0;
> +			if (cmp == XFS_CMP_EXACT) {
> +				/*
> +				 * case exact match: release the case-insens.
> +				 * match buffer if it exists and return the
> +				 * current data buffer.
> +				 */
> +				if (cbp && cbp != dbp)
> +					xfs_da_brelse(tp, cbp);
> +				*dbpp = dbp;
> +				return 0;
> +			}
> +			cbp = dbp;
>  		}
>  	}
> +	ASSERT(args->oknoent);
> +	if (args->cmpresult == XFS_CMP_CASE) {
> +		/*
> +		 * case-insensitive match: release current buffer and
> +		 * return the buffer with the case-insensitive match.
> +		 */
> +		if (cbp != dbp)
> +			xfs_da_brelse(tp, dbp);
> +		*dbpp = cbp;
> +		return 0;
> +	}
>  	/*
>  	 * No match found, return ENOENT.
>  	 */
> -	ASSERT(args->oknoent);

Same question about promoting the assert....

> @@ -578,19 +579,27 @@ xfs_dir2_leafn_lookup_int(
>  			/*
>  			 * Compare the entry, return it if it matches.
>  			 */
> -			if (dep->namelen == args->namelen &&
> -			    dep->name[0] == args->name[0] &&
> -			    memcmp(dep->name, args->name, args->namelen) == 0) {
> +			cmp = args->oknoent ?
> +				xfs_dir_compname(dp, dep->name, dep->namelen,
> +						args->name, args->namelen):
> +				xfs_da_compname(dep->name, dep->namelen,
> +						args->name, args->namelen);

Same again.

> @@ -907,9 +914,8 @@ xfs_dir2_sf_removename(
>  	for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp);
>  	     i < sfp->hdr.count;
>  	     i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) {
> -		if (sfep->namelen == args->namelen &&
> -		    sfep->name[0] == args->name[0] &&
> -		    memcmp(sfep->name, args->name, args->namelen) == 0) {
> +		if (xfs_da_compname(sfep->name, sfep->namelen,
> +				args->name, args->namelen) == XFS_CMP_EXACT) {
>  			ASSERT(xfs_dir2_sf_get_inumber(sfp,
>  					xfs_dir2_sf_inumberp(sfep)) ==
>  				args->inumber);

This only checks for an exact match - what is supposed to happen
with a XFS_CMP_CASE return?

> @@ -1044,9 +1050,9 @@ xfs_dir2_sf_replace(
>  		for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp);
>  		     i < sfp->hdr.count;
>  		     i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) {
> -			if (sfep->namelen == args->namelen &&
> -			    sfep->name[0] == args->name[0] &&
> -			    memcmp(args->name, sfep->name, args->namelen) == 0) {
> +			if (xfs_da_compname(sfep->name, sfep->namelen,
> +					    args->name, args->namelen) ==
> +					XFS_CMP_EXACT) {

ditto.

Cheers,

Dave.
-- 
Dave Chinner
Principal Engineer
SGI Australian Software Group

  parent reply	other threads:[~2008-04-03  1:28 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-02  6:25 [PATCH 0/7] XFS: case-insensitive lookup and Unicode support Barry Naujok
2008-04-02  6:25 ` [PATCH 1/7] XFS: Name operation vector for hash and compare Barry Naujok
2008-04-03  0:22   ` Josef 'Jeff' Sipek
2008-04-03  4:50     ` Barry Naujok
2008-04-03  1:29   ` David Chinner [this message]
2008-04-03  1:45     ` Barry Naujok
2008-04-03 22:51     ` Christoph Hellwig
2008-04-02  6:25 ` [PATCH 2/7] XFS: ASCII case-insensitive support Barry Naujok
2008-04-03  0:35   ` Josef 'Jeff' Sipek
2008-04-03  1:53   ` David Chinner
2008-04-03 17:09     ` Christoph Hellwig
2008-04-03 22:55   ` Christoph Hellwig
2008-04-03 23:01     ` Nathan Scott
2008-04-02  6:25 ` [PATCH 3/7] XFS: Refactor node format directory lookup/addname Barry Naujok
2008-04-03  1:51   ` Josef 'Jeff' Sipek
2008-04-03  4:04     ` Barry Naujok
2008-04-03  4:10       ` Barry Naujok
2008-04-03  4:33   ` David Chinner
2008-04-02  6:25 ` [PATCH 4/7] XFS: Return case-insensitive match for dentry cache Barry Naujok
2008-04-03  2:34   ` Josef 'Jeff' Sipek
2008-04-03  5:22   ` David Chinner
2008-04-03  5:41     ` Stephen Rothwell
2008-04-03 14:56       ` Christoph Hellwig
2008-04-03 23:06   ` Christoph Hellwig
2008-04-02  6:25 ` [PATCH 5/7] XFS: Unicode case-insensitive lookup implementation Barry Naujok
2008-04-03  8:31   ` David Chinner
2008-04-17  5:38     ` Barry Naujok
2008-04-17  8:49       ` David Chinner
2008-04-03 17:14   ` Christoph Hellwig
2008-04-03 17:24     ` Jeremy Allison
2008-04-03 18:09       ` Josef 'Jeff' Sipek
2008-04-03 18:11       ` Eric Sandeen
2008-04-03 18:22         ` Jeremy Allison
2008-04-04  0:00         ` Mark Goodwin
2008-04-03 18:43       ` Christoph Hellwig
2008-04-03 18:47         ` Jeremy Allison
2008-04-03 18:55           ` Christoph Hellwig
2008-04-03 18:57             ` Christoph Hellwig
2008-04-03 22:34               ` Jeremy Allison
2008-04-03 22:20     ` David Chinner
2008-04-03 22:31       ` Christoph Hellwig
2008-04-03 23:00       ` Jamie Lokier
2008-04-02  6:25 ` [PATCH 6/7] XFS: Native Language Support for Unicode in XFS Barry Naujok
2008-04-02  6:25   ` Barry Naujok
2008-04-04  0:05   ` David Chinner
2008-04-04  0:05     ` David Chinner
2008-04-02  6:25 ` [PATCH 7/7] XFS: NLS config option Barry Naujok
2008-04-03  1:26   ` Josef 'Jeff' Sipek
2008-04-03  1:38     ` Barry Naujok
2008-04-08 11:45 ` [PATCH 0/7] XFS: case-insensitive lookup and Unicode support Christoph Hellwig
2008-04-09  1:53   ` Barry Naujok

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=20080403012912.GO103491721@sgi.com \
    --to=dgc@sgi.com \
    --cc=bnaujok@sgi.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.