Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 71980
b: refs/heads/master
c: 6e91ea2
h: refs/heads/master
v: v3
  • Loading branch information
Christoph Hellwig authored and Linus Torvalds committed Oct 22, 2007
1 parent dc4ed39 commit d2f670a
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 58 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 00bf4098beb15ca174b54f3af1f1e1908d7d18a3
refs/heads/master: 6e91ea2bb0b6a3ddf6d4faeb54a9c20d4e20bc42
36 changes: 18 additions & 18 deletions trunk/fs/exportfs/expfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,29 +434,29 @@ static int get_name(struct dentry *dentry, char *name,
* can be used to check that it is still valid. It places them in the
* filehandle fragment where export_decode_fh expects to find them.
*/
static int export_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
int connectable)
static int export_encode_fh(struct dentry *dentry, struct fid *fid,
int *max_len, int connectable)
{
struct inode * inode = dentry->d_inode;
int len = *max_len;
int type = 1;
int type = FILEID_INO32_GEN;

if (len < 2 || (connectable && len < 4))
return 255;

len = 2;
fh[0] = inode->i_ino;
fh[1] = inode->i_generation;
fid->i32.ino = inode->i_ino;
fid->i32.gen = inode->i_generation;
if (connectable && !S_ISDIR(inode->i_mode)) {
struct inode *parent;

spin_lock(&dentry->d_lock);
parent = dentry->d_parent->d_inode;
fh[2] = parent->i_ino;
fh[3] = parent->i_generation;
fid->i32.parent_ino = parent->i_ino;
fid->i32.parent_gen = parent->i_generation;
spin_unlock(&dentry->d_lock);
len = 4;
type = 2;
type = FILEID_INO32_GEN_PARENT;
}
*max_len = len;
return type;
Expand Down Expand Up @@ -494,34 +494,34 @@ static struct dentry *export_decode_fh(struct super_block *sb, __u32 *fh, int fh
acceptable, context);
}

int exportfs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, int *max_len,
int connectable)
{
struct export_operations *nop = dentry->d_sb->s_export_op;
int error;

if (nop->encode_fh)
error = nop->encode_fh(dentry, fh, max_len, connectable);
error = nop->encode_fh(dentry, fid->raw, max_len, connectable);
else
error = export_encode_fh(dentry, fh, max_len, connectable);
error = export_encode_fh(dentry, fid, max_len, connectable);

return error;
}
EXPORT_SYMBOL_GPL(exportfs_encode_fh);

struct dentry *exportfs_decode_fh(struct vfsmount *mnt, __u32 *fh, int fh_len,
int fileid_type, int (*acceptable)(void *, struct dentry *),
void *context)
struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
int fh_len, int fileid_type,
int (*acceptable)(void *, struct dentry *), void *context)
{
struct export_operations *nop = mnt->mnt_sb->s_export_op;
struct dentry *result;

if (nop->decode_fh) {
result = nop->decode_fh(mnt->mnt_sb, fh, fh_len, fileid_type,
acceptable, context);
result = nop->decode_fh(mnt->mnt_sb, fid->raw, fh_len,
fileid_type, acceptable, context);
} else {
result = export_decode_fh(mnt->mnt_sb, fh, fh_len, fileid_type,
acceptable, context);
result = export_decode_fh(mnt->mnt_sb, fid->raw, fh_len,
fileid_type, acceptable, context);
}

return result;
Expand Down
67 changes: 31 additions & 36 deletions trunk/fs/nfsd/nfsfh.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));

if (!fhp->fh_dentry) {
__u32 *datap=NULL;
__u32 tfh[3]; /* filehandle fragment for oldstyle filehandles */
struct fid *fid = NULL, sfid;
int fileid_type;
int data_left = fh->fh_size/4;

Expand All @@ -128,7 +127,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)

if (fh->fh_version == 1) {
int len;
datap = fh->fh_auth;
if (--data_left<0) goto out;
switch (fh->fh_auth_type) {
case 0: break;
Expand All @@ -144,9 +142,11 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
fh->fh_fsid[1] = fh->fh_fsid[2];
}
if ((data_left -= len)<0) goto out;
exp = rqst_exp_find(rqstp, fh->fh_fsid_type, datap);
datap += len;
exp = rqst_exp_find(rqstp, fh->fh_fsid_type,
fh->fh_auth);
fid = (struct fid *)(fh->fh_auth + len);
} else {
__u32 tfh[2];
dev_t xdev;
ino_t xino;
if (fh->fh_size != NFS_FHSIZE)
Expand Down Expand Up @@ -190,22 +190,22 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
error = nfserr_badhandle;

if (fh->fh_version != 1) {
tfh[0] = fh->ofh_ino;
tfh[1] = fh->ofh_generation;
tfh[2] = fh->ofh_dirino;
datap = tfh;
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 = 1;
fileid_type = FILEID_INO32_GEN;
else
fileid_type = 2;
fileid_type = FILEID_INO32_GEN_PARENT;
} else
fileid_type = fh->fh_fileid_type;

if (fileid_type == 0)
if (fileid_type == FILEID_ROOT)
dentry = dget(exp->ex_dentry);
else {
dentry = exportfs_decode_fh(exp->ex_mnt, datap,
dentry = exportfs_decode_fh(exp->ex_mnt, fid,
data_left, fileid_type,
nfsd_acceptable, exp);
}
Expand Down Expand Up @@ -286,16 +286,21 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
* an inode. In this case a call to fh_update should be made
* before the fh goes out on the wire ...
*/
static inline int _fh_update(struct dentry *dentry, struct svc_export *exp,
__u32 *datap, int *maxsize)
static void _fh_update(struct svc_fh *fhp, struct svc_export *exp,
struct dentry *dentry)
{
if (dentry == exp->ex_dentry) {
*maxsize = 0;
return 0;
}
if (dentry != exp->ex_dentry) {
struct fid *fid = (struct fid *)
(fhp->fh_handle.fh_auth + fhp->fh_handle.fh_size/4 - 1);
int maxsize = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
int subtreecheck = !(exp->ex_flags & NFSEXP_NOSUBTREECHECK);

return exportfs_encode_fh(dentry, datap, maxsize,
!(exp->ex_flags & NFSEXP_NOSUBTREECHECK));
fhp->fh_handle.fh_fileid_type =
exportfs_encode_fh(dentry, fid, &maxsize, subtreecheck);
fhp->fh_handle.fh_size += maxsize * 4;
} else {
fhp->fh_handle.fh_fileid_type = FILEID_ROOT;
}
}

/*
Expand Down Expand Up @@ -457,12 +462,8 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
datap += len/4;
fhp->fh_handle.fh_size = 4 + len;

if (inode) {
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;
}
if (inode)
_fh_update(fhp, exp, dentry);
if (fhp->fh_handle.fh_fileid_type == 255)
return nfserr_opnotsupp;
}
Expand All @@ -479,7 +480,6 @@ __be32
fh_update(struct svc_fh *fhp)
{
struct dentry *dentry;
__u32 *datap;

if (!fhp->fh_dentry)
goto out_bad;
Expand All @@ -490,15 +490,10 @@ fh_update(struct svc_fh *fhp)
if (fhp->fh_handle.fh_version != 1) {
_fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle);
} else {
int size;
if (fhp->fh_handle.fh_fileid_type != 0)
if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT)
goto out;
datap = fhp->fh_handle.fh_auth+
fhp->fh_handle.fh_size/4 -1;
size = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
fhp->fh_handle.fh_fileid_type =
_fh_update(dentry, fhp->fh_export, datap, &size);
fhp->fh_handle.fh_size += size*4;

_fh_update(fhp, fhp->fh_export, dentry);
if (fhp->fh_handle.fh_fileid_type == 255)
return nfserr_opnotsupp;
}
Expand Down
44 changes: 41 additions & 3 deletions trunk/include/linux/exportfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,44 @@ struct dentry;
struct super_block;
struct vfsmount;

/*
* The fileid_type identifies how the file within the filesystem is encoded.
* In theory this is freely set and parsed by the filesystem, but we try to
* stick to conventions so we can share some generic code and don't confuse
* sniffers like ethereal/wireshark.
*
* The filesystem must not use the value '0' or '0xff'.
*/
enum fid_type {
/*
* The root, or export point, of the filesystem.
* (Never actually passed down to the filesystem.
*/
FILEID_ROOT = 0,

/*
* 32bit inode number, 32 bit generation number.
*/
FILEID_INO32_GEN = 1,

/*
* 32bit inode number, 32 bit generation number,
* 32 bit parent directory inode number.
*/
FILEID_INO32_GEN_PARENT = 2,
};

struct fid {
union {
struct {
u32 ino;
u32 gen;
u32 parent_ino;
u32 parent_gen;
} i32;
__u32 raw[6];
};
};

/**
* struct export_operations - for nfsd to communicate with file systems
Expand Down Expand Up @@ -117,9 +155,9 @@ extern struct dentry *find_exported_dentry(struct super_block *sb, void *obj,
void *parent, int (*acceptable)(void *context, struct dentry *de),
void *context);

extern int exportfs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
int connectable);
extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, __u32 *fh,
extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid,
int *max_len, int connectable);
extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
int fh_len, int fileid_type, int (*acceptable)(void *, struct dentry *),
void *context);

Expand Down

0 comments on commit d2f670a

Please sign in to comment.