Commit 1610726a authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] kNFSd - Tidy up new filehandle type.

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.
parent b02a51da
...@@ -56,11 +56,6 @@ static int exp_verify_string(char *cp, int max); ...@@ -56,11 +56,6 @@ static int exp_verify_string(char *cp, int max);
#define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1) #define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1)
static struct cache_head *expkey_table[EXPKEY_HASHMAX]; 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) static inline int svc_expkey_hash(struct svc_expkey *item)
{ {
int hash = item->ek_fsidtype; int hash = item->ek_fsidtype;
...@@ -547,8 +542,8 @@ exp_get_key(svc_client *clp, dev_t dev, ino_t ino) ...@@ -547,8 +542,8 @@ exp_get_key(svc_client *clp, dev_t dev, ino_t ino)
mk_fsid_v0(fsidv, dev, ino); mk_fsid_v0(fsidv, dev, ino);
return exp_find_key(clp, 0, fsidv, NULL); return exp_find_key(clp, 0, fsidv, NULL);
} }
mk_fsid_v2(fsidv, dev, ino); mk_fsid_v3(fsidv, dev, ino);
return exp_find_key(clp, 2, fsidv, NULL); return exp_find_key(clp, 3, fsidv, NULL);
} }
/* /*
...@@ -684,8 +679,8 @@ static int exp_hash(struct auth_domain *clp, struct svc_export *exp) ...@@ -684,8 +679,8 @@ static int exp_hash(struct auth_domain *clp, struct svc_export *exp)
mk_fsid_v0(fsid, dev, inode->i_ino); mk_fsid_v0(fsid, dev, inode->i_ino);
return exp_set_key(clp, 0, fsid, exp); return exp_set_key(clp, 0, fsid, exp);
} }
mk_fsid_v2(fsid, dev, inode->i_ino); mk_fsid_v3(fsid, dev, inode->i_ino);
return exp_set_key(clp, 2, fsid, exp); return exp_set_key(clp, 3, fsid, exp);
} }
static void exp_unhash(struct svc_export *exp) static void exp_unhash(struct svc_export *exp)
......
...@@ -117,19 +117,14 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) ...@@ -117,19 +117,14 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
case 0: break; case 0: break;
default: goto out; default: goto out;
} }
len = key_len(fh->fh_fsid_type) / 4;
switch (fh->fh_fsid_type) { if (len == 0) goto out;
case 0: if (fh->fh_fsid_type == 2) {
len = 2; /* deprecated, convert to type 3 */
break;
case 1:
len = 1;
break;
case 2:
len = 3; len = 3;
break; fh->fh_fsid_type = 3;
default: fh->fh_fsid[0] = new_encode_dev(MKDEV(ntohl(fh->fh_fsid[0]), ntohl(fh->fh_fsid[1])));
goto out; fh->fh_fsid[1] = fh->fh_fsid[2];
} }
if ((data_left -= len)<0) goto out; if ((data_left -= len)<0) goto out;
exp = exp_find(rqstp->rq_client, fh->fh_fsid_type, datap, &rqstp->rq_chandle); 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 ...@@ -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, parent->d_name.name, dentry->d_name.name,
(inode ? inode->i_ino : 0)); (inode ? inode->i_ino : 0));
/* for large devnums rules are simple */ if (ref_fh) {
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) {
ref_fh_version = ref_fh->fh_handle.fh_version; ref_fh_version = ref_fh->fh_handle.fh_version;
if (ref_fh_version == 0xca)
ref_fh_fsid_type = 0;
else
ref_fh_fsid_type = ref_fh->fh_handle.fh_fsid_type; 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_fsid_type > 3)
ref_fh_fsid_type = 0; 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) if (ref_fh == fhp)
fh_put(ref_fh); fh_put(ref_fh);
...@@ -376,16 +383,22 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st ...@@ -376,16 +383,22 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
if (inode) if (inode)
_fh_update_old(dentry, exp, &fhp->fh_handle); _fh_update_old(dentry, exp, &fhp->fh_handle);
} else { } else {
int len;
fhp->fh_handle.fh_version = 1; fhp->fh_handle.fh_version = 1;
fhp->fh_handle.fh_auth_type = 0; fhp->fh_handle.fh_auth_type = 0;
datap = fhp->fh_handle.fh_auth+0; datap = fhp->fh_handle.fh_auth+0;
fhp->fh_handle.fh_fsid_type = ref_fh_fsid_type; fhp->fh_handle.fh_fsid_type = ref_fh_fsid_type;
switch (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: case 1:
/* fsid_type 1 == 4 bytes filesystem id */ /* fsid_type 1 == 4 bytes filesystem id */
mk_fsid_v1(datap, exp->ex_fsid); mk_fsid_v1(datap, exp->ex_fsid);
datap += 1;
fhp->fh_handle.fh_size = 2*4;
break; break;
case 2: case 2:
/* /*
...@@ -394,21 +407,22 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st ...@@ -394,21 +407,22 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
*/ */
mk_fsid_v2(datap, ex_dev, mk_fsid_v2(datap, ex_dev,
exp->ex_dentry->d_inode->i_ino); exp->ex_dentry->d_inode->i_ino);
datap += 3;
fhp->fh_handle.fh_size = 4*4;
break; break;
default: case 3:
/* /*
* fsid_type 0: * fsid_type 3:
* 2byte major, 2byte minor, 4byte inode * 4byte devicenumber, 4byte inode
*/ */
mk_fsid_v0(datap, ex_dev, mk_fsid_v3(datap, ex_dev,
exp->ex_dentry->d_inode->i_ino); exp->ex_dentry->d_inode->i_ino);
datap += 2; break;
fhp->fh_handle.fh_size = 3*4;
} }
len = key_len(ref_fh_fsid_type);
datap += len/4;
fhp->fh_handle.fh_size = 4 + len;
if (inode) { if (inode) {
int size = fhp->fh_maxsize/4 - 3; int size = (fhp->fh_maxsize-len-4)/4;
fhp->fh_handle.fh_fileid_type = fhp->fh_handle.fh_fileid_type =
_fh_update(dentry, exp, datap, &size); _fh_update(dentry, exp, datap, &size);
fhp->fh_handle.fh_size += size*4; fhp->fh_handle.fh_size += size*4;
......
...@@ -66,8 +66,9 @@ struct nfs_fhbase_old { ...@@ -66,8 +66,9 @@ struct nfs_fhbase_old {
* 0 - 4 byte device id (ms-2-bytes major, ls-2-bytes minor), 4byte inode number * 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 * 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. * says we mustn't. We must break it up and reassemble.
* Possible future encodings:
* 1 - 4 byte user specified identifier * 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. * 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 * This is (will be) passed to, and set by, the underlying filesystem if it supports
...@@ -114,6 +115,7 @@ struct knfsd_fh { ...@@ -114,6 +115,7 @@ struct knfsd_fh {
#define fh_auth_type fh_base.fh_new.fb_auth_type #define fh_auth_type fh_base.fh_new.fb_auth_type
#define fh_fileid_type fh_base.fh_new.fb_fileid_type #define fh_fileid_type fh_base.fh_new.fb_fileid_type
#define fh_auth fh_base.fh_new.fb_auth #define fh_auth fh_base.fh_new.fb_auth
#define fh_fsid fh_base.fh_new.fb_auth
#ifdef __KERNEL__ #ifdef __KERNEL__
...@@ -183,6 +185,23 @@ static inline void mk_fsid_v2(u32 *fsidv, dev_t dev, ino_t ino) ...@@ -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); 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 * Shorthand for dprintk()'s
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment