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);
#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)
......
......@@ -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;
if (ref_fh_version == 0xca)
ref_fh_fsid_type = 0;
else
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;
}
/* 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;
......
......@@ -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
*/
......
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