|
@@ -295,7 +295,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
|
|
|
if (!iap->ia_valid)
|
|
|
goto out;
|
|
|
|
|
|
- /* NFSv2 does not differentiate between "set-[ac]time-to-now"
|
|
|
+ /*
|
|
|
+ * NFSv2 does not differentiate between "set-[ac]time-to-now"
|
|
|
* which only requires access, and "set-[ac]time-to-X" which
|
|
|
* requires ownership.
|
|
|
* 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,
|
|
|
*/
|
|
|
#define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
|
|
|
#define MAX_TOUCH_TIME_ERROR (30*60)
|
|
|
- if ((iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET
|
|
|
- && iap->ia_mtime.tv_sec == iap->ia_atime.tv_sec
|
|
|
- ) {
|
|
|
- /* Looks probable. Now just make sure time is in the right ballpark.
|
|
|
- * Solaris, at least, doesn't seem to care what the time request is.
|
|
|
- * We require it be within 30 minutes of now.
|
|
|
- */
|
|
|
- time_t delta = iap->ia_atime.tv_sec - get_seconds();
|
|
|
- if (delta<0) delta = -delta;
|
|
|
- if (delta < MAX_TOUCH_TIME_ERROR &&
|
|
|
- inode_change_ok(inode, iap) != 0) {
|
|
|
- /* turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME
|
|
|
- * this will cause notify_change to set these times to "now"
|
|
|
+ if ((iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET &&
|
|
|
+ iap->ia_mtime.tv_sec == iap->ia_atime.tv_sec) {
|
|
|
+ /*
|
|
|
+ * Looks probable.
|
|
|
+ *
|
|
|
+ * Now just make sure time is in the right ballpark.
|
|
|
+ * Solaris, at least, doesn't seem to care what the time
|
|
|
+ * request is. We require it be within 30 minutes of now.
|
|
|
*/
|
|
|
- iap->ia_valid &= ~BOTH_TIME_SET;
|
|
|
- }
|
|
|
+ time_t delta = iap->ia_atime.tv_sec - get_seconds();
|
|
|
+ if (delta < 0)
|
|
|
+ delta = -delta;
|
|
|
+ if (delta < MAX_TOUCH_TIME_ERROR &&
|
|
|
+ inode_change_ok(inode, iap) != 0) {
|
|
|
+ /*
|
|
|
+ * Turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME.
|
|
|
+ * This will cause notify_change to set these times
|
|
|
+ * to "now"
|
|
|
+ */
|
|
|
+ iap->ia_valid &= ~BOTH_TIME_SET;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- /* The size case is special. It changes the file as well as the attributes. */
|
|
|
+ /*
|
|
|
+ * The size case is special.
|
|
|
+ * It changes the file as well as the attributes.
|
|
|
+ */
|
|
|
if (iap->ia_valid & ATTR_SIZE) {
|
|
|
if (iap->ia_size < inode->i_size) {
|
|
|
err = nfsd_permission(rqstp, fhp->fh_export, dentry, MAY_TRUNC|MAY_OWNER_OVERRIDE);
|