diff options
Diffstat (limited to 'fs/ext2')
-rw-r--r-- | fs/ext2/acl.c | 79 | ||||
-rw-r--r-- | fs/ext2/balloc.c | 13 | ||||
-rw-r--r-- | fs/ext2/dir.c | 6 | ||||
-rw-r--r-- | fs/ext2/ext2.h | 5 | ||||
-rw-r--r-- | fs/ext2/file.c | 26 | ||||
-rw-r--r-- | fs/ext2/ialloc.c | 14 | ||||
-rw-r--r-- | fs/ext2/inode.c | 24 | ||||
-rw-r--r-- | fs/ext2/namei.c | 51 | ||||
-rw-r--r-- | fs/ext2/super.c | 208 | ||||
-rw-r--r-- | fs/ext2/symlink.c | 2 | ||||
-rw-r--r-- | fs/ext2/xattr.c | 21 | ||||
-rw-r--r-- | fs/ext2/xattr_security.c | 17 | ||||
-rw-r--r-- | fs/ext2/xattr_trusted.c | 16 | ||||
-rw-r--r-- | fs/ext2/xattr_user.c | 25 | ||||
-rw-r--r-- | fs/ext2/xip.c | 5 |
15 files changed, 301 insertions, 211 deletions
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index a63d44256a70..a99e54318c3d 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c | |||
@@ -339,12 +339,12 @@ ext2_acl_chmod(struct inode *inode) | |||
339 | * Extended attribut handlers | 339 | * Extended attribut handlers |
340 | */ | 340 | */ |
341 | static size_t | 341 | static size_t |
342 | ext2_xattr_list_acl_access(struct inode *inode, char *list, size_t list_size, | 342 | ext2_xattr_list_acl_access(struct dentry *dentry, char *list, size_t list_size, |
343 | const char *name, size_t name_len) | 343 | const char *name, size_t name_len, int type) |
344 | { | 344 | { |
345 | const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS); | 345 | const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS); |
346 | 346 | ||
347 | if (!test_opt(inode->i_sb, POSIX_ACL)) | 347 | if (!test_opt(dentry->d_sb, POSIX_ACL)) |
348 | return 0; | 348 | return 0; |
349 | if (list && size <= list_size) | 349 | if (list && size <= list_size) |
350 | memcpy(list, POSIX_ACL_XATTR_ACCESS, size); | 350 | memcpy(list, POSIX_ACL_XATTR_ACCESS, size); |
@@ -352,12 +352,12 @@ ext2_xattr_list_acl_access(struct inode *inode, char *list, size_t list_size, | |||
352 | } | 352 | } |
353 | 353 | ||
354 | static size_t | 354 | static size_t |
355 | ext2_xattr_list_acl_default(struct inode *inode, char *list, size_t list_size, | 355 | ext2_xattr_list_acl_default(struct dentry *dentry, char *list, size_t list_size, |
356 | const char *name, size_t name_len) | 356 | const char *name, size_t name_len, int type) |
357 | { | 357 | { |
358 | const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT); | 358 | const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT); |
359 | 359 | ||
360 | if (!test_opt(inode->i_sb, POSIX_ACL)) | 360 | if (!test_opt(dentry->d_sb, POSIX_ACL)) |
361 | return 0; | 361 | return 0; |
362 | if (list && size <= list_size) | 362 | if (list && size <= list_size) |
363 | memcpy(list, POSIX_ACL_XATTR_DEFAULT, size); | 363 | memcpy(list, POSIX_ACL_XATTR_DEFAULT, size); |
@@ -365,15 +365,18 @@ ext2_xattr_list_acl_default(struct inode *inode, char *list, size_t list_size, | |||
365 | } | 365 | } |
366 | 366 | ||
367 | static int | 367 | static int |
368 | ext2_xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size) | 368 | ext2_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer, |
369 | size_t size, int type) | ||
369 | { | 370 | { |
370 | struct posix_acl *acl; | 371 | struct posix_acl *acl; |
371 | int error; | 372 | int error; |
372 | 373 | ||
373 | if (!test_opt(inode->i_sb, POSIX_ACL)) | 374 | if (strcmp(name, "") != 0) |
375 | return -EINVAL; | ||
376 | if (!test_opt(dentry->d_sb, POSIX_ACL)) | ||
374 | return -EOPNOTSUPP; | 377 | return -EOPNOTSUPP; |
375 | 378 | ||
376 | acl = ext2_get_acl(inode, type); | 379 | acl = ext2_get_acl(dentry->d_inode, type); |
377 | if (IS_ERR(acl)) | 380 | if (IS_ERR(acl)) |
378 | return PTR_ERR(acl); | 381 | return PTR_ERR(acl); |
379 | if (acl == NULL) | 382 | if (acl == NULL) |
@@ -385,33 +388,17 @@ ext2_xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size) | |||
385 | } | 388 | } |
386 | 389 | ||
387 | static int | 390 | static int |
388 | ext2_xattr_get_acl_access(struct inode *inode, const char *name, | 391 | ext2_xattr_set_acl(struct dentry *dentry, const char *name, const void *value, |
389 | void *buffer, size_t size) | 392 | size_t size, int flags, int type) |
390 | { | ||
391 | if (strcmp(name, "") != 0) | ||
392 | return -EINVAL; | ||
393 | return ext2_xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size); | ||
394 | } | ||
395 | |||
396 | static int | ||
397 | ext2_xattr_get_acl_default(struct inode *inode, const char *name, | ||
398 | void *buffer, size_t size) | ||
399 | { | ||
400 | if (strcmp(name, "") != 0) | ||
401 | return -EINVAL; | ||
402 | return ext2_xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size); | ||
403 | } | ||
404 | |||
405 | static int | ||
406 | ext2_xattr_set_acl(struct inode *inode, int type, const void *value, | ||
407 | size_t size) | ||
408 | { | 393 | { |
409 | struct posix_acl *acl; | 394 | struct posix_acl *acl; |
410 | int error; | 395 | int error; |
411 | 396 | ||
412 | if (!test_opt(inode->i_sb, POSIX_ACL)) | 397 | if (strcmp(name, "") != 0) |
398 | return -EINVAL; | ||
399 | if (!test_opt(dentry->d_sb, POSIX_ACL)) | ||
413 | return -EOPNOTSUPP; | 400 | return -EOPNOTSUPP; |
414 | if (!is_owner_or_cap(inode)) | 401 | if (!is_owner_or_cap(dentry->d_inode)) |
415 | return -EPERM; | 402 | return -EPERM; |
416 | 403 | ||
417 | if (value) { | 404 | if (value) { |
@@ -426,41 +413,25 @@ ext2_xattr_set_acl(struct inode *inode, int type, const void *value, | |||
426 | } else | 413 | } else |
427 | acl = NULL; | 414 | acl = NULL; |
428 | 415 | ||
429 | error = ext2_set_acl(inode, type, acl); | 416 | error = ext2_set_acl(dentry->d_inode, type, acl); |
430 | 417 | ||
431 | release_and_out: | 418 | release_and_out: |
432 | posix_acl_release(acl); | 419 | posix_acl_release(acl); |
433 | return error; | 420 | return error; |
434 | } | 421 | } |
435 | 422 | ||
436 | static int | ||
437 | ext2_xattr_set_acl_access(struct inode *inode, const char *name, | ||
438 | const void *value, size_t size, int flags) | ||
439 | { | ||
440 | if (strcmp(name, "") != 0) | ||
441 | return -EINVAL; | ||
442 | return ext2_xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size); | ||
443 | } | ||
444 | |||
445 | static int | ||
446 | ext2_xattr_set_acl_default(struct inode *inode, const char *name, | ||
447 | const void *value, size_t size, int flags) | ||
448 | { | ||
449 | if (strcmp(name, "") != 0) | ||
450 | return -EINVAL; | ||
451 | return ext2_xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); | ||
452 | } | ||
453 | |||
454 | struct xattr_handler ext2_xattr_acl_access_handler = { | 423 | struct xattr_handler ext2_xattr_acl_access_handler = { |
455 | .prefix = POSIX_ACL_XATTR_ACCESS, | 424 | .prefix = POSIX_ACL_XATTR_ACCESS, |
425 | .flags = ACL_TYPE_ACCESS, | ||
456 | .list = ext2_xattr_list_acl_access, | 426 | .list = ext2_xattr_list_acl_access, |
457 | .get = ext2_xattr_get_acl_access, | 427 | .get = ext2_xattr_get_acl, |
458 | .set = ext2_xattr_set_acl_access, | 428 | .set = ext2_xattr_set_acl, |
459 | }; | 429 | }; |
460 | 430 | ||
461 | struct xattr_handler ext2_xattr_acl_default_handler = { | 431 | struct xattr_handler ext2_xattr_acl_default_handler = { |
462 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 432 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
433 | .flags = ACL_TYPE_DEFAULT, | ||
463 | .list = ext2_xattr_list_acl_default, | 434 | .list = ext2_xattr_list_acl_default, |
464 | .get = ext2_xattr_get_acl_default, | 435 | .get = ext2_xattr_get_acl, |
465 | .set = ext2_xattr_set_acl_default, | 436 | .set = ext2_xattr_set_acl, |
466 | }; | 437 | }; |
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index 7f8d2e5a7ea6..3cf038c055d7 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include "ext2.h" | 14 | #include "ext2.h" |
15 | #include <linux/quotaops.h> | 15 | #include <linux/quotaops.h> |
16 | #include <linux/slab.h> | ||
16 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
17 | #include <linux/buffer_head.h> | 18 | #include <linux/buffer_head.h> |
18 | #include <linux/capability.h> | 19 | #include <linux/capability.h> |
@@ -570,7 +571,7 @@ do_more: | |||
570 | error_return: | 571 | error_return: |
571 | brelse(bitmap_bh); | 572 | brelse(bitmap_bh); |
572 | release_blocks(sb, freed); | 573 | release_blocks(sb, freed); |
573 | vfs_dq_free_block(inode, freed); | 574 | dquot_free_block(inode, freed); |
574 | } | 575 | } |
575 | 576 | ||
576 | /** | 577 | /** |
@@ -1236,6 +1237,7 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal, | |||
1236 | unsigned short windowsz = 0; | 1237 | unsigned short windowsz = 0; |
1237 | unsigned long ngroups; | 1238 | unsigned long ngroups; |
1238 | unsigned long num = *count; | 1239 | unsigned long num = *count; |
1240 | int ret; | ||
1239 | 1241 | ||
1240 | *errp = -ENOSPC; | 1242 | *errp = -ENOSPC; |
1241 | sb = inode->i_sb; | 1243 | sb = inode->i_sb; |
@@ -1247,8 +1249,9 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal, | |||
1247 | /* | 1249 | /* |
1248 | * Check quota for allocation of this block. | 1250 | * Check quota for allocation of this block. |
1249 | */ | 1251 | */ |
1250 | if (vfs_dq_alloc_block(inode, num)) { | 1252 | ret = dquot_alloc_block(inode, num); |
1251 | *errp = -EDQUOT; | 1253 | if (ret) { |
1254 | *errp = ret; | ||
1252 | return 0; | 1255 | return 0; |
1253 | } | 1256 | } |
1254 | 1257 | ||
@@ -1409,7 +1412,7 @@ allocated: | |||
1409 | 1412 | ||
1410 | *errp = 0; | 1413 | *errp = 0; |
1411 | brelse(bitmap_bh); | 1414 | brelse(bitmap_bh); |
1412 | vfs_dq_free_block(inode, *count-num); | 1415 | dquot_free_block(inode, *count-num); |
1413 | *count = num; | 1416 | *count = num; |
1414 | return ret_block; | 1417 | return ret_block; |
1415 | 1418 | ||
@@ -1420,7 +1423,7 @@ out: | |||
1420 | * Undo the block allocation | 1423 | * Undo the block allocation |
1421 | */ | 1424 | */ |
1422 | if (!performed_allocation) | 1425 | if (!performed_allocation) |
1423 | vfs_dq_free_block(inode, *count); | 1426 | dquot_free_block(inode, *count); |
1424 | brelse(bitmap_bh); | 1427 | brelse(bitmap_bh); |
1425 | return 0; | 1428 | return 0; |
1426 | } | 1429 | } |
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 6cde970b0a1a..7516957273ed 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c | |||
@@ -353,8 +353,8 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir) | |||
353 | * ext2_find_entry() | 353 | * ext2_find_entry() |
354 | * | 354 | * |
355 | * finds an entry in the specified directory with the wanted name. It | 355 | * finds an entry in the specified directory with the wanted name. It |
356 | * returns the page in which the entry was found, and the entry itself | 356 | * returns the page in which the entry was found (as a parameter - res_page), |
357 | * (as a parameter - res_dir). Page is returned mapped and unlocked. | 357 | * and the entry itself. Page is returned mapped and unlocked. |
358 | * Entry is guaranteed to be valid. | 358 | * Entry is guaranteed to be valid. |
359 | */ | 359 | */ |
360 | struct ext2_dir_entry_2 *ext2_find_entry (struct inode * dir, | 360 | struct ext2_dir_entry_2 *ext2_find_entry (struct inode * dir, |
@@ -721,5 +721,5 @@ const struct file_operations ext2_dir_operations = { | |||
721 | #ifdef CONFIG_COMPAT | 721 | #ifdef CONFIG_COMPAT |
722 | .compat_ioctl = ext2_compat_ioctl, | 722 | .compat_ioctl = ext2_compat_ioctl, |
723 | #endif | 723 | #endif |
724 | .fsync = simple_fsync, | 724 | .fsync = ext2_fsync, |
725 | }; | 725 | }; |
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 9a8a8e27a063..0b038e47ad2f 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h | |||
@@ -118,7 +118,7 @@ extern unsigned long ext2_count_free (struct buffer_head *, unsigned); | |||
118 | 118 | ||
119 | /* inode.c */ | 119 | /* inode.c */ |
120 | extern struct inode *ext2_iget (struct super_block *, unsigned long); | 120 | extern struct inode *ext2_iget (struct super_block *, unsigned long); |
121 | extern int ext2_write_inode (struct inode *, int); | 121 | extern int ext2_write_inode (struct inode *, struct writeback_control *); |
122 | extern void ext2_delete_inode (struct inode *); | 122 | extern void ext2_delete_inode (struct inode *); |
123 | extern int ext2_sync_inode (struct inode *); | 123 | extern int ext2_sync_inode (struct inode *); |
124 | extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int); | 124 | extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int); |
@@ -142,7 +142,7 @@ struct dentry *ext2_get_parent(struct dentry *child); | |||
142 | /* super.c */ | 142 | /* super.c */ |
143 | extern void ext2_error (struct super_block *, const char *, const char *, ...) | 143 | extern void ext2_error (struct super_block *, const char *, const char *, ...) |
144 | __attribute__ ((format (printf, 3, 4))); | 144 | __attribute__ ((format (printf, 3, 4))); |
145 | extern void ext2_warning (struct super_block *, const char *, const char *, ...) | 145 | extern void ext2_msg(struct super_block *, const char *, const char *, ...) |
146 | __attribute__ ((format (printf, 3, 4))); | 146 | __attribute__ ((format (printf, 3, 4))); |
147 | extern void ext2_update_dynamic_rev (struct super_block *sb); | 147 | extern void ext2_update_dynamic_rev (struct super_block *sb); |
148 | extern void ext2_write_super (struct super_block *); | 148 | extern void ext2_write_super (struct super_block *); |
@@ -155,6 +155,7 @@ extern void ext2_write_super (struct super_block *); | |||
155 | extern const struct file_operations ext2_dir_operations; | 155 | extern const struct file_operations ext2_dir_operations; |
156 | 156 | ||
157 | /* file.c */ | 157 | /* file.c */ |
158 | extern int ext2_fsync(struct file *file, struct dentry *dentry, int datasync); | ||
158 | extern const struct inode_operations ext2_file_inode_operations; | 159 | extern const struct inode_operations ext2_file_inode_operations; |
159 | extern const struct file_operations ext2_file_operations; | 160 | extern const struct file_operations ext2_file_operations; |
160 | extern const struct file_operations ext2_xip_file_operations; | 161 | extern const struct file_operations ext2_xip_file_operations; |
diff --git a/fs/ext2/file.c b/fs/ext2/file.c index a2f3afd1a1c1..5d198d0697fb 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c | |||
@@ -19,6 +19,8 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/time.h> | 21 | #include <linux/time.h> |
22 | #include <linux/pagemap.h> | ||
23 | #include <linux/quotaops.h> | ||
22 | #include "ext2.h" | 24 | #include "ext2.h" |
23 | #include "xattr.h" | 25 | #include "xattr.h" |
24 | #include "acl.h" | 26 | #include "acl.h" |
@@ -38,6 +40,22 @@ static int ext2_release_file (struct inode * inode, struct file * filp) | |||
38 | return 0; | 40 | return 0; |
39 | } | 41 | } |
40 | 42 | ||
43 | int ext2_fsync(struct file *file, struct dentry *dentry, int datasync) | ||
44 | { | ||
45 | int ret; | ||
46 | struct super_block *sb = dentry->d_inode->i_sb; | ||
47 | struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; | ||
48 | |||
49 | ret = simple_fsync(file, dentry, datasync); | ||
50 | if (ret == -EIO || test_and_clear_bit(AS_EIO, &mapping->flags)) { | ||
51 | /* We don't really know where the IO error happened... */ | ||
52 | ext2_error(sb, __func__, | ||
53 | "detected IO error when writing metadata buffers"); | ||
54 | ret = -EIO; | ||
55 | } | ||
56 | return ret; | ||
57 | } | ||
58 | |||
41 | /* | 59 | /* |
42 | * We have mostly NULL's here: the current defaults are ok for | 60 | * We have mostly NULL's here: the current defaults are ok for |
43 | * the ext2 filesystem. | 61 | * the ext2 filesystem. |
@@ -53,9 +71,9 @@ const struct file_operations ext2_file_operations = { | |||
53 | .compat_ioctl = ext2_compat_ioctl, | 71 | .compat_ioctl = ext2_compat_ioctl, |
54 | #endif | 72 | #endif |
55 | .mmap = generic_file_mmap, | 73 | .mmap = generic_file_mmap, |
56 | .open = generic_file_open, | 74 | .open = dquot_file_open, |
57 | .release = ext2_release_file, | 75 | .release = ext2_release_file, |
58 | .fsync = simple_fsync, | 76 | .fsync = ext2_fsync, |
59 | .splice_read = generic_file_splice_read, | 77 | .splice_read = generic_file_splice_read, |
60 | .splice_write = generic_file_splice_write, | 78 | .splice_write = generic_file_splice_write, |
61 | }; | 79 | }; |
@@ -70,9 +88,9 @@ const struct file_operations ext2_xip_file_operations = { | |||
70 | .compat_ioctl = ext2_compat_ioctl, | 88 | .compat_ioctl = ext2_compat_ioctl, |
71 | #endif | 89 | #endif |
72 | .mmap = xip_file_mmap, | 90 | .mmap = xip_file_mmap, |
73 | .open = generic_file_open, | 91 | .open = dquot_file_open, |
74 | .release = ext2_release_file, | 92 | .release = ext2_release_file, |
75 | .fsync = simple_fsync, | 93 | .fsync = ext2_fsync, |
76 | }; | 94 | }; |
77 | #endif | 95 | #endif |
78 | 96 | ||
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 15387c9c17d8..ad7d572ee8dc 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c | |||
@@ -121,8 +121,8 @@ void ext2_free_inode (struct inode * inode) | |||
121 | if (!is_bad_inode(inode)) { | 121 | if (!is_bad_inode(inode)) { |
122 | /* Quota is already initialized in iput() */ | 122 | /* Quota is already initialized in iput() */ |
123 | ext2_xattr_delete_inode(inode); | 123 | ext2_xattr_delete_inode(inode); |
124 | vfs_dq_free_inode(inode); | 124 | dquot_free_inode(inode); |
125 | vfs_dq_drop(inode); | 125 | dquot_drop(inode); |
126 | } | 126 | } |
127 | 127 | ||
128 | es = EXT2_SB(sb)->s_es; | 128 | es = EXT2_SB(sb)->s_es; |
@@ -586,10 +586,10 @@ got: | |||
586 | goto fail_drop; | 586 | goto fail_drop; |
587 | } | 587 | } |
588 | 588 | ||
589 | if (vfs_dq_alloc_inode(inode)) { | 589 | dquot_initialize(inode); |
590 | err = -EDQUOT; | 590 | err = dquot_alloc_inode(inode); |
591 | if (err) | ||
591 | goto fail_drop; | 592 | goto fail_drop; |
592 | } | ||
593 | 593 | ||
594 | err = ext2_init_acl(inode, dir); | 594 | err = ext2_init_acl(inode, dir); |
595 | if (err) | 595 | if (err) |
@@ -605,10 +605,10 @@ got: | |||
605 | return inode; | 605 | return inode; |
606 | 606 | ||
607 | fail_free_drop: | 607 | fail_free_drop: |
608 | vfs_dq_free_inode(inode); | 608 | dquot_free_inode(inode); |
609 | 609 | ||
610 | fail_drop: | 610 | fail_drop: |
611 | vfs_dq_drop(inode); | 611 | dquot_drop(inode); |
612 | inode->i_flags |= S_NOQUOTA; | 612 | inode->i_flags |= S_NOQUOTA; |
613 | inode->i_nlink = 0; | 613 | inode->i_nlink = 0; |
614 | unlock_new_inode(inode); | 614 | unlock_new_inode(inode); |
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index ade634076d0a..fc13cc119aad 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -41,6 +41,8 @@ MODULE_AUTHOR("Remy Card and others"); | |||
41 | MODULE_DESCRIPTION("Second Extended Filesystem"); | 41 | MODULE_DESCRIPTION("Second Extended Filesystem"); |
42 | MODULE_LICENSE("GPL"); | 42 | MODULE_LICENSE("GPL"); |
43 | 43 | ||
44 | static int __ext2_write_inode(struct inode *inode, int do_sync); | ||
45 | |||
44 | /* | 46 | /* |
45 | * Test whether an inode is a fast symlink. | 47 | * Test whether an inode is a fast symlink. |
46 | */ | 48 | */ |
@@ -58,13 +60,15 @@ static inline int ext2_inode_is_fast_symlink(struct inode *inode) | |||
58 | */ | 60 | */ |
59 | void ext2_delete_inode (struct inode * inode) | 61 | void ext2_delete_inode (struct inode * inode) |
60 | { | 62 | { |
63 | if (!is_bad_inode(inode)) | ||
64 | dquot_initialize(inode); | ||
61 | truncate_inode_pages(&inode->i_data, 0); | 65 | truncate_inode_pages(&inode->i_data, 0); |
62 | 66 | ||
63 | if (is_bad_inode(inode)) | 67 | if (is_bad_inode(inode)) |
64 | goto no_delete; | 68 | goto no_delete; |
65 | EXT2_I(inode)->i_dtime = get_seconds(); | 69 | EXT2_I(inode)->i_dtime = get_seconds(); |
66 | mark_inode_dirty(inode); | 70 | mark_inode_dirty(inode); |
67 | ext2_write_inode(inode, inode_needs_sync(inode)); | 71 | __ext2_write_inode(inode, inode_needs_sync(inode)); |
68 | 72 | ||
69 | inode->i_size = 0; | 73 | inode->i_size = 0; |
70 | if (inode->i_blocks) | 74 | if (inode->i_blocks) |
@@ -137,7 +141,8 @@ static int ext2_block_to_path(struct inode *inode, | |||
137 | int final = 0; | 141 | int final = 0; |
138 | 142 | ||
139 | if (i_block < 0) { | 143 | if (i_block < 0) { |
140 | ext2_warning (inode->i_sb, "ext2_block_to_path", "block < 0"); | 144 | ext2_msg(inode->i_sb, KERN_WARNING, |
145 | "warning: %s: block < 0", __func__); | ||
141 | } else if (i_block < direct_blocks) { | 146 | } else if (i_block < direct_blocks) { |
142 | offsets[n++] = i_block; | 147 | offsets[n++] = i_block; |
143 | final = direct_blocks; | 148 | final = direct_blocks; |
@@ -157,7 +162,8 @@ static int ext2_block_to_path(struct inode *inode, | |||
157 | offsets[n++] = i_block & (ptrs - 1); | 162 | offsets[n++] = i_block & (ptrs - 1); |
158 | final = ptrs; | 163 | final = ptrs; |
159 | } else { | 164 | } else { |
160 | ext2_warning (inode->i_sb, "ext2_block_to_path", "block > big"); | 165 | ext2_msg(inode->i_sb, KERN_WARNING, |
166 | "warning: %s: block is too big", __func__); | ||
161 | } | 167 | } |
162 | if (boundary) | 168 | if (boundary) |
163 | *boundary = final - 1 - (i_block & (ptrs - 1)); | 169 | *boundary = final - 1 - (i_block & (ptrs - 1)); |
@@ -1333,7 +1339,7 @@ bad_inode: | |||
1333 | return ERR_PTR(ret); | 1339 | return ERR_PTR(ret); |
1334 | } | 1340 | } |
1335 | 1341 | ||
1336 | int ext2_write_inode(struct inode *inode, int do_sync) | 1342 | static int __ext2_write_inode(struct inode *inode, int do_sync) |
1337 | { | 1343 | { |
1338 | struct ext2_inode_info *ei = EXT2_I(inode); | 1344 | struct ext2_inode_info *ei = EXT2_I(inode); |
1339 | struct super_block *sb = inode->i_sb; | 1345 | struct super_block *sb = inode->i_sb; |
@@ -1438,6 +1444,11 @@ int ext2_write_inode(struct inode *inode, int do_sync) | |||
1438 | return err; | 1444 | return err; |
1439 | } | 1445 | } |
1440 | 1446 | ||
1447 | int ext2_write_inode(struct inode *inode, struct writeback_control *wbc) | ||
1448 | { | ||
1449 | return __ext2_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); | ||
1450 | } | ||
1451 | |||
1441 | int ext2_sync_inode(struct inode *inode) | 1452 | int ext2_sync_inode(struct inode *inode) |
1442 | { | 1453 | { |
1443 | struct writeback_control wbc = { | 1454 | struct writeback_control wbc = { |
@@ -1455,9 +1466,12 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr) | |||
1455 | error = inode_change_ok(inode, iattr); | 1466 | error = inode_change_ok(inode, iattr); |
1456 | if (error) | 1467 | if (error) |
1457 | return error; | 1468 | return error; |
1469 | |||
1470 | if (iattr->ia_valid & ATTR_SIZE) | ||
1471 | dquot_initialize(inode); | ||
1458 | if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || | 1472 | if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || |
1459 | (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { | 1473 | (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { |
1460 | error = vfs_dq_transfer(inode, iattr) ? -EDQUOT : 0; | 1474 | error = dquot_transfer(inode, iattr); |
1461 | if (error) | 1475 | if (error) |
1462 | return error; | 1476 | return error; |
1463 | } | 1477 | } |
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index dd7175ce5606..71efb0e9a3f2 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c | |||
@@ -31,6 +31,7 @@ | |||
31 | */ | 31 | */ |
32 | 32 | ||
33 | #include <linux/pagemap.h> | 33 | #include <linux/pagemap.h> |
34 | #include <linux/quotaops.h> | ||
34 | #include "ext2.h" | 35 | #include "ext2.h" |
35 | #include "xattr.h" | 36 | #include "xattr.h" |
36 | #include "acl.h" | 37 | #include "acl.h" |
@@ -99,24 +100,27 @@ struct dentry *ext2_get_parent(struct dentry *child) | |||
99 | */ | 100 | */ |
100 | static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, struct nameidata *nd) | 101 | static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, struct nameidata *nd) |
101 | { | 102 | { |
102 | struct inode * inode = ext2_new_inode (dir, mode); | 103 | struct inode *inode; |
103 | int err = PTR_ERR(inode); | 104 | |
104 | if (!IS_ERR(inode)) { | 105 | dquot_initialize(dir); |
105 | inode->i_op = &ext2_file_inode_operations; | 106 | |
106 | if (ext2_use_xip(inode->i_sb)) { | 107 | inode = ext2_new_inode(dir, mode); |
107 | inode->i_mapping->a_ops = &ext2_aops_xip; | 108 | if (IS_ERR(inode)) |
108 | inode->i_fop = &ext2_xip_file_operations; | 109 | return PTR_ERR(inode); |
109 | } else if (test_opt(inode->i_sb, NOBH)) { | 110 | |
110 | inode->i_mapping->a_ops = &ext2_nobh_aops; | 111 | inode->i_op = &ext2_file_inode_operations; |
111 | inode->i_fop = &ext2_file_operations; | 112 | if (ext2_use_xip(inode->i_sb)) { |
112 | } else { | 113 | inode->i_mapping->a_ops = &ext2_aops_xip; |
113 | inode->i_mapping->a_ops = &ext2_aops; | 114 | inode->i_fop = &ext2_xip_file_operations; |
114 | inode->i_fop = &ext2_file_operations; | 115 | } else if (test_opt(inode->i_sb, NOBH)) { |
115 | } | 116 | inode->i_mapping->a_ops = &ext2_nobh_aops; |
116 | mark_inode_dirty(inode); | 117 | inode->i_fop = &ext2_file_operations; |
117 | err = ext2_add_nondir(dentry, inode); | 118 | } else { |
119 | inode->i_mapping->a_ops = &ext2_aops; | ||
120 | inode->i_fop = &ext2_file_operations; | ||
118 | } | 121 | } |
119 | return err; | 122 | mark_inode_dirty(inode); |
123 | return ext2_add_nondir(dentry, inode); | ||
120 | } | 124 | } |
121 | 125 | ||
122 | static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) | 126 | static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) |
@@ -127,6 +131,8 @@ static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_ | |||
127 | if (!new_valid_dev(rdev)) | 131 | if (!new_valid_dev(rdev)) |
128 | return -EINVAL; | 132 | return -EINVAL; |
129 | 133 | ||
134 | dquot_initialize(dir); | ||
135 | |||
130 | inode = ext2_new_inode (dir, mode); | 136 | inode = ext2_new_inode (dir, mode); |
131 | err = PTR_ERR(inode); | 137 | err = PTR_ERR(inode); |
132 | if (!IS_ERR(inode)) { | 138 | if (!IS_ERR(inode)) { |
@@ -151,6 +157,8 @@ static int ext2_symlink (struct inode * dir, struct dentry * dentry, | |||
151 | if (l > sb->s_blocksize) | 157 | if (l > sb->s_blocksize) |
152 | goto out; | 158 | goto out; |
153 | 159 | ||
160 | dquot_initialize(dir); | ||
161 | |||
154 | inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO); | 162 | inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO); |
155 | err = PTR_ERR(inode); | 163 | err = PTR_ERR(inode); |
156 | if (IS_ERR(inode)) | 164 | if (IS_ERR(inode)) |
@@ -194,6 +202,8 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir, | |||
194 | if (inode->i_nlink >= EXT2_LINK_MAX) | 202 | if (inode->i_nlink >= EXT2_LINK_MAX) |
195 | return -EMLINK; | 203 | return -EMLINK; |
196 | 204 | ||
205 | dquot_initialize(dir); | ||
206 | |||
197 | inode->i_ctime = CURRENT_TIME_SEC; | 207 | inode->i_ctime = CURRENT_TIME_SEC; |
198 | inode_inc_link_count(inode); | 208 | inode_inc_link_count(inode); |
199 | atomic_inc(&inode->i_count); | 209 | atomic_inc(&inode->i_count); |
@@ -216,6 +226,8 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode) | |||
216 | if (dir->i_nlink >= EXT2_LINK_MAX) | 226 | if (dir->i_nlink >= EXT2_LINK_MAX) |
217 | goto out; | 227 | goto out; |
218 | 228 | ||
229 | dquot_initialize(dir); | ||
230 | |||
219 | inode_inc_link_count(dir); | 231 | inode_inc_link_count(dir); |
220 | 232 | ||
221 | inode = ext2_new_inode (dir, S_IFDIR | mode); | 233 | inode = ext2_new_inode (dir, S_IFDIR | mode); |
@@ -262,6 +274,8 @@ static int ext2_unlink(struct inode * dir, struct dentry *dentry) | |||
262 | struct page * page; | 274 | struct page * page; |
263 | int err = -ENOENT; | 275 | int err = -ENOENT; |
264 | 276 | ||
277 | dquot_initialize(dir); | ||
278 | |||
265 | de = ext2_find_entry (dir, &dentry->d_name, &page); | 279 | de = ext2_find_entry (dir, &dentry->d_name, &page); |
266 | if (!de) | 280 | if (!de) |
267 | goto out; | 281 | goto out; |
@@ -304,6 +318,9 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, | |||
304 | struct ext2_dir_entry_2 * old_de; | 318 | struct ext2_dir_entry_2 * old_de; |
305 | int err = -ENOENT; | 319 | int err = -ENOENT; |
306 | 320 | ||
321 | dquot_initialize(old_dir); | ||
322 | dquot_initialize(new_dir); | ||
323 | |||
307 | old_de = ext2_find_entry (old_dir, &old_dentry->d_name, &old_page); | 324 | old_de = ext2_find_entry (old_dir, &old_dentry->d_name, &old_page); |
308 | if (!old_de) | 325 | if (!old_de) |
309 | goto out; | 326 | goto out; |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 1a9ffee47d56..42e4a303b675 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -58,27 +58,27 @@ void ext2_error (struct super_block * sb, const char * function, | |||
58 | } | 58 | } |
59 | 59 | ||
60 | va_start(args, fmt); | 60 | va_start(args, fmt); |
61 | printk(KERN_CRIT "EXT2-fs error (device %s): %s: ",sb->s_id, function); | 61 | printk(KERN_CRIT "EXT2-fs (%s): error: %s: ", sb->s_id, function); |
62 | vprintk(fmt, args); | 62 | vprintk(fmt, args); |
63 | printk("\n"); | 63 | printk("\n"); |
64 | va_end(args); | 64 | va_end(args); |
65 | 65 | ||
66 | if (test_opt(sb, ERRORS_PANIC)) | 66 | if (test_opt(sb, ERRORS_PANIC)) |
67 | panic("EXT2-fs panic from previous error\n"); | 67 | panic("EXT2-fs: panic from previous error\n"); |
68 | if (test_opt(sb, ERRORS_RO)) { | 68 | if (test_opt(sb, ERRORS_RO)) { |
69 | printk("Remounting filesystem read-only\n"); | 69 | ext2_msg(sb, KERN_CRIT, |
70 | "error: remounting filesystem read-only"); | ||
70 | sb->s_flags |= MS_RDONLY; | 71 | sb->s_flags |= MS_RDONLY; |
71 | } | 72 | } |
72 | } | 73 | } |
73 | 74 | ||
74 | void ext2_warning (struct super_block * sb, const char * function, | 75 | void ext2_msg(struct super_block *sb, const char *prefix, |
75 | const char * fmt, ...) | 76 | const char *fmt, ...) |
76 | { | 77 | { |
77 | va_list args; | 78 | va_list args; |
78 | 79 | ||
79 | va_start(args, fmt); | 80 | va_start(args, fmt); |
80 | printk(KERN_WARNING "EXT2-fs warning (device %s): %s: ", | 81 | printk("%sEXT2-fs (%s): ", prefix, sb->s_id); |
81 | sb->s_id, function); | ||
82 | vprintk(fmt, args); | 82 | vprintk(fmt, args); |
83 | printk("\n"); | 83 | printk("\n"); |
84 | va_end(args); | 84 | va_end(args); |
@@ -91,9 +91,9 @@ void ext2_update_dynamic_rev(struct super_block *sb) | |||
91 | if (le32_to_cpu(es->s_rev_level) > EXT2_GOOD_OLD_REV) | 91 | if (le32_to_cpu(es->s_rev_level) > EXT2_GOOD_OLD_REV) |
92 | return; | 92 | return; |
93 | 93 | ||
94 | ext2_warning(sb, __func__, | 94 | ext2_msg(sb, KERN_WARNING, |
95 | "updating to rev %d because of new feature flag, " | 95 | "warning: updating to rev %d because of " |
96 | "running e2fsck is recommended", | 96 | "new feature flag, running e2fsck is recommended", |
97 | EXT2_DYNAMIC_REV); | 97 | EXT2_DYNAMIC_REV); |
98 | 98 | ||
99 | es->s_first_ino = cpu_to_le32(EXT2_GOOD_OLD_FIRST_INO); | 99 | es->s_first_ino = cpu_to_le32(EXT2_GOOD_OLD_FIRST_INO); |
@@ -194,6 +194,8 @@ static void destroy_inodecache(void) | |||
194 | static void ext2_clear_inode(struct inode *inode) | 194 | static void ext2_clear_inode(struct inode *inode) |
195 | { | 195 | { |
196 | struct ext2_block_alloc_info *rsv = EXT2_I(inode)->i_block_alloc_info; | 196 | struct ext2_block_alloc_info *rsv = EXT2_I(inode)->i_block_alloc_info; |
197 | |||
198 | dquot_drop(inode); | ||
197 | ext2_discard_reservation(inode); | 199 | ext2_discard_reservation(inode); |
198 | EXT2_I(inode)->i_block_alloc_info = NULL; | 200 | EXT2_I(inode)->i_block_alloc_info = NULL; |
199 | if (unlikely(rsv)) | 201 | if (unlikely(rsv)) |
@@ -419,10 +421,10 @@ static const match_table_t tokens = { | |||
419 | {Opt_err, NULL} | 421 | {Opt_err, NULL} |
420 | }; | 422 | }; |
421 | 423 | ||
422 | static int parse_options (char * options, | 424 | static int parse_options(char *options, struct super_block *sb) |
423 | struct ext2_sb_info *sbi) | ||
424 | { | 425 | { |
425 | char * p; | 426 | char *p; |
427 | struct ext2_sb_info *sbi = EXT2_SB(sb); | ||
426 | substring_t args[MAX_OPT_ARGS]; | 428 | substring_t args[MAX_OPT_ARGS]; |
427 | int option; | 429 | int option; |
428 | 430 | ||
@@ -505,7 +507,8 @@ static int parse_options (char * options, | |||
505 | #else | 507 | #else |
506 | case Opt_user_xattr: | 508 | case Opt_user_xattr: |
507 | case Opt_nouser_xattr: | 509 | case Opt_nouser_xattr: |
508 | printk("EXT2 (no)user_xattr options not supported\n"); | 510 | ext2_msg(sb, KERN_INFO, "(no)user_xattr options" |
511 | "not supported"); | ||
509 | break; | 512 | break; |
510 | #endif | 513 | #endif |
511 | #ifdef CONFIG_EXT2_FS_POSIX_ACL | 514 | #ifdef CONFIG_EXT2_FS_POSIX_ACL |
@@ -518,14 +521,15 @@ static int parse_options (char * options, | |||
518 | #else | 521 | #else |
519 | case Opt_acl: | 522 | case Opt_acl: |
520 | case Opt_noacl: | 523 | case Opt_noacl: |
521 | printk("EXT2 (no)acl options not supported\n"); | 524 | ext2_msg(sb, KERN_INFO, |
525 | "(no)acl options not supported"); | ||
522 | break; | 526 | break; |
523 | #endif | 527 | #endif |
524 | case Opt_xip: | 528 | case Opt_xip: |
525 | #ifdef CONFIG_EXT2_FS_XIP | 529 | #ifdef CONFIG_EXT2_FS_XIP |
526 | set_opt (sbi->s_mount_opt, XIP); | 530 | set_opt (sbi->s_mount_opt, XIP); |
527 | #else | 531 | #else |
528 | printk("EXT2 xip option not supported\n"); | 532 | ext2_msg(sb, KERN_INFO, "xip option not supported"); |
529 | #endif | 533 | #endif |
530 | break; | 534 | break; |
531 | 535 | ||
@@ -542,19 +546,18 @@ static int parse_options (char * options, | |||
542 | case Opt_quota: | 546 | case Opt_quota: |
543 | case Opt_usrquota: | 547 | case Opt_usrquota: |
544 | case Opt_grpquota: | 548 | case Opt_grpquota: |
545 | printk(KERN_ERR | 549 | ext2_msg(sb, KERN_INFO, |
546 | "EXT2-fs: quota operations not supported.\n"); | 550 | "quota operations not supported"); |
547 | |||
548 | break; | 551 | break; |
549 | #endif | 552 | #endif |
550 | 553 | ||
551 | case Opt_reservation: | 554 | case Opt_reservation: |
552 | set_opt(sbi->s_mount_opt, RESERVATION); | 555 | set_opt(sbi->s_mount_opt, RESERVATION); |
553 | printk("reservations ON\n"); | 556 | ext2_msg(sb, KERN_INFO, "reservations ON"); |
554 | break; | 557 | break; |
555 | case Opt_noreservation: | 558 | case Opt_noreservation: |
556 | clear_opt(sbi->s_mount_opt, RESERVATION); | 559 | clear_opt(sbi->s_mount_opt, RESERVATION); |
557 | printk("reservations OFF\n"); | 560 | ext2_msg(sb, KERN_INFO, "reservations OFF"); |
558 | break; | 561 | break; |
559 | case Opt_ignore: | 562 | case Opt_ignore: |
560 | break; | 563 | break; |
@@ -573,34 +576,40 @@ static int ext2_setup_super (struct super_block * sb, | |||
573 | struct ext2_sb_info *sbi = EXT2_SB(sb); | 576 | struct ext2_sb_info *sbi = EXT2_SB(sb); |
574 | 577 | ||
575 | if (le32_to_cpu(es->s_rev_level) > EXT2_MAX_SUPP_REV) { | 578 | if (le32_to_cpu(es->s_rev_level) > EXT2_MAX_SUPP_REV) { |
576 | printk ("EXT2-fs warning: revision level too high, " | 579 | ext2_msg(sb, KERN_ERR, |
577 | "forcing read-only mode\n"); | 580 | "error: revision level too high, " |
581 | "forcing read-only mode"); | ||
578 | res = MS_RDONLY; | 582 | res = MS_RDONLY; |
579 | } | 583 | } |
580 | if (read_only) | 584 | if (read_only) |
581 | return res; | 585 | return res; |
582 | if (!(sbi->s_mount_state & EXT2_VALID_FS)) | 586 | if (!(sbi->s_mount_state & EXT2_VALID_FS)) |
583 | printk ("EXT2-fs warning: mounting unchecked fs, " | 587 | ext2_msg(sb, KERN_WARNING, |
584 | "running e2fsck is recommended\n"); | 588 | "warning: mounting unchecked fs, " |
589 | "running e2fsck is recommended"); | ||
585 | else if ((sbi->s_mount_state & EXT2_ERROR_FS)) | 590 | else if ((sbi->s_mount_state & EXT2_ERROR_FS)) |
586 | printk ("EXT2-fs warning: mounting fs with errors, " | 591 | ext2_msg(sb, KERN_WARNING, |
587 | "running e2fsck is recommended\n"); | 592 | "warning: mounting fs with errors, " |
593 | "running e2fsck is recommended"); | ||
588 | else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 && | 594 | else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 && |
589 | le16_to_cpu(es->s_mnt_count) >= | 595 | le16_to_cpu(es->s_mnt_count) >= |
590 | (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count)) | 596 | (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count)) |
591 | printk ("EXT2-fs warning: maximal mount count reached, " | 597 | ext2_msg(sb, KERN_WARNING, |
592 | "running e2fsck is recommended\n"); | 598 | "warning: maximal mount count reached, " |
599 | "running e2fsck is recommended"); | ||
593 | else if (le32_to_cpu(es->s_checkinterval) && | 600 | else if (le32_to_cpu(es->s_checkinterval) && |
594 | (le32_to_cpu(es->s_lastcheck) + le32_to_cpu(es->s_checkinterval) <= get_seconds())) | 601 | (le32_to_cpu(es->s_lastcheck) + |
595 | printk ("EXT2-fs warning: checktime reached, " | 602 | le32_to_cpu(es->s_checkinterval) <= get_seconds())) |
596 | "running e2fsck is recommended\n"); | 603 | ext2_msg(sb, KERN_WARNING, |
604 | "warning: checktime reached, " | ||
605 | "running e2fsck is recommended"); | ||
597 | if (!le16_to_cpu(es->s_max_mnt_count)) | 606 | if (!le16_to_cpu(es->s_max_mnt_count)) |
598 | es->s_max_mnt_count = cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT); | 607 | es->s_max_mnt_count = cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT); |
599 | le16_add_cpu(&es->s_mnt_count, 1); | 608 | le16_add_cpu(&es->s_mnt_count, 1); |
600 | ext2_write_super(sb); | 609 | ext2_write_super(sb); |
601 | if (test_opt (sb, DEBUG)) | 610 | if (test_opt (sb, DEBUG)) |
602 | printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, " | 611 | ext2_msg(sb, KERN_INFO, "%s, %s, bs=%lu, fs=%lu, gc=%lu, " |
603 | "bpg=%lu, ipg=%lu, mo=%04lx]\n", | 612 | "bpg=%lu, ipg=%lu, mo=%04lx]", |
604 | EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize, | 613 | EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize, |
605 | sbi->s_frag_size, | 614 | sbi->s_frag_size, |
606 | sbi->s_groups_count, | 615 | sbi->s_groups_count, |
@@ -767,7 +776,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
767 | */ | 776 | */ |
768 | blocksize = sb_min_blocksize(sb, BLOCK_SIZE); | 777 | blocksize = sb_min_blocksize(sb, BLOCK_SIZE); |
769 | if (!blocksize) { | 778 | if (!blocksize) { |
770 | printk ("EXT2-fs: unable to set blocksize\n"); | 779 | ext2_msg(sb, KERN_ERR, "error: unable to set blocksize"); |
771 | goto failed_sbi; | 780 | goto failed_sbi; |
772 | } | 781 | } |
773 | 782 | ||
@@ -783,7 +792,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
783 | } | 792 | } |
784 | 793 | ||
785 | if (!(bh = sb_bread(sb, logic_sb_block))) { | 794 | if (!(bh = sb_bread(sb, logic_sb_block))) { |
786 | printk ("EXT2-fs: unable to read superblock\n"); | 795 | ext2_msg(sb, KERN_ERR, "error: unable to read superblock"); |
787 | goto failed_sbi; | 796 | goto failed_sbi; |
788 | } | 797 | } |
789 | /* | 798 | /* |
@@ -826,7 +835,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
826 | 835 | ||
827 | set_opt(sbi->s_mount_opt, RESERVATION); | 836 | set_opt(sbi->s_mount_opt, RESERVATION); |
828 | 837 | ||
829 | if (!parse_options ((char *) data, sbi)) | 838 | if (!parse_options((char *) data, sb)) |
830 | goto failed_mount; | 839 | goto failed_mount; |
831 | 840 | ||
832 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | | 841 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
@@ -840,8 +849,9 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
840 | (EXT2_HAS_COMPAT_FEATURE(sb, ~0U) || | 849 | (EXT2_HAS_COMPAT_FEATURE(sb, ~0U) || |
841 | EXT2_HAS_RO_COMPAT_FEATURE(sb, ~0U) || | 850 | EXT2_HAS_RO_COMPAT_FEATURE(sb, ~0U) || |
842 | EXT2_HAS_INCOMPAT_FEATURE(sb, ~0U))) | 851 | EXT2_HAS_INCOMPAT_FEATURE(sb, ~0U))) |
843 | printk("EXT2-fs warning: feature flags set on rev 0 fs, " | 852 | ext2_msg(sb, KERN_WARNING, |
844 | "running e2fsck is recommended\n"); | 853 | "warning: feature flags set on rev 0 fs, " |
854 | "running e2fsck is recommended"); | ||
845 | /* | 855 | /* |
846 | * Check feature flags regardless of the revision level, since we | 856 | * Check feature flags regardless of the revision level, since we |
847 | * previously didn't change the revision level when setting the flags, | 857 | * previously didn't change the revision level when setting the flags, |
@@ -849,16 +859,16 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
849 | */ | 859 | */ |
850 | features = EXT2_HAS_INCOMPAT_FEATURE(sb, ~EXT2_FEATURE_INCOMPAT_SUPP); | 860 | features = EXT2_HAS_INCOMPAT_FEATURE(sb, ~EXT2_FEATURE_INCOMPAT_SUPP); |
851 | if (features) { | 861 | if (features) { |
852 | printk("EXT2-fs: %s: couldn't mount because of " | 862 | ext2_msg(sb, KERN_ERR, "error: couldn't mount because of " |
853 | "unsupported optional features (%x).\n", | 863 | "unsupported optional features (%x)", |
854 | sb->s_id, le32_to_cpu(features)); | 864 | le32_to_cpu(features)); |
855 | goto failed_mount; | 865 | goto failed_mount; |
856 | } | 866 | } |
857 | if (!(sb->s_flags & MS_RDONLY) && | 867 | if (!(sb->s_flags & MS_RDONLY) && |
858 | (features = EXT2_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP))){ | 868 | (features = EXT2_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP))){ |
859 | printk("EXT2-fs: %s: couldn't mount RDWR because of " | 869 | ext2_msg(sb, KERN_ERR, "error: couldn't mount RDWR because of " |
860 | "unsupported optional features (%x).\n", | 870 | "unsupported optional features (%x)", |
861 | sb->s_id, le32_to_cpu(features)); | 871 | le32_to_cpu(features)); |
862 | goto failed_mount; | 872 | goto failed_mount; |
863 | } | 873 | } |
864 | 874 | ||
@@ -866,7 +876,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
866 | 876 | ||
867 | if (ext2_use_xip(sb) && blocksize != PAGE_SIZE) { | 877 | if (ext2_use_xip(sb) && blocksize != PAGE_SIZE) { |
868 | if (!silent) | 878 | if (!silent) |
869 | printk("XIP: Unsupported blocksize\n"); | 879 | ext2_msg(sb, KERN_ERR, |
880 | "error: unsupported blocksize for xip"); | ||
870 | goto failed_mount; | 881 | goto failed_mount; |
871 | } | 882 | } |
872 | 883 | ||
@@ -875,7 +886,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
875 | brelse(bh); | 886 | brelse(bh); |
876 | 887 | ||
877 | if (!sb_set_blocksize(sb, blocksize)) { | 888 | if (!sb_set_blocksize(sb, blocksize)) { |
878 | printk(KERN_ERR "EXT2-fs: blocksize too small for device.\n"); | 889 | ext2_msg(sb, KERN_ERR, "error: blocksize is too small"); |
879 | goto failed_sbi; | 890 | goto failed_sbi; |
880 | } | 891 | } |
881 | 892 | ||
@@ -883,14 +894,14 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
883 | offset = (sb_block*BLOCK_SIZE) % blocksize; | 894 | offset = (sb_block*BLOCK_SIZE) % blocksize; |
884 | bh = sb_bread(sb, logic_sb_block); | 895 | bh = sb_bread(sb, logic_sb_block); |
885 | if(!bh) { | 896 | if(!bh) { |
886 | printk("EXT2-fs: Couldn't read superblock on " | 897 | ext2_msg(sb, KERN_ERR, "error: couldn't read" |
887 | "2nd try.\n"); | 898 | "superblock on 2nd try"); |
888 | goto failed_sbi; | 899 | goto failed_sbi; |
889 | } | 900 | } |
890 | es = (struct ext2_super_block *) (((char *)bh->b_data) + offset); | 901 | es = (struct ext2_super_block *) (((char *)bh->b_data) + offset); |
891 | sbi->s_es = es; | 902 | sbi->s_es = es; |
892 | if (es->s_magic != cpu_to_le16(EXT2_SUPER_MAGIC)) { | 903 | if (es->s_magic != cpu_to_le16(EXT2_SUPER_MAGIC)) { |
893 | printk ("EXT2-fs: Magic mismatch, very weird !\n"); | 904 | ext2_msg(sb, KERN_ERR, "error: magic mismatch"); |
894 | goto failed_mount; | 905 | goto failed_mount; |
895 | } | 906 | } |
896 | } | 907 | } |
@@ -906,7 +917,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
906 | if ((sbi->s_inode_size < EXT2_GOOD_OLD_INODE_SIZE) || | 917 | if ((sbi->s_inode_size < EXT2_GOOD_OLD_INODE_SIZE) || |
907 | !is_power_of_2(sbi->s_inode_size) || | 918 | !is_power_of_2(sbi->s_inode_size) || |
908 | (sbi->s_inode_size > blocksize)) { | 919 | (sbi->s_inode_size > blocksize)) { |
909 | printk ("EXT2-fs: unsupported inode size: %d\n", | 920 | ext2_msg(sb, KERN_ERR, |
921 | "error: unsupported inode size: %d", | ||
910 | sbi->s_inode_size); | 922 | sbi->s_inode_size); |
911 | goto failed_mount; | 923 | goto failed_mount; |
912 | } | 924 | } |
@@ -943,29 +955,33 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
943 | 955 | ||
944 | if (sb->s_blocksize != bh->b_size) { | 956 | if (sb->s_blocksize != bh->b_size) { |
945 | if (!silent) | 957 | if (!silent) |
946 | printk ("VFS: Unsupported blocksize on dev " | 958 | ext2_msg(sb, KERN_ERR, "error: unsupported blocksize"); |
947 | "%s.\n", sb->s_id); | ||
948 | goto failed_mount; | 959 | goto failed_mount; |
949 | } | 960 | } |
950 | 961 | ||
951 | if (sb->s_blocksize != sbi->s_frag_size) { | 962 | if (sb->s_blocksize != sbi->s_frag_size) { |
952 | printk ("EXT2-fs: fragsize %lu != blocksize %lu (not supported yet)\n", | 963 | ext2_msg(sb, KERN_ERR, |
964 | "error: fragsize %lu != blocksize %lu" | ||
965 | "(not supported yet)", | ||
953 | sbi->s_frag_size, sb->s_blocksize); | 966 | sbi->s_frag_size, sb->s_blocksize); |
954 | goto failed_mount; | 967 | goto failed_mount; |
955 | } | 968 | } |
956 | 969 | ||
957 | if (sbi->s_blocks_per_group > sb->s_blocksize * 8) { | 970 | if (sbi->s_blocks_per_group > sb->s_blocksize * 8) { |
958 | printk ("EXT2-fs: #blocks per group too big: %lu\n", | 971 | ext2_msg(sb, KERN_ERR, |
972 | "error: #blocks per group too big: %lu", | ||
959 | sbi->s_blocks_per_group); | 973 | sbi->s_blocks_per_group); |
960 | goto failed_mount; | 974 | goto failed_mount; |
961 | } | 975 | } |
962 | if (sbi->s_frags_per_group > sb->s_blocksize * 8) { | 976 | if (sbi->s_frags_per_group > sb->s_blocksize * 8) { |
963 | printk ("EXT2-fs: #fragments per group too big: %lu\n", | 977 | ext2_msg(sb, KERN_ERR, |
978 | "error: #fragments per group too big: %lu", | ||
964 | sbi->s_frags_per_group); | 979 | sbi->s_frags_per_group); |
965 | goto failed_mount; | 980 | goto failed_mount; |
966 | } | 981 | } |
967 | if (sbi->s_inodes_per_group > sb->s_blocksize * 8) { | 982 | if (sbi->s_inodes_per_group > sb->s_blocksize * 8) { |
968 | printk ("EXT2-fs: #inodes per group too big: %lu\n", | 983 | ext2_msg(sb, KERN_ERR, |
984 | "error: #inodes per group too big: %lu", | ||
969 | sbi->s_inodes_per_group); | 985 | sbi->s_inodes_per_group); |
970 | goto failed_mount; | 986 | goto failed_mount; |
971 | } | 987 | } |
@@ -979,13 +995,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
979 | EXT2_DESC_PER_BLOCK(sb); | 995 | EXT2_DESC_PER_BLOCK(sb); |
980 | sbi->s_group_desc = kmalloc (db_count * sizeof (struct buffer_head *), GFP_KERNEL); | 996 | sbi->s_group_desc = kmalloc (db_count * sizeof (struct buffer_head *), GFP_KERNEL); |
981 | if (sbi->s_group_desc == NULL) { | 997 | if (sbi->s_group_desc == NULL) { |
982 | printk ("EXT2-fs: not enough memory\n"); | 998 | ext2_msg(sb, KERN_ERR, "error: not enough memory"); |
983 | goto failed_mount; | 999 | goto failed_mount; |
984 | } | 1000 | } |
985 | bgl_lock_init(sbi->s_blockgroup_lock); | 1001 | bgl_lock_init(sbi->s_blockgroup_lock); |
986 | sbi->s_debts = kcalloc(sbi->s_groups_count, sizeof(*sbi->s_debts), GFP_KERNEL); | 1002 | sbi->s_debts = kcalloc(sbi->s_groups_count, sizeof(*sbi->s_debts), GFP_KERNEL); |
987 | if (!sbi->s_debts) { | 1003 | if (!sbi->s_debts) { |
988 | printk ("EXT2-fs: not enough memory\n"); | 1004 | ext2_msg(sb, KERN_ERR, "error: not enough memory"); |
989 | goto failed_mount_group_desc; | 1005 | goto failed_mount_group_desc; |
990 | } | 1006 | } |
991 | for (i = 0; i < db_count; i++) { | 1007 | for (i = 0; i < db_count; i++) { |
@@ -994,12 +1010,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
994 | if (!sbi->s_group_desc[i]) { | 1010 | if (!sbi->s_group_desc[i]) { |
995 | for (j = 0; j < i; j++) | 1011 | for (j = 0; j < i; j++) |
996 | brelse (sbi->s_group_desc[j]); | 1012 | brelse (sbi->s_group_desc[j]); |
997 | printk ("EXT2-fs: unable to read group descriptors\n"); | 1013 | ext2_msg(sb, KERN_ERR, |
1014 | "error: unable to read group descriptors"); | ||
998 | goto failed_mount_group_desc; | 1015 | goto failed_mount_group_desc; |
999 | } | 1016 | } |
1000 | } | 1017 | } |
1001 | if (!ext2_check_descriptors (sb)) { | 1018 | if (!ext2_check_descriptors (sb)) { |
1002 | printk ("EXT2-fs: group descriptors corrupted!\n"); | 1019 | ext2_msg(sb, KERN_ERR, "group descriptors corrupted"); |
1003 | goto failed_mount2; | 1020 | goto failed_mount2; |
1004 | } | 1021 | } |
1005 | sbi->s_gdb_count = db_count; | 1022 | sbi->s_gdb_count = db_count; |
@@ -1032,7 +1049,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
1032 | ext2_count_dirs(sb)); | 1049 | ext2_count_dirs(sb)); |
1033 | } | 1050 | } |
1034 | if (err) { | 1051 | if (err) { |
1035 | printk(KERN_ERR "EXT2-fs: insufficient memory\n"); | 1052 | ext2_msg(sb, KERN_ERR, "error: insufficient memory"); |
1036 | goto failed_mount3; | 1053 | goto failed_mount3; |
1037 | } | 1054 | } |
1038 | /* | 1055 | /* |
@@ -1048,27 +1065,28 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
1048 | } | 1065 | } |
1049 | if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { | 1066 | if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { |
1050 | iput(root); | 1067 | iput(root); |
1051 | printk(KERN_ERR "EXT2-fs: corrupt root inode, run e2fsck\n"); | 1068 | ext2_msg(sb, KERN_ERR, "error: corrupt root inode, run e2fsck"); |
1052 | goto failed_mount3; | 1069 | goto failed_mount3; |
1053 | } | 1070 | } |
1054 | 1071 | ||
1055 | sb->s_root = d_alloc_root(root); | 1072 | sb->s_root = d_alloc_root(root); |
1056 | if (!sb->s_root) { | 1073 | if (!sb->s_root) { |
1057 | iput(root); | 1074 | iput(root); |
1058 | printk(KERN_ERR "EXT2-fs: get root inode failed\n"); | 1075 | ext2_msg(sb, KERN_ERR, "error: get root inode failed"); |
1059 | ret = -ENOMEM; | 1076 | ret = -ENOMEM; |
1060 | goto failed_mount3; | 1077 | goto failed_mount3; |
1061 | } | 1078 | } |
1062 | if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) | 1079 | if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) |
1063 | ext2_warning(sb, __func__, | 1080 | ext2_msg(sb, KERN_WARNING, |
1064 | "mounting ext3 filesystem as ext2"); | 1081 | "warning: mounting ext3 filesystem as ext2"); |
1065 | ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY); | 1082 | ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY); |
1066 | return 0; | 1083 | return 0; |
1067 | 1084 | ||
1068 | cantfind_ext2: | 1085 | cantfind_ext2: |
1069 | if (!silent) | 1086 | if (!silent) |
1070 | printk("VFS: Can't find an ext2 filesystem on dev %s.\n", | 1087 | ext2_msg(sb, KERN_ERR, |
1071 | sb->s_id); | 1088 | "error: can't find an ext2 filesystem on dev %s.", |
1089 | sb->s_id); | ||
1072 | goto failed_mount; | 1090 | goto failed_mount; |
1073 | failed_mount3: | 1091 | failed_mount3: |
1074 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | 1092 | percpu_counter_destroy(&sbi->s_freeblocks_counter); |
@@ -1089,9 +1107,30 @@ failed_sbi: | |||
1089 | return ret; | 1107 | return ret; |
1090 | } | 1108 | } |
1091 | 1109 | ||
1110 | static void ext2_clear_super_error(struct super_block *sb) | ||
1111 | { | ||
1112 | struct buffer_head *sbh = EXT2_SB(sb)->s_sbh; | ||
1113 | |||
1114 | if (buffer_write_io_error(sbh)) { | ||
1115 | /* | ||
1116 | * Oh, dear. A previous attempt to write the | ||
1117 | * superblock failed. This could happen because the | ||
1118 | * USB device was yanked out. Or it could happen to | ||
1119 | * be a transient write error and maybe the block will | ||
1120 | * be remapped. Nothing we can do but to retry the | ||
1121 | * write and hope for the best. | ||
1122 | */ | ||
1123 | printk(KERN_ERR "EXT2-fs: %s previous I/O error to " | ||
1124 | "superblock detected", sb->s_id); | ||
1125 | clear_buffer_write_io_error(sbh); | ||
1126 | set_buffer_uptodate(sbh); | ||
1127 | } | ||
1128 | } | ||
1129 | |||
1092 | static void ext2_commit_super (struct super_block * sb, | 1130 | static void ext2_commit_super (struct super_block * sb, |
1093 | struct ext2_super_block * es) | 1131 | struct ext2_super_block * es) |
1094 | { | 1132 | { |
1133 | ext2_clear_super_error(sb); | ||
1095 | es->s_wtime = cpu_to_le32(get_seconds()); | 1134 | es->s_wtime = cpu_to_le32(get_seconds()); |
1096 | mark_buffer_dirty(EXT2_SB(sb)->s_sbh); | 1135 | mark_buffer_dirty(EXT2_SB(sb)->s_sbh); |
1097 | sb->s_dirt = 0; | 1136 | sb->s_dirt = 0; |
@@ -1099,6 +1138,7 @@ static void ext2_commit_super (struct super_block * sb, | |||
1099 | 1138 | ||
1100 | static void ext2_sync_super(struct super_block *sb, struct ext2_super_block *es) | 1139 | static void ext2_sync_super(struct super_block *sb, struct ext2_super_block *es) |
1101 | { | 1140 | { |
1141 | ext2_clear_super_error(sb); | ||
1102 | es->s_free_blocks_count = cpu_to_le32(ext2_count_free_blocks(sb)); | 1142 | es->s_free_blocks_count = cpu_to_le32(ext2_count_free_blocks(sb)); |
1103 | es->s_free_inodes_count = cpu_to_le32(ext2_count_free_inodes(sb)); | 1143 | es->s_free_inodes_count = cpu_to_le32(ext2_count_free_inodes(sb)); |
1104 | es->s_wtime = cpu_to_le32(get_seconds()); | 1144 | es->s_wtime = cpu_to_le32(get_seconds()); |
@@ -1121,8 +1161,24 @@ static void ext2_sync_super(struct super_block *sb, struct ext2_super_block *es) | |||
1121 | static int ext2_sync_fs(struct super_block *sb, int wait) | 1161 | static int ext2_sync_fs(struct super_block *sb, int wait) |
1122 | { | 1162 | { |
1123 | struct ext2_super_block *es = EXT2_SB(sb)->s_es; | 1163 | struct ext2_super_block *es = EXT2_SB(sb)->s_es; |
1164 | struct buffer_head *sbh = EXT2_SB(sb)->s_sbh; | ||
1124 | 1165 | ||
1125 | lock_kernel(); | 1166 | lock_kernel(); |
1167 | if (buffer_write_io_error(sbh)) { | ||
1168 | /* | ||
1169 | * Oh, dear. A previous attempt to write the | ||
1170 | * superblock failed. This could happen because the | ||
1171 | * USB device was yanked out. Or it could happen to | ||
1172 | * be a transient write error and maybe the block will | ||
1173 | * be remapped. Nothing we can do but to retry the | ||
1174 | * write and hope for the best. | ||
1175 | */ | ||
1176 | ext2_msg(sb, KERN_ERR, | ||
1177 | "previous I/O error to superblock detected\n"); | ||
1178 | clear_buffer_write_io_error(sbh); | ||
1179 | set_buffer_uptodate(sbh); | ||
1180 | } | ||
1181 | |||
1126 | if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) { | 1182 | if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) { |
1127 | ext2_debug("setting valid to 0\n"); | 1183 | ext2_debug("setting valid to 0\n"); |
1128 | es->s_state &= cpu_to_le16(~EXT2_VALID_FS); | 1184 | es->s_state &= cpu_to_le16(~EXT2_VALID_FS); |
@@ -1170,7 +1226,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) | |||
1170 | /* | 1226 | /* |
1171 | * Allow the "check" option to be passed as a remount option. | 1227 | * Allow the "check" option to be passed as a remount option. |
1172 | */ | 1228 | */ |
1173 | if (!parse_options (data, sbi)) { | 1229 | if (!parse_options(data, sb)) { |
1174 | err = -EINVAL; | 1230 | err = -EINVAL; |
1175 | goto restore_opts; | 1231 | goto restore_opts; |
1176 | } | 1232 | } |
@@ -1182,7 +1238,8 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) | |||
1182 | EXT2_MOUNT_XIP if not */ | 1238 | EXT2_MOUNT_XIP if not */ |
1183 | 1239 | ||
1184 | if ((ext2_use_xip(sb)) && (sb->s_blocksize != PAGE_SIZE)) { | 1240 | if ((ext2_use_xip(sb)) && (sb->s_blocksize != PAGE_SIZE)) { |
1185 | printk("XIP: Unsupported blocksize\n"); | 1241 | ext2_msg(sb, KERN_WARNING, |
1242 | "warning: unsupported blocksize for xip"); | ||
1186 | err = -EINVAL; | 1243 | err = -EINVAL; |
1187 | goto restore_opts; | 1244 | goto restore_opts; |
1188 | } | 1245 | } |
@@ -1191,8 +1248,8 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) | |||
1191 | if (((sbi->s_mount_opt & EXT2_MOUNT_XIP) != | 1248 | if (((sbi->s_mount_opt & EXT2_MOUNT_XIP) != |
1192 | (old_mount_opt & EXT2_MOUNT_XIP)) && | 1249 | (old_mount_opt & EXT2_MOUNT_XIP)) && |
1193 | invalidate_inodes(sb)) { | 1250 | invalidate_inodes(sb)) { |
1194 | ext2_warning(sb, __func__, "refusing change of xip flag " | 1251 | ext2_msg(sb, KERN_WARNING, "warning: refusing change of " |
1195 | "with busy inodes while remounting"); | 1252 | "xip flag with busy inodes while remounting"); |
1196 | sbi->s_mount_opt &= ~EXT2_MOUNT_XIP; | 1253 | sbi->s_mount_opt &= ~EXT2_MOUNT_XIP; |
1197 | sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP; | 1254 | sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP; |
1198 | } | 1255 | } |
@@ -1216,9 +1273,10 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) | |||
1216 | __le32 ret = EXT2_HAS_RO_COMPAT_FEATURE(sb, | 1273 | __le32 ret = EXT2_HAS_RO_COMPAT_FEATURE(sb, |
1217 | ~EXT2_FEATURE_RO_COMPAT_SUPP); | 1274 | ~EXT2_FEATURE_RO_COMPAT_SUPP); |
1218 | if (ret) { | 1275 | if (ret) { |
1219 | printk("EXT2-fs: %s: couldn't remount RDWR because of " | 1276 | ext2_msg(sb, KERN_WARNING, |
1220 | "unsupported optional features (%x).\n", | 1277 | "warning: couldn't remount RDWR because of " |
1221 | sb->s_id, le32_to_cpu(ret)); | 1278 | "unsupported optional features (%x).", |
1279 | le32_to_cpu(ret)); | ||
1222 | err = -EROFS; | 1280 | err = -EROFS; |
1223 | goto restore_opts; | 1281 | goto restore_opts; |
1224 | } | 1282 | } |
diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c index 4e2426e22bbe..565cf817bbf1 100644 --- a/fs/ext2/symlink.c +++ b/fs/ext2/symlink.c | |||
@@ -32,6 +32,7 @@ const struct inode_operations ext2_symlink_inode_operations = { | |||
32 | .readlink = generic_readlink, | 32 | .readlink = generic_readlink, |
33 | .follow_link = page_follow_link_light, | 33 | .follow_link = page_follow_link_light, |
34 | .put_link = page_put_link, | 34 | .put_link = page_put_link, |
35 | .setattr = ext2_setattr, | ||
35 | #ifdef CONFIG_EXT2_FS_XATTR | 36 | #ifdef CONFIG_EXT2_FS_XATTR |
36 | .setxattr = generic_setxattr, | 37 | .setxattr = generic_setxattr, |
37 | .getxattr = generic_getxattr, | 38 | .getxattr = generic_getxattr, |
@@ -43,6 +44,7 @@ const struct inode_operations ext2_symlink_inode_operations = { | |||
43 | const struct inode_operations ext2_fast_symlink_inode_operations = { | 44 | const struct inode_operations ext2_fast_symlink_inode_operations = { |
44 | .readlink = generic_readlink, | 45 | .readlink = generic_readlink, |
45 | .follow_link = ext2_follow_link, | 46 | .follow_link = ext2_follow_link, |
47 | .setattr = ext2_setattr, | ||
46 | #ifdef CONFIG_EXT2_FS_XATTR | 48 | #ifdef CONFIG_EXT2_FS_XATTR |
47 | .setxattr = generic_setxattr, | 49 | .setxattr = generic_setxattr, |
48 | .getxattr = generic_getxattr, | 50 | .getxattr = generic_getxattr, |
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 7913531ec6d5..e44dc92609be 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c | |||
@@ -60,6 +60,7 @@ | |||
60 | #include <linux/mbcache.h> | 60 | #include <linux/mbcache.h> |
61 | #include <linux/quotaops.h> | 61 | #include <linux/quotaops.h> |
62 | #include <linux/rwsem.h> | 62 | #include <linux/rwsem.h> |
63 | #include <linux/security.h> | ||
63 | #include "ext2.h" | 64 | #include "ext2.h" |
64 | #include "xattr.h" | 65 | #include "xattr.h" |
65 | #include "acl.h" | 66 | #include "acl.h" |
@@ -249,8 +250,9 @@ cleanup: | |||
249 | * used / required on success. | 250 | * used / required on success. |
250 | */ | 251 | */ |
251 | static int | 252 | static int |
252 | ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) | 253 | ext2_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size) |
253 | { | 254 | { |
255 | struct inode *inode = dentry->d_inode; | ||
254 | struct buffer_head *bh = NULL; | 256 | struct buffer_head *bh = NULL; |
255 | struct ext2_xattr_entry *entry; | 257 | struct ext2_xattr_entry *entry; |
256 | char *end; | 258 | char *end; |
@@ -300,9 +302,10 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list", | |||
300 | ext2_xattr_handler(entry->e_name_index); | 302 | ext2_xattr_handler(entry->e_name_index); |
301 | 303 | ||
302 | if (handler) { | 304 | if (handler) { |
303 | size_t size = handler->list(inode, buffer, rest, | 305 | size_t size = handler->list(dentry, buffer, rest, |
304 | entry->e_name, | 306 | entry->e_name, |
305 | entry->e_name_len); | 307 | entry->e_name_len, |
308 | handler->flags); | ||
306 | if (buffer) { | 309 | if (buffer) { |
307 | if (size > rest) { | 310 | if (size > rest) { |
308 | error = -ERANGE; | 311 | error = -ERANGE; |
@@ -330,7 +333,7 @@ cleanup: | |||
330 | ssize_t | 333 | ssize_t |
331 | ext2_listxattr(struct dentry *dentry, char *buffer, size_t size) | 334 | ext2_listxattr(struct dentry *dentry, char *buffer, size_t size) |
332 | { | 335 | { |
333 | return ext2_xattr_list(dentry->d_inode, buffer, size); | 336 | return ext2_xattr_list(dentry, buffer, size); |
334 | } | 337 | } |
335 | 338 | ||
336 | /* | 339 | /* |
@@ -641,8 +644,8 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh, | |||
641 | the inode. */ | 644 | the inode. */ |
642 | ea_bdebug(new_bh, "reusing block"); | 645 | ea_bdebug(new_bh, "reusing block"); |
643 | 646 | ||
644 | error = -EDQUOT; | 647 | error = dquot_alloc_block(inode, 1); |
645 | if (vfs_dq_alloc_block(inode, 1)) { | 648 | if (error) { |
646 | unlock_buffer(new_bh); | 649 | unlock_buffer(new_bh); |
647 | goto cleanup; | 650 | goto cleanup; |
648 | } | 651 | } |
@@ -699,7 +702,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh, | |||
699 | * as if nothing happened and cleanup the unused block */ | 702 | * as if nothing happened and cleanup the unused block */ |
700 | if (error && error != -ENOSPC) { | 703 | if (error && error != -ENOSPC) { |
701 | if (new_bh && new_bh != old_bh) | 704 | if (new_bh && new_bh != old_bh) |
702 | vfs_dq_free_block(inode, 1); | 705 | dquot_free_block(inode, 1); |
703 | goto cleanup; | 706 | goto cleanup; |
704 | } | 707 | } |
705 | } else | 708 | } else |
@@ -731,7 +734,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh, | |||
731 | le32_add_cpu(&HDR(old_bh)->h_refcount, -1); | 734 | le32_add_cpu(&HDR(old_bh)->h_refcount, -1); |
732 | if (ce) | 735 | if (ce) |
733 | mb_cache_entry_release(ce); | 736 | mb_cache_entry_release(ce); |
734 | vfs_dq_free_block(inode, 1); | 737 | dquot_free_block(inode, 1); |
735 | mark_buffer_dirty(old_bh); | 738 | mark_buffer_dirty(old_bh); |
736 | ea_bdebug(old_bh, "refcount now=%d", | 739 | ea_bdebug(old_bh, "refcount now=%d", |
737 | le32_to_cpu(HDR(old_bh)->h_refcount)); | 740 | le32_to_cpu(HDR(old_bh)->h_refcount)); |
@@ -794,7 +797,7 @@ ext2_xattr_delete_inode(struct inode *inode) | |||
794 | mark_buffer_dirty(bh); | 797 | mark_buffer_dirty(bh); |
795 | if (IS_SYNC(inode)) | 798 | if (IS_SYNC(inode)) |
796 | sync_dirty_buffer(bh); | 799 | sync_dirty_buffer(bh); |
797 | vfs_dq_free_block(inode, 1); | 800 | dquot_free_block(inode, 1); |
798 | } | 801 | } |
799 | EXT2_I(inode)->i_file_acl = 0; | 802 | EXT2_I(inode)->i_file_acl = 0; |
800 | 803 | ||
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c index 70c0dbdcdcb7..b118c6383c6d 100644 --- a/fs/ext2/xattr_security.c +++ b/fs/ext2/xattr_security.c | |||
@@ -4,6 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/slab.h> | ||
7 | #include <linux/string.h> | 8 | #include <linux/string.h> |
8 | #include <linux/fs.h> | 9 | #include <linux/fs.h> |
9 | #include <linux/ext2_fs.h> | 10 | #include <linux/ext2_fs.h> |
@@ -11,8 +12,8 @@ | |||
11 | #include "xattr.h" | 12 | #include "xattr.h" |
12 | 13 | ||
13 | static size_t | 14 | static size_t |
14 | ext2_xattr_security_list(struct inode *inode, char *list, size_t list_size, | 15 | ext2_xattr_security_list(struct dentry *dentry, char *list, size_t list_size, |
15 | const char *name, size_t name_len) | 16 | const char *name, size_t name_len, int type) |
16 | { | 17 | { |
17 | const int prefix_len = XATTR_SECURITY_PREFIX_LEN; | 18 | const int prefix_len = XATTR_SECURITY_PREFIX_LEN; |
18 | const size_t total_len = prefix_len + name_len + 1; | 19 | const size_t total_len = prefix_len + name_len + 1; |
@@ -26,22 +27,22 @@ ext2_xattr_security_list(struct inode *inode, char *list, size_t list_size, | |||
26 | } | 27 | } |
27 | 28 | ||
28 | static int | 29 | static int |
29 | ext2_xattr_security_get(struct inode *inode, const char *name, | 30 | ext2_xattr_security_get(struct dentry *dentry, const char *name, |
30 | void *buffer, size_t size) | 31 | void *buffer, size_t size, int type) |
31 | { | 32 | { |
32 | if (strcmp(name, "") == 0) | 33 | if (strcmp(name, "") == 0) |
33 | return -EINVAL; | 34 | return -EINVAL; |
34 | return ext2_xattr_get(inode, EXT2_XATTR_INDEX_SECURITY, name, | 35 | return ext2_xattr_get(dentry->d_inode, EXT2_XATTR_INDEX_SECURITY, name, |
35 | buffer, size); | 36 | buffer, size); |
36 | } | 37 | } |
37 | 38 | ||
38 | static int | 39 | static int |
39 | ext2_xattr_security_set(struct inode *inode, const char *name, | 40 | ext2_xattr_security_set(struct dentry *dentry, const char *name, |
40 | const void *value, size_t size, int flags) | 41 | const void *value, size_t size, int flags, int type) |
41 | { | 42 | { |
42 | if (strcmp(name, "") == 0) | 43 | if (strcmp(name, "") == 0) |
43 | return -EINVAL; | 44 | return -EINVAL; |
44 | return ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY, name, | 45 | return ext2_xattr_set(dentry->d_inode, EXT2_XATTR_INDEX_SECURITY, name, |
45 | value, size, flags); | 46 | value, size, flags); |
46 | } | 47 | } |
47 | 48 | ||
diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c index e8219f8eae9f..2a26d71f4771 100644 --- a/fs/ext2/xattr_trusted.c +++ b/fs/ext2/xattr_trusted.c | |||
@@ -13,8 +13,8 @@ | |||
13 | #include "xattr.h" | 13 | #include "xattr.h" |
14 | 14 | ||
15 | static size_t | 15 | static size_t |
16 | ext2_xattr_trusted_list(struct inode *inode, char *list, size_t list_size, | 16 | ext2_xattr_trusted_list(struct dentry *dentry, char *list, size_t list_size, |
17 | const char *name, size_t name_len) | 17 | const char *name, size_t name_len, int type) |
18 | { | 18 | { |
19 | const int prefix_len = XATTR_TRUSTED_PREFIX_LEN; | 19 | const int prefix_len = XATTR_TRUSTED_PREFIX_LEN; |
20 | const size_t total_len = prefix_len + name_len + 1; | 20 | const size_t total_len = prefix_len + name_len + 1; |
@@ -31,22 +31,22 @@ ext2_xattr_trusted_list(struct inode *inode, char *list, size_t list_size, | |||
31 | } | 31 | } |
32 | 32 | ||
33 | static int | 33 | static int |
34 | ext2_xattr_trusted_get(struct inode *inode, const char *name, | 34 | ext2_xattr_trusted_get(struct dentry *dentry, const char *name, |
35 | void *buffer, size_t size) | 35 | void *buffer, size_t size, int type) |
36 | { | 36 | { |
37 | if (strcmp(name, "") == 0) | 37 | if (strcmp(name, "") == 0) |
38 | return -EINVAL; | 38 | return -EINVAL; |
39 | return ext2_xattr_get(inode, EXT2_XATTR_INDEX_TRUSTED, name, | 39 | return ext2_xattr_get(dentry->d_inode, EXT2_XATTR_INDEX_TRUSTED, name, |
40 | buffer, size); | 40 | buffer, size); |
41 | } | 41 | } |
42 | 42 | ||
43 | static int | 43 | static int |
44 | ext2_xattr_trusted_set(struct inode *inode, const char *name, | 44 | ext2_xattr_trusted_set(struct dentry *dentry, const char *name, |
45 | const void *value, size_t size, int flags) | 45 | const void *value, size_t size, int flags, int type) |
46 | { | 46 | { |
47 | if (strcmp(name, "") == 0) | 47 | if (strcmp(name, "") == 0) |
48 | return -EINVAL; | 48 | return -EINVAL; |
49 | return ext2_xattr_set(inode, EXT2_XATTR_INDEX_TRUSTED, name, | 49 | return ext2_xattr_set(dentry->d_inode, EXT2_XATTR_INDEX_TRUSTED, name, |
50 | value, size, flags); | 50 | value, size, flags); |
51 | } | 51 | } |
52 | 52 | ||
diff --git a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c index 92495d28c62f..3f6caf3684b4 100644 --- a/fs/ext2/xattr_user.c +++ b/fs/ext2/xattr_user.c | |||
@@ -12,13 +12,13 @@ | |||
12 | #include "xattr.h" | 12 | #include "xattr.h" |
13 | 13 | ||
14 | static size_t | 14 | static size_t |
15 | ext2_xattr_user_list(struct inode *inode, char *list, size_t list_size, | 15 | ext2_xattr_user_list(struct dentry *dentry, char *list, size_t list_size, |
16 | const char *name, size_t name_len) | 16 | const char *name, size_t name_len, int type) |
17 | { | 17 | { |
18 | const size_t prefix_len = XATTR_USER_PREFIX_LEN; | 18 | const size_t prefix_len = XATTR_USER_PREFIX_LEN; |
19 | const size_t total_len = prefix_len + name_len + 1; | 19 | const size_t total_len = prefix_len + name_len + 1; |
20 | 20 | ||
21 | if (!test_opt(inode->i_sb, XATTR_USER)) | 21 | if (!test_opt(dentry->d_sb, XATTR_USER)) |
22 | return 0; | 22 | return 0; |
23 | 23 | ||
24 | if (list && total_len <= list_size) { | 24 | if (list && total_len <= list_size) { |
@@ -30,27 +30,28 @@ ext2_xattr_user_list(struct inode *inode, char *list, size_t list_size, | |||
30 | } | 30 | } |
31 | 31 | ||
32 | static int | 32 | static int |
33 | ext2_xattr_user_get(struct inode *inode, const char *name, | 33 | ext2_xattr_user_get(struct dentry *dentry, const char *name, |
34 | void *buffer, size_t size) | 34 | void *buffer, size_t size, int type) |
35 | { | 35 | { |
36 | if (strcmp(name, "") == 0) | 36 | if (strcmp(name, "") == 0) |
37 | return -EINVAL; | 37 | return -EINVAL; |
38 | if (!test_opt(inode->i_sb, XATTR_USER)) | 38 | if (!test_opt(dentry->d_sb, XATTR_USER)) |
39 | return -EOPNOTSUPP; | 39 | return -EOPNOTSUPP; |
40 | return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name, buffer, size); | 40 | return ext2_xattr_get(dentry->d_inode, EXT2_XATTR_INDEX_USER, |
41 | name, buffer, size); | ||
41 | } | 42 | } |
42 | 43 | ||
43 | static int | 44 | static int |
44 | ext2_xattr_user_set(struct inode *inode, const char *name, | 45 | ext2_xattr_user_set(struct dentry *dentry, const char *name, |
45 | const void *value, size_t size, int flags) | 46 | const void *value, size_t size, int flags, int type) |
46 | { | 47 | { |
47 | if (strcmp(name, "") == 0) | 48 | if (strcmp(name, "") == 0) |
48 | return -EINVAL; | 49 | return -EINVAL; |
49 | if (!test_opt(inode->i_sb, XATTR_USER)) | 50 | if (!test_opt(dentry->d_sb, XATTR_USER)) |
50 | return -EOPNOTSUPP; | 51 | return -EOPNOTSUPP; |
51 | 52 | ||
52 | return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name, | 53 | return ext2_xattr_set(dentry->d_inode, EXT2_XATTR_INDEX_USER, |
53 | value, size, flags); | 54 | name, value, size, flags); |
54 | } | 55 | } |
55 | 56 | ||
56 | struct xattr_handler ext2_xattr_user_handler = { | 57 | struct xattr_handler ext2_xattr_user_handler = { |
diff --git a/fs/ext2/xip.c b/fs/ext2/xip.c index c18fbf3e4068..322a56b2dfb1 100644 --- a/fs/ext2/xip.c +++ b/fs/ext2/xip.c | |||
@@ -69,8 +69,9 @@ void ext2_xip_verify_sb(struct super_block *sb) | |||
69 | if ((sbi->s_mount_opt & EXT2_MOUNT_XIP) && | 69 | if ((sbi->s_mount_opt & EXT2_MOUNT_XIP) && |
70 | !sb->s_bdev->bd_disk->fops->direct_access) { | 70 | !sb->s_bdev->bd_disk->fops->direct_access) { |
71 | sbi->s_mount_opt &= (~EXT2_MOUNT_XIP); | 71 | sbi->s_mount_opt &= (~EXT2_MOUNT_XIP); |
72 | ext2_warning(sb, __func__, | 72 | ext2_msg(sb, KERN_WARNING, |
73 | "ignoring xip option - not supported by bdev"); | 73 | "warning: ignoring xip option - " |
74 | "not supported by bdev"); | ||
74 | } | 75 | } |
75 | } | 76 | } |
76 | 77 | ||