summaryrefslogtreecommitdiff
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c45
1 files changed, 33 insertions, 12 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index a15b3a9bbff4..9c6a40f5cc57 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1889,18 +1889,27 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
CIFS_MOUNT_MAP_SPECIAL_CHR);
}
- if (!rc) {
- rc = inode_setattr(inode, attrs);
+ if (rc)
+ goto out;
- /* force revalidate when any of these times are set since some
- of the fs types (eg ext3, fat) do not have fine enough
- time granularity to match protocol, and we do not have a
- a way (yet) to query the server fs's time granularity (and
- whether it rounds times down).
- */
- if (!rc && (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME)))
- cifsInode->time = 0;
+ if ((attrs->ia_valid & ATTR_SIZE) &&
+ attrs->ia_size != i_size_read(inode)) {
+ rc = vmtruncate(inode, attrs->ia_size);
+ if (rc)
+ goto out;
}
+
+ setattr_copy(inode, attrs);
+ mark_inode_dirty(inode);
+
+ /* force revalidate when any of these times are set since some
+ of the fs types (eg ext3, fat) do not have fine enough
+ time granularity to match protocol, and we do not have a
+ a way (yet) to query the server fs's time granularity (and
+ whether it rounds times down).
+ */
+ if (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME))
+ cifsInode->time = 0;
out:
kfree(args);
kfree(full_path);
@@ -2040,8 +2049,20 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
/* do not need local check to inode_check_ok since the server does
that */
- if (!rc)
- rc = inode_setattr(inode, attrs);
+ if (rc)
+ goto cifs_setattr_exit;
+
+ if ((attrs->ia_valid & ATTR_SIZE) &&
+ attrs->ia_size != i_size_read(inode)) {
+ rc = vmtruncate(inode, attrs->ia_size);
+ if (rc)
+ goto cifs_setattr_exit;
+ }
+
+ setattr_copy(inode, attrs);
+ mark_inode_dirty(inode);
+ return 0;
+
cifs_setattr_exit:
kfree(full_path);
FreeXid(xid);