NFSD: drop support for ancient filehandles
[ Upstream commit c645a883df
]
Filehandles not in the "new" or "version 1" format have not been handed
out for new mounts since Linux 2.4 which was released 20 years ago.
I think it is safe to say that no such file handles are still in use,
and that we can drop support for them.
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
Родитель
f829bb3a06
Коммит
ed0815c8b7
154
fs/nfsd/nfsfh.c
154
fs/nfsd/nfsfh.c
|
@ -154,11 +154,12 @@ static inline __be32 check_pseudo_root(struct svc_rqst *rqstp,
|
||||||
static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
|
static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
|
||||||
{
|
{
|
||||||
struct knfsd_fh *fh = &fhp->fh_handle;
|
struct knfsd_fh *fh = &fhp->fh_handle;
|
||||||
struct fid *fid = NULL, sfid;
|
struct fid *fid = NULL;
|
||||||
struct svc_export *exp;
|
struct svc_export *exp;
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
int fileid_type;
|
int fileid_type;
|
||||||
int data_left = fh->fh_size/4;
|
int data_left = fh->fh_size/4;
|
||||||
|
int len;
|
||||||
__be32 error;
|
__be32 error;
|
||||||
|
|
||||||
error = nfserr_stale;
|
error = nfserr_stale;
|
||||||
|
@ -167,48 +168,35 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
|
||||||
if (rqstp->rq_vers == 4 && fh->fh_size == 0)
|
if (rqstp->rq_vers == 4 && fh->fh_size == 0)
|
||||||
return nfserr_nofilehandle;
|
return nfserr_nofilehandle;
|
||||||
|
|
||||||
if (fh->fh_version == 1) {
|
if (fh->fh_version != 1)
|
||||||
int len;
|
return error;
|
||||||
|
|
||||||
if (--data_left < 0)
|
if (--data_left < 0)
|
||||||
return error;
|
return error;
|
||||||
if (fh->fh_auth_type != 0)
|
if (fh->fh_auth_type != 0)
|
||||||
return error;
|
return error;
|
||||||
len = key_len(fh->fh_fsid_type) / 4;
|
len = key_len(fh->fh_fsid_type) / 4;
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return error;
|
return error;
|
||||||
if (fh->fh_fsid_type == FSID_MAJOR_MINOR) {
|
if (fh->fh_fsid_type == FSID_MAJOR_MINOR) {
|
||||||
/* deprecated, convert to type 3 */
|
/* deprecated, convert to type 3 */
|
||||||
len = key_len(FSID_ENCODE_DEV)/4;
|
len = key_len(FSID_ENCODE_DEV)/4;
|
||||||
fh->fh_fsid_type = FSID_ENCODE_DEV;
|
fh->fh_fsid_type = FSID_ENCODE_DEV;
|
||||||
/*
|
/*
|
||||||
* struct knfsd_fh uses host-endian fields, which are
|
* struct knfsd_fh uses host-endian fields, which are
|
||||||
* sometimes used to hold net-endian values. This
|
* sometimes used to hold net-endian values. This
|
||||||
* confuses sparse, so we must use __force here to
|
* confuses sparse, so we must use __force here to
|
||||||
* keep it from complaining.
|
* keep it from complaining.
|
||||||
*/
|
*/
|
||||||
fh->fh_fsid[0] = new_encode_dev(MKDEV(ntohl((__force __be32)fh->fh_fsid[0]),
|
fh->fh_fsid[0] = new_encode_dev(MKDEV(ntohl((__force __be32)fh->fh_fsid[0]),
|
||||||
ntohl((__force __be32)fh->fh_fsid[1])));
|
ntohl((__force __be32)fh->fh_fsid[1])));
|
||||||
fh->fh_fsid[1] = fh->fh_fsid[2];
|
fh->fh_fsid[1] = fh->fh_fsid[2];
|
||||||
}
|
|
||||||
data_left -= len;
|
|
||||||
if (data_left < 0)
|
|
||||||
return error;
|
|
||||||
exp = rqst_exp_find(rqstp, fh->fh_fsid_type, fh->fh_fsid);
|
|
||||||
fid = (struct fid *)(fh->fh_fsid + len);
|
|
||||||
} else {
|
|
||||||
__u32 tfh[2];
|
|
||||||
dev_t xdev;
|
|
||||||
ino_t xino;
|
|
||||||
|
|
||||||
if (fh->fh_size != NFS_FHSIZE)
|
|
||||||
return error;
|
|
||||||
/* assume old filehandle format */
|
|
||||||
xdev = old_decode_dev(fh->ofh_xdev);
|
|
||||||
xino = u32_to_ino_t(fh->ofh_xino);
|
|
||||||
mk_fsid(FSID_DEV, tfh, xdev, xino, 0, NULL);
|
|
||||||
exp = rqst_exp_find(rqstp, FSID_DEV, tfh);
|
|
||||||
}
|
}
|
||||||
|
data_left -= len;
|
||||||
|
if (data_left < 0)
|
||||||
|
return error;
|
||||||
|
exp = rqst_exp_find(rqstp, fh->fh_fsid_type, fh->fh_fsid);
|
||||||
|
fid = (struct fid *)(fh->fh_fsid + len);
|
||||||
|
|
||||||
error = nfserr_stale;
|
error = nfserr_stale;
|
||||||
if (IS_ERR(exp)) {
|
if (IS_ERR(exp)) {
|
||||||
|
@ -253,18 +241,7 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
|
||||||
if (rqstp->rq_vers > 2)
|
if (rqstp->rq_vers > 2)
|
||||||
error = nfserr_badhandle;
|
error = nfserr_badhandle;
|
||||||
|
|
||||||
if (fh->fh_version != 1) {
|
fileid_type = fh->fh_fileid_type;
|
||||||
sfid.i32.ino = fh->ofh_ino;
|
|
||||||
sfid.i32.gen = fh->ofh_generation;
|
|
||||||
sfid.i32.parent_ino = fh->ofh_dirino;
|
|
||||||
fid = &sfid;
|
|
||||||
data_left = 3;
|
|
||||||
if (fh->ofh_dirino == 0)
|
|
||||||
fileid_type = FILEID_INO32_GEN;
|
|
||||||
else
|
|
||||||
fileid_type = FILEID_INO32_GEN_PARENT;
|
|
||||||
} else
|
|
||||||
fileid_type = fh->fh_fileid_type;
|
|
||||||
|
|
||||||
if (fileid_type == FILEID_ROOT)
|
if (fileid_type == FILEID_ROOT)
|
||||||
dentry = dget(exp->ex_path.dentry);
|
dentry = dget(exp->ex_path.dentry);
|
||||||
|
@ -452,20 +429,6 @@ static void _fh_update(struct svc_fh *fhp, struct svc_export *exp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* for composing old style file handles
|
|
||||||
*/
|
|
||||||
static inline void _fh_update_old(struct dentry *dentry,
|
|
||||||
struct svc_export *exp,
|
|
||||||
struct knfsd_fh *fh)
|
|
||||||
{
|
|
||||||
fh->ofh_ino = ino_t_to_u32(d_inode(dentry)->i_ino);
|
|
||||||
fh->ofh_generation = d_inode(dentry)->i_generation;
|
|
||||||
if (d_is_dir(dentry) ||
|
|
||||||
(exp->ex_flags & NFSEXP_NOSUBTREECHECK))
|
|
||||||
fh->ofh_dirino = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_root_export(struct svc_export *exp)
|
static bool is_root_export(struct svc_export *exp)
|
||||||
{
|
{
|
||||||
return exp->ex_path.dentry == exp->ex_path.dentry->d_sb->s_root;
|
return exp->ex_path.dentry == exp->ex_path.dentry->d_sb->s_root;
|
||||||
|
@ -562,9 +525,6 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
|
||||||
/* ref_fh is a reference file handle.
|
/* ref_fh is a reference file handle.
|
||||||
* if it is non-null and for the same filesystem, then we should compose
|
* if it is non-null and for the same filesystem, then we should compose
|
||||||
* a filehandle which is of the same version, where possible.
|
* a filehandle which is of the same version, where possible.
|
||||||
* Currently, that means that if ref_fh->fh_handle.fh_version == 0xca
|
|
||||||
* Then create a 32byte filehandle using nfs_fhbase_old
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct inode * inode = d_inode(dentry);
|
struct inode * inode = d_inode(dentry);
|
||||||
|
@ -600,35 +560,21 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
|
||||||
fhp->fh_dentry = dget(dentry); /* our internal copy */
|
fhp->fh_dentry = dget(dentry); /* our internal copy */
|
||||||
fhp->fh_export = exp_get(exp);
|
fhp->fh_export = exp_get(exp);
|
||||||
|
|
||||||
if (fhp->fh_handle.fh_version == 0xca) {
|
fhp->fh_handle.fh_size =
|
||||||
/* old style filehandle please */
|
key_len(fhp->fh_handle.fh_fsid_type) + 4;
|
||||||
memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE);
|
fhp->fh_handle.fh_auth_type = 0;
|
||||||
fhp->fh_handle.fh_size = NFS_FHSIZE;
|
|
||||||
fhp->fh_handle.ofh_dcookie = 0xfeebbaca;
|
|
||||||
fhp->fh_handle.ofh_dev = old_encode_dev(ex_dev);
|
|
||||||
fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev;
|
|
||||||
fhp->fh_handle.ofh_xino =
|
|
||||||
ino_t_to_u32(d_inode(exp->ex_path.dentry)->i_ino);
|
|
||||||
fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry));
|
|
||||||
if (inode)
|
|
||||||
_fh_update_old(dentry, exp, &fhp->fh_handle);
|
|
||||||
} else {
|
|
||||||
fhp->fh_handle.fh_size =
|
|
||||||
key_len(fhp->fh_handle.fh_fsid_type) + 4;
|
|
||||||
fhp->fh_handle.fh_auth_type = 0;
|
|
||||||
|
|
||||||
mk_fsid(fhp->fh_handle.fh_fsid_type,
|
mk_fsid(fhp->fh_handle.fh_fsid_type,
|
||||||
fhp->fh_handle.fh_fsid,
|
fhp->fh_handle.fh_fsid,
|
||||||
ex_dev,
|
ex_dev,
|
||||||
d_inode(exp->ex_path.dentry)->i_ino,
|
d_inode(exp->ex_path.dentry)->i_ino,
|
||||||
exp->ex_fsid, exp->ex_uuid);
|
exp->ex_fsid, exp->ex_uuid);
|
||||||
|
|
||||||
if (inode)
|
if (inode)
|
||||||
_fh_update(fhp, exp, dentry);
|
_fh_update(fhp, exp, dentry);
|
||||||
if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) {
|
if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) {
|
||||||
fh_put(fhp);
|
fh_put(fhp);
|
||||||
return nfserr_opnotsupp;
|
return nfserr_opnotsupp;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -649,16 +595,12 @@ fh_update(struct svc_fh *fhp)
|
||||||
dentry = fhp->fh_dentry;
|
dentry = fhp->fh_dentry;
|
||||||
if (d_really_is_negative(dentry))
|
if (d_really_is_negative(dentry))
|
||||||
goto out_negative;
|
goto out_negative;
|
||||||
if (fhp->fh_handle.fh_version != 1) {
|
if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT)
|
||||||
_fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle);
|
return 0;
|
||||||
} else {
|
|
||||||
if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
_fh_update(fhp, fhp->fh_export, dentry);
|
_fh_update(fhp, fhp->fh_export, dentry);
|
||||||
if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID)
|
if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID)
|
||||||
return nfserr_opnotsupp;
|
return nfserr_opnotsupp;
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
out_bad:
|
out_bad:
|
||||||
printk(KERN_ERR "fh_update: fh not verified!\n");
|
printk(KERN_ERR "fh_update: fh not verified!\n");
|
||||||
|
|
|
@ -14,26 +14,7 @@
|
||||||
#include <linux/exportfs.h>
|
#include <linux/exportfs.h>
|
||||||
#include <linux/nfs4.h>
|
#include <linux/nfs4.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the old "dentry style" Linux NFSv2 file handle.
|
|
||||||
*
|
|
||||||
* The xino and xdev fields are currently used to transport the
|
|
||||||
* ino/dev of the exported inode.
|
|
||||||
*/
|
|
||||||
struct nfs_fhbase_old {
|
|
||||||
u32 fb_dcookie; /* dentry cookie - always 0xfeebbaca */
|
|
||||||
u32 fb_ino; /* our inode number */
|
|
||||||
u32 fb_dirino; /* dir inode number, 0 for directories */
|
|
||||||
u32 fb_dev; /* our device */
|
|
||||||
u32 fb_xdev;
|
|
||||||
u32 fb_xino;
|
|
||||||
u32 fb_generation;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is the new flexible, extensible style NFSv2/v3/v4 file handle.
|
|
||||||
*
|
|
||||||
* The file handle starts with a sequence of four-byte words.
|
* The file handle starts with a sequence of four-byte words.
|
||||||
* The first word contains a version number (1) and three descriptor bytes
|
* The first word contains a version number (1) and three descriptor bytes
|
||||||
* that tell how the remaining 3 variable length fields should be handled.
|
* that tell how the remaining 3 variable length fields should be handled.
|
||||||
|
@ -57,7 +38,7 @@ struct nfs_fhbase_old {
|
||||||
* 6 - 16 byte uuid
|
* 6 - 16 byte uuid
|
||||||
* 7 - 8 byte inode number and 16 byte uuid
|
* 7 - 8 byte inode number and 16 byte uuid
|
||||||
*
|
*
|
||||||
* The fileid_type identified how the file within the filesystem is encoded.
|
* The fileid_type identifies how the file within the filesystem is encoded.
|
||||||
* The values for this field are filesystem specific, exccept that
|
* The values for this field are filesystem specific, exccept that
|
||||||
* filesystems must not use the values '0' or '0xff'. 'See enum fid_type'
|
* filesystems must not use the values '0' or '0xff'. 'See enum fid_type'
|
||||||
* in include/linux/exportfs.h for currently registered values.
|
* in include/linux/exportfs.h for currently registered values.
|
||||||
|
@ -65,7 +46,7 @@ struct nfs_fhbase_old {
|
||||||
struct nfs_fhbase_new {
|
struct nfs_fhbase_new {
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
u8 fb_version_aux; /* == 1, even => nfs_fhbase_old */
|
u8 fb_version_aux; /* == 1 */
|
||||||
u8 fb_auth_type_aux;
|
u8 fb_auth_type_aux;
|
||||||
u8 fb_fsid_type_aux;
|
u8 fb_fsid_type_aux;
|
||||||
u8 fb_fileid_type_aux;
|
u8 fb_fileid_type_aux;
|
||||||
|
@ -74,7 +55,7 @@ struct nfs_fhbase_new {
|
||||||
/* u32 fb_fileid[0]; floating */
|
/* u32 fb_fileid[0]; floating */
|
||||||
};
|
};
|
||||||
struct {
|
struct {
|
||||||
u8 fb_version; /* == 1, even => nfs_fhbase_old */
|
u8 fb_version; /* == 1 */
|
||||||
u8 fb_auth_type;
|
u8 fb_auth_type;
|
||||||
u8 fb_fsid_type;
|
u8 fb_fsid_type;
|
||||||
u8 fb_fileid_type;
|
u8 fb_fileid_type;
|
||||||
|
@ -89,20 +70,11 @@ struct knfsd_fh {
|
||||||
* a new file handle
|
* a new file handle
|
||||||
*/
|
*/
|
||||||
union {
|
union {
|
||||||
struct nfs_fhbase_old fh_old;
|
|
||||||
u32 fh_pad[NFS4_FHSIZE/4];
|
u32 fh_pad[NFS4_FHSIZE/4];
|
||||||
struct nfs_fhbase_new fh_new;
|
struct nfs_fhbase_new fh_new;
|
||||||
} fh_base;
|
} fh_base;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ofh_dcookie fh_base.fh_old.fb_dcookie
|
|
||||||
#define ofh_ino fh_base.fh_old.fb_ino
|
|
||||||
#define ofh_dirino fh_base.fh_old.fb_dirino
|
|
||||||
#define ofh_dev fh_base.fh_old.fb_dev
|
|
||||||
#define ofh_xdev fh_base.fh_old.fb_xdev
|
|
||||||
#define ofh_xino fh_base.fh_old.fb_xino
|
|
||||||
#define ofh_generation fh_base.fh_old.fb_generation
|
|
||||||
|
|
||||||
#define fh_version fh_base.fh_new.fb_version
|
#define fh_version fh_base.fh_new.fb_version
|
||||||
#define fh_fsid_type fh_base.fh_new.fb_fsid_type
|
#define fh_fsid_type fh_base.fh_new.fb_fsid_type
|
||||||
#define fh_auth_type fh_base.fh_new.fb_auth_type
|
#define fh_auth_type fh_base.fh_new.fb_auth_type
|
||||||
|
|
Загрузка…
Ссылка в новой задаче