]> git.hungrycats.org Git - linux/commitdiff
[PATCH] PATCH 3 of 4 : knfsd : Store the fsid in the returned attributes instead...
authorNeil Brown <neilb@cse.unsw.edu.au>
Fri, 5 Apr 2002 07:11:29 +0000 (23:11 -0800)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Fri, 5 Apr 2002 07:11:29 +0000 (23:11 -0800)
When a filesystem is exported with  fsid=  we should use that
fsid instead of the i_dev number when returning NFS attributes,
so that there is no chance of clients that depend on the filesys
id in the attributes getting confused by device numbers changing.

We only do this if the reference filehandle uses fsid to identify
the filesystem, so that a server can be converted from non-fsid= to
using fsid= without confusing active clients.

fs/nfsd/nfs3xdr.c
fs/nfsd/nfsfh.c
fs/nfsd/nfsxdr.c
include/linux/sunrpc/svc.h

index b60c4f504dcb44d966426c25d6d9ce7065204106..20b86a0e79df7f4b7a5140ddf21ff83df408bb5d 100644 (file)
@@ -154,9 +154,9 @@ decode_sattr3(u32 *p, struct iattr *iap)
 }
 
 static inline u32 *
-encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct dentry *dentry)
+encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
 {
-       struct inode    *inode = dentry->d_inode;
+       struct inode    *inode = fhp->fh_dentry->d_inode;
 
        *p++ = htonl(nfs3_ftypes[(inode->i_mode & S_IFMT) >> 12]);
        *p++ = htonl((u32) inode->i_mode);
@@ -175,7 +175,12 @@ encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct dentry *dentry)
                p = xdr_encode_hyper(p, ((u64)inode->i_blocks) << 9);
        *p++ = htonl((u32) major(inode->i_rdev));
        *p++ = htonl((u32) minor(inode->i_rdev));
-       p = xdr_encode_hyper(p, (u64) kdev_t_to_nr(inode->i_dev));
+       if (rqstp->rq_reffh->fh_version == 1
+           && rqstp->rq_reffh->fh_fsid_type == 1
+           && (fhp->fh_export->ex_flags & NFSEXP_FSID))
+               p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
+       else
+               p = xdr_encode_hyper(p, (u64) kdev_t_to_nr(inode->i_dev));
        p = xdr_encode_hyper(p, (u64) inode->i_ino);
        p = encode_time3(p, inode->i_atime);
        p = encode_time3(p, lease_get_mtime(inode));
@@ -205,7 +210,12 @@ encode_saved_post_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
        p = xdr_encode_hyper(p, ((u64)fhp->fh_post_blocks) << 9);
        *p++ = htonl((u32) major(fhp->fh_post_rdev));
        *p++ = htonl((u32) minor(fhp->fh_post_rdev));
-       p = xdr_encode_hyper(p, (u64) kdev_t_to_nr(inode->i_dev));
+       if (rqstp->rq_reffh->fh_version == 1
+           && rqstp->rq_reffh->fh_fsid_type == 1
+           && (fhp->fh_export->ex_flags & NFSEXP_FSID))
+               p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
+       else
+               p = xdr_encode_hyper(p, (u64) kdev_t_to_nr(inode->i_dev));
        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);
@@ -220,11 +230,12 @@ encode_saved_post_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
  * handle. In this case, no attributes are returned.
  */
 static u32 *
-encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct dentry *dentry)
+encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
 {
+       struct dentry *dentry = fhp->fh_dentry;
        if (dentry && dentry->d_inode != NULL) {
                *p++ = xdr_one;         /* attributes follow */
-               return encode_fattr3(rqstp, p, dentry);
+               return encode_fattr3(rqstp, p, fhp);
        }
        *p++ = xdr_zero;
        return p;
@@ -251,7 +262,7 @@ encode_wcc_data(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
        }
        /* no pre- or post-attrs */
        *p++ = xdr_zero;
-       return encode_post_op_attr(rqstp, p, dentry);
+       return encode_post_op_attr(rqstp, p, fhp);
 }
 
 /*
@@ -509,7 +520,7 @@ nfs3svc_encode_attrstat(struct svc_rqst *rqstp, u32 *p,
                                        struct nfsd3_attrstat *resp)
 {
        if (resp->status == 0)
-               p = encode_fattr3(rqstp, p, resp->fh.fh_dentry);
+               p = encode_fattr3(rqstp, p, &resp->fh);
        return xdr_ressize_check(rqstp, p);
 }
 
@@ -529,9 +540,9 @@ nfs3svc_encode_diropres(struct svc_rqst *rqstp, u32 *p,
 {
        if (resp->status == 0) {
                p = encode_fh(p, &resp->fh);
-               p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry);
+               p = encode_post_op_attr(rqstp, p, &resp->fh);
        }
-       p = encode_post_op_attr(rqstp, p, resp->dirfh.fh_dentry);
+       p = encode_post_op_attr(rqstp, p, &resp->dirfh);
        return xdr_ressize_check(rqstp, p);
 }
 
@@ -540,7 +551,7 @@ int
 nfs3svc_encode_accessres(struct svc_rqst *rqstp, u32 *p,
                                        struct nfsd3_accessres *resp)
 {
-       p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry);
+       p = encode_post_op_attr(rqstp, p, &resp->fh);
        if (resp->status == 0)
                *p++ = htonl(resp->access);
        return xdr_ressize_check(rqstp, p);
@@ -551,7 +562,7 @@ int
 nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
                                        struct nfsd3_readlinkres *resp)
 {
-       p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry);
+       p = encode_post_op_attr(rqstp, p, &resp->fh);
        if (resp->status == 0) {
                *p++ = htonl(resp->len);
                p += XDR_QUADLEN(resp->len);
@@ -564,7 +575,7 @@ int
 nfs3svc_encode_readres(struct svc_rqst *rqstp, u32 *p,
                                        struct nfsd3_readres *resp)
 {
-       p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry);
+       p = encode_post_op_attr(rqstp, p, &resp->fh);
        if (resp->status == 0) {
                *p++ = htonl(resp->count);
                *p++ = htonl(resp->eof);
@@ -597,7 +608,7 @@ nfs3svc_encode_createres(struct svc_rqst *rqstp, u32 *p,
        if (resp->status == 0) {
                *p++ = xdr_one;
                p = encode_fh(p, &resp->fh);
-               p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry);
+               p = encode_post_op_attr(rqstp, p, &resp->fh);
        }
        p = encode_wcc_data(rqstp, p, &resp->dirfh);
        return xdr_ressize_check(rqstp, p);
@@ -618,7 +629,7 @@ int
 nfs3svc_encode_linkres(struct svc_rqst *rqstp, u32 *p,
                                        struct nfsd3_linkres *resp)
 {
-       p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry);
+       p = encode_post_op_attr(rqstp, p, &resp->fh);
        p = encode_wcc_data(rqstp, p, &resp->tfh);
        return xdr_ressize_check(rqstp, p);
 }
@@ -628,7 +639,7 @@ int
 nfs3svc_encode_readdirres(struct svc_rqst *rqstp, u32 *p,
                                        struct nfsd3_readdirres *resp)
 {
-       p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry);
+       p = encode_post_op_attr(rqstp, p, &resp->fh);
        if (resp->status == 0) {
                /* stupid readdir cookie */
                memcpy(p, resp->verf, 8); p += 2;
@@ -711,7 +722,7 @@ encode_entry(struct readdir_cd *cd, const char *name,
                        goto noexec;
                if (fh_compose(&fh, exp, dchild, cd->dirfh) != 0 || !dchild->d_inode)
                        goto noexec;
-               p = encode_post_op_attr(cd->rqstp, p, fh.fh_dentry);
+               p = encode_post_op_attr(cd->rqstp, p, &fh);
                *p++ = xdr_one; /* yes, a file handle follows */
                p = encode_fh(p, &fh);
                fh_put(&fh);
index 01e2d4ed3b4ebf7702bb6af62320c32b5a49d657..3e43875de60f1398bb953f5c645e38935a3d41f0 100644 (file)
@@ -546,6 +546,9 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
 
        dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));
 
+       /* keep this filehandle for possible reference  when encoding attributes */
+       rqstp->rq_reffh = fhp;
+
        if (!fhp->fh_dentry) {
                kdev_t xdev = NODEV;
                ino_t xino = 0;
index 4611beb2f99e892b768ecdac12493a6bf358e614..3e59bdb864d222190634fef14a07111c09d29e04 100644 (file)
@@ -132,8 +132,9 @@ decode_sattr(u32 *p, struct iattr *iap)
 }
 
 static inline u32 *
-encode_fattr(struct svc_rqst *rqstp, u32 *p, struct inode *inode)
+encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
 {
+       struct inode *inode = fhp->fh_dentry->d_inode;
        int type = (inode->i_mode & S_IFMT);
 
        *p++ = htonl(nfs_ftypes[type >> 12]);
@@ -153,7 +154,12 @@ encode_fattr(struct svc_rqst *rqstp, u32 *p, struct inode *inode)
        else
                *p++ = htonl(0xffffffff);
        *p++ = htonl((u32) inode->i_blocks);
-       *p++ = htonl((u32) kdev_t_to_nr(inode->i_dev));
+       if (rqstp->rq_reffh->fh_version == 1 
+           && rqstp->rq_reffh->fh_fsid_type == 1
+           && (fhp->fh_export->ex_flags & NFSEXP_FSID))
+               *p++ = htonl((u32) fhp->fh_export->ex_fsid);
+       else
+               *p++ = htonl((u32) kdev_t_to_nr(inode->i_dev));
        *p++ = htonl((u32) inode->i_ino);
        *p++ = htonl((u32) inode->i_atime);
        *p++ = 0;
@@ -332,7 +338,7 @@ int
 nfssvc_encode_attrstat(struct svc_rqst *rqstp, u32 *p,
                                        struct nfsd_attrstat *resp)
 {
-       p = encode_fattr(rqstp, p, resp->fh.fh_dentry->d_inode);
+       p = encode_fattr(rqstp, p, &resp->fh);
        return xdr_ressize_check(rqstp, p);
 }
 
@@ -341,7 +347,7 @@ nfssvc_encode_diropres(struct svc_rqst *rqstp, u32 *p,
                                        struct nfsd_diropres *resp)
 {
        p = encode_fh(p, &resp->fh);
-       p = encode_fattr(rqstp, p, resp->fh.fh_dentry->d_inode);
+       p = encode_fattr(rqstp, p, &resp->fh);
        return xdr_ressize_check(rqstp, p);
 }
 
@@ -358,7 +364,7 @@ int
 nfssvc_encode_readres(struct svc_rqst *rqstp, u32 *p,
                                        struct nfsd_readres *resp)
 {
-       p = encode_fattr(rqstp, p, resp->fh.fh_dentry->d_inode);
+       p = encode_fattr(rqstp, p, &resp->fh);
        *p++ = htonl(resp->count);
        p += XDR_QUADLEN(resp->count);
 
index 2d2461bb38c8ecc697b9a93cdc718a5c441240a1..71054b826df23a0962fc319398e36d39d9d26421 100644 (file)
@@ -123,6 +123,10 @@ struct svc_rqst {
        /* Catering to nfsd */
        struct svc_client *     rq_client;      /* RPC peer info */
        struct svc_cacherep *   rq_cacherep;    /* cache info */
+       struct knfsd_fh *       rq_reffh;       /* Referrence filehandle, used to
+                                                * determine what device number
+                                                * to report (real or virtual)
+                                                */
 
        wait_queue_head_t       rq_wait;        /* synchronozation */
 };