aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext2/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext2/inode.c')
-rw-r--r--fs/ext2/inode.c87
1 files changed, 42 insertions, 45 deletions
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 */
72void ext2_delete_inode (struct inode * inode) 72void 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);
90no_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
94typedef struct { 110typedef struct {
@@ -423,6 +439,8 @@ static int ext2_alloc_blocks(struct inode *inode,
423failed_out: 439failed_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
768int __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
776static int 786static int
777ext2_write_begin(struct file *file, struct address_space *mapping, 787ext2_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
1172int ext2_setsize(struct inode *inode, loff_t newsize) 1177static 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);