diff options
Diffstat (limited to 'fs/ext3')
-rw-r--r-- | fs/ext3/ialloc.c | 12 | ||||
-rw-r--r-- | fs/ext3/inode.c | 63 | ||||
-rw-r--r-- | fs/ext3/super.c | 14 | ||||
-rw-r--r-- | fs/ext3/xattr.c | 12 |
4 files changed, 55 insertions, 46 deletions
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 498021eb88fb..4ab72db3559e 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c | |||
@@ -119,20 +119,8 @@ void ext3_free_inode (handle_t *handle, struct inode * inode) | |||
119 | ino = inode->i_ino; | 119 | ino = inode->i_ino; |
120 | ext3_debug ("freeing inode %lu\n", ino); | 120 | ext3_debug ("freeing inode %lu\n", ino); |
121 | 121 | ||
122 | /* | ||
123 | * Note: we must free any quota before locking the superblock, | ||
124 | * as writing the quota to disk may need the lock as well. | ||
125 | */ | ||
126 | dquot_initialize(inode); | ||
127 | ext3_xattr_delete_inode(handle, inode); | ||
128 | dquot_free_inode(inode); | ||
129 | dquot_drop(inode); | ||
130 | |||
131 | is_directory = S_ISDIR(inode->i_mode); | 122 | is_directory = S_ISDIR(inode->i_mode); |
132 | 123 | ||
133 | /* Do this BEFORE marking the inode not in use or returning an error */ | ||
134 | clear_inode (inode); | ||
135 | |||
136 | es = EXT3_SB(sb)->s_es; | 124 | es = EXT3_SB(sb)->s_es; |
137 | if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) { | 125 | if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) { |
138 | ext3_error (sb, "ext3_free_inode", | 126 | ext3_error (sb, "ext3_free_inode", |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 001eb0e2d48e..5e0faf4cda79 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -190,18 +190,28 @@ static int truncate_restart_transaction(handle_t *handle, struct inode *inode) | |||
190 | } | 190 | } |
191 | 191 | ||
192 | /* | 192 | /* |
193 | * Called at the last iput() if i_nlink is zero. | 193 | * Called at inode eviction from icache |
194 | */ | 194 | */ |
195 | void ext3_delete_inode (struct inode * inode) | 195 | void ext3_evict_inode (struct inode *inode) |
196 | { | 196 | { |
197 | struct ext3_block_alloc_info *rsv; | ||
197 | handle_t *handle; | 198 | handle_t *handle; |
199 | int want_delete = 0; | ||
198 | 200 | ||
199 | if (!is_bad_inode(inode)) | 201 | if (!inode->i_nlink && !is_bad_inode(inode)) { |
200 | dquot_initialize(inode); | 202 | dquot_initialize(inode); |
203 | want_delete = 1; | ||
204 | } | ||
201 | 205 | ||
202 | truncate_inode_pages(&inode->i_data, 0); | 206 | truncate_inode_pages(&inode->i_data, 0); |
203 | 207 | ||
204 | if (is_bad_inode(inode)) | 208 | ext3_discard_reservation(inode); |
209 | rsv = EXT3_I(inode)->i_block_alloc_info; | ||
210 | EXT3_I(inode)->i_block_alloc_info = NULL; | ||
211 | if (unlikely(rsv)) | ||
212 | kfree(rsv); | ||
213 | |||
214 | if (!want_delete) | ||
205 | goto no_delete; | 215 | goto no_delete; |
206 | 216 | ||
207 | handle = start_transaction(inode); | 217 | handle = start_transaction(inode); |
@@ -238,15 +248,22 @@ void ext3_delete_inode (struct inode * inode) | |||
238 | * having errors), but we can't free the inode if the mark_dirty | 248 | * having errors), but we can't free the inode if the mark_dirty |
239 | * fails. | 249 | * fails. |
240 | */ | 250 | */ |
241 | if (ext3_mark_inode_dirty(handle, inode)) | 251 | if (ext3_mark_inode_dirty(handle, inode)) { |
242 | /* If that failed, just do the required in-core inode clear. */ | 252 | /* If that failed, just dquot_drop() and be done with that */ |
243 | clear_inode(inode); | 253 | dquot_drop(inode); |
244 | else | 254 | end_writeback(inode); |
255 | } else { | ||
256 | ext3_xattr_delete_inode(handle, inode); | ||
257 | dquot_free_inode(inode); | ||
258 | dquot_drop(inode); | ||
259 | end_writeback(inode); | ||
245 | ext3_free_inode(handle, inode); | 260 | ext3_free_inode(handle, inode); |
261 | } | ||
246 | ext3_journal_stop(handle); | 262 | ext3_journal_stop(handle); |
247 | return; | 263 | return; |
248 | no_delete: | 264 | no_delete: |
249 | clear_inode(inode); /* We must guarantee clearing of inode... */ | 265 | end_writeback(inode); |
266 | dquot_drop(inode); | ||
250 | } | 267 | } |
251 | 268 | ||
252 | typedef struct { | 269 | typedef struct { |
@@ -1212,8 +1229,7 @@ retry: | |||
1212 | ret = PTR_ERR(handle); | 1229 | ret = PTR_ERR(handle); |
1213 | goto out; | 1230 | goto out; |
1214 | } | 1231 | } |
1215 | ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 1232 | ret = __block_write_begin(page, pos, len, ext3_get_block); |
1216 | ext3_get_block); | ||
1217 | if (ret) | 1233 | if (ret) |
1218 | goto write_begin_failed; | 1234 | goto write_begin_failed; |
1219 | 1235 | ||
@@ -1798,6 +1814,17 @@ retry: | |||
1798 | ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, | 1814 | ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, |
1799 | offset, nr_segs, | 1815 | offset, nr_segs, |
1800 | ext3_get_block, NULL); | 1816 | ext3_get_block, NULL); |
1817 | /* | ||
1818 | * In case of error extending write may have instantiated a few | ||
1819 | * blocks outside i_size. Trim these off again. | ||
1820 | */ | ||
1821 | if (unlikely((rw & WRITE) && ret < 0)) { | ||
1822 | loff_t isize = i_size_read(inode); | ||
1823 | loff_t end = offset + iov_length(iov, nr_segs); | ||
1824 | |||
1825 | if (end > isize) | ||
1826 | vmtruncate(inode, isize); | ||
1827 | } | ||
1801 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) | 1828 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) |
1802 | goto retry; | 1829 | goto retry; |
1803 | 1830 | ||
@@ -2560,7 +2587,7 @@ out_stop: | |||
2560 | * If this was a simple ftruncate(), and the file will remain alive | 2587 | * If this was a simple ftruncate(), and the file will remain alive |
2561 | * then we need to clear up the orphan record which we created above. | 2588 | * then we need to clear up the orphan record which we created above. |
2562 | * However, if this was a real unlink then we were called by | 2589 | * However, if this was a real unlink then we were called by |
2563 | * ext3_delete_inode(), and we allow that function to clean up the | 2590 | * ext3_evict_inode(), and we allow that function to clean up the |
2564 | * orphan info for us. | 2591 | * orphan info for us. |
2565 | */ | 2592 | */ |
2566 | if (inode->i_nlink) | 2593 | if (inode->i_nlink) |
@@ -3204,9 +3231,17 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr) | |||
3204 | ext3_journal_stop(handle); | 3231 | ext3_journal_stop(handle); |
3205 | } | 3232 | } |
3206 | 3233 | ||
3207 | rc = inode_setattr(inode, attr); | 3234 | if ((attr->ia_valid & ATTR_SIZE) && |
3235 | attr->ia_size != i_size_read(inode)) { | ||
3236 | rc = vmtruncate(inode, attr->ia_size); | ||
3237 | if (rc) | ||
3238 | goto err_out; | ||
3239 | } | ||
3240 | |||
3241 | setattr_copy(inode, attr); | ||
3242 | mark_inode_dirty(inode); | ||
3208 | 3243 | ||
3209 | if (!rc && (ia_valid & ATTR_MODE)) | 3244 | if (ia_valid & ATTR_MODE) |
3210 | rc = ext3_acl_chmod(inode); | 3245 | rc = ext3_acl_chmod(inode); |
3211 | 3246 | ||
3212 | err_out: | 3247 | err_out: |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 9650a956fd0e..5dbf4dba03c4 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -527,17 +527,6 @@ static void destroy_inodecache(void) | |||
527 | kmem_cache_destroy(ext3_inode_cachep); | 527 | kmem_cache_destroy(ext3_inode_cachep); |
528 | } | 528 | } |
529 | 529 | ||
530 | static void ext3_clear_inode(struct inode *inode) | ||
531 | { | ||
532 | struct ext3_block_alloc_info *rsv = EXT3_I(inode)->i_block_alloc_info; | ||
533 | |||
534 | dquot_drop(inode); | ||
535 | ext3_discard_reservation(inode); | ||
536 | EXT3_I(inode)->i_block_alloc_info = NULL; | ||
537 | if (unlikely(rsv)) | ||
538 | kfree(rsv); | ||
539 | } | ||
540 | |||
541 | static inline void ext3_show_quota_options(struct seq_file *seq, struct super_block *sb) | 530 | static inline void ext3_show_quota_options(struct seq_file *seq, struct super_block *sb) |
542 | { | 531 | { |
543 | #if defined(CONFIG_QUOTA) | 532 | #if defined(CONFIG_QUOTA) |
@@ -780,14 +769,13 @@ static const struct super_operations ext3_sops = { | |||
780 | .destroy_inode = ext3_destroy_inode, | 769 | .destroy_inode = ext3_destroy_inode, |
781 | .write_inode = ext3_write_inode, | 770 | .write_inode = ext3_write_inode, |
782 | .dirty_inode = ext3_dirty_inode, | 771 | .dirty_inode = ext3_dirty_inode, |
783 | .delete_inode = ext3_delete_inode, | 772 | .evict_inode = ext3_evict_inode, |
784 | .put_super = ext3_put_super, | 773 | .put_super = ext3_put_super, |
785 | .sync_fs = ext3_sync_fs, | 774 | .sync_fs = ext3_sync_fs, |
786 | .freeze_fs = ext3_freeze, | 775 | .freeze_fs = ext3_freeze, |
787 | .unfreeze_fs = ext3_unfreeze, | 776 | .unfreeze_fs = ext3_unfreeze, |
788 | .statfs = ext3_statfs, | 777 | .statfs = ext3_statfs, |
789 | .remount_fs = ext3_remount, | 778 | .remount_fs = ext3_remount, |
790 | .clear_inode = ext3_clear_inode, | ||
791 | .show_options = ext3_show_options, | 779 | .show_options = ext3_show_options, |
792 | #ifdef CONFIG_QUOTA | 780 | #ifdef CONFIG_QUOTA |
793 | .quota_read = ext3_quota_read, | 781 | .quota_read = ext3_quota_read, |
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index 71fb8d65e54c..e69dc6dfaa89 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c | |||
@@ -1139,7 +1139,7 @@ ext3_xattr_cache_insert(struct buffer_head *bh) | |||
1139 | ea_bdebug(bh, "out of memory"); | 1139 | ea_bdebug(bh, "out of memory"); |
1140 | return; | 1140 | return; |
1141 | } | 1141 | } |
1142 | error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash); | 1142 | error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, hash); |
1143 | if (error) { | 1143 | if (error) { |
1144 | mb_cache_entry_free(ce); | 1144 | mb_cache_entry_free(ce); |
1145 | if (error == -EBUSY) { | 1145 | if (error == -EBUSY) { |
@@ -1211,8 +1211,8 @@ ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header, | |||
1211 | return NULL; /* never share */ | 1211 | return NULL; /* never share */ |
1212 | ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); | 1212 | ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); |
1213 | again: | 1213 | again: |
1214 | ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, | 1214 | ce = mb_cache_entry_find_first(ext3_xattr_cache, inode->i_sb->s_bdev, |
1215 | inode->i_sb->s_bdev, hash); | 1215 | hash); |
1216 | while (ce) { | 1216 | while (ce) { |
1217 | struct buffer_head *bh; | 1217 | struct buffer_head *bh; |
1218 | 1218 | ||
@@ -1237,7 +1237,7 @@ again: | |||
1237 | return bh; | 1237 | return bh; |
1238 | } | 1238 | } |
1239 | brelse(bh); | 1239 | brelse(bh); |
1240 | ce = mb_cache_entry_find_next(ce, 0, inode->i_sb->s_bdev, hash); | 1240 | ce = mb_cache_entry_find_next(ce, inode->i_sb->s_bdev, hash); |
1241 | } | 1241 | } |
1242 | return NULL; | 1242 | return NULL; |
1243 | } | 1243 | } |
@@ -1313,9 +1313,7 @@ static void ext3_xattr_rehash(struct ext3_xattr_header *header, | |||
1313 | int __init | 1313 | int __init |
1314 | init_ext3_xattr(void) | 1314 | init_ext3_xattr(void) |
1315 | { | 1315 | { |
1316 | ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL, | 1316 | ext3_xattr_cache = mb_cache_create("ext3_xattr", 6); |
1317 | sizeof(struct mb_cache_entry) + | ||
1318 | sizeof(((struct mb_cache_entry *) 0)->e_indexes[0]), 1, 6); | ||
1319 | if (!ext3_xattr_cache) | 1317 | if (!ext3_xattr_cache) |
1320 | return -ENOMEM; | 1318 | return -ENOMEM; |
1321 | return 0; | 1319 | return 0; |