diff options
Diffstat (limited to 'fs/ext2')
-rw-r--r-- | fs/ext2/acl.c | 4 | ||||
-rw-r--r-- | fs/ext2/ext2.h | 3 | ||||
-rw-r--r-- | fs/ext2/file.c | 7 | ||||
-rw-r--r-- | fs/ext2/ialloc.c | 12 | ||||
-rw-r--r-- | fs/ext2/inode.c | 153 | ||||
-rw-r--r-- | fs/ext2/super.c | 20 | ||||
-rw-r--r-- | fs/ext2/xattr.c | 10 | ||||
-rw-r--r-- | fs/ext2/xattr.h | 12 | ||||
-rw-r--r-- | fs/ext2/xattr_security.c | 2 | ||||
-rw-r--r-- | fs/ext2/xattr_trusted.c | 2 | ||||
-rw-r--r-- | fs/ext2/xattr_user.c | 2 |
11 files changed, 163 insertions, 64 deletions
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index a99e54318c3d..ca7e2a0ed98a 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c | |||
@@ -420,7 +420,7 @@ release_and_out: | |||
420 | return error; | 420 | return error; |
421 | } | 421 | } |
422 | 422 | ||
423 | struct xattr_handler ext2_xattr_acl_access_handler = { | 423 | const struct xattr_handler ext2_xattr_acl_access_handler = { |
424 | .prefix = POSIX_ACL_XATTR_ACCESS, | 424 | .prefix = POSIX_ACL_XATTR_ACCESS, |
425 | .flags = ACL_TYPE_ACCESS, | 425 | .flags = ACL_TYPE_ACCESS, |
426 | .list = ext2_xattr_list_acl_access, | 426 | .list = ext2_xattr_list_acl_access, |
@@ -428,7 +428,7 @@ struct xattr_handler ext2_xattr_acl_access_handler = { | |||
428 | .set = ext2_xattr_set_acl, | 428 | .set = ext2_xattr_set_acl, |
429 | }; | 429 | }; |
430 | 430 | ||
431 | struct xattr_handler ext2_xattr_acl_default_handler = { | 431 | const struct xattr_handler ext2_xattr_acl_default_handler = { |
432 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 432 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
433 | .flags = ACL_TYPE_DEFAULT, | 433 | .flags = ACL_TYPE_DEFAULT, |
434 | .list = ext2_xattr_list_acl_default, | 434 | .list = ext2_xattr_list_acl_default, |
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 0b038e47ad2f..52b34f1d2738 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h | |||
@@ -122,7 +122,6 @@ extern int ext2_write_inode (struct inode *, struct writeback_control *); | |||
122 | extern void ext2_delete_inode (struct inode *); | 122 | extern void ext2_delete_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 void ext2_truncate (struct inode *); | ||
126 | extern int ext2_setattr (struct dentry *, struct iattr *); | 125 | extern int ext2_setattr (struct dentry *, struct iattr *); |
127 | extern void ext2_set_inode_flags(struct inode *inode); | 126 | extern void ext2_set_inode_flags(struct inode *inode); |
128 | extern void ext2_get_inode_flags(struct ext2_inode_info *); | 127 | extern void ext2_get_inode_flags(struct ext2_inode_info *); |
@@ -155,7 +154,7 @@ extern void ext2_write_super (struct super_block *); | |||
155 | extern const struct file_operations ext2_dir_operations; | 154 | extern const struct file_operations ext2_dir_operations; |
156 | 155 | ||
157 | /* file.c */ | 156 | /* file.c */ |
158 | extern int ext2_fsync(struct file *file, struct dentry *dentry, int datasync); | 157 | extern int ext2_fsync(struct file *file, int datasync); |
159 | extern const struct inode_operations ext2_file_inode_operations; | 158 | extern const struct inode_operations ext2_file_inode_operations; |
160 | extern const struct file_operations ext2_file_operations; | 159 | extern const struct file_operations ext2_file_operations; |
161 | extern const struct file_operations ext2_xip_file_operations; | 160 | extern const struct file_operations ext2_xip_file_operations; |
diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 5d198d0697fb..49eec9456c5b 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c | |||
@@ -40,13 +40,13 @@ static int ext2_release_file (struct inode * inode, struct file * filp) | |||
40 | return 0; | 40 | return 0; |
41 | } | 41 | } |
42 | 42 | ||
43 | int ext2_fsync(struct file *file, struct dentry *dentry, int datasync) | 43 | int ext2_fsync(struct file *file, int datasync) |
44 | { | 44 | { |
45 | int ret; | 45 | int ret; |
46 | struct super_block *sb = dentry->d_inode->i_sb; | 46 | struct super_block *sb = file->f_mapping->host->i_sb; |
47 | struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; | 47 | struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; |
48 | 48 | ||
49 | ret = simple_fsync(file, dentry, datasync); | 49 | ret = generic_file_fsync(file, datasync); |
50 | if (ret == -EIO || test_and_clear_bit(AS_EIO, &mapping->flags)) { | 50 | if (ret == -EIO || test_and_clear_bit(AS_EIO, &mapping->flags)) { |
51 | /* We don't really know where the IO error happened... */ | 51 | /* We don't really know where the IO error happened... */ |
52 | ext2_error(sb, __func__, | 52 | ext2_error(sb, __func__, |
@@ -95,7 +95,6 @@ const struct file_operations ext2_xip_file_operations = { | |||
95 | #endif | 95 | #endif |
96 | 96 | ||
97 | const struct inode_operations ext2_file_inode_operations = { | 97 | const struct inode_operations ext2_file_inode_operations = { |
98 | .truncate = ext2_truncate, | ||
99 | #ifdef CONFIG_EXT2_FS_XATTR | 98 | #ifdef CONFIG_EXT2_FS_XATTR |
100 | .setxattr = generic_setxattr, | 99 | .setxattr = generic_setxattr, |
101 | .getxattr = generic_getxattr, | 100 | .getxattr = generic_getxattr, |
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index f0c5286f9342..938dbc739d00 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c | |||
@@ -549,16 +549,12 @@ got: | |||
549 | 549 | ||
550 | sb->s_dirt = 1; | 550 | sb->s_dirt = 1; |
551 | mark_buffer_dirty(bh2); | 551 | mark_buffer_dirty(bh2); |
552 | inode->i_uid = current_fsuid(); | 552 | if (test_opt(sb, GRPID)) { |
553 | if (test_opt (sb, GRPID)) | 553 | inode->i_mode = mode; |
554 | inode->i_uid = current_fsuid(); | ||
554 | inode->i_gid = dir->i_gid; | 555 | inode->i_gid = dir->i_gid; |
555 | else if (dir->i_mode & S_ISGID) { | ||
556 | inode->i_gid = dir->i_gid; | ||
557 | if (S_ISDIR(mode)) | ||
558 | mode |= S_ISGID; | ||
559 | } else | 556 | } else |
560 | inode->i_gid = current_fsgid(); | 557 | inode_init_owner(inode, dir, mode); |
561 | inode->i_mode = mode; | ||
562 | 558 | ||
563 | inode->i_ino = ino; | 559 | inode->i_ino = ino; |
564 | inode->i_blocks = 0; | 560 | inode->i_blocks = 0; |
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 527c46d9bc1f..3675088cb88c 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -54,6 +54,18 @@ static inline int ext2_inode_is_fast_symlink(struct inode *inode) | |||
54 | inode->i_blocks - ea_blocks == 0); | 54 | inode->i_blocks - ea_blocks == 0); |
55 | } | 55 | } |
56 | 56 | ||
57 | static void ext2_truncate_blocks(struct inode *inode, loff_t offset); | ||
58 | |||
59 | static 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 | |||
57 | /* | 69 | /* |
58 | * Called at the last iput() if i_nlink is zero. | 70 | * Called at the last iput() if i_nlink is zero. |
59 | */ | 71 | */ |
@@ -71,7 +83,7 @@ void ext2_delete_inode (struct inode * inode) | |||
71 | 83 | ||
72 | inode->i_size = 0; | 84 | inode->i_size = 0; |
73 | if (inode->i_blocks) | 85 | if (inode->i_blocks) |
74 | ext2_truncate (inode); | 86 | ext2_truncate_blocks(inode, 0); |
75 | ext2_free_inode (inode); | 87 | ext2_free_inode (inode); |
76 | 88 | ||
77 | return; | 89 | return; |
@@ -757,8 +769,8 @@ int __ext2_write_begin(struct file *file, struct address_space *mapping, | |||
757 | loff_t pos, unsigned len, unsigned flags, | 769 | loff_t pos, unsigned len, unsigned flags, |
758 | struct page **pagep, void **fsdata) | 770 | struct page **pagep, void **fsdata) |
759 | { | 771 | { |
760 | return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 772 | return block_write_begin_newtrunc(file, mapping, pos, len, flags, |
761 | ext2_get_block); | 773 | pagep, fsdata, ext2_get_block); |
762 | } | 774 | } |
763 | 775 | ||
764 | static int | 776 | static int |
@@ -766,8 +778,25 @@ ext2_write_begin(struct file *file, struct address_space *mapping, | |||
766 | loff_t pos, unsigned len, unsigned flags, | 778 | loff_t pos, unsigned len, unsigned flags, |
767 | struct page **pagep, void **fsdata) | 779 | struct page **pagep, void **fsdata) |
768 | { | 780 | { |
781 | int ret; | ||
782 | |||
769 | *pagep = NULL; | 783 | *pagep = NULL; |
770 | return __ext2_write_begin(file, mapping, pos, len, flags, pagep,fsdata); | 784 | ret = __ext2_write_begin(file, mapping, pos, len, flags, pagep, fsdata); |
785 | if (ret < 0) | ||
786 | ext2_write_failed(mapping, pos + len); | ||
787 | return ret; | ||
788 | } | ||
789 | |||
790 | static int ext2_write_end(struct file *file, struct address_space *mapping, | ||
791 | loff_t pos, unsigned len, unsigned copied, | ||
792 | struct page *page, void *fsdata) | ||
793 | { | ||
794 | int ret; | ||
795 | |||
796 | ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata); | ||
797 | if (ret < len) | ||
798 | ext2_write_failed(mapping, pos + len); | ||
799 | return ret; | ||
771 | } | 800 | } |
772 | 801 | ||
773 | static int | 802 | static int |
@@ -775,13 +804,18 @@ ext2_nobh_write_begin(struct file *file, struct address_space *mapping, | |||
775 | loff_t pos, unsigned len, unsigned flags, | 804 | loff_t pos, unsigned len, unsigned flags, |
776 | struct page **pagep, void **fsdata) | 805 | struct page **pagep, void **fsdata) |
777 | { | 806 | { |
807 | int ret; | ||
808 | |||
778 | /* | 809 | /* |
779 | * Dir-in-pagecache still uses ext2_write_begin. Would have to rework | 810 | * Dir-in-pagecache still uses ext2_write_begin. Would have to rework |
780 | * directory handling code to pass around offsets rather than struct | 811 | * directory handling code to pass around offsets rather than struct |
781 | * pages in order to make this work easily. | 812 | * pages in order to make this work easily. |
782 | */ | 813 | */ |
783 | return nobh_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 814 | ret = nobh_write_begin_newtrunc(file, mapping, pos, len, flags, pagep, |
784 | ext2_get_block); | 815 | fsdata, ext2_get_block); |
816 | if (ret < 0) | ||
817 | ext2_write_failed(mapping, pos + len); | ||
818 | return ret; | ||
785 | } | 819 | } |
786 | 820 | ||
787 | static int ext2_nobh_writepage(struct page *page, | 821 | static int ext2_nobh_writepage(struct page *page, |
@@ -800,10 +834,15 @@ ext2_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | |||
800 | loff_t offset, unsigned long nr_segs) | 834 | loff_t offset, unsigned long nr_segs) |
801 | { | 835 | { |
802 | struct file *file = iocb->ki_filp; | 836 | struct file *file = iocb->ki_filp; |
803 | struct inode *inode = file->f_mapping->host; | 837 | struct address_space *mapping = file->f_mapping; |
804 | 838 | struct inode *inode = mapping->host; | |
805 | return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, | 839 | ssize_t ret; |
806 | offset, nr_segs, ext2_get_block, NULL); | 840 | |
841 | ret = blockdev_direct_IO_newtrunc(rw, iocb, inode, inode->i_sb->s_bdev, | ||
842 | iov, offset, nr_segs, ext2_get_block, NULL); | ||
843 | if (ret < 0 && (rw & WRITE)) | ||
844 | ext2_write_failed(mapping, offset + iov_length(iov, nr_segs)); | ||
845 | return ret; | ||
807 | } | 846 | } |
808 | 847 | ||
809 | static int | 848 | static int |
@@ -818,7 +857,7 @@ const struct address_space_operations ext2_aops = { | |||
818 | .writepage = ext2_writepage, | 857 | .writepage = ext2_writepage, |
819 | .sync_page = block_sync_page, | 858 | .sync_page = block_sync_page, |
820 | .write_begin = ext2_write_begin, | 859 | .write_begin = ext2_write_begin, |
821 | .write_end = generic_write_end, | 860 | .write_end = ext2_write_end, |
822 | .bmap = ext2_bmap, | 861 | .bmap = ext2_bmap, |
823 | .direct_IO = ext2_direct_IO, | 862 | .direct_IO = ext2_direct_IO, |
824 | .writepages = ext2_writepages, | 863 | .writepages = ext2_writepages, |
@@ -1027,7 +1066,7 @@ static void ext2_free_branches(struct inode *inode, __le32 *p, __le32 *q, int de | |||
1027 | ext2_free_data(inode, p, q); | 1066 | ext2_free_data(inode, p, q); |
1028 | } | 1067 | } |
1029 | 1068 | ||
1030 | void ext2_truncate(struct inode *inode) | 1069 | static void __ext2_truncate_blocks(struct inode *inode, loff_t offset) |
1031 | { | 1070 | { |
1032 | __le32 *i_data = EXT2_I(inode)->i_data; | 1071 | __le32 *i_data = EXT2_I(inode)->i_data; |
1033 | struct ext2_inode_info *ei = EXT2_I(inode); | 1072 | struct ext2_inode_info *ei = EXT2_I(inode); |
@@ -1039,27 +1078,8 @@ void ext2_truncate(struct inode *inode) | |||
1039 | int n; | 1078 | int n; |
1040 | long iblock; | 1079 | long iblock; |
1041 | unsigned blocksize; | 1080 | unsigned blocksize; |
1042 | |||
1043 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | ||
1044 | S_ISLNK(inode->i_mode))) | ||
1045 | return; | ||
1046 | if (ext2_inode_is_fast_symlink(inode)) | ||
1047 | return; | ||
1048 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | ||
1049 | return; | ||
1050 | |||
1051 | blocksize = inode->i_sb->s_blocksize; | 1081 | blocksize = inode->i_sb->s_blocksize; |
1052 | iblock = (inode->i_size + blocksize-1) | 1082 | iblock = (offset + blocksize-1) >> EXT2_BLOCK_SIZE_BITS(inode->i_sb); |
1053 | >> EXT2_BLOCK_SIZE_BITS(inode->i_sb); | ||
1054 | |||
1055 | if (mapping_is_xip(inode->i_mapping)) | ||
1056 | xip_truncate_page(inode->i_mapping, inode->i_size); | ||
1057 | else if (test_opt(inode->i_sb, NOBH)) | ||
1058 | nobh_truncate_page(inode->i_mapping, | ||
1059 | inode->i_size, ext2_get_block); | ||
1060 | else | ||
1061 | block_truncate_page(inode->i_mapping, | ||
1062 | inode->i_size, ext2_get_block); | ||
1063 | 1083 | ||
1064 | n = ext2_block_to_path(inode, iblock, offsets, NULL); | 1084 | n = ext2_block_to_path(inode, iblock, offsets, NULL); |
1065 | if (n == 0) | 1085 | if (n == 0) |
@@ -1127,6 +1147,62 @@ do_indirects: | |||
1127 | ext2_discard_reservation(inode); | 1147 | ext2_discard_reservation(inode); |
1128 | 1148 | ||
1129 | mutex_unlock(&ei->truncate_mutex); | 1149 | mutex_unlock(&ei->truncate_mutex); |
1150 | } | ||
1151 | |||
1152 | static void ext2_truncate_blocks(struct inode *inode, loff_t offset) | ||
1153 | { | ||
1154 | /* | ||
1155 | * XXX: it seems like a bug here that we don't allow | ||
1156 | * IS_APPEND inode to have blocks-past-i_size trimmed off. | ||
1157 | * review and fix this. | ||
1158 | * | ||
1159 | * Also would be nice to be able to handle IO errors and such, | ||
1160 | * but that's probably too much to ask. | ||
1161 | */ | ||
1162 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | ||
1163 | S_ISLNK(inode->i_mode))) | ||
1164 | return; | ||
1165 | if (ext2_inode_is_fast_symlink(inode)) | ||
1166 | return; | ||
1167 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | ||
1168 | return; | ||
1169 | __ext2_truncate_blocks(inode, offset); | ||
1170 | } | ||
1171 | |||
1172 | int ext2_setsize(struct inode *inode, loff_t newsize) | ||
1173 | { | ||
1174 | loff_t oldsize; | ||
1175 | int error; | ||
1176 | |||
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) || | ||
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 | oldsize = inode->i_size; | ||
1201 | i_size_write(inode, newsize); | ||
1202 | truncate_pagecache(inode, oldsize, newsize); | ||
1203 | |||
1204 | __ext2_truncate_blocks(inode, newsize); | ||
1205 | |||
1130 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; | 1206 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; |
1131 | if (inode_needs_sync(inode)) { | 1207 | if (inode_needs_sync(inode)) { |
1132 | sync_mapping_buffers(inode->i_mapping); | 1208 | sync_mapping_buffers(inode->i_mapping); |
@@ -1134,6 +1210,8 @@ do_indirects: | |||
1134 | } else { | 1210 | } else { |
1135 | mark_inode_dirty(inode); | 1211 | mark_inode_dirty(inode); |
1136 | } | 1212 | } |
1213 | |||
1214 | return 0; | ||
1137 | } | 1215 | } |
1138 | 1216 | ||
1139 | static struct ext2_inode *ext2_get_inode(struct super_block *sb, ino_t ino, | 1217 | static struct ext2_inode *ext2_get_inode(struct super_block *sb, ino_t ino, |
@@ -1474,8 +1552,15 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr) | |||
1474 | if (error) | 1552 | if (error) |
1475 | return error; | 1553 | return error; |
1476 | } | 1554 | } |
1477 | error = inode_setattr(inode, iattr); | 1555 | if (iattr->ia_valid & ATTR_SIZE && iattr->ia_size != inode->i_size) { |
1478 | if (!error && (iattr->ia_valid & ATTR_MODE)) | 1556 | error = ext2_setsize(inode, iattr->ia_size); |
1557 | if (error) | ||
1558 | return error; | ||
1559 | } | ||
1560 | generic_setattr(inode, iattr); | ||
1561 | if (iattr->ia_valid & ATTR_MODE) | ||
1479 | error = ext2_acl_chmod(inode); | 1562 | error = ext2_acl_chmod(inode); |
1563 | mark_inode_dirty(inode); | ||
1564 | |||
1480 | return error; | 1565 | return error; |
1481 | } | 1566 | } |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 71e9eb1fa696..7ff43f4a59cd 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -119,6 +119,8 @@ static void ext2_put_super (struct super_block * sb) | |||
119 | int i; | 119 | int i; |
120 | struct ext2_sb_info *sbi = EXT2_SB(sb); | 120 | struct ext2_sb_info *sbi = EXT2_SB(sb); |
121 | 121 | ||
122 | dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); | ||
123 | |||
122 | if (sb->s_dirt) | 124 | if (sb->s_dirt) |
123 | ext2_write_super(sb); | 125 | ext2_write_super(sb); |
124 | 126 | ||
@@ -1063,6 +1065,12 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
1063 | sb->s_op = &ext2_sops; | 1065 | sb->s_op = &ext2_sops; |
1064 | sb->s_export_op = &ext2_export_ops; | 1066 | sb->s_export_op = &ext2_export_ops; |
1065 | sb->s_xattr = ext2_xattr_handlers; | 1067 | sb->s_xattr = ext2_xattr_handlers; |
1068 | |||
1069 | #ifdef CONFIG_QUOTA | ||
1070 | sb->dq_op = &dquot_operations; | ||
1071 | sb->s_qcop = &dquot_quotactl_ops; | ||
1072 | #endif | ||
1073 | |||
1066 | root = ext2_iget(sb, EXT2_ROOT_INO); | 1074 | root = ext2_iget(sb, EXT2_ROOT_INO); |
1067 | if (IS_ERR(root)) { | 1075 | if (IS_ERR(root)) { |
1068 | ret = PTR_ERR(root); | 1076 | ret = PTR_ERR(root); |
@@ -1241,6 +1249,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) | |||
1241 | spin_unlock(&sbi->s_lock); | 1249 | spin_unlock(&sbi->s_lock); |
1242 | return 0; | 1250 | return 0; |
1243 | } | 1251 | } |
1252 | |||
1244 | /* | 1253 | /* |
1245 | * OK, we are remounting a valid rw partition rdonly, so set | 1254 | * OK, we are remounting a valid rw partition rdonly, so set |
1246 | * the rdonly flag and then mark the partition as valid again. | 1255 | * the rdonly flag and then mark the partition as valid again. |
@@ -1248,6 +1257,13 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) | |||
1248 | es->s_state = cpu_to_le16(sbi->s_mount_state); | 1257 | es->s_state = cpu_to_le16(sbi->s_mount_state); |
1249 | es->s_mtime = cpu_to_le32(get_seconds()); | 1258 | es->s_mtime = cpu_to_le32(get_seconds()); |
1250 | spin_unlock(&sbi->s_lock); | 1259 | spin_unlock(&sbi->s_lock); |
1260 | |||
1261 | err = dquot_suspend(sb, -1); | ||
1262 | if (err < 0) { | ||
1263 | spin_lock(&sbi->s_lock); | ||
1264 | goto restore_opts; | ||
1265 | } | ||
1266 | |||
1251 | ext2_sync_super(sb, es, 1); | 1267 | ext2_sync_super(sb, es, 1); |
1252 | } else { | 1268 | } else { |
1253 | __le32 ret = EXT2_HAS_RO_COMPAT_FEATURE(sb, | 1269 | __le32 ret = EXT2_HAS_RO_COMPAT_FEATURE(sb, |
@@ -1269,8 +1285,12 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) | |||
1269 | if (!ext2_setup_super (sb, es, 0)) | 1285 | if (!ext2_setup_super (sb, es, 0)) |
1270 | sb->s_flags &= ~MS_RDONLY; | 1286 | sb->s_flags &= ~MS_RDONLY; |
1271 | spin_unlock(&sbi->s_lock); | 1287 | spin_unlock(&sbi->s_lock); |
1288 | |||
1272 | ext2_write_super(sb); | 1289 | ext2_write_super(sb); |
1290 | |||
1291 | dquot_resume(sb, -1); | ||
1273 | } | 1292 | } |
1293 | |||
1274 | return 0; | 1294 | return 0; |
1275 | restore_opts: | 1295 | restore_opts: |
1276 | sbi->s_mount_opt = old_opts.s_mount_opt; | 1296 | sbi->s_mount_opt = old_opts.s_mount_opt; |
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 3b96045a00ce..7c3915780b19 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c | |||
@@ -101,7 +101,7 @@ static void ext2_xattr_rehash(struct ext2_xattr_header *, | |||
101 | 101 | ||
102 | static struct mb_cache *ext2_xattr_cache; | 102 | static struct mb_cache *ext2_xattr_cache; |
103 | 103 | ||
104 | static struct xattr_handler *ext2_xattr_handler_map[] = { | 104 | static const struct xattr_handler *ext2_xattr_handler_map[] = { |
105 | [EXT2_XATTR_INDEX_USER] = &ext2_xattr_user_handler, | 105 | [EXT2_XATTR_INDEX_USER] = &ext2_xattr_user_handler, |
106 | #ifdef CONFIG_EXT2_FS_POSIX_ACL | 106 | #ifdef CONFIG_EXT2_FS_POSIX_ACL |
107 | [EXT2_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext2_xattr_acl_access_handler, | 107 | [EXT2_XATTR_INDEX_POSIX_ACL_ACCESS] = &ext2_xattr_acl_access_handler, |
@@ -113,7 +113,7 @@ static struct xattr_handler *ext2_xattr_handler_map[] = { | |||
113 | #endif | 113 | #endif |
114 | }; | 114 | }; |
115 | 115 | ||
116 | struct xattr_handler *ext2_xattr_handlers[] = { | 116 | const struct xattr_handler *ext2_xattr_handlers[] = { |
117 | &ext2_xattr_user_handler, | 117 | &ext2_xattr_user_handler, |
118 | &ext2_xattr_trusted_handler, | 118 | &ext2_xattr_trusted_handler, |
119 | #ifdef CONFIG_EXT2_FS_POSIX_ACL | 119 | #ifdef CONFIG_EXT2_FS_POSIX_ACL |
@@ -126,10 +126,10 @@ struct xattr_handler *ext2_xattr_handlers[] = { | |||
126 | NULL | 126 | NULL |
127 | }; | 127 | }; |
128 | 128 | ||
129 | static inline struct xattr_handler * | 129 | static inline const struct xattr_handler * |
130 | ext2_xattr_handler(int name_index) | 130 | ext2_xattr_handler(int name_index) |
131 | { | 131 | { |
132 | struct xattr_handler *handler = NULL; | 132 | const struct xattr_handler *handler = NULL; |
133 | 133 | ||
134 | if (name_index > 0 && name_index < ARRAY_SIZE(ext2_xattr_handler_map)) | 134 | if (name_index > 0 && name_index < ARRAY_SIZE(ext2_xattr_handler_map)) |
135 | handler = ext2_xattr_handler_map[name_index]; | 135 | handler = ext2_xattr_handler_map[name_index]; |
@@ -298,7 +298,7 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list", | |||
298 | /* list the attribute names */ | 298 | /* list the attribute names */ |
299 | for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); | 299 | for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); |
300 | entry = EXT2_XATTR_NEXT(entry)) { | 300 | entry = EXT2_XATTR_NEXT(entry)) { |
301 | struct xattr_handler *handler = | 301 | const struct xattr_handler *handler = |
302 | ext2_xattr_handler(entry->e_name_index); | 302 | ext2_xattr_handler(entry->e_name_index); |
303 | 303 | ||
304 | if (handler) { | 304 | if (handler) { |
diff --git a/fs/ext2/xattr.h b/fs/ext2/xattr.h index bf8175b2ced9..a1a1c2184616 100644 --- a/fs/ext2/xattr.h +++ b/fs/ext2/xattr.h | |||
@@ -55,11 +55,11 @@ struct ext2_xattr_entry { | |||
55 | 55 | ||
56 | # ifdef CONFIG_EXT2_FS_XATTR | 56 | # ifdef CONFIG_EXT2_FS_XATTR |
57 | 57 | ||
58 | extern struct xattr_handler ext2_xattr_user_handler; | 58 | extern const struct xattr_handler ext2_xattr_user_handler; |
59 | extern struct xattr_handler ext2_xattr_trusted_handler; | 59 | extern const struct xattr_handler ext2_xattr_trusted_handler; |
60 | extern struct xattr_handler ext2_xattr_acl_access_handler; | 60 | extern const struct xattr_handler ext2_xattr_acl_access_handler; |
61 | extern struct xattr_handler ext2_xattr_acl_default_handler; | 61 | extern const struct xattr_handler ext2_xattr_acl_default_handler; |
62 | extern struct xattr_handler ext2_xattr_security_handler; | 62 | extern const struct xattr_handler ext2_xattr_security_handler; |
63 | 63 | ||
64 | extern ssize_t ext2_listxattr(struct dentry *, char *, size_t); | 64 | extern ssize_t ext2_listxattr(struct dentry *, char *, size_t); |
65 | 65 | ||
@@ -72,7 +72,7 @@ extern void ext2_xattr_put_super(struct super_block *); | |||
72 | extern int init_ext2_xattr(void); | 72 | extern int init_ext2_xattr(void); |
73 | extern void exit_ext2_xattr(void); | 73 | extern void exit_ext2_xattr(void); |
74 | 74 | ||
75 | extern struct xattr_handler *ext2_xattr_handlers[]; | 75 | extern const struct xattr_handler *ext2_xattr_handlers[]; |
76 | 76 | ||
77 | # else /* CONFIG_EXT2_FS_XATTR */ | 77 | # else /* CONFIG_EXT2_FS_XATTR */ |
78 | 78 | ||
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c index b118c6383c6d..3004e15d5da5 100644 --- a/fs/ext2/xattr_security.c +++ b/fs/ext2/xattr_security.c | |||
@@ -67,7 +67,7 @@ ext2_init_security(struct inode *inode, struct inode *dir) | |||
67 | return err; | 67 | return err; |
68 | } | 68 | } |
69 | 69 | ||
70 | struct xattr_handler ext2_xattr_security_handler = { | 70 | const struct xattr_handler ext2_xattr_security_handler = { |
71 | .prefix = XATTR_SECURITY_PREFIX, | 71 | .prefix = XATTR_SECURITY_PREFIX, |
72 | .list = ext2_xattr_security_list, | 72 | .list = ext2_xattr_security_list, |
73 | .get = ext2_xattr_security_get, | 73 | .get = ext2_xattr_security_get, |
diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c index 2a26d71f4771..667e46a8d62d 100644 --- a/fs/ext2/xattr_trusted.c +++ b/fs/ext2/xattr_trusted.c | |||
@@ -50,7 +50,7 @@ ext2_xattr_trusted_set(struct dentry *dentry, const char *name, | |||
50 | value, size, flags); | 50 | value, size, flags); |
51 | } | 51 | } |
52 | 52 | ||
53 | struct xattr_handler ext2_xattr_trusted_handler = { | 53 | const struct xattr_handler ext2_xattr_trusted_handler = { |
54 | .prefix = XATTR_TRUSTED_PREFIX, | 54 | .prefix = XATTR_TRUSTED_PREFIX, |
55 | .list = ext2_xattr_trusted_list, | 55 | .list = ext2_xattr_trusted_list, |
56 | .get = ext2_xattr_trusted_get, | 56 | .get = ext2_xattr_trusted_get, |
diff --git a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c index 3f6caf3684b4..099d20f47163 100644 --- a/fs/ext2/xattr_user.c +++ b/fs/ext2/xattr_user.c | |||
@@ -54,7 +54,7 @@ ext2_xattr_user_set(struct dentry *dentry, const char *name, | |||
54 | name, value, size, flags); | 54 | name, value, size, flags); |
55 | } | 55 | } |
56 | 56 | ||
57 | struct xattr_handler ext2_xattr_user_handler = { | 57 | const struct xattr_handler ext2_xattr_user_handler = { |
58 | .prefix = XATTR_USER_PREFIX, | 58 | .prefix = XATTR_USER_PREFIX, |
59 | .list = ext2_xattr_user_list, | 59 | .list = ext2_xattr_user_list, |
60 | .get = ext2_xattr_user_get, | 60 | .get = ext2_xattr_user_get, |