aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs3xdr.c59
-rw-r--r--fs/nfsd/nfs4xdr.c17
-rw-r--r--fs/nfsd/nfsxdr.c4
3 files changed, 39 insertions, 41 deletions
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 10f6e7dcf633..2d116d2298f8 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -174,9 +174,6 @@ static __be32 *
174encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, 174encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
175 struct kstat *stat) 175 struct kstat *stat)
176{ 176{
177 struct dentry *dentry = fhp->fh_dentry;
178 struct timespec time;
179
180 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); 177 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
181 *p++ = htonl((u32) stat->mode); 178 *p++ = htonl((u32) stat->mode);
182 *p++ = htonl((u32) stat->nlink); 179 *p++ = htonl((u32) stat->nlink);
@@ -191,10 +188,9 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
191 *p++ = htonl((u32) MAJOR(stat->rdev)); 188 *p++ = htonl((u32) MAJOR(stat->rdev));
192 *p++ = htonl((u32) MINOR(stat->rdev)); 189 *p++ = htonl((u32) MINOR(stat->rdev));
193 p = encode_fsid(p, fhp); 190 p = encode_fsid(p, fhp);
194 p = xdr_encode_hyper(p, (u64) stat->ino); 191 p = xdr_encode_hyper(p, stat->ino);
195 p = encode_time3(p, &stat->atime); 192 p = encode_time3(p, &stat->atime);
196 lease_get_mtime(dentry->d_inode, &time); 193 p = encode_time3(p, &stat->mtime);
197 p = encode_time3(p, &time);
198 p = encode_time3(p, &stat->ctime); 194 p = encode_time3(p, &stat->ctime);
199 195
200 return p; 196 return p;
@@ -203,31 +199,9 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
203static __be32 * 199static __be32 *
204encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) 200encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
205{ 201{
206 struct inode *inode = fhp->fh_dentry->d_inode;
207
208 /* Attributes to follow */ 202 /* Attributes to follow */
209 *p++ = xdr_one; 203 *p++ = xdr_one;
210 204 return encode_fattr3(rqstp, p, fhp, &fhp->fh_post_attr);
211 *p++ = htonl(nfs3_ftypes[(fhp->fh_post_mode & S_IFMT) >> 12]);
212 *p++ = htonl((u32) fhp->fh_post_mode);
213 *p++ = htonl((u32) fhp->fh_post_nlink);
214 *p++ = htonl((u32) nfsd_ruid(rqstp, fhp->fh_post_uid));
215 *p++ = htonl((u32) nfsd_rgid(rqstp, fhp->fh_post_gid));
216 if (S_ISLNK(fhp->fh_post_mode) && fhp->fh_post_size > NFS3_MAXPATHLEN) {
217 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
218 } else {
219 p = xdr_encode_hyper(p, (u64) fhp->fh_post_size);
220 }
221 p = xdr_encode_hyper(p, ((u64)fhp->fh_post_blocks) << 9);
222 *p++ = fhp->fh_post_rdev[0];
223 *p++ = fhp->fh_post_rdev[1];
224 p = encode_fsid(p, fhp);
225 p = xdr_encode_hyper(p, (u64) inode->i_ino);
226 p = encode_time3(p, &fhp->fh_post_atime);
227 p = encode_time3(p, &fhp->fh_post_mtime);
228 p = encode_time3(p, &fhp->fh_post_ctime);
229
230 return p;
231} 205}
232 206
233/* 207/*
@@ -246,6 +220,7 @@ encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
246 err = vfs_getattr(fhp->fh_export->ex_mnt, dentry, &stat); 220 err = vfs_getattr(fhp->fh_export->ex_mnt, dentry, &stat);
247 if (!err) { 221 if (!err) {
248 *p++ = xdr_one; /* attributes follow */ 222 *p++ = xdr_one; /* attributes follow */
223 lease_get_mtime(dentry->d_inode, &stat.mtime);
249 return encode_fattr3(rqstp, p, fhp, &stat); 224 return encode_fattr3(rqstp, p, fhp, &stat);
250 } 225 }
251 } 226 }
@@ -284,6 +259,23 @@ encode_wcc_data(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
284 return encode_post_op_attr(rqstp, p, fhp); 259 return encode_post_op_attr(rqstp, p, fhp);
285} 260}
286 261
262/*
263 * Fill in the post_op attr for the wcc data
264 */
265void fill_post_wcc(struct svc_fh *fhp)
266{
267 int err;
268
269 if (fhp->fh_post_saved)
270 printk("nfsd: inode locked twice during operation.\n");
271
272 err = vfs_getattr(fhp->fh_export->ex_mnt, fhp->fh_dentry,
273 &fhp->fh_post_attr);
274 if (err)
275 fhp->fh_post_saved = 0;
276 else
277 fhp->fh_post_saved = 1;
278}
287 279
288/* 280/*
289 * XDR decode functions 281 * XDR decode functions
@@ -643,8 +635,11 @@ int
643nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p, 635nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p,
644 struct nfsd3_attrstat *resp) 636 struct nfsd3_attrstat *resp)
645{ 637{
646 if (resp->status == 0) 638 if (resp->status == 0) {
639 lease_get_mtime(resp->fh.fh_dentry->d_inode,
640 &resp->stat.mtime);
647 p = encode_fattr3(rqstp, p, &resp->fh, &resp->stat); 641 p = encode_fattr3(rqstp, p, &resp->fh, &resp->stat);
642 }
648 return xdr_ressize_check(rqstp, p); 643 return xdr_ressize_check(rqstp, p);
649} 644}
650 645
@@ -802,7 +797,7 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p,
802 797
803static __be32 * 798static __be32 *
804encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, 799encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name,
805 int namlen, ino_t ino) 800 int namlen, u64 ino)
806{ 801{
807 *p++ = xdr_one; /* mark entry present */ 802 *p++ = xdr_one; /* mark entry present */
808 p = xdr_encode_hyper(p, ino); /* file id */ 803 p = xdr_encode_hyper(p, ino); /* file id */
@@ -873,7 +868,7 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
873#define NFS3_ENTRYPLUS_BAGGAGE (1 + 21 + 1 + (NFS3_FHSIZE >> 2)) 868#define NFS3_ENTRYPLUS_BAGGAGE (1 + 21 + 1 + (NFS3_FHSIZE >> 2))
874static int 869static int
875encode_entry(struct readdir_cd *ccd, const char *name, int namlen, 870encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
876 loff_t offset, ino_t ino, unsigned int d_type, int plus) 871 loff_t offset, u64 ino, unsigned int d_type, int plus)
877{ 872{
878 struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres, 873 struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres,
879 common); 874 common);
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 8ef0964179bc..9cf900740c76 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1679,7 +1679,7 @@ out_acl:
1679 if (bmval0 & FATTR4_WORD0_FILEID) { 1679 if (bmval0 & FATTR4_WORD0_FILEID) {
1680 if ((buflen -= 8) < 0) 1680 if ((buflen -= 8) < 0)
1681 goto out_resource; 1681 goto out_resource;
1682 WRITE64((u64) stat.ino); 1682 WRITE64(stat.ino);
1683 } 1683 }
1684 if (bmval0 & FATTR4_WORD0_FILES_AVAIL) { 1684 if (bmval0 & FATTR4_WORD0_FILES_AVAIL) {
1685 if ((buflen -= 8) < 0) 1685 if ((buflen -= 8) < 0)
@@ -1821,16 +1821,15 @@ out_acl:
1821 WRITE32(stat.mtime.tv_nsec); 1821 WRITE32(stat.mtime.tv_nsec);
1822 } 1822 }
1823 if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) { 1823 if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {
1824 struct dentry *mnt_pnt, *mnt_root;
1825
1826 if ((buflen -= 8) < 0) 1824 if ((buflen -= 8) < 0)
1827 goto out_resource; 1825 goto out_resource;
1828 mnt_root = exp->ex_mnt->mnt_root; 1826 if (exp->ex_mnt->mnt_root->d_inode == dentry->d_inode) {
1829 if (mnt_root->d_inode == dentry->d_inode) { 1827 err = vfs_getattr(exp->ex_mnt->mnt_parent,
1830 mnt_pnt = exp->ex_mnt->mnt_mountpoint; 1828 exp->ex_mnt->mnt_mountpoint, &stat);
1831 WRITE64((u64) mnt_pnt->d_inode->i_ino); 1829 if (err)
1832 } else 1830 goto out_nfserr;
1833 WRITE64((u64) stat.ino); 1831 }
1832 WRITE64(stat.ino);
1834 } 1833 }
1835 *attrlenp = htonl((char *)p - (char *)attrlenp - 4); 1834 *attrlenp = htonl((char *)p - (char *)attrlenp - 4);
1836 *countp = p - buffer; 1835 *countp = p - buffer;
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index cb3e7fadb772..986f9b32083c 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -523,6 +523,10 @@ nfssvc_encode_entry(void *ccdv, const char *name,
523 cd->common.err = nfserr_toosmall; 523 cd->common.err = nfserr_toosmall;
524 return -EINVAL; 524 return -EINVAL;
525 } 525 }
526 if (ino > ~((u32) 0)) {
527 cd->common.err = nfserr_fbig;
528 return -EINVAL;
529 }
526 *p++ = xdr_one; /* mark entry present */ 530 *p++ = xdr_one; /* mark entry present */
527 *p++ = htonl((u32) ino); /* file id */ 531 *p++ = htonl((u32) ino); /* file id */
528 p = xdr_encode_array(p, name, namlen);/* name length & name */ 532 p = xdr_encode_array(p, name, namlen);/* name length & name */