diff options
Diffstat (limited to 'fs/attr.c')
-rw-r--r-- | fs/attr.c | 24 |
1 files changed, 8 insertions, 16 deletions
@@ -67,20 +67,12 @@ EXPORT_SYMBOL(inode_change_ok); | |||
67 | int inode_setattr(struct inode * inode, struct iattr * attr) | 67 | int 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); |
107 | out: | 99 | |
108 | return error; | 100 | return 0; |
109 | } | 101 | } |
110 | EXPORT_SYMBOL(inode_setattr); | 102 | EXPORT_SYMBOL(inode_setattr); |
111 | 103 | ||