diff options
Diffstat (limited to 'fs/ext2')
-rw-r--r-- | fs/ext2/acl.c | 65 | ||||
-rw-r--r-- | fs/ext2/acl.h | 3 | ||||
-rw-r--r-- | fs/ext2/ext2.h | 3 | ||||
-rw-r--r-- | fs/ext2/file.c | 6 | ||||
-rw-r--r-- | fs/ext2/inode.c | 6 | ||||
-rw-r--r-- | fs/ext2/namei.c | 18 | ||||
-rw-r--r-- | fs/ext2/xattr.c | 10 |
7 files changed, 35 insertions, 76 deletions
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index abea5a17c76..35d6a3cfd9f 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c | |||
@@ -128,7 +128,7 @@ fail: | |||
128 | /* | 128 | /* |
129 | * inode->i_mutex: don't care | 129 | * inode->i_mutex: don't care |
130 | */ | 130 | */ |
131 | static struct posix_acl * | 131 | struct posix_acl * |
132 | ext2_get_acl(struct inode *inode, int type) | 132 | ext2_get_acl(struct inode *inode, int type) |
133 | { | 133 | { |
134 | int name_index; | 134 | int name_index; |
@@ -194,12 +194,10 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) | |||
194 | case ACL_TYPE_ACCESS: | 194 | case ACL_TYPE_ACCESS: |
195 | name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; | 195 | name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS; |
196 | if (acl) { | 196 | if (acl) { |
197 | mode_t mode = inode->i_mode; | 197 | error = posix_acl_equiv_mode(acl, &inode->i_mode); |
198 | error = posix_acl_equiv_mode(acl, &mode); | ||
199 | if (error < 0) | 198 | if (error < 0) |
200 | return error; | 199 | return error; |
201 | else { | 200 | else { |
202 | inode->i_mode = mode; | ||
203 | inode->i_ctime = CURRENT_TIME_SEC; | 201 | inode->i_ctime = CURRENT_TIME_SEC; |
204 | mark_inode_dirty(inode); | 202 | mark_inode_dirty(inode); |
205 | if (error == 0) | 203 | if (error == 0) |
@@ -231,29 +229,6 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) | |||
231 | return error; | 229 | return error; |
232 | } | 230 | } |
233 | 231 | ||
234 | int | ||
235 | ext2_check_acl(struct inode *inode, int mask, unsigned int flags) | ||
236 | { | ||
237 | struct posix_acl *acl; | ||
238 | |||
239 | if (flags & IPERM_FLAG_RCU) { | ||
240 | if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) | ||
241 | return -ECHILD; | ||
242 | return -EAGAIN; | ||
243 | } | ||
244 | |||
245 | acl = ext2_get_acl(inode, ACL_TYPE_ACCESS); | ||
246 | if (IS_ERR(acl)) | ||
247 | return PTR_ERR(acl); | ||
248 | if (acl) { | ||
249 | int error = posix_acl_permission(inode, acl, mask); | ||
250 | posix_acl_release(acl); | ||
251 | return error; | ||
252 | } | ||
253 | |||
254 | return -EAGAIN; | ||
255 | } | ||
256 | |||
257 | /* | 232 | /* |
258 | * Initialize the ACLs of a new inode. Called from ext2_new_inode. | 233 | * Initialize the ACLs of a new inode. Called from ext2_new_inode. |
259 | * | 234 | * |
@@ -276,29 +251,18 @@ ext2_init_acl(struct inode *inode, struct inode *dir) | |||
276 | inode->i_mode &= ~current_umask(); | 251 | inode->i_mode &= ~current_umask(); |
277 | } | 252 | } |
278 | if (test_opt(inode->i_sb, POSIX_ACL) && acl) { | 253 | if (test_opt(inode->i_sb, POSIX_ACL) && acl) { |
279 | struct posix_acl *clone; | ||
280 | mode_t mode; | ||
281 | |||
282 | if (S_ISDIR(inode->i_mode)) { | 254 | if (S_ISDIR(inode->i_mode)) { |
283 | error = ext2_set_acl(inode, ACL_TYPE_DEFAULT, acl); | 255 | error = ext2_set_acl(inode, ACL_TYPE_DEFAULT, acl); |
284 | if (error) | 256 | if (error) |
285 | goto cleanup; | 257 | goto cleanup; |
286 | } | 258 | } |
287 | clone = posix_acl_clone(acl, GFP_KERNEL); | 259 | error = posix_acl_create(&acl, GFP_KERNEL, &inode->i_mode); |
288 | error = -ENOMEM; | 260 | if (error < 0) |
289 | if (!clone) | 261 | return error; |
290 | goto cleanup; | 262 | if (error > 0) { |
291 | mode = inode->i_mode; | 263 | /* This is an extended ACL */ |
292 | error = posix_acl_create_masq(clone, &mode); | 264 | error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl); |
293 | if (error >= 0) { | ||
294 | inode->i_mode = mode; | ||
295 | if (error > 0) { | ||
296 | /* This is an extended ACL */ | ||
297 | error = ext2_set_acl(inode, | ||
298 | ACL_TYPE_ACCESS, clone); | ||
299 | } | ||
300 | } | 265 | } |
301 | posix_acl_release(clone); | ||
302 | } | 266 | } |
303 | cleanup: | 267 | cleanup: |
304 | posix_acl_release(acl); | 268 | posix_acl_release(acl); |
@@ -322,7 +286,7 @@ cleanup: | |||
322 | int | 286 | int |
323 | ext2_acl_chmod(struct inode *inode) | 287 | ext2_acl_chmod(struct inode *inode) |
324 | { | 288 | { |
325 | struct posix_acl *acl, *clone; | 289 | struct posix_acl *acl; |
326 | int error; | 290 | int error; |
327 | 291 | ||
328 | if (!test_opt(inode->i_sb, POSIX_ACL)) | 292 | if (!test_opt(inode->i_sb, POSIX_ACL)) |
@@ -332,14 +296,11 @@ ext2_acl_chmod(struct inode *inode) | |||
332 | acl = ext2_get_acl(inode, ACL_TYPE_ACCESS); | 296 | acl = ext2_get_acl(inode, ACL_TYPE_ACCESS); |
333 | if (IS_ERR(acl) || !acl) | 297 | if (IS_ERR(acl) || !acl) |
334 | return PTR_ERR(acl); | 298 | return PTR_ERR(acl); |
335 | clone = posix_acl_clone(acl, GFP_KERNEL); | 299 | error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); |
300 | if (error) | ||
301 | return error; | ||
302 | error = ext2_set_acl(inode, ACL_TYPE_ACCESS, acl); | ||
336 | posix_acl_release(acl); | 303 | posix_acl_release(acl); |
337 | if (!clone) | ||
338 | return -ENOMEM; | ||
339 | error = posix_acl_chmod_masq(clone, inode->i_mode); | ||
340 | if (!error) | ||
341 | error = ext2_set_acl(inode, ACL_TYPE_ACCESS, clone); | ||
342 | posix_acl_release(clone); | ||
343 | return error; | 304 | return error; |
344 | } | 305 | } |
345 | 306 | ||
diff --git a/fs/ext2/acl.h b/fs/ext2/acl.h index c939b7b1209..503bfb0ed79 100644 --- a/fs/ext2/acl.h +++ b/fs/ext2/acl.h | |||
@@ -54,13 +54,12 @@ static inline int ext2_acl_count(size_t size) | |||
54 | #ifdef CONFIG_EXT2_FS_POSIX_ACL | 54 | #ifdef CONFIG_EXT2_FS_POSIX_ACL |
55 | 55 | ||
56 | /* acl.c */ | 56 | /* acl.c */ |
57 | extern int ext2_check_acl (struct inode *, int, unsigned int); | 57 | extern struct posix_acl *ext2_get_acl(struct inode *inode, int type); |
58 | extern int ext2_acl_chmod (struct inode *); | 58 | extern int ext2_acl_chmod (struct inode *); |
59 | extern int ext2_init_acl (struct inode *, struct inode *); | 59 | extern int ext2_init_acl (struct inode *, struct inode *); |
60 | 60 | ||
61 | #else | 61 | #else |
62 | #include <linux/sched.h> | 62 | #include <linux/sched.h> |
63 | #define ext2_check_acl NULL | ||
64 | #define ext2_get_acl NULL | 63 | #define ext2_get_acl NULL |
65 | #define ext2_set_acl NULL | 64 | #define ext2_set_acl NULL |
66 | 65 | ||
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 645be9e7ee4..af9fc89b1b2 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h | |||
@@ -150,7 +150,8 @@ extern void ext2_write_super (struct super_block *); | |||
150 | extern const struct file_operations ext2_dir_operations; | 150 | extern const struct file_operations ext2_dir_operations; |
151 | 151 | ||
152 | /* file.c */ | 152 | /* file.c */ |
153 | extern int ext2_fsync(struct file *file, int datasync); | 153 | extern int ext2_fsync(struct file *file, loff_t start, loff_t end, |
154 | int datasync); | ||
154 | extern const struct inode_operations ext2_file_inode_operations; | 155 | extern const struct inode_operations ext2_file_inode_operations; |
155 | extern const struct file_operations ext2_file_operations; | 156 | extern const struct file_operations ext2_file_operations; |
156 | extern const struct file_operations ext2_xip_file_operations; | 157 | extern const struct file_operations ext2_xip_file_operations; |
diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 49eec9456c5..a5b3a5db312 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c | |||
@@ -40,13 +40,13 @@ static int ext2_release_file (struct inode * inode, struct file * filp) | |||
40 | return 0; | 40 | return 0; |
41 | } | 41 | } |
42 | 42 | ||
43 | int ext2_fsync(struct file *file, int datasync) | 43 | int ext2_fsync(struct file *file, loff_t start, loff_t end, int datasync) |
44 | { | 44 | { |
45 | int ret; | 45 | int ret; |
46 | struct super_block *sb = file->f_mapping->host->i_sb; | 46 | struct super_block *sb = file->f_mapping->host->i_sb; |
47 | struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; | 47 | struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; |
48 | 48 | ||
49 | ret = generic_file_fsync(file, datasync); | 49 | ret = generic_file_fsync(file, start, end, datasync); |
50 | if (ret == -EIO || test_and_clear_bit(AS_EIO, &mapping->flags)) { | 50 | if (ret == -EIO || test_and_clear_bit(AS_EIO, &mapping->flags)) { |
51 | /* We don't really know where the IO error happened... */ | 51 | /* We don't really know where the IO error happened... */ |
52 | ext2_error(sb, __func__, | 52 | ext2_error(sb, __func__, |
@@ -102,6 +102,6 @@ const struct inode_operations ext2_file_inode_operations = { | |||
102 | .removexattr = generic_removexattr, | 102 | .removexattr = generic_removexattr, |
103 | #endif | 103 | #endif |
104 | .setattr = ext2_setattr, | 104 | .setattr = ext2_setattr, |
105 | .check_acl = ext2_check_acl, | 105 | .get_acl = ext2_get_acl, |
106 | .fiemap = ext2_fiemap, | 106 | .fiemap = ext2_fiemap, |
107 | }; | 107 | }; |
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 788e09a07f7..a8a58f63f07 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -843,8 +843,8 @@ ext2_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | |||
843 | struct inode *inode = mapping->host; | 843 | struct inode *inode = mapping->host; |
844 | ssize_t ret; | 844 | ssize_t ret; |
845 | 845 | ||
846 | ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, | 846 | ret = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs, |
847 | iov, offset, nr_segs, ext2_get_block, NULL); | 847 | ext2_get_block); |
848 | if (ret < 0 && (rw & WRITE)) | 848 | if (ret < 0 && (rw & WRITE)) |
849 | ext2_write_failed(mapping, offset + iov_length(iov, nr_segs)); | 849 | ext2_write_failed(mapping, offset + iov_length(iov, nr_segs)); |
850 | return ret; | 850 | return ret; |
@@ -1184,6 +1184,8 @@ static int ext2_setsize(struct inode *inode, loff_t newsize) | |||
1184 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | 1184 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
1185 | return -EPERM; | 1185 | return -EPERM; |
1186 | 1186 | ||
1187 | inode_dio_wait(inode); | ||
1188 | |||
1187 | if (mapping_is_xip(inode->i_mapping)) | 1189 | if (mapping_is_xip(inode->i_mapping)) |
1188 | error = xip_truncate_page(inode->i_mapping, newsize); | 1190 | error = xip_truncate_page(inode->i_mapping, newsize); |
1189 | else if (test_opt(inode->i_sb, NOBH)) | 1191 | else if (test_opt(inode->i_sb, NOBH)) |
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index ed5c5d496ee..761fde807fc 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c | |||
@@ -67,15 +67,11 @@ static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, str | |||
67 | inode = NULL; | 67 | inode = NULL; |
68 | if (ino) { | 68 | if (ino) { |
69 | inode = ext2_iget(dir->i_sb, ino); | 69 | inode = ext2_iget(dir->i_sb, ino); |
70 | if (IS_ERR(inode)) { | 70 | if (inode == ERR_PTR(-ESTALE)) { |
71 | if (PTR_ERR(inode) == -ESTALE) { | 71 | ext2_error(dir->i_sb, __func__, |
72 | ext2_error(dir->i_sb, __func__, | 72 | "deleted inode referenced: %lu", |
73 | "deleted inode referenced: %lu", | 73 | (unsigned long) ino); |
74 | (unsigned long) ino); | 74 | return ERR_PTR(-EIO); |
75 | return ERR_PTR(-EIO); | ||
76 | } else { | ||
77 | return ERR_CAST(inode); | ||
78 | } | ||
79 | } | 75 | } |
80 | } | 76 | } |
81 | return d_splice_alias(inode, dentry); | 77 | return d_splice_alias(inode, dentry); |
@@ -412,7 +408,7 @@ const struct inode_operations ext2_dir_inode_operations = { | |||
412 | .removexattr = generic_removexattr, | 408 | .removexattr = generic_removexattr, |
413 | #endif | 409 | #endif |
414 | .setattr = ext2_setattr, | 410 | .setattr = ext2_setattr, |
415 | .check_acl = ext2_check_acl, | 411 | .get_acl = ext2_get_acl, |
416 | }; | 412 | }; |
417 | 413 | ||
418 | const struct inode_operations ext2_special_inode_operations = { | 414 | const struct inode_operations ext2_special_inode_operations = { |
@@ -423,5 +419,5 @@ const struct inode_operations ext2_special_inode_operations = { | |||
423 | .removexattr = generic_removexattr, | 419 | .removexattr = generic_removexattr, |
424 | #endif | 420 | #endif |
425 | .setattr = ext2_setattr, | 421 | .setattr = ext2_setattr, |
426 | .check_acl = ext2_check_acl, | 422 | .get_acl = ext2_get_acl, |
427 | }; | 423 | }; |
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 529970617a2..d27b71f1d18 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c | |||
@@ -161,6 +161,10 @@ ext2_xattr_get(struct inode *inode, int name_index, const char *name, | |||
161 | 161 | ||
162 | if (name == NULL) | 162 | if (name == NULL) |
163 | return -EINVAL; | 163 | return -EINVAL; |
164 | name_len = strlen(name); | ||
165 | if (name_len > 255) | ||
166 | return -ERANGE; | ||
167 | |||
164 | down_read(&EXT2_I(inode)->xattr_sem); | 168 | down_read(&EXT2_I(inode)->xattr_sem); |
165 | error = -ENODATA; | 169 | error = -ENODATA; |
166 | if (!EXT2_I(inode)->i_file_acl) | 170 | if (!EXT2_I(inode)->i_file_acl) |
@@ -181,12 +185,8 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_get", | |||
181 | error = -EIO; | 185 | error = -EIO; |
182 | goto cleanup; | 186 | goto cleanup; |
183 | } | 187 | } |
184 | /* find named attribute */ | ||
185 | name_len = strlen(name); | ||
186 | 188 | ||
187 | error = -ERANGE; | 189 | /* find named attribute */ |
188 | if (name_len > 255) | ||
189 | goto cleanup; | ||
190 | entry = FIRST_ENTRY(bh); | 190 | entry = FIRST_ENTRY(bh); |
191 | while (!IS_LAST_ENTRY(entry)) { | 191 | while (!IS_LAST_ENTRY(entry)) { |
192 | struct ext2_xattr_entry *next = | 192 | struct ext2_xattr_entry *next = |