summaryrefslogtreecommitdiff
path: root/fs/nfsd/nfs3xdr.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2007-02-14 00:33:12 -0800
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-14 08:09:53 -0800
commitaf6a4e280e3ff453653f39190b57b345ff0bec16 (patch)
tree4895c90613737db7354f43431ed10a55dc0c98f0 /fs/nfsd/nfs3xdr.c
parent982aedfd091e6d9831216f8519f12242091be4fd (diff)
downloadlwn-af6a4e280e3ff453653f39190b57b345ff0bec16.tar.gz
lwn-af6a4e280e3ff453653f39190b57b345ff0bec16.zip
[PATCH] knfsd: add some new fsid types
Add support for using a filesystem UUID to identify and export point in the filehandle. For NFSv2, this UUID is xor-ed down to 4 or 8 bytes so that it doesn't take up too much room. For NFSv3+, we use the full 16 bytes, and possibly also a 64bit inode number for exports beneath the root of a filesystem. When generating an fsid to return in 'stat' information, use the UUID (hashed down to size) if it is available and a small 'fsid' was not specifically provided. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/nfsd/nfs3xdr.c')
-rw-r--r--fs/nfsd/nfs3xdr.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index e695660921ec..6f677988c71d 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -149,6 +149,27 @@ decode_sattr3(__be32 *p, struct iattr *iap)
return p;
}
+static __be32 *encode_fsid(__be32 *p, struct svc_fh *fhp)
+{
+ u64 f;
+ switch(fsid_source(fhp)) {
+ default:
+ case FSIDSOURCE_DEV:
+ p = xdr_encode_hyper(p, (u64)huge_encode_dev
+ (fhp->fh_dentry->d_inode->i_sb->s_dev));
+ break;
+ case FSIDSOURCE_FSID:
+ p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
+ break;
+ case FSIDSOURCE_UUID:
+ f = ((u64*)fhp->fh_export->ex_uuid)[0];
+ f ^= ((u64*)fhp->fh_export->ex_uuid)[1];
+ p = xdr_encode_hyper(p, f);
+ break;
+ }
+ return p;
+}
+
static __be32 *
encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
struct kstat *stat)
@@ -169,10 +190,7 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
p = xdr_encode_hyper(p, ((u64)stat->blocks) << 9);
*p++ = htonl((u32) MAJOR(stat->rdev));
*p++ = htonl((u32) MINOR(stat->rdev));
- if (is_fsid(fhp, rqstp->rq_reffh))
- p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
- else
- p = xdr_encode_hyper(p, (u64) huge_encode_dev(stat->dev));
+ p = encode_fsid(p, fhp);
p = xdr_encode_hyper(p, (u64) stat->ino);
p = encode_time3(p, &stat->atime);
lease_get_mtime(dentry->d_inode, &time);
@@ -203,10 +221,7 @@ encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
p = xdr_encode_hyper(p, ((u64)fhp->fh_post_blocks) << 9);
*p++ = fhp->fh_post_rdev[0];
*p++ = fhp->fh_post_rdev[1];
- if (is_fsid(fhp, rqstp->rq_reffh))
- p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
- else
- p = xdr_encode_hyper(p, (u64)huge_encode_dev(inode->i_sb->s_dev));
+ p = encode_fsid(p, fhp);
p = xdr_encode_hyper(p, (u64) inode->i_ino);
p = encode_time3(p, &fhp->fh_post_atime);
p = encode_time3(p, &fhp->fh_post_mtime);