aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/vfs.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-15 11:16:53 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-15 11:16:53 -0400
commit37ca506adc395a028cd12760eca419dd0dc14b5c (patch)
treebab6f2644ef6bda4df1518f7063852012b69f458 /fs/nfsd/vfs.c
parentb9090071a57185707c27b9d61b81bf941dbdf122 (diff)
parenta16e92edcd0a2846455a30823e1bac964e743baa (diff)
Merge branch 'nfs-server-stable' of git://linux-nfs.org/~bfields/linux
* 'nfs-server-stable' of git://linux-nfs.org/~bfields/linux: knfsd: query filesystem for NFSv4 getattr of FATTR4_MAXNAME knfsd: nfsv4 delegation recall should take reference on client knfsd: don't shutdown callbacks until nfsv4 client is freed knfsd: let nfsd manage timing out its own leases knfsd: Add source address to sunrpc svc errors knfsd: 64 bit ino support for NFS server svcgss: move init code into separate function knfsd: remove code duplication in nfsd4_setclientid() nfsd warning fix knfsd: fix callback rpc cred knfsd: move nfsv4 slab creation/destruction to module init/exit knfsd: spawn kernel thread to probe callback channel knfsd: nfs4 name->id mapping not correctly parsing negative downcall knfsd: demote some printk()s to dprintk()s knfsd: cleanup of nfsd4 cmp_* functions knfsd: delete code made redundant by map_new_errors nfsd: fix horrible indentation in nfsd_setattr nfsd: remove unused cache_for_each macro nfsd: tone down inaccurate dprintk
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r--fs/nfsd/vfs.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 7867151ebb83..cec78c82b1f9 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -295,7 +295,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
295 if (!iap->ia_valid) 295 if (!iap->ia_valid)
296 goto out; 296 goto out;
297 297
298 /* NFSv2 does not differentiate between "set-[ac]time-to-now" 298 /*
299 * NFSv2 does not differentiate between "set-[ac]time-to-now"
299 * which only requires access, and "set-[ac]time-to-X" which 300 * which only requires access, and "set-[ac]time-to-X" which
300 * requires ownership. 301 * requires ownership.
301 * So if it looks like it might be "set both to the same time which 302 * So if it looks like it might be "set both to the same time which
@@ -308,25 +309,33 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
308 */ 309 */
309#define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET) 310#define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
310#define MAX_TOUCH_TIME_ERROR (30*60) 311#define MAX_TOUCH_TIME_ERROR (30*60)
311 if ((iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET 312 if ((iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET &&
312 && iap->ia_mtime.tv_sec == iap->ia_atime.tv_sec 313 iap->ia_mtime.tv_sec == iap->ia_atime.tv_sec) {
313 ) { 314 /*
314 /* Looks probable. Now just make sure time is in the right ballpark. 315 * Looks probable.
315 * Solaris, at least, doesn't seem to care what the time request is. 316 *
316 * We require it be within 30 minutes of now. 317 * Now just make sure time is in the right ballpark.
317 */ 318 * Solaris, at least, doesn't seem to care what the time
318 time_t delta = iap->ia_atime.tv_sec - get_seconds(); 319 * request is. We require it be within 30 minutes of now.
319 if (delta<0) delta = -delta;
320 if (delta < MAX_TOUCH_TIME_ERROR &&
321 inode_change_ok(inode, iap) != 0) {
322 /* turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME
323 * this will cause notify_change to set these times to "now"
324 */ 320 */
325 iap->ia_valid &= ~BOTH_TIME_SET; 321 time_t delta = iap->ia_atime.tv_sec - get_seconds();
326 } 322 if (delta < 0)
323 delta = -delta;
324 if (delta < MAX_TOUCH_TIME_ERROR &&
325 inode_change_ok(inode, iap) != 0) {
326 /*
327 * Turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME.
328 * This will cause notify_change to set these times
329 * to "now"
330 */
331 iap->ia_valid &= ~BOTH_TIME_SET;
332 }
327 } 333 }
328 334
329 /* The size case is special. It changes the file as well as the attributes. */ 335 /*
336 * The size case is special.
337 * It changes the file as well as the attributes.
338 */
330 if (iap->ia_valid & ATTR_SIZE) { 339 if (iap->ia_valid & ATTR_SIZE) {
331 if (iap->ia_size < inode->i_size) { 340 if (iap->ia_size < inode->i_size) {
332 err = nfsd_permission(rqstp, fhp->fh_export, dentry, MAY_TRUNC|MAY_OWNER_OVERRIDE); 341 err = nfsd_permission(rqstp, fhp->fh_export, dentry, MAY_TRUNC|MAY_OWNER_OVERRIDE);