diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-10 14:26:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-10 14:26:52 -0400 |
commit | 5f248c9c251c60af3403902b26e08de43964ea0b (patch) | |
tree | 6d3328e72a7e4015a64017eb30be18095c6a3c64 /fs/ext2 | |
parent | f6cec0ae58c17522a7bc4e2f39dae19f199ab534 (diff) | |
parent | dca332528bc69e05f67161e1ed59929633d5e63d (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (96 commits)
no need for list_for_each_entry_safe()/resetting with superblock list
Fix sget() race with failing mount
vfs: don't hold s_umount over close_bdev_exclusive() call
sysv: do not mark superblock dirty on remount
sysv: do not mark superblock dirty on mount
btrfs: remove junk sb_dirt change
BFS: clean up the superblock usage
AFFS: wait for sb synchronization when needed
AFFS: clean up dirty flag usage
cifs: truncate fallout
mbcache: fix shrinker function return value
mbcache: Remove unused features
add f_flags to struct statfs(64)
pass a struct path to vfs_statfs
update VFS documentation for method changes.
All filesystems that need invalidate_inode_buffers() are doing that explicitly
convert remaining ->clear_inode() to ->evict_inode()
Make ->drop_inode() just return whether inode needs to be dropped
fs/inode.c:clear_inode() is gone
fs/inode.c:evict() doesn't care about delete vs. non-delete paths now
...
Fix up trivial conflicts in fs/nilfs2/super.c
Diffstat (limited to 'fs/ext2')
-rw-r--r-- | fs/ext2/balloc.c | 11 | ||||
-rw-r--r-- | fs/ext2/dir.c | 23 | ||||
-rw-r--r-- | fs/ext2/ext2.h | 5 | ||||
-rw-r--r-- | fs/ext2/ialloc.c | 13 | ||||
-rw-r--r-- | fs/ext2/inode.c | 87 | ||||
-rw-r--r-- | fs/ext2/super.c | 14 | ||||
-rw-r--r-- | fs/ext2/xattr.c | 25 |
7 files changed, 80 insertions, 98 deletions
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index e8766a396776..c6c684b44ea1 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c | |||
@@ -571,7 +571,7 @@ do_more: | |||
571 | error_return: | 571 | error_return: |
572 | brelse(bitmap_bh); | 572 | brelse(bitmap_bh); |
573 | release_blocks(sb, freed); | 573 | release_blocks(sb, freed); |
574 | dquot_free_block(inode, freed); | 574 | dquot_free_block_nodirty(inode, freed); |
575 | } | 575 | } |
576 | 576 | ||
577 | /** | 577 | /** |
@@ -1418,7 +1418,8 @@ allocated: | |||
1418 | 1418 | ||
1419 | *errp = 0; | 1419 | *errp = 0; |
1420 | brelse(bitmap_bh); | 1420 | brelse(bitmap_bh); |
1421 | dquot_free_block(inode, *count-num); | 1421 | dquot_free_block_nodirty(inode, *count-num); |
1422 | mark_inode_dirty(inode); | ||
1422 | *count = num; | 1423 | *count = num; |
1423 | return ret_block; | 1424 | return ret_block; |
1424 | 1425 | ||
@@ -1428,8 +1429,10 @@ out: | |||
1428 | /* | 1429 | /* |
1429 | * Undo the block allocation | 1430 | * Undo the block allocation |
1430 | */ | 1431 | */ |
1431 | if (!performed_allocation) | 1432 | if (!performed_allocation) { |
1432 | dquot_free_block(inode, *count); | 1433 | dquot_free_block_nodirty(inode, *count); |
1434 | mark_inode_dirty(inode); | ||
1435 | } | ||
1433 | brelse(bitmap_bh); | 1436 | brelse(bitmap_bh); |
1434 | return 0; | 1437 | return 0; |
1435 | } | 1438 | } |
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 7516957273ed..764109886ec0 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c | |||
@@ -448,6 +448,11 @@ ino_t ext2_inode_by_name(struct inode *dir, struct qstr *child) | |||
448 | return res; | 448 | return res; |
449 | } | 449 | } |
450 | 450 | ||
451 | static int ext2_prepare_chunk(struct page *page, loff_t pos, unsigned len) | ||
452 | { | ||
453 | return __block_write_begin(page, pos, len, ext2_get_block); | ||
454 | } | ||
455 | |||
451 | /* Releases the page */ | 456 | /* Releases the page */ |
452 | void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, | 457 | void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, |
453 | struct page *page, struct inode *inode, int update_times) | 458 | struct page *page, struct inode *inode, int update_times) |
@@ -458,8 +463,7 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, | |||
458 | int err; | 463 | int err; |
459 | 464 | ||
460 | lock_page(page); | 465 | lock_page(page); |
461 | err = __ext2_write_begin(NULL, page->mapping, pos, len, | 466 | err = ext2_prepare_chunk(page, pos, len); |
462 | AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); | ||
463 | BUG_ON(err); | 467 | BUG_ON(err); |
464 | de->inode = cpu_to_le32(inode->i_ino); | 468 | de->inode = cpu_to_le32(inode->i_ino); |
465 | ext2_set_de_type(de, inode); | 469 | ext2_set_de_type(de, inode); |
@@ -542,8 +546,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode) | |||
542 | got_it: | 546 | got_it: |
543 | pos = page_offset(page) + | 547 | pos = page_offset(page) + |
544 | (char*)de - (char*)page_address(page); | 548 | (char*)de - (char*)page_address(page); |
545 | err = __ext2_write_begin(NULL, page->mapping, pos, rec_len, 0, | 549 | err = ext2_prepare_chunk(page, pos, rec_len); |
546 | &page, NULL); | ||
547 | if (err) | 550 | if (err) |
548 | goto out_unlock; | 551 | goto out_unlock; |
549 | if (de->inode) { | 552 | if (de->inode) { |
@@ -576,8 +579,7 @@ out_unlock: | |||
576 | */ | 579 | */ |
577 | int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) | 580 | int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) |
578 | { | 581 | { |
579 | struct address_space *mapping = page->mapping; | 582 | struct inode *inode = page->mapping->host; |
580 | struct inode *inode = mapping->host; | ||
581 | char *kaddr = page_address(page); | 583 | char *kaddr = page_address(page); |
582 | unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); | 584 | unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); |
583 | unsigned to = ((char *)dir - kaddr) + | 585 | unsigned to = ((char *)dir - kaddr) + |
@@ -601,8 +603,7 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page ) | |||
601 | from = (char*)pde - (char*)page_address(page); | 603 | from = (char*)pde - (char*)page_address(page); |
602 | pos = page_offset(page) + from; | 604 | pos = page_offset(page) + from; |
603 | lock_page(page); | 605 | lock_page(page); |
604 | err = __ext2_write_begin(NULL, page->mapping, pos, to - from, 0, | 606 | err = ext2_prepare_chunk(page, pos, to - from); |
605 | &page, NULL); | ||
606 | BUG_ON(err); | 607 | BUG_ON(err); |
607 | if (pde) | 608 | if (pde) |
608 | pde->rec_len = ext2_rec_len_to_disk(to - from); | 609 | pde->rec_len = ext2_rec_len_to_disk(to - from); |
@@ -621,8 +622,7 @@ out: | |||
621 | */ | 622 | */ |
622 | int ext2_make_empty(struct inode *inode, struct inode *parent) | 623 | int ext2_make_empty(struct inode *inode, struct inode *parent) |
623 | { | 624 | { |
624 | struct address_space *mapping = inode->i_mapping; | 625 | struct page *page = grab_cache_page(inode->i_mapping, 0); |
625 | struct page *page = grab_cache_page(mapping, 0); | ||
626 | unsigned chunk_size = ext2_chunk_size(inode); | 626 | unsigned chunk_size = ext2_chunk_size(inode); |
627 | struct ext2_dir_entry_2 * de; | 627 | struct ext2_dir_entry_2 * de; |
628 | int err; | 628 | int err; |
@@ -631,8 +631,7 @@ int ext2_make_empty(struct inode *inode, struct inode *parent) | |||
631 | if (!page) | 631 | if (!page) |
632 | return -ENOMEM; | 632 | return -ENOMEM; |
633 | 633 | ||
634 | err = __ext2_write_begin(NULL, page->mapping, 0, chunk_size, 0, | 634 | err = ext2_prepare_chunk(page, 0, chunk_size); |
635 | &page, NULL); | ||
636 | if (err) { | 635 | if (err) { |
637 | unlock_page(page); | 636 | unlock_page(page); |
638 | goto fail; | 637 | goto fail; |
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 52b34f1d2738..416daa62242c 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h | |||
@@ -119,7 +119,7 @@ extern unsigned long ext2_count_free (struct buffer_head *, unsigned); | |||
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 *, struct writeback_control *); | 121 | extern int ext2_write_inode (struct inode *, struct writeback_control *); |
122 | extern void ext2_delete_inode (struct inode *); | 122 | extern void ext2_evict_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); |
125 | extern int ext2_setattr (struct dentry *, struct iattr *); | 125 | extern int ext2_setattr (struct dentry *, struct iattr *); |
@@ -127,9 +127,6 @@ extern void ext2_set_inode_flags(struct inode *inode); | |||
127 | extern void ext2_get_inode_flags(struct ext2_inode_info *); | 127 | extern void ext2_get_inode_flags(struct ext2_inode_info *); |
128 | extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 128 | extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
129 | u64 start, u64 len); | 129 | u64 start, u64 len); |
130 | int __ext2_write_begin(struct file *file, struct address_space *mapping, | ||
131 | loff_t pos, unsigned len, unsigned flags, | ||
132 | struct page **pagep, void **fsdata); | ||
133 | 130 | ||
134 | /* ioctl.c */ | 131 | /* ioctl.c */ |
135 | extern long ext2_ioctl(struct file *, unsigned int, unsigned long); | 132 | extern long ext2_ioctl(struct file *, unsigned int, unsigned long); |
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 938dbc739d00..ad70479aabff 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c | |||
@@ -118,19 +118,14 @@ void ext2_free_inode (struct inode * inode) | |||
118 | * Note: we must free any quota before locking the superblock, | 118 | * Note: we must free any quota before locking the superblock, |
119 | * as writing the quota to disk may need the lock as well. | 119 | * as writing the quota to disk may need the lock as well. |
120 | */ | 120 | */ |
121 | if (!is_bad_inode(inode)) { | 121 | /* Quota is already initialized in iput() */ |
122 | /* Quota is already initialized in iput() */ | 122 | ext2_xattr_delete_inode(inode); |
123 | ext2_xattr_delete_inode(inode); | 123 | dquot_free_inode(inode); |
124 | dquot_free_inode(inode); | 124 | dquot_drop(inode); |
125 | dquot_drop(inode); | ||
126 | } | ||
127 | 125 | ||
128 | es = EXT2_SB(sb)->s_es; | 126 | es = EXT2_SB(sb)->s_es; |
129 | is_directory = S_ISDIR(inode->i_mode); | 127 | is_directory = S_ISDIR(inode->i_mode); |
130 | 128 | ||
131 | /* Do this BEFORE marking the inode not in use or returning an error */ | ||
132 | clear_inode (inode); | ||
133 | |||
134 | if (ino < EXT2_FIRST_INO(sb) || | 129 | if (ino < EXT2_FIRST_INO(sb) || |
135 | ino > le32_to_cpu(es->s_inodes_count)) { | 130 | ino > le32_to_cpu(es->s_inodes_count)) { |
136 | ext2_error (sb, "ext2_free_inode", | 131 | ext2_error (sb, "ext2_free_inode", |
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 3675088cb88c..940c96168868 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -69,26 +69,42 @@ static void ext2_write_failed(struct address_space *mapping, loff_t to) | |||
69 | /* | 69 | /* |
70 | * Called at the last iput() if i_nlink is zero. | 70 | * Called at the last iput() if i_nlink is zero. |
71 | */ | 71 | */ |
72 | void ext2_delete_inode (struct inode * inode) | 72 | void ext2_evict_inode(struct inode * inode) |
73 | { | 73 | { |
74 | if (!is_bad_inode(inode)) | 74 | struct ext2_block_alloc_info *rsv; |
75 | int want_delete = 0; | ||
76 | |||
77 | if (!inode->i_nlink && !is_bad_inode(inode)) { | ||
78 | want_delete = 1; | ||
75 | dquot_initialize(inode); | 79 | dquot_initialize(inode); |
80 | } else { | ||
81 | dquot_drop(inode); | ||
82 | } | ||
83 | |||
76 | truncate_inode_pages(&inode->i_data, 0); | 84 | truncate_inode_pages(&inode->i_data, 0); |
77 | 85 | ||
78 | if (is_bad_inode(inode)) | 86 | if (want_delete) { |
79 | goto no_delete; | 87 | /* set dtime */ |
80 | EXT2_I(inode)->i_dtime = get_seconds(); | 88 | EXT2_I(inode)->i_dtime = get_seconds(); |
81 | mark_inode_dirty(inode); | 89 | mark_inode_dirty(inode); |
82 | __ext2_write_inode(inode, inode_needs_sync(inode)); | 90 | __ext2_write_inode(inode, inode_needs_sync(inode)); |
91 | /* truncate to 0 */ | ||
92 | inode->i_size = 0; | ||
93 | if (inode->i_blocks) | ||
94 | ext2_truncate_blocks(inode, 0); | ||
95 | } | ||
83 | 96 | ||
84 | inode->i_size = 0; | 97 | invalidate_inode_buffers(inode); |
85 | if (inode->i_blocks) | 98 | end_writeback(inode); |
86 | ext2_truncate_blocks(inode, 0); | ||
87 | ext2_free_inode (inode); | ||
88 | 99 | ||
89 | return; | 100 | ext2_discard_reservation(inode); |
90 | no_delete: | 101 | rsv = EXT2_I(inode)->i_block_alloc_info; |
91 | clear_inode(inode); /* We must guarantee clearing of inode... */ | 102 | EXT2_I(inode)->i_block_alloc_info = NULL; |
103 | if (unlikely(rsv)) | ||
104 | kfree(rsv); | ||
105 | |||
106 | if (want_delete) | ||
107 | ext2_free_inode(inode); | ||
92 | } | 108 | } |
93 | 109 | ||
94 | typedef struct { | 110 | typedef struct { |
@@ -423,6 +439,8 @@ static int ext2_alloc_blocks(struct inode *inode, | |||
423 | failed_out: | 439 | failed_out: |
424 | for (i = 0; i <index; i++) | 440 | for (i = 0; i <index; i++) |
425 | ext2_free_blocks(inode, new_blocks[i], 1); | 441 | ext2_free_blocks(inode, new_blocks[i], 1); |
442 | if (index) | ||
443 | mark_inode_dirty(inode); | ||
426 | return ret; | 444 | return ret; |
427 | } | 445 | } |
428 | 446 | ||
@@ -765,14 +783,6 @@ ext2_readpages(struct file *file, struct address_space *mapping, | |||
765 | return mpage_readpages(mapping, pages, nr_pages, ext2_get_block); | 783 | return mpage_readpages(mapping, pages, nr_pages, ext2_get_block); |
766 | } | 784 | } |
767 | 785 | ||
768 | int __ext2_write_begin(struct file *file, struct address_space *mapping, | ||
769 | loff_t pos, unsigned len, unsigned flags, | ||
770 | struct page **pagep, void **fsdata) | ||
771 | { | ||
772 | return block_write_begin_newtrunc(file, mapping, pos, len, flags, | ||
773 | pagep, fsdata, ext2_get_block); | ||
774 | } | ||
775 | |||
776 | static int | 786 | static int |
777 | ext2_write_begin(struct file *file, struct address_space *mapping, | 787 | ext2_write_begin(struct file *file, struct address_space *mapping, |
778 | loff_t pos, unsigned len, unsigned flags, | 788 | loff_t pos, unsigned len, unsigned flags, |
@@ -780,8 +790,8 @@ ext2_write_begin(struct file *file, struct address_space *mapping, | |||
780 | { | 790 | { |
781 | int ret; | 791 | int ret; |
782 | 792 | ||
783 | *pagep = NULL; | 793 | ret = block_write_begin(mapping, pos, len, flags, pagep, |
784 | ret = __ext2_write_begin(file, mapping, pos, len, flags, pagep, fsdata); | 794 | ext2_get_block); |
785 | if (ret < 0) | 795 | if (ret < 0) |
786 | ext2_write_failed(mapping, pos + len); | 796 | ext2_write_failed(mapping, pos + len); |
787 | return ret; | 797 | return ret; |
@@ -806,13 +816,8 @@ ext2_nobh_write_begin(struct file *file, struct address_space *mapping, | |||
806 | { | 816 | { |
807 | int ret; | 817 | int ret; |
808 | 818 | ||
809 | /* | 819 | ret = nobh_write_begin(mapping, pos, len, flags, pagep, fsdata, |
810 | * Dir-in-pagecache still uses ext2_write_begin. Would have to rework | 820 | ext2_get_block); |
811 | * directory handling code to pass around offsets rather than struct | ||
812 | * pages in order to make this work easily. | ||
813 | */ | ||
814 | ret = nobh_write_begin_newtrunc(file, mapping, pos, len, flags, pagep, | ||
815 | fsdata, ext2_get_block); | ||
816 | if (ret < 0) | 821 | if (ret < 0) |
817 | ext2_write_failed(mapping, pos + len); | 822 | ext2_write_failed(mapping, pos + len); |
818 | return ret; | 823 | return ret; |
@@ -838,7 +843,7 @@ ext2_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | |||
838 | struct inode *inode = mapping->host; | 843 | struct inode *inode = mapping->host; |
839 | ssize_t ret; | 844 | ssize_t ret; |
840 | 845 | ||
841 | ret = blockdev_direct_IO_newtrunc(rw, iocb, inode, inode->i_sb->s_bdev, | 846 | ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, |
842 | iov, offset, nr_segs, ext2_get_block, NULL); | 847 | iov, offset, nr_segs, ext2_get_block, NULL); |
843 | if (ret < 0 && (rw & WRITE)) | 848 | if (ret < 0 && (rw & WRITE)) |
844 | ext2_write_failed(mapping, offset + iov_length(iov, nr_segs)); | 849 | ext2_write_failed(mapping, offset + iov_length(iov, nr_segs)); |
@@ -1006,8 +1011,8 @@ static inline void ext2_free_data(struct inode *inode, __le32 *p, __le32 *q) | |||
1006 | else if (block_to_free == nr - count) | 1011 | else if (block_to_free == nr - count) |
1007 | count++; | 1012 | count++; |
1008 | else { | 1013 | else { |
1009 | mark_inode_dirty(inode); | ||
1010 | ext2_free_blocks (inode, block_to_free, count); | 1014 | ext2_free_blocks (inode, block_to_free, count); |
1015 | mark_inode_dirty(inode); | ||
1011 | free_this: | 1016 | free_this: |
1012 | block_to_free = nr; | 1017 | block_to_free = nr; |
1013 | count = 1; | 1018 | count = 1; |
@@ -1015,8 +1020,8 @@ static inline void ext2_free_data(struct inode *inode, __le32 *p, __le32 *q) | |||
1015 | } | 1020 | } |
1016 | } | 1021 | } |
1017 | if (count > 0) { | 1022 | if (count > 0) { |
1018 | mark_inode_dirty(inode); | ||
1019 | ext2_free_blocks (inode, block_to_free, count); | 1023 | ext2_free_blocks (inode, block_to_free, count); |
1024 | mark_inode_dirty(inode); | ||
1020 | } | 1025 | } |
1021 | } | 1026 | } |
1022 | 1027 | ||
@@ -1169,15 +1174,10 @@ static void ext2_truncate_blocks(struct inode *inode, loff_t offset) | |||
1169 | __ext2_truncate_blocks(inode, offset); | 1174 | __ext2_truncate_blocks(inode, offset); |
1170 | } | 1175 | } |
1171 | 1176 | ||
1172 | int ext2_setsize(struct inode *inode, loff_t newsize) | 1177 | static int ext2_setsize(struct inode *inode, loff_t newsize) |
1173 | { | 1178 | { |
1174 | loff_t oldsize; | ||
1175 | int error; | 1179 | int error; |
1176 | 1180 | ||
1177 | error = inode_newsize_ok(inode, newsize); | ||
1178 | if (error) | ||
1179 | return error; | ||
1180 | |||
1181 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | 1181 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || |
1182 | S_ISLNK(inode->i_mode))) | 1182 | S_ISLNK(inode->i_mode))) |
1183 | return -EINVAL; | 1183 | return -EINVAL; |
@@ -1197,10 +1197,7 @@ int ext2_setsize(struct inode *inode, loff_t newsize) | |||
1197 | if (error) | 1197 | if (error) |
1198 | return error; | 1198 | return error; |
1199 | 1199 | ||
1200 | oldsize = inode->i_size; | 1200 | truncate_setsize(inode, newsize); |
1201 | i_size_write(inode, newsize); | ||
1202 | truncate_pagecache(inode, oldsize, newsize); | ||
1203 | |||
1204 | __ext2_truncate_blocks(inode, newsize); | 1201 | __ext2_truncate_blocks(inode, newsize); |
1205 | 1202 | ||
1206 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; | 1203 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; |
@@ -1557,7 +1554,7 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr) | |||
1557 | if (error) | 1554 | if (error) |
1558 | return error; | 1555 | return error; |
1559 | } | 1556 | } |
1560 | generic_setattr(inode, iattr); | 1557 | setattr_copy(inode, iattr); |
1561 | if (iattr->ia_valid & ATTR_MODE) | 1558 | if (iattr->ia_valid & ATTR_MODE) |
1562 | error = ext2_acl_chmod(inode); | 1559 | error = ext2_acl_chmod(inode); |
1563 | mark_inode_dirty(inode); | 1560 | mark_inode_dirty(inode); |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 7ff43f4a59cd..1ec602673ea8 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -195,17 +195,6 @@ static void destroy_inodecache(void) | |||
195 | kmem_cache_destroy(ext2_inode_cachep); | 195 | kmem_cache_destroy(ext2_inode_cachep); |
196 | } | 196 | } |
197 | 197 | ||
198 | static void ext2_clear_inode(struct inode *inode) | ||
199 | { | ||
200 | struct ext2_block_alloc_info *rsv = EXT2_I(inode)->i_block_alloc_info; | ||
201 | |||
202 | dquot_drop(inode); | ||
203 | ext2_discard_reservation(inode); | ||
204 | EXT2_I(inode)->i_block_alloc_info = NULL; | ||
205 | if (unlikely(rsv)) | ||
206 | kfree(rsv); | ||
207 | } | ||
208 | |||
209 | static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs) | 198 | static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs) |
210 | { | 199 | { |
211 | struct super_block *sb = vfs->mnt_sb; | 200 | struct super_block *sb = vfs->mnt_sb; |
@@ -299,13 +288,12 @@ static const struct super_operations ext2_sops = { | |||
299 | .alloc_inode = ext2_alloc_inode, | 288 | .alloc_inode = ext2_alloc_inode, |
300 | .destroy_inode = ext2_destroy_inode, | 289 | .destroy_inode = ext2_destroy_inode, |
301 | .write_inode = ext2_write_inode, | 290 | .write_inode = ext2_write_inode, |
302 | .delete_inode = ext2_delete_inode, | 291 | .evict_inode = ext2_evict_inode, |
303 | .put_super = ext2_put_super, | 292 | .put_super = ext2_put_super, |
304 | .write_super = ext2_write_super, | 293 | .write_super = ext2_write_super, |
305 | .sync_fs = ext2_sync_fs, | 294 | .sync_fs = ext2_sync_fs, |
306 | .statfs = ext2_statfs, | 295 | .statfs = ext2_statfs, |
307 | .remount_fs = ext2_remount, | 296 | .remount_fs = ext2_remount, |
308 | .clear_inode = ext2_clear_inode, | ||
309 | .show_options = ext2_show_options, | 297 | .show_options = ext2_show_options, |
310 | #ifdef CONFIG_QUOTA | 298 | #ifdef CONFIG_QUOTA |
311 | .quota_read = ext2_quota_read, | 299 | .quota_read = ext2_quota_read, |
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 7c3915780b19..8c29ae15129e 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c | |||
@@ -674,6 +674,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh, | |||
674 | new_bh = sb_getblk(sb, block); | 674 | new_bh = sb_getblk(sb, block); |
675 | if (!new_bh) { | 675 | if (!new_bh) { |
676 | ext2_free_blocks(inode, block, 1); | 676 | ext2_free_blocks(inode, block, 1); |
677 | mark_inode_dirty(inode); | ||
677 | error = -EIO; | 678 | error = -EIO; |
678 | goto cleanup; | 679 | goto cleanup; |
679 | } | 680 | } |
@@ -703,8 +704,10 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh, | |||
703 | * written (only some dirty data were not) so we just proceed | 704 | * written (only some dirty data were not) so we just proceed |
704 | * as if nothing happened and cleanup the unused block */ | 705 | * as if nothing happened and cleanup the unused block */ |
705 | if (error && error != -ENOSPC) { | 706 | if (error && error != -ENOSPC) { |
706 | if (new_bh && new_bh != old_bh) | 707 | if (new_bh && new_bh != old_bh) { |
707 | dquot_free_block(inode, 1); | 708 | dquot_free_block_nodirty(inode, 1); |
709 | mark_inode_dirty(inode); | ||
710 | } | ||
708 | goto cleanup; | 711 | goto cleanup; |
709 | } | 712 | } |
710 | } else | 713 | } else |
@@ -727,6 +730,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh, | |||
727 | mb_cache_entry_free(ce); | 730 | mb_cache_entry_free(ce); |
728 | ea_bdebug(old_bh, "freeing"); | 731 | ea_bdebug(old_bh, "freeing"); |
729 | ext2_free_blocks(inode, old_bh->b_blocknr, 1); | 732 | ext2_free_blocks(inode, old_bh->b_blocknr, 1); |
733 | mark_inode_dirty(inode); | ||
730 | /* We let our caller release old_bh, so we | 734 | /* We let our caller release old_bh, so we |
731 | * need to duplicate the buffer before. */ | 735 | * need to duplicate the buffer before. */ |
732 | get_bh(old_bh); | 736 | get_bh(old_bh); |
@@ -736,7 +740,8 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh, | |||
736 | le32_add_cpu(&HDR(old_bh)->h_refcount, -1); | 740 | le32_add_cpu(&HDR(old_bh)->h_refcount, -1); |
737 | if (ce) | 741 | if (ce) |
738 | mb_cache_entry_release(ce); | 742 | mb_cache_entry_release(ce); |
739 | dquot_free_block(inode, 1); | 743 | dquot_free_block_nodirty(inode, 1); |
744 | mark_inode_dirty(inode); | ||
740 | mark_buffer_dirty(old_bh); | 745 | mark_buffer_dirty(old_bh); |
741 | ea_bdebug(old_bh, "refcount now=%d", | 746 | ea_bdebug(old_bh, "refcount now=%d", |
742 | le32_to_cpu(HDR(old_bh)->h_refcount)); | 747 | le32_to_cpu(HDR(old_bh)->h_refcount)); |
@@ -799,7 +804,7 @@ ext2_xattr_delete_inode(struct inode *inode) | |||
799 | mark_buffer_dirty(bh); | 804 | mark_buffer_dirty(bh); |
800 | if (IS_SYNC(inode)) | 805 | if (IS_SYNC(inode)) |
801 | sync_dirty_buffer(bh); | 806 | sync_dirty_buffer(bh); |
802 | dquot_free_block(inode, 1); | 807 | dquot_free_block_nodirty(inode, 1); |
803 | } | 808 | } |
804 | EXT2_I(inode)->i_file_acl = 0; | 809 | EXT2_I(inode)->i_file_acl = 0; |
805 | 810 | ||
@@ -838,7 +843,7 @@ ext2_xattr_cache_insert(struct buffer_head *bh) | |||
838 | ce = mb_cache_entry_alloc(ext2_xattr_cache, GFP_NOFS); | 843 | ce = mb_cache_entry_alloc(ext2_xattr_cache, GFP_NOFS); |
839 | if (!ce) | 844 | if (!ce) |
840 | return -ENOMEM; | 845 | return -ENOMEM; |
841 | error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash); | 846 | error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, hash); |
842 | if (error) { | 847 | if (error) { |
843 | mb_cache_entry_free(ce); | 848 | mb_cache_entry_free(ce); |
844 | if (error == -EBUSY) { | 849 | if (error == -EBUSY) { |
@@ -912,8 +917,8 @@ ext2_xattr_cache_find(struct inode *inode, struct ext2_xattr_header *header) | |||
912 | return NULL; /* never share */ | 917 | return NULL; /* never share */ |
913 | ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); | 918 | ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); |
914 | again: | 919 | again: |
915 | ce = mb_cache_entry_find_first(ext2_xattr_cache, 0, | 920 | ce = mb_cache_entry_find_first(ext2_xattr_cache, inode->i_sb->s_bdev, |
916 | inode->i_sb->s_bdev, hash); | 921 | hash); |
917 | while (ce) { | 922 | while (ce) { |
918 | struct buffer_head *bh; | 923 | struct buffer_head *bh; |
919 | 924 | ||
@@ -945,7 +950,7 @@ again: | |||
945 | unlock_buffer(bh); | 950 | unlock_buffer(bh); |
946 | brelse(bh); | 951 | brelse(bh); |
947 | } | 952 | } |
948 | ce = mb_cache_entry_find_next(ce, 0, inode->i_sb->s_bdev, hash); | 953 | ce = mb_cache_entry_find_next(ce, inode->i_sb->s_bdev, hash); |
949 | } | 954 | } |
950 | return NULL; | 955 | return NULL; |
951 | } | 956 | } |
@@ -1021,9 +1026,7 @@ static void ext2_xattr_rehash(struct ext2_xattr_header *header, | |||
1021 | int __init | 1026 | int __init |
1022 | init_ext2_xattr(void) | 1027 | init_ext2_xattr(void) |
1023 | { | 1028 | { |
1024 | ext2_xattr_cache = mb_cache_create("ext2_xattr", NULL, | 1029 | ext2_xattr_cache = mb_cache_create("ext2_xattr", 6); |
1025 | sizeof(struct mb_cache_entry) + | ||
1026 | sizeof(((struct mb_cache_entry *) 0)->e_indexes[0]), 1, 6); | ||
1027 | if (!ext2_xattr_cache) | 1030 | if (!ext2_xattr_cache) |
1028 | return -ENOMEM; | 1031 | return -ENOMEM; |
1029 | return 0; | 1032 | return 0; |