aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/ext4.h3
-rw-r--r--fs/ext4/ialloc.c2
-rw-r--r--fs/ext4/inode.c53
-rw-r--r--fs/ext4/super.c10
-rw-r--r--fs/ext4/xattr.c12
5 files changed, 49 insertions, 31 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index e03841d9f30b..889ec9d5e6ad 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1643,7 +1643,8 @@ extern int ext4_write_inode(struct inode *, struct writeback_control *);
1643extern int ext4_setattr(struct dentry *, struct iattr *); 1643extern int ext4_setattr(struct dentry *, struct iattr *);
1644extern int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, 1644extern int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,
1645 struct kstat *stat); 1645 struct kstat *stat);
1646extern void ext4_delete_inode(struct inode *); 1646extern void ext4_evict_inode(struct inode *);
1647extern void ext4_clear_inode(struct inode *);
1647extern int ext4_sync_inode(handle_t *, struct inode *); 1648extern int ext4_sync_inode(handle_t *, struct inode *);
1648extern void ext4_dirty_inode(struct inode *); 1649extern void ext4_dirty_inode(struct inode *);
1649extern int ext4_change_inode_journal_flag(struct inode *, int); 1650extern int ext4_change_inode_journal_flag(struct inode *, int);
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index ac377505ed57..45853e0d1f21 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -222,7 +222,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
222 is_directory = S_ISDIR(inode->i_mode); 222 is_directory = S_ISDIR(inode->i_mode);
223 223
224 /* Do this BEFORE marking the inode not in use or returning an error */ 224 /* Do this BEFORE marking the inode not in use or returning an error */
225 clear_inode(inode); 225 ext4_clear_inode(inode);
226 226
227 es = EXT4_SB(sb)->s_es; 227 es = EXT4_SB(sb)->s_es;
228 if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) { 228 if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index a0ab3754d0d6..4b8debeb3965 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -167,11 +167,16 @@ int ext4_truncate_restart_trans(handle_t *handle, struct inode *inode,
167/* 167/*
168 * Called at the last iput() if i_nlink is zero. 168 * Called at the last iput() if i_nlink is zero.
169 */ 169 */
170void ext4_delete_inode(struct inode *inode) 170void ext4_evict_inode(struct inode *inode)
171{ 171{
172 handle_t *handle; 172 handle_t *handle;
173 int err; 173 int err;
174 174
175 if (inode->i_nlink) {
176 truncate_inode_pages(&inode->i_data, 0);
177 goto no_delete;
178 }
179
175 if (!is_bad_inode(inode)) 180 if (!is_bad_inode(inode))
176 dquot_initialize(inode); 181 dquot_initialize(inode);
177 182
@@ -246,13 +251,13 @@ void ext4_delete_inode(struct inode *inode)
246 */ 251 */
247 if (ext4_mark_inode_dirty(handle, inode)) 252 if (ext4_mark_inode_dirty(handle, inode))
248 /* If that failed, just do the required in-core inode clear. */ 253 /* If that failed, just do the required in-core inode clear. */
249 clear_inode(inode); 254 ext4_clear_inode(inode);
250 else 255 else
251 ext4_free_inode(handle, inode); 256 ext4_free_inode(handle, inode);
252 ext4_journal_stop(handle); 257 ext4_journal_stop(handle);
253 return; 258 return;
254no_delete: 259no_delete:
255 clear_inode(inode); /* We must guarantee clearing of inode... */ 260 ext4_clear_inode(inode); /* We must guarantee clearing of inode... */
256} 261}
257 262
258typedef struct { 263typedef struct {
@@ -1602,11 +1607,9 @@ retry:
1602 *pagep = page; 1607 *pagep = page;
1603 1608
1604 if (ext4_should_dioread_nolock(inode)) 1609 if (ext4_should_dioread_nolock(inode))
1605 ret = block_write_begin(file, mapping, pos, len, flags, pagep, 1610 ret = __block_write_begin(page, pos, len, ext4_get_block_write);
1606 fsdata, ext4_get_block_write);
1607 else 1611 else
1608 ret = block_write_begin(file, mapping, pos, len, flags, pagep, 1612 ret = __block_write_begin(page, pos, len, ext4_get_block);
1609 fsdata, ext4_get_block);
1610 1613
1611 if (!ret && ext4_should_journal_data(inode)) { 1614 if (!ret && ext4_should_journal_data(inode)) {
1612 ret = walk_page_buffers(handle, page_buffers(page), 1615 ret = walk_page_buffers(handle, page_buffers(page),
@@ -1617,7 +1620,7 @@ retry:
1617 unlock_page(page); 1620 unlock_page(page);
1618 page_cache_release(page); 1621 page_cache_release(page);
1619 /* 1622 /*
1620 * block_write_begin may have instantiated a few blocks 1623 * __block_write_begin may have instantiated a few blocks
1621 * outside i_size. Trim these off again. Don't need 1624 * outside i_size. Trim these off again. Don't need
1622 * i_size_read because we hold i_mutex. 1625 * i_size_read because we hold i_mutex.
1623 * 1626 *
@@ -3205,8 +3208,7 @@ retry:
3205 } 3208 }
3206 *pagep = page; 3209 *pagep = page;
3207 3210
3208 ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 3211 ret = __block_write_begin(page, pos, len, ext4_da_get_block_prep);
3209 ext4_da_get_block_prep);
3210 if (ret < 0) { 3212 if (ret < 0) {
3211 unlock_page(page); 3213 unlock_page(page);
3212 ext4_journal_stop(handle); 3214 ext4_journal_stop(handle);
@@ -3565,15 +3567,24 @@ static ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
3565 3567
3566retry: 3568retry:
3567 if (rw == READ && ext4_should_dioread_nolock(inode)) 3569 if (rw == READ && ext4_should_dioread_nolock(inode))
3568 ret = blockdev_direct_IO_no_locking(rw, iocb, inode, 3570 ret = __blockdev_direct_IO(rw, iocb, inode,
3569 inode->i_sb->s_bdev, iov, 3571 inode->i_sb->s_bdev, iov,
3570 offset, nr_segs, 3572 offset, nr_segs,
3571 ext4_get_block, NULL); 3573 ext4_get_block, NULL, NULL, 0);
3572 else 3574 else {
3573 ret = blockdev_direct_IO(rw, iocb, inode, 3575 ret = blockdev_direct_IO(rw, iocb, inode,
3574 inode->i_sb->s_bdev, iov, 3576 inode->i_sb->s_bdev, iov,
3575 offset, nr_segs, 3577 offset, nr_segs,
3576 ext4_get_block, NULL); 3578 ext4_get_block, NULL);
3579
3580 if (unlikely((rw & WRITE) && ret < 0)) {
3581 loff_t isize = i_size_read(inode);
3582 loff_t end = offset + iov_length(iov, nr_segs);
3583
3584 if (end > isize)
3585 vmtruncate(inode, isize);
3586 }
3587 }
3577 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) 3588 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
3578 goto retry; 3589 goto retry;
3579 3590
@@ -5536,11 +5547,19 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
5536 ext4_truncate(inode); 5547 ext4_truncate(inode);
5537 } 5548 }
5538 5549
5539 rc = inode_setattr(inode, attr); 5550 if ((attr->ia_valid & ATTR_SIZE) &&
5551 attr->ia_size != i_size_read(inode))
5552 rc = vmtruncate(inode, attr->ia_size);
5540 5553
5541 /* If inode_setattr's call to ext4_truncate failed to get a 5554 if (!rc) {
5542 * transaction handle at all, we need to clean up the in-core 5555 setattr_copy(inode, attr);
5543 * orphan list manually. */ 5556 mark_inode_dirty(inode);
5557 }
5558
5559 /*
5560 * If the call to ext4_truncate failed to get a transaction handle at
5561 * all, we need to clean up the in-core orphan list manually.
5562 */
5544 if (inode->i_nlink) 5563 if (inode->i_nlink)
5545 ext4_orphan_del(NULL, inode); 5564 ext4_orphan_del(NULL, inode);
5546 5565
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 8d65575f8c8c..26147746c272 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -868,8 +868,10 @@ static void destroy_inodecache(void)
868 kmem_cache_destroy(ext4_inode_cachep); 868 kmem_cache_destroy(ext4_inode_cachep);
869} 869}
870 870
871static void ext4_clear_inode(struct inode *inode) 871void ext4_clear_inode(struct inode *inode)
872{ 872{
873 invalidate_inode_buffers(inode);
874 end_writeback(inode);
873 dquot_drop(inode); 875 dquot_drop(inode);
874 ext4_discard_preallocations(inode); 876 ext4_discard_preallocations(inode);
875 if (EXT4_JOURNAL(inode)) 877 if (EXT4_JOURNAL(inode))
@@ -1158,14 +1160,13 @@ static const struct super_operations ext4_sops = {
1158 .destroy_inode = ext4_destroy_inode, 1160 .destroy_inode = ext4_destroy_inode,
1159 .write_inode = ext4_write_inode, 1161 .write_inode = ext4_write_inode,
1160 .dirty_inode = ext4_dirty_inode, 1162 .dirty_inode = ext4_dirty_inode,
1161 .delete_inode = ext4_delete_inode, 1163 .evict_inode = ext4_evict_inode,
1162 .put_super = ext4_put_super, 1164 .put_super = ext4_put_super,
1163 .sync_fs = ext4_sync_fs, 1165 .sync_fs = ext4_sync_fs,
1164 .freeze_fs = ext4_freeze, 1166 .freeze_fs = ext4_freeze,
1165 .unfreeze_fs = ext4_unfreeze, 1167 .unfreeze_fs = ext4_unfreeze,
1166 .statfs = ext4_statfs, 1168 .statfs = ext4_statfs,
1167 .remount_fs = ext4_remount, 1169 .remount_fs = ext4_remount,
1168 .clear_inode = ext4_clear_inode,
1169 .show_options = ext4_show_options, 1170 .show_options = ext4_show_options,
1170#ifdef CONFIG_QUOTA 1171#ifdef CONFIG_QUOTA
1171 .quota_read = ext4_quota_read, 1172 .quota_read = ext4_quota_read,
@@ -1179,12 +1180,11 @@ static const struct super_operations ext4_nojournal_sops = {
1179 .destroy_inode = ext4_destroy_inode, 1180 .destroy_inode = ext4_destroy_inode,
1180 .write_inode = ext4_write_inode, 1181 .write_inode = ext4_write_inode,
1181 .dirty_inode = ext4_dirty_inode, 1182 .dirty_inode = ext4_dirty_inode,
1182 .delete_inode = ext4_delete_inode, 1183 .evict_inode = ext4_evict_inode,
1183 .write_super = ext4_write_super, 1184 .write_super = ext4_write_super,
1184 .put_super = ext4_put_super, 1185 .put_super = ext4_put_super,
1185 .statfs = ext4_statfs, 1186 .statfs = ext4_statfs,
1186 .remount_fs = ext4_remount, 1187 .remount_fs = ext4_remount,
1187 .clear_inode = ext4_clear_inode,
1188 .show_options = ext4_show_options, 1188 .show_options = ext4_show_options,
1189#ifdef CONFIG_QUOTA 1189#ifdef CONFIG_QUOTA
1190 .quota_read = ext4_quota_read, 1190 .quota_read = ext4_quota_read,
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index a6f314249574..3a8cd8dff1ad 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -1417,7 +1417,7 @@ ext4_xattr_cache_insert(struct buffer_head *bh)
1417 ea_bdebug(bh, "out of memory"); 1417 ea_bdebug(bh, "out of memory");
1418 return; 1418 return;
1419 } 1419 }
1420 error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash); 1420 error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, hash);
1421 if (error) { 1421 if (error) {
1422 mb_cache_entry_free(ce); 1422 mb_cache_entry_free(ce);
1423 if (error == -EBUSY) { 1423 if (error == -EBUSY) {
@@ -1489,8 +1489,8 @@ ext4_xattr_cache_find(struct inode *inode, struct ext4_xattr_header *header,
1489 return NULL; /* never share */ 1489 return NULL; /* never share */
1490 ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); 1490 ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
1491again: 1491again:
1492 ce = mb_cache_entry_find_first(ext4_xattr_cache, 0, 1492 ce = mb_cache_entry_find_first(ext4_xattr_cache, inode->i_sb->s_bdev,
1493 inode->i_sb->s_bdev, hash); 1493 hash);
1494 while (ce) { 1494 while (ce) {
1495 struct buffer_head *bh; 1495 struct buffer_head *bh;
1496 1496
@@ -1514,7 +1514,7 @@ again:
1514 return bh; 1514 return bh;
1515 } 1515 }
1516 brelse(bh); 1516 brelse(bh);
1517 ce = mb_cache_entry_find_next(ce, 0, inode->i_sb->s_bdev, hash); 1517 ce = mb_cache_entry_find_next(ce, inode->i_sb->s_bdev, hash);
1518 } 1518 }
1519 return NULL; 1519 return NULL;
1520} 1520}
@@ -1590,9 +1590,7 @@ static void ext4_xattr_rehash(struct ext4_xattr_header *header,
1590int __init 1590int __init
1591init_ext4_xattr(void) 1591init_ext4_xattr(void)
1592{ 1592{
1593 ext4_xattr_cache = mb_cache_create("ext4_xattr", NULL, 1593 ext4_xattr_cache = mb_cache_create("ext4_xattr", 6);
1594 sizeof(struct mb_cache_entry) +
1595 sizeof(((struct mb_cache_entry *) 0)->e_indexes[0]), 1, 6);
1596 if (!ext4_xattr_cache) 1594 if (!ext4_xattr_cache)
1597 return -ENOMEM; 1595 return -ENOMEM;
1598 return 0; 1596 return 0;