]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] kNFSd - Tidy up new filehandle type.
authorNeil Brown <neilb@cse.unsw.edu.au>
Thu, 4 Mar 2004 23:57:24 +0000 (15:57 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 4 Mar 2004 23:57:24 +0000 (15:57 -0800)
nfsd uses several different mechanisms for identifying the filesystem
from the filehandle.

This patch:
  Marks type 2 as deprecated - it wastes space, and space in 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 of type 2 broke this code.

fs/nfsd/export.c
fs/nfsd/nfsfh.c
include/linux/nfsd/nfsfh.h

index 6fd2193ece8d4c16d424fb320eee5b0a06c55e1d..fabf60532101a5100b73a1faa9cb8ae4575c3631 100644 (file)
@@ -56,11 +56,6 @@ static int           exp_verify_string(char *cp, int max);
 #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, ino_t ino)
                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 *clp, struct svc_export *exp)
                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)
index aa4d31490e35238504d22dcfeeb02bfc74491211..a16bcdb18a7d84ca503a0a8113cccc481fa09b02 100644 (file)
@@ -117,19 +117,14 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
                        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 svc_export *exp, struct dentry *dentry, st
                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 svc_export *exp, struct dentry *dentry, st
                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 svc_export *exp, struct dentry *dentry, st
                                 */
                                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;
index 06281634b083a92a566a27816f931709652a07e6..bb842ea410334ec6a2163480c1591aad6e163110 100644 (file)
@@ -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, dev_t dev, ino_t ino)
        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
  */