#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;
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);
}
/*
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)
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);
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);
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:
/*
*/
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;
* 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
#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__
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
*/