aboutsummaryrefslogtreecommitdiffstats
path: root/fs/attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/attr.c')
-rw-r--r--fs/attr.c24
1 files changed, 8 insertions, 16 deletions
diff --git a/fs/attr.c b/fs/attr.c
index 67bcd9b14ea5..b34732506f1d 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -67,20 +67,12 @@ EXPORT_SYMBOL(inode_change_ok);
67int inode_setattr(struct inode * inode, struct iattr * attr) 67int inode_setattr(struct inode * inode, struct iattr * attr)
68{ 68{
69 unsigned int ia_valid = attr->ia_valid; 69 unsigned int ia_valid = attr->ia_valid;
70 int error = 0; 70
71 71 if (ia_valid & ATTR_SIZE &&
72 if (ia_valid & ATTR_SIZE) { 72 attr->ia_size != i_size_read(inode)) {
73 if (attr->ia_size != i_size_read(inode)) { 73 int error = vmtruncate(inode, attr->ia_size);
74 error = vmtruncate(inode, attr->ia_size); 74 if (error)
75 if (error || (ia_valid == ATTR_SIZE)) 75 return error;
76 goto out;
77 } else {
78 /*
79 * We skipped the truncate but must still update
80 * timestamps
81 */
82 ia_valid |= ATTR_MTIME|ATTR_CTIME;
83 }
84 } 76 }
85 77
86 if (ia_valid & ATTR_UID) 78 if (ia_valid & ATTR_UID)
@@ -104,8 +96,8 @@ int inode_setattr(struct inode * inode, struct iattr * attr)
104 inode->i_mode = mode; 96 inode->i_mode = mode;
105 } 97 }
106 mark_inode_dirty(inode); 98 mark_inode_dirty(inode);
107out: 99
108 return error; 100 return 0;
109} 101}
110EXPORT_SYMBOL(inode_setattr); 102EXPORT_SYMBOL(inode_setattr);
111 103