All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] kNFSd -  Tidy up new filehandle type.
       [not found] <20040305163625.1829.patches@notabene>
@ 2004-03-05  5:42 ` NeilBrown
  0 siblings, 0 replies; only message in thread
From: NeilBrown @ 2004-03-05  5:42 UTC (permalink / raw)
  To: Andrew Morton; +Cc: nfs

Hi Andrew,
 I would really like this patch to go into 2.6.4.  I think it is ready - it 
is fairly simple and tested.  But if it is too late, so be it.

A change was made to nfsd filehandles about 6 months ago when the 32bit dev_t 
stuff went in which I wasn't consulted on and I don't like.  It basically wastes 32bits 
of the filehandle when the filesystem is on a device with a new/large device number.
Not only don't I like it, but it broken handling for 'fsid=' for such filesystems.

This patch fixes it in an upwards-compatable way (so people already serving files from 
such a filesystem with a 2.6.3 kernel should not notice any issues).
NeilBrown

======================================
nfsd uses several different mechanisms for identifying the filesystem
from the filehandle.

This patch:
  Marks type 2 as deprecated - it wastes space, and space if the filehandle
     is not unlimited
  Adds type 3 which handles new, large device number in 32bits of space
  Tidies up the code for determining which type to use in a newly created
  filehandle - the addition type 2 broke this code.

 ----------- Diffstat output ------------
 ./fs/nfsd/export.c           |   13 ++----
 ./fs/nfsd/nfsfh.c            |   80 +++++++++++++++++++++++++------------------
 ./include/linux/nfsd/nfsfh.h |   21 ++++++++++-
 3 files changed, 71 insertions(+), 43 deletions(-)

diff ./fs/nfsd/export.c~current~ ./fs/nfsd/export.c
--- ./fs/nfsd/export.c~current~	2004-03-05 16:36:13.000000000 +1100
+++ ./fs/nfsd/export.c	2004-03-05 16:36:13.000000000 +1100
@@ -56,11 +56,6 @@ static int		exp_verify_string(char *cp, 
 #define	EXPKEY_HASHMASK		(EXPKEY_HASHMAX -1)
 static struct cache_head *expkey_table[EXPKEY_HASHMAX];
 
-static inline int key_len(int type)
-{
-	return type == 0 ? 8 : type == 1 ? 4 : 12;
-}
-
 static inline int svc_expkey_hash(struct svc_expkey *item)
 {
 	int hash = item->ek_fsidtype;
@@ -547,8 +542,8 @@ exp_get_key(svc_client *clp, dev_t dev, 
 		mk_fsid_v0(fsidv, dev, ino);
 		return exp_find_key(clp, 0, fsidv, NULL);
 	}
-	mk_fsid_v2(fsidv, dev, ino);
-	return exp_find_key(clp, 2, fsidv, NULL);
+	mk_fsid_v3(fsidv, dev, ino);
+	return exp_find_key(clp, 3, fsidv, NULL);
 }
 
 /*
@@ -684,8 +679,8 @@ static int exp_hash(struct auth_domain *
 		mk_fsid_v0(fsid, dev, inode->i_ino);
 		return exp_set_key(clp, 0, fsid, exp);
 	}
-	mk_fsid_v2(fsid, dev, inode->i_ino);
-	return exp_set_key(clp, 2, fsid, exp);
+	mk_fsid_v3(fsid, dev, inode->i_ino);
+	return exp_set_key(clp, 3, fsid, exp);
 }
 
 static void exp_unhash(struct svc_export *exp)

diff ./fs/nfsd/nfsfh.c~current~ ./fs/nfsd/nfsfh.c
--- ./fs/nfsd/nfsfh.c~current~	2004-03-05 16:36:13.000000000 +1100
+++ ./fs/nfsd/nfsfh.c	2004-03-05 16:36:13.000000000 +1100
@@ -117,19 +117,14 @@ fh_verify(struct svc_rqst *rqstp, struct
 			case 0: break;
 			default: goto out;
 			}
-
-			switch (fh->fh_fsid_type) {
-			case 0:
-				len = 2;
-				break;
-			case 1:
-				len = 1;
-				break;
-			case 2:
+			len = key_len(fh->fh_fsid_type) / 4;
+			if (len == 0) goto out;
+			if  (fh->fh_fsid_type == 2) {
+				/* deprecated, convert to type 3 */
 				len = 3;
-				break;
-			default:
-				goto out;
+				fh->fh_fsid_type = 3;
+				fh->fh_fsid[0] = new_encode_dev(MKDEV(ntohl(fh->fh_fsid[0]), ntohl(fh->fh_fsid[1])));
+				fh->fh_fsid[1] = fh->fh_fsid[2];
 			}
 			if ((data_left -= len)<0) goto out;
 			exp = exp_find(rqstp->rq_client, fh->fh_fsid_type, datap, &rqstp->rq_chandle);
@@ -336,19 +331,31 @@ fh_compose(struct svc_fh *fhp, struct sv
 		parent->d_name.name, dentry->d_name.name,
 		(inode ? inode->i_ino : 0));
 
-	/* for large devnums rules are simple */
-	if (!old_valid_dev(ex_dev)) {
-		ref_fh_version = 1;
-		if (exp->ex_flags & NFSEXP_FSID)
-			ref_fh_fsid_type = 1;
-		else
-			ref_fh_fsid_type = 2;
-	} else if (ref_fh) {
+	if (ref_fh) {
 		ref_fh_version = ref_fh->fh_handle.fh_version;
-		ref_fh_fsid_type = ref_fh->fh_handle.fh_fsid_type;
-		if (!(exp->ex_flags & NFSEXP_FSID) || ref_fh_fsid_type == 2)
+		if (ref_fh_version == 0xca)
 			ref_fh_fsid_type = 0;
+		else
+			ref_fh_fsid_type = ref_fh->fh_handle.fh_fsid_type;
+		if (ref_fh_fsid_type > 3)
+			ref_fh_fsid_type = 0;
+	}
+	/* make sure ref_fh type works for given export */
+	if (ref_fh_fsid_type == 1 &&
+	    !(exp->ex_flags & NFSEXP_FSID)) {
+		/* if we don't have an fsid, we cannot provide one... */
+		ref_fh_fsid_type = 0;
+	}
+	if (!old_valid_dev(ex_dev) && ref_fh_fsid_type == 0) {
+		/* for newer device numbers, we must use a newer fsid format */
+		ref_fh_version = 1;
+		ref_fh_fsid_type = 3;
 	}
+	if (old_valid_dev(ex_dev) &&
+	    (ref_fh_fsid_type == 2 || ref_fh_fsid_type == 3))
+		/* must use type1 for smaller device numbers */
+		ref_fh_fsid_type = 0;
+
 	if (ref_fh == fhp)
 		fh_put(ref_fh);
 
@@ -376,16 +383,22 @@ fh_compose(struct svc_fh *fhp, struct sv
 		if (inode)
 			_fh_update_old(dentry, exp, &fhp->fh_handle);
 	} else {
+		int len;
 		fhp->fh_handle.fh_version = 1;
 		fhp->fh_handle.fh_auth_type = 0;
 		datap = fhp->fh_handle.fh_auth+0;
 		fhp->fh_handle.fh_fsid_type = ref_fh_fsid_type;
 		switch (ref_fh_fsid_type) {
+			case 0:
+				/*
+				 * fsid_type 0:
+				 * 2byte major, 2byte minor, 4byte inode
+				 */
+				mk_fsid_v0(datap, ex_dev,
+					exp->ex_dentry->d_inode->i_ino);
 			case 1:
 				/* fsid_type 1 == 4 bytes filesystem id */
 				mk_fsid_v1(datap, exp->ex_fsid);
-				datap += 1;
-				fhp->fh_handle.fh_size = 2*4;
 				break;
 			case 2:
 				/*
@@ -394,21 +407,22 @@ fh_compose(struct svc_fh *fhp, struct sv
 				 */
 				mk_fsid_v2(datap, ex_dev,
 					exp->ex_dentry->d_inode->i_ino);
-				datap += 3;
-				fhp->fh_handle.fh_size = 4*4;
 				break;
-			default:
+			case 3:
 				/*
-				 * fsid_type 0:
-				 * 2byte major, 2byte minor, 4byte inode
+				 * fsid_type 3:
+				 * 4byte devicenumber, 4byte inode
 				 */
-				mk_fsid_v0(datap, ex_dev,
+				mk_fsid_v3(datap, ex_dev,
 					exp->ex_dentry->d_inode->i_ino);
-				datap += 2;
-				fhp->fh_handle.fh_size = 3*4;
+				break;
 		}
+		len = key_len(ref_fh_fsid_type);
+		datap += len/4;
+		fhp->fh_handle.fh_size = 4 + len;
+
 		if (inode) {
-			int size = fhp->fh_maxsize/4 - 3;
+			int size = (fhp->fh_maxsize-len-4)/4;
 			fhp->fh_handle.fh_fileid_type =
 				_fh_update(dentry, exp, datap, &size);
 			fhp->fh_handle.fh_size += size*4;

diff ./include/linux/nfsd/nfsfh.h~current~ ./include/linux/nfsd/nfsfh.h
--- ./include/linux/nfsd/nfsfh.h~current~	2004-03-05 16:36:13.000000000 +1100
+++ ./include/linux/nfsd/nfsfh.h	2004-03-05 16:36:13.000000000 +1100
@@ -66,8 +66,9 @@ struct nfs_fhbase_old {
  *     0  - 4 byte device id (ms-2-bytes major, ls-2-bytes minor), 4byte inode number
  *        NOTE: we cannot use the kdev_t device id value, because kdev_t.h
  *              says we mustn't.  We must break it up and reassemble.
- *  Possible future encodings:
  *     1  - 4 byte user specified identifier
+ *     2  - 4 byte major, 4 byte minor, 4 byte inode number - DEPRECATED
+ *     3  - 4 byte device id, encoded for user-space, 4 byte inode number
  *
  * The fileid_type identified how the file within the filesystem is encoded.
  * This is (will be) passed to, and set by, the underlying filesystem if it supports
@@ -114,6 +115,7 @@ struct knfsd_fh {
 #define	fh_auth_type		fh_base.fh_new.fb_auth_type
 #define	fh_fileid_type		fh_base.fh_new.fb_fileid_type
 #define	fh_auth			fh_base.fh_new.fb_auth
+#define	fh_fsid			fh_base.fh_new.fb_auth
 
 #ifdef __KERNEL__
 
@@ -183,6 +185,23 @@ static inline void mk_fsid_v2(u32 *fsidv
 	fsidv[2] = ino_t_to_u32(ino);
 }
 
+static inline void mk_fsid_v3(u32 *fsidv, dev_t dev, ino_t ino)
+{
+	fsidv[0] = new_encode_dev(dev);
+	fsidv[1] = ino_t_to_u32(ino);
+}
+
+static inline int key_len(int type)
+{
+	switch(type) {
+	case 0: return 8;
+	case 1: return 4;
+	case 2: return 12;
+	case 3: return 8;
+	default: return 0;
+	}
+}
+
 /*
  * Shorthand for dprintk()'s
  */


-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2004-03-05  5:49 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20040305163625.1829.patches@notabene>
2004-03-05  5:42 ` [PATCH] kNFSd - Tidy up new filehandle type NeilBrown

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.