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.c209
1 files changed, 145 insertions, 64 deletions
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index fc13cc119aad..940c96168868 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -22,7 +22,6 @@
22 * Assorted race fixes, rewrite of ext2_get_block() by Al Viro, 2000 22 * Assorted race fixes, rewrite of ext2_get_block() by Al Viro, 2000
23 */ 23 */
24 24
25#include <linux/smp_lock.h>
26#include <linux/time.h> 25#include <linux/time.h>
27#include <linux/highuid.h> 26#include <linux/highuid.h>
28#include <linux/pagemap.h> 27#include <linux/pagemap.h>
@@ -55,29 +54,57 @@ static inline int ext2_inode_is_fast_symlink(struct inode *inode)
55 inode->i_blocks - ea_blocks == 0); 54 inode->i_blocks - ea_blocks == 0);
56} 55}
57 56
57static void ext2_truncate_blocks(struct inode *inode, loff_t offset);
58
59static void ext2_write_failed(struct address_space *mapping, loff_t to)
60{
61 struct inode *inode = mapping->host;
62
63 if (to > inode->i_size) {
64 truncate_pagecache(inode, to, inode->i_size);
65 ext2_truncate_blocks(inode, inode->i_size);
66 }
67}
68
58/* 69/*
59 * Called at the last iput() if i_nlink is zero. 70 * Called at the last iput() if i_nlink is zero.
60 */ 71 */
61void ext2_delete_inode (struct inode * inode) 72void ext2_evict_inode(struct inode * inode)
62{ 73{
63 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;
64 dquot_initialize(inode); 79 dquot_initialize(inode);
80 } else {
81 dquot_drop(inode);
82 }
83
65 truncate_inode_pages(&inode->i_data, 0); 84 truncate_inode_pages(&inode->i_data, 0);
66 85
67 if (is_bad_inode(inode)) 86 if (want_delete) {
68 goto no_delete; 87 /* set dtime */
69 EXT2_I(inode)->i_dtime = get_seconds(); 88 EXT2_I(inode)->i_dtime = get_seconds();
70 mark_inode_dirty(inode); 89 mark_inode_dirty(inode);
71 __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 }
96
97 invalidate_inode_buffers(inode);
98 end_writeback(inode);
72 99
73 inode->i_size = 0; 100 ext2_discard_reservation(inode);
74 if (inode->i_blocks) 101 rsv = EXT2_I(inode)->i_block_alloc_info;
75 ext2_truncate (inode); 102 EXT2_I(inode)->i_block_alloc_info = NULL;
76 ext2_free_inode (inode); 103 if (unlikely(rsv))
104 kfree(rsv);
77 105
78 return; 106 if (want_delete)
79no_delete: 107 ext2_free_inode(inode);
80 clear_inode(inode); /* We must guarantee clearing of inode... */
81} 108}
82 109
83typedef struct { 110typedef struct {
@@ -412,6 +439,8 @@ static int ext2_alloc_blocks(struct inode *inode,
412failed_out: 439failed_out:
413 for (i = 0; i <index; i++) 440 for (i = 0; i <index; i++)
414 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);
415 return ret; 444 return ret;
416} 445}
417 446
@@ -754,21 +783,30 @@ ext2_readpages(struct file *file, struct address_space *mapping,
754 return mpage_readpages(mapping, pages, nr_pages, ext2_get_block); 783 return mpage_readpages(mapping, pages, nr_pages, ext2_get_block);
755} 784}
756 785
757int __ext2_write_begin(struct file *file, struct address_space *mapping, 786static int
787ext2_write_begin(struct file *file, struct address_space *mapping,
758 loff_t pos, unsigned len, unsigned flags, 788 loff_t pos, unsigned len, unsigned flags,
759 struct page **pagep, void **fsdata) 789 struct page **pagep, void **fsdata)
760{ 790{
761 return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 791 int ret;
762 ext2_get_block); 792
793 ret = block_write_begin(mapping, pos, len, flags, pagep,
794 ext2_get_block);
795 if (ret < 0)
796 ext2_write_failed(mapping, pos + len);
797 return ret;
763} 798}
764 799
765static int 800static int ext2_write_end(struct file *file, struct address_space *mapping,
766ext2_write_begin(struct file *file, struct address_space *mapping, 801 loff_t pos, unsigned len, unsigned copied,
767 loff_t pos, unsigned len, unsigned flags, 802 struct page *page, void *fsdata)
768 struct page **pagep, void **fsdata)
769{ 803{
770 *pagep = NULL; 804 int ret;
771 return __ext2_write_begin(file, mapping, pos, len, flags, pagep,fsdata); 805
806 ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
807 if (ret < len)
808 ext2_write_failed(mapping, pos + len);
809 return ret;
772} 810}
773 811
774static int 812static int
@@ -776,13 +814,13 @@ ext2_nobh_write_begin(struct file *file, struct address_space *mapping,
776 loff_t pos, unsigned len, unsigned flags, 814 loff_t pos, unsigned len, unsigned flags,
777 struct page **pagep, void **fsdata) 815 struct page **pagep, void **fsdata)
778{ 816{
779 /* 817 int ret;
780 * Dir-in-pagecache still uses ext2_write_begin. Would have to rework 818
781 * directory handling code to pass around offsets rather than struct 819 ret = nobh_write_begin(mapping, pos, len, flags, pagep, fsdata,
782 * pages in order to make this work easily. 820 ext2_get_block);
783 */ 821 if (ret < 0)
784 return nobh_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 822 ext2_write_failed(mapping, pos + len);
785 ext2_get_block); 823 return ret;
786} 824}
787 825
788static int ext2_nobh_writepage(struct page *page, 826static int ext2_nobh_writepage(struct page *page,
@@ -801,10 +839,15 @@ ext2_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
801 loff_t offset, unsigned long nr_segs) 839 loff_t offset, unsigned long nr_segs)
802{ 840{
803 struct file *file = iocb->ki_filp; 841 struct file *file = iocb->ki_filp;
804 struct inode *inode = file->f_mapping->host; 842 struct address_space *mapping = file->f_mapping;
805 843 struct inode *inode = mapping->host;
806 return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, 844 ssize_t ret;
807 offset, nr_segs, ext2_get_block, NULL); 845
846 ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev,
847 iov, offset, nr_segs, ext2_get_block, NULL);
848 if (ret < 0 && (rw & WRITE))
849 ext2_write_failed(mapping, offset + iov_length(iov, nr_segs));
850 return ret;
808} 851}
809 852
810static int 853static int
@@ -819,7 +862,7 @@ const struct address_space_operations ext2_aops = {
819 .writepage = ext2_writepage, 862 .writepage = ext2_writepage,
820 .sync_page = block_sync_page, 863 .sync_page = block_sync_page,
821 .write_begin = ext2_write_begin, 864 .write_begin = ext2_write_begin,
822 .write_end = generic_write_end, 865 .write_end = ext2_write_end,
823 .bmap = ext2_bmap, 866 .bmap = ext2_bmap,
824 .direct_IO = ext2_direct_IO, 867 .direct_IO = ext2_direct_IO,
825 .writepages = ext2_writepages, 868 .writepages = ext2_writepages,
@@ -968,8 +1011,8 @@ static inline void ext2_free_data(struct inode *inode, __le32 *p, __le32 *q)
968 else if (block_to_free == nr - count) 1011 else if (block_to_free == nr - count)
969 count++; 1012 count++;
970 else { 1013 else {
971 mark_inode_dirty(inode);
972 ext2_free_blocks (inode, block_to_free, count); 1014 ext2_free_blocks (inode, block_to_free, count);
1015 mark_inode_dirty(inode);
973 free_this: 1016 free_this:
974 block_to_free = nr; 1017 block_to_free = nr;
975 count = 1; 1018 count = 1;
@@ -977,8 +1020,8 @@ static inline void ext2_free_data(struct inode *inode, __le32 *p, __le32 *q)
977 } 1020 }
978 } 1021 }
979 if (count > 0) { 1022 if (count > 0) {
980 mark_inode_dirty(inode);
981 ext2_free_blocks (inode, block_to_free, count); 1023 ext2_free_blocks (inode, block_to_free, count);
1024 mark_inode_dirty(inode);
982 } 1025 }
983} 1026}
984 1027
@@ -1028,7 +1071,7 @@ static void ext2_free_branches(struct inode *inode, __le32 *p, __le32 *q, int de
1028 ext2_free_data(inode, p, q); 1071 ext2_free_data(inode, p, q);
1029} 1072}
1030 1073
1031void ext2_truncate(struct inode *inode) 1074static void __ext2_truncate_blocks(struct inode *inode, loff_t offset)
1032{ 1075{
1033 __le32 *i_data = EXT2_I(inode)->i_data; 1076 __le32 *i_data = EXT2_I(inode)->i_data;
1034 struct ext2_inode_info *ei = EXT2_I(inode); 1077 struct ext2_inode_info *ei = EXT2_I(inode);
@@ -1040,27 +1083,8 @@ void ext2_truncate(struct inode *inode)
1040 int n; 1083 int n;
1041 long iblock; 1084 long iblock;
1042 unsigned blocksize; 1085 unsigned blocksize;
1043
1044 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
1045 S_ISLNK(inode->i_mode)))
1046 return;
1047 if (ext2_inode_is_fast_symlink(inode))
1048 return;
1049 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
1050 return;
1051
1052 blocksize = inode->i_sb->s_blocksize; 1086 blocksize = inode->i_sb->s_blocksize;
1053 iblock = (inode->i_size + blocksize-1) 1087 iblock = (offset + blocksize-1) >> EXT2_BLOCK_SIZE_BITS(inode->i_sb);
1054 >> EXT2_BLOCK_SIZE_BITS(inode->i_sb);
1055
1056 if (mapping_is_xip(inode->i_mapping))
1057 xip_truncate_page(inode->i_mapping, inode->i_size);
1058 else if (test_opt(inode->i_sb, NOBH))
1059 nobh_truncate_page(inode->i_mapping,
1060 inode->i_size, ext2_get_block);
1061 else
1062 block_truncate_page(inode->i_mapping,
1063 inode->i_size, ext2_get_block);
1064 1088
1065 n = ext2_block_to_path(inode, iblock, offsets, NULL); 1089 n = ext2_block_to_path(inode, iblock, offsets, NULL);
1066 if (n == 0) 1090 if (n == 0)
@@ -1128,6 +1152,54 @@ do_indirects:
1128 ext2_discard_reservation(inode); 1152 ext2_discard_reservation(inode);
1129 1153
1130 mutex_unlock(&ei->truncate_mutex); 1154 mutex_unlock(&ei->truncate_mutex);
1155}
1156
1157static void ext2_truncate_blocks(struct inode *inode, loff_t offset)
1158{
1159 /*
1160 * XXX: it seems like a bug here that we don't allow
1161 * IS_APPEND inode to have blocks-past-i_size trimmed off.
1162 * review and fix this.
1163 *
1164 * Also would be nice to be able to handle IO errors and such,
1165 * but that's probably too much to ask.
1166 */
1167 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
1168 S_ISLNK(inode->i_mode)))
1169 return;
1170 if (ext2_inode_is_fast_symlink(inode))
1171 return;
1172 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
1173 return;
1174 __ext2_truncate_blocks(inode, offset);
1175}
1176
1177static int ext2_setsize(struct inode *inode, loff_t newsize)
1178{
1179 int error;
1180
1181 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
1182 S_ISLNK(inode->i_mode)))
1183 return -EINVAL;
1184 if (ext2_inode_is_fast_symlink(inode))
1185 return -EINVAL;
1186 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
1187 return -EPERM;
1188
1189 if (mapping_is_xip(inode->i_mapping))
1190 error = xip_truncate_page(inode->i_mapping, newsize);
1191 else if (test_opt(inode->i_sb, NOBH))
1192 error = nobh_truncate_page(inode->i_mapping,
1193 newsize, ext2_get_block);
1194 else
1195 error = block_truncate_page(inode->i_mapping,
1196 newsize, ext2_get_block);
1197 if (error)
1198 return error;
1199
1200 truncate_setsize(inode, newsize);
1201 __ext2_truncate_blocks(inode, newsize);
1202
1131 inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; 1203 inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
1132 if (inode_needs_sync(inode)) { 1204 if (inode_needs_sync(inode)) {
1133 sync_mapping_buffers(inode->i_mapping); 1205 sync_mapping_buffers(inode->i_mapping);
@@ -1135,6 +1207,8 @@ do_indirects:
1135 } else { 1207 } else {
1136 mark_inode_dirty(inode); 1208 mark_inode_dirty(inode);
1137 } 1209 }
1210
1211 return 0;
1138} 1212}
1139 1213
1140static struct ext2_inode *ext2_get_inode(struct super_block *sb, ino_t ino, 1214static struct ext2_inode *ext2_get_inode(struct super_block *sb, ino_t ino,
@@ -1406,11 +1480,11 @@ static int __ext2_write_inode(struct inode *inode, int do_sync)
1406 /* If this is the first large file 1480 /* If this is the first large file
1407 * created, add a flag to the superblock. 1481 * created, add a flag to the superblock.
1408 */ 1482 */
1409 lock_kernel(); 1483 spin_lock(&EXT2_SB(sb)->s_lock);
1410 ext2_update_dynamic_rev(sb); 1484 ext2_update_dynamic_rev(sb);
1411 EXT2_SET_RO_COMPAT_FEATURE(sb, 1485 EXT2_SET_RO_COMPAT_FEATURE(sb,
1412 EXT2_FEATURE_RO_COMPAT_LARGE_FILE); 1486 EXT2_FEATURE_RO_COMPAT_LARGE_FILE);
1413 unlock_kernel(); 1487 spin_unlock(&EXT2_SB(sb)->s_lock);
1414 ext2_write_super(sb); 1488 ext2_write_super(sb);
1415 } 1489 }
1416 } 1490 }
@@ -1467,7 +1541,7 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
1467 if (error) 1541 if (error)
1468 return error; 1542 return error;
1469 1543
1470 if (iattr->ia_valid & ATTR_SIZE) 1544 if (is_quota_modification(inode, iattr))
1471 dquot_initialize(inode); 1545 dquot_initialize(inode);
1472 if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || 1546 if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
1473 (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { 1547 (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
@@ -1475,8 +1549,15 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
1475 if (error) 1549 if (error)
1476 return error; 1550 return error;
1477 } 1551 }
1478 error = inode_setattr(inode, iattr); 1552 if (iattr->ia_valid & ATTR_SIZE && iattr->ia_size != inode->i_size) {
1479 if (!error && (iattr->ia_valid & ATTR_MODE)) 1553 error = ext2_setsize(inode, iattr->ia_size);
1554 if (error)
1555 return error;
1556 }
1557 setattr_copy(inode, iattr);
1558 if (iattr->ia_valid & ATTR_MODE)
1480 error = ext2_acl_chmod(inode); 1559 error = ext2_acl_chmod(inode);
1560 mark_inode_dirty(inode);
1561
1481 return error; 1562 return error;
1482} 1563}