mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
nfsd: special case truncates some more
am: a3c6cbc4ea
Change-Id: Iac8449fa5d6abf4b195fd0a7287b2c0416115515
This commit is contained in:
@@ -414,13 +414,19 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
|
||||
|
||||
/*
|
||||
* The size case is special, it changes the file in addition to the
|
||||
* attributes.
|
||||
* attributes, and file systems don't expect it to be mixed with
|
||||
* "random" attribute changes. We thus split out the size change
|
||||
* into a separate call to ->setattr, and do the rest as a separate
|
||||
* setattr call.
|
||||
*/
|
||||
if (size_change) {
|
||||
err = nfsd_get_write_access(rqstp, fhp, iap);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
fh_lock(fhp);
|
||||
if (size_change) {
|
||||
/*
|
||||
* RFC5661, Section 18.30.4:
|
||||
* Changing the size of a file with SETATTR indirectly
|
||||
@@ -428,16 +434,30 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
|
||||
*
|
||||
* (and similar for the older RFCs)
|
||||
*/
|
||||
if (iap->ia_size != i_size_read(inode))
|
||||
iap->ia_valid |= ATTR_MTIME;
|
||||
struct iattr size_attr = {
|
||||
.ia_valid = ATTR_SIZE | ATTR_CTIME | ATTR_MTIME,
|
||||
.ia_size = iap->ia_size,
|
||||
};
|
||||
|
||||
host_err = notify_change(dentry, &size_attr, NULL);
|
||||
if (host_err)
|
||||
goto out_unlock;
|
||||
iap->ia_valid &= ~ATTR_SIZE;
|
||||
|
||||
/*
|
||||
* Avoid the additional setattr call below if the only other
|
||||
* attribute that the client sends is the mtime, as we update
|
||||
* it as part of the size change above.
|
||||
*/
|
||||
if ((iap->ia_valid & ~ATTR_MTIME) == 0)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
iap->ia_valid |= ATTR_CTIME;
|
||||
|
||||
fh_lock(fhp);
|
||||
host_err = notify_change(dentry, iap, NULL);
|
||||
fh_unlock(fhp);
|
||||
|
||||
out_unlock:
|
||||
fh_unlock(fhp);
|
||||
if (size_change)
|
||||
put_write_access(inode);
|
||||
out:
|
||||
|
||||
Reference in New Issue
Block a user