diff options
-rw-r--r-- | fs/nfsd/nfs3xdr.c | 59 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 17 | ||||
-rw-r--r-- | fs/nfsd/nfsxdr.c | 4 | ||||
-rw-r--r-- | include/linux/nfsd/nfsfh.h | 42 | ||||
-rw-r--r-- | include/linux/nfsd/xdr4.h | 4 |
5 files changed, 45 insertions, 81 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 * | |||
174 | encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, | 174 | encode_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, | |||
203 | static __be32 * | 199 | static __be32 * |
204 | encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) | 200 | encode_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 | */ | ||
265 | void 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 | |||
643 | nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p, | 635 | nfs3svc_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 | ||
803 | static __be32 * | 798 | static __be32 * |
804 | encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, | 799 | encode_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)) |
874 | static int | 869 | static int |
875 | encode_entry(struct readdir_cd *ccd, const char *name, int namlen, | 870 | encode_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 */ |
diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h index 11e568ee0eeb..d1941cb965e9 100644 --- a/include/linux/nfsd/nfsfh.h +++ b/include/linux/nfsd/nfsfh.h | |||
@@ -150,17 +150,7 @@ typedef struct svc_fh { | |||
150 | struct timespec fh_pre_ctime; /* ctime before oper */ | 150 | struct timespec fh_pre_ctime; /* ctime before oper */ |
151 | 151 | ||
152 | /* Post-op attributes saved in fh_unlock */ | 152 | /* Post-op attributes saved in fh_unlock */ |
153 | umode_t fh_post_mode; /* i_mode */ | 153 | struct kstat fh_post_attr; /* full attrs after operation */ |
154 | nlink_t fh_post_nlink; /* i_nlink */ | ||
155 | uid_t fh_post_uid; /* i_uid */ | ||
156 | gid_t fh_post_gid; /* i_gid */ | ||
157 | __u64 fh_post_size; /* i_size */ | ||
158 | unsigned long fh_post_blocks; /* i_blocks */ | ||
159 | unsigned long fh_post_blksize;/* i_blksize */ | ||
160 | __be32 fh_post_rdev[2];/* i_rdev */ | ||
161 | struct timespec fh_post_atime; /* i_atime */ | ||
162 | struct timespec fh_post_mtime; /* i_mtime */ | ||
163 | struct timespec fh_post_ctime; /* i_ctime */ | ||
164 | #endif /* CONFIG_NFSD_V3 */ | 154 | #endif /* CONFIG_NFSD_V3 */ |
165 | 155 | ||
166 | } svc_fh; | 156 | } svc_fh; |
@@ -297,36 +287,12 @@ fill_pre_wcc(struct svc_fh *fhp) | |||
297 | if (!fhp->fh_pre_saved) { | 287 | if (!fhp->fh_pre_saved) { |
298 | fhp->fh_pre_mtime = inode->i_mtime; | 288 | fhp->fh_pre_mtime = inode->i_mtime; |
299 | fhp->fh_pre_ctime = inode->i_ctime; | 289 | fhp->fh_pre_ctime = inode->i_ctime; |
300 | fhp->fh_pre_size = inode->i_size; | 290 | fhp->fh_pre_size = inode->i_size; |
301 | fhp->fh_pre_saved = 1; | 291 | fhp->fh_pre_saved = 1; |
302 | } | 292 | } |
303 | } | 293 | } |
304 | 294 | ||
305 | /* | 295 | extern void fill_post_wcc(struct svc_fh *); |
306 | * Fill in the post_op attr for the wcc data | ||
307 | */ | ||
308 | static inline void | ||
309 | fill_post_wcc(struct svc_fh *fhp) | ||
310 | { | ||
311 | struct inode *inode = fhp->fh_dentry->d_inode; | ||
312 | |||
313 | if (fhp->fh_post_saved) | ||
314 | printk("nfsd: inode locked twice during operation.\n"); | ||
315 | |||
316 | fhp->fh_post_mode = inode->i_mode; | ||
317 | fhp->fh_post_nlink = inode->i_nlink; | ||
318 | fhp->fh_post_uid = inode->i_uid; | ||
319 | fhp->fh_post_gid = inode->i_gid; | ||
320 | fhp->fh_post_size = inode->i_size; | ||
321 | fhp->fh_post_blksize = BLOCK_SIZE; | ||
322 | fhp->fh_post_blocks = inode->i_blocks; | ||
323 | fhp->fh_post_rdev[0] = htonl((u32)imajor(inode)); | ||
324 | fhp->fh_post_rdev[1] = htonl((u32)iminor(inode)); | ||
325 | fhp->fh_post_atime = inode->i_atime; | ||
326 | fhp->fh_post_mtime = inode->i_mtime; | ||
327 | fhp->fh_post_ctime = inode->i_ctime; | ||
328 | fhp->fh_post_saved = 1; | ||
329 | } | ||
330 | #else | 296 | #else |
331 | #define fill_pre_wcc(ignored) | 297 | #define fill_pre_wcc(ignored) |
332 | #define fill_post_wcc(notused) | 298 | #define fill_post_wcc(notused) |
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h index 1b653267133a..b0ddfb41c790 100644 --- a/include/linux/nfsd/xdr4.h +++ b/include/linux/nfsd/xdr4.h | |||
@@ -428,8 +428,8 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) | |||
428 | cinfo->atomic = 1; | 428 | cinfo->atomic = 1; |
429 | cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec; | 429 | cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec; |
430 | cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec; | 430 | cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec; |
431 | cinfo->after_ctime_sec = fhp->fh_post_ctime.tv_sec; | 431 | cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec; |
432 | cinfo->after_ctime_nsec = fhp->fh_post_ctime.tv_nsec; | 432 | cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec; |
433 | } | 433 | } |
434 | 434 | ||
435 | int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); | 435 | int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); |