diff options
Diffstat (limited to 'fs/ext3')
-rw-r--r-- | fs/ext3/Makefile | 2 | ||||
-rw-r--r-- | fs/ext3/balloc.c | 31 | ||||
-rw-r--r-- | fs/ext3/dir.c | 3 | ||||
-rw-r--r-- | fs/ext3/ext3_jbd.c | 59 | ||||
-rw-r--r-- | fs/ext3/inode.c | 85 | ||||
-rw-r--r-- | fs/ext3/namei.c | 9 | ||||
-rw-r--r-- | fs/ext3/super.c | 17 | ||||
-rw-r--r-- | fs/ext3/xattr.c | 5 |
8 files changed, 179 insertions, 32 deletions
diff --git a/fs/ext3/Makefile b/fs/ext3/Makefile index 704cd44a40c2..e77766a8b3f0 100644 --- a/fs/ext3/Makefile +++ b/fs/ext3/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | obj-$(CONFIG_EXT3_FS) += ext3.o | 5 | obj-$(CONFIG_EXT3_FS) += ext3.o |
6 | 6 | ||
7 | ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ | 7 | ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ |
8 | ioctl.o namei.o super.o symlink.o hash.o resize.o | 8 | ioctl.o namei.o super.o symlink.o hash.o resize.o ext3_jbd.o |
9 | 9 | ||
10 | ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o | 10 | ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o |
11 | ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o | 11 | ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o |
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index b41a7d7e20f0..22161740ba29 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
@@ -144,7 +144,7 @@ restart: | |||
144 | 144 | ||
145 | printk("Block Allocation Reservation Windows Map (%s):\n", fn); | 145 | printk("Block Allocation Reservation Windows Map (%s):\n", fn); |
146 | while (n) { | 146 | while (n) { |
147 | rsv = list_entry(n, struct ext3_reserve_window_node, rsv_node); | 147 | rsv = rb_entry(n, struct ext3_reserve_window_node, rsv_node); |
148 | if (verbose) | 148 | if (verbose) |
149 | printk("reservation window 0x%p " | 149 | printk("reservation window 0x%p " |
150 | "start: %lu, end: %lu\n", | 150 | "start: %lu, end: %lu\n", |
@@ -730,7 +730,7 @@ find_next_usable_block(ext3_grpblk_t start, struct buffer_head *bh, | |||
730 | here = 0; | 730 | here = 0; |
731 | 731 | ||
732 | p = ((char *)bh->b_data) + (here >> 3); | 732 | p = ((char *)bh->b_data) + (here >> 3); |
733 | r = memscan(p, 0, (maxblocks - here + 7) >> 3); | 733 | r = memscan(p, 0, ((maxblocks + 7) >> 3) - (here >> 3)); |
734 | next = (r - ((char *)bh->b_data)) << 3; | 734 | next = (r - ((char *)bh->b_data)) << 3; |
735 | 735 | ||
736 | if (next < maxblocks && next >= start && ext3_test_allocatable(next, bh)) | 736 | if (next < maxblocks && next >= start && ext3_test_allocatable(next, bh)) |
@@ -949,7 +949,7 @@ static int find_next_reservable_window( | |||
949 | 949 | ||
950 | prev = rsv; | 950 | prev = rsv; |
951 | next = rb_next(&rsv->rsv_node); | 951 | next = rb_next(&rsv->rsv_node); |
952 | rsv = list_entry(next,struct ext3_reserve_window_node,rsv_node); | 952 | rsv = rb_entry(next,struct ext3_reserve_window_node,rsv_node); |
953 | 953 | ||
954 | /* | 954 | /* |
955 | * Reached the last reservation, we can just append to the | 955 | * Reached the last reservation, we can just append to the |
@@ -1148,7 +1148,7 @@ retry: | |||
1148 | * check if the first free block is within the | 1148 | * check if the first free block is within the |
1149 | * free space we just reserved | 1149 | * free space we just reserved |
1150 | */ | 1150 | */ |
1151 | if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end) | 1151 | if (start_block >= my_rsv->rsv_start && start_block <= my_rsv->rsv_end) |
1152 | return 0; /* success */ | 1152 | return 0; /* success */ |
1153 | /* | 1153 | /* |
1154 | * if the first free bit we found is out of the reservable space | 1154 | * if the first free bit we found is out of the reservable space |
@@ -1193,7 +1193,7 @@ static void try_to_extend_reservation(struct ext3_reserve_window_node *my_rsv, | |||
1193 | if (!next) | 1193 | if (!next) |
1194 | my_rsv->rsv_end += size; | 1194 | my_rsv->rsv_end += size; |
1195 | else { | 1195 | else { |
1196 | next_rsv = list_entry(next, struct ext3_reserve_window_node, rsv_node); | 1196 | next_rsv = rb_entry(next, struct ext3_reserve_window_node, rsv_node); |
1197 | 1197 | ||
1198 | if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size) | 1198 | if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size) |
1199 | my_rsv->rsv_end += size; | 1199 | my_rsv->rsv_end += size; |
@@ -1271,7 +1271,7 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1271 | } | 1271 | } |
1272 | /* | 1272 | /* |
1273 | * grp_goal is a group relative block number (if there is a goal) | 1273 | * grp_goal is a group relative block number (if there is a goal) |
1274 | * 0 < grp_goal < EXT3_BLOCKS_PER_GROUP(sb) | 1274 | * 0 <= grp_goal < EXT3_BLOCKS_PER_GROUP(sb) |
1275 | * first block is a filesystem wide block number | 1275 | * first block is a filesystem wide block number |
1276 | * first block is the block number of the first block in this group | 1276 | * first block is the block number of the first block in this group |
1277 | */ | 1277 | */ |
@@ -1307,10 +1307,14 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1307 | if (!goal_in_my_reservation(&my_rsv->rsv_window, | 1307 | if (!goal_in_my_reservation(&my_rsv->rsv_window, |
1308 | grp_goal, group, sb)) | 1308 | grp_goal, group, sb)) |
1309 | grp_goal = -1; | 1309 | grp_goal = -1; |
1310 | } else if (grp_goal > 0 && | 1310 | } else if (grp_goal >= 0) { |
1311 | (my_rsv->rsv_end-grp_goal+1) < *count) | 1311 | int curr = my_rsv->rsv_end - |
1312 | try_to_extend_reservation(my_rsv, sb, | 1312 | (grp_goal + group_first_block) + 1; |
1313 | *count-my_rsv->rsv_end + grp_goal - 1); | 1313 | |
1314 | if (curr < *count) | ||
1315 | try_to_extend_reservation(my_rsv, sb, | ||
1316 | *count - curr); | ||
1317 | } | ||
1314 | 1318 | ||
1315 | if ((my_rsv->rsv_start > group_last_block) || | 1319 | if ((my_rsv->rsv_start > group_last_block) || |
1316 | (my_rsv->rsv_end < group_first_block)) { | 1320 | (my_rsv->rsv_end < group_first_block)) { |
@@ -1511,10 +1515,8 @@ retry_alloc: | |||
1511 | if (group_no >= ngroups) | 1515 | if (group_no >= ngroups) |
1512 | group_no = 0; | 1516 | group_no = 0; |
1513 | gdp = ext3_get_group_desc(sb, group_no, &gdp_bh); | 1517 | gdp = ext3_get_group_desc(sb, group_no, &gdp_bh); |
1514 | if (!gdp) { | 1518 | if (!gdp) |
1515 | *errp = -EIO; | 1519 | goto io_error; |
1516 | goto out; | ||
1517 | } | ||
1518 | free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); | 1520 | free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); |
1519 | /* | 1521 | /* |
1520 | * skip this group if the number of | 1522 | * skip this group if the number of |
@@ -1548,6 +1550,7 @@ retry_alloc: | |||
1548 | */ | 1550 | */ |
1549 | if (my_rsv) { | 1551 | if (my_rsv) { |
1550 | my_rsv = NULL; | 1552 | my_rsv = NULL; |
1553 | windowsz = 0; | ||
1551 | group_no = goal_group; | 1554 | group_no = goal_group; |
1552 | goto retry_alloc; | 1555 | goto retry_alloc; |
1553 | } | 1556 | } |
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c index d0b54f30b914..5a9313ecd4ef 100644 --- a/fs/ext3/dir.c +++ b/fs/ext3/dir.c | |||
@@ -154,6 +154,9 @@ static int ext3_readdir(struct file * filp, | |||
154 | ext3_error (sb, "ext3_readdir", | 154 | ext3_error (sb, "ext3_readdir", |
155 | "directory #%lu contains a hole at offset %lu", | 155 | "directory #%lu contains a hole at offset %lu", |
156 | inode->i_ino, (unsigned long)filp->f_pos); | 156 | inode->i_ino, (unsigned long)filp->f_pos); |
157 | /* corrupt size? Maybe no more blocks to read */ | ||
158 | if (filp->f_pos > inode->i_blocks << 9) | ||
159 | break; | ||
157 | filp->f_pos += sb->s_blocksize - offset; | 160 | filp->f_pos += sb->s_blocksize - offset; |
158 | continue; | 161 | continue; |
159 | } | 162 | } |
diff --git a/fs/ext3/ext3_jbd.c b/fs/ext3/ext3_jbd.c new file mode 100644 index 000000000000..e1f91fd26a93 --- /dev/null +++ b/fs/ext3/ext3_jbd.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * Interface between ext3 and JBD | ||
3 | */ | ||
4 | |||
5 | #include <linux/ext3_jbd.h> | ||
6 | |||
7 | int __ext3_journal_get_undo_access(const char *where, handle_t *handle, | ||
8 | struct buffer_head *bh) | ||
9 | { | ||
10 | int err = journal_get_undo_access(handle, bh); | ||
11 | if (err) | ||
12 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
13 | return err; | ||
14 | } | ||
15 | |||
16 | int __ext3_journal_get_write_access(const char *where, handle_t *handle, | ||
17 | struct buffer_head *bh) | ||
18 | { | ||
19 | int err = journal_get_write_access(handle, bh); | ||
20 | if (err) | ||
21 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
22 | return err; | ||
23 | } | ||
24 | |||
25 | int __ext3_journal_forget(const char *where, handle_t *handle, | ||
26 | struct buffer_head *bh) | ||
27 | { | ||
28 | int err = journal_forget(handle, bh); | ||
29 | if (err) | ||
30 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
31 | return err; | ||
32 | } | ||
33 | |||
34 | int __ext3_journal_revoke(const char *where, handle_t *handle, | ||
35 | unsigned long blocknr, struct buffer_head *bh) | ||
36 | { | ||
37 | int err = journal_revoke(handle, blocknr, bh); | ||
38 | if (err) | ||
39 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
40 | return err; | ||
41 | } | ||
42 | |||
43 | int __ext3_journal_get_create_access(const char *where, | ||
44 | handle_t *handle, struct buffer_head *bh) | ||
45 | { | ||
46 | int err = journal_get_create_access(handle, bh); | ||
47 | if (err) | ||
48 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
49 | return err; | ||
50 | } | ||
51 | |||
52 | int __ext3_journal_dirty_metadata(const char *where, | ||
53 | handle_t *handle, struct buffer_head *bh) | ||
54 | { | ||
55 | int err = journal_dirty_metadata(handle, bh); | ||
56 | if (err) | ||
57 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
58 | return err; | ||
59 | } | ||
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 03ba5bcab186..beaf25f5112f 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -1148,37 +1148,102 @@ static int do_journal_get_write_access(handle_t *handle, | |||
1148 | return ext3_journal_get_write_access(handle, bh); | 1148 | return ext3_journal_get_write_access(handle, bh); |
1149 | } | 1149 | } |
1150 | 1150 | ||
1151 | /* | ||
1152 | * The idea of this helper function is following: | ||
1153 | * if prepare_write has allocated some blocks, but not all of them, the | ||
1154 | * transaction must include the content of the newly allocated blocks. | ||
1155 | * This content is expected to be set to zeroes by block_prepare_write(). | ||
1156 | * 2006/10/14 SAW | ||
1157 | */ | ||
1158 | static int ext3_prepare_failure(struct file *file, struct page *page, | ||
1159 | unsigned from, unsigned to) | ||
1160 | { | ||
1161 | struct address_space *mapping; | ||
1162 | struct buffer_head *bh, *head, *next; | ||
1163 | unsigned block_start, block_end; | ||
1164 | unsigned blocksize; | ||
1165 | int ret; | ||
1166 | handle_t *handle = ext3_journal_current_handle(); | ||
1167 | |||
1168 | mapping = page->mapping; | ||
1169 | if (ext3_should_writeback_data(mapping->host)) { | ||
1170 | /* optimization: no constraints about data */ | ||
1171 | skip: | ||
1172 | return ext3_journal_stop(handle); | ||
1173 | } | ||
1174 | |||
1175 | head = page_buffers(page); | ||
1176 | blocksize = head->b_size; | ||
1177 | for ( bh = head, block_start = 0; | ||
1178 | bh != head || !block_start; | ||
1179 | block_start = block_end, bh = next) | ||
1180 | { | ||
1181 | next = bh->b_this_page; | ||
1182 | block_end = block_start + blocksize; | ||
1183 | if (block_end <= from) | ||
1184 | continue; | ||
1185 | if (block_start >= to) { | ||
1186 | block_start = to; | ||
1187 | break; | ||
1188 | } | ||
1189 | if (!buffer_mapped(bh)) | ||
1190 | /* prepare_write failed on this bh */ | ||
1191 | break; | ||
1192 | if (ext3_should_journal_data(mapping->host)) { | ||
1193 | ret = do_journal_get_write_access(handle, bh); | ||
1194 | if (ret) { | ||
1195 | ext3_journal_stop(handle); | ||
1196 | return ret; | ||
1197 | } | ||
1198 | } | ||
1199 | /* | ||
1200 | * block_start here becomes the first block where the current iteration | ||
1201 | * of prepare_write failed. | ||
1202 | */ | ||
1203 | } | ||
1204 | if (block_start <= from) | ||
1205 | goto skip; | ||
1206 | |||
1207 | /* commit allocated and zeroed buffers */ | ||
1208 | return mapping->a_ops->commit_write(file, page, from, block_start); | ||
1209 | } | ||
1210 | |||
1151 | static int ext3_prepare_write(struct file *file, struct page *page, | 1211 | static int ext3_prepare_write(struct file *file, struct page *page, |
1152 | unsigned from, unsigned to) | 1212 | unsigned from, unsigned to) |
1153 | { | 1213 | { |
1154 | struct inode *inode = page->mapping->host; | 1214 | struct inode *inode = page->mapping->host; |
1155 | int ret, needed_blocks = ext3_writepage_trans_blocks(inode); | 1215 | int ret, ret2; |
1216 | int needed_blocks = ext3_writepage_trans_blocks(inode); | ||
1156 | handle_t *handle; | 1217 | handle_t *handle; |
1157 | int retries = 0; | 1218 | int retries = 0; |
1158 | 1219 | ||
1159 | retry: | 1220 | retry: |
1160 | handle = ext3_journal_start(inode, needed_blocks); | 1221 | handle = ext3_journal_start(inode, needed_blocks); |
1161 | if (IS_ERR(handle)) { | 1222 | if (IS_ERR(handle)) |
1162 | ret = PTR_ERR(handle); | 1223 | return PTR_ERR(handle); |
1163 | goto out; | ||
1164 | } | ||
1165 | if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) | 1224 | if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) |
1166 | ret = nobh_prepare_write(page, from, to, ext3_get_block); | 1225 | ret = nobh_prepare_write(page, from, to, ext3_get_block); |
1167 | else | 1226 | else |
1168 | ret = block_prepare_write(page, from, to, ext3_get_block); | 1227 | ret = block_prepare_write(page, from, to, ext3_get_block); |
1169 | if (ret) | 1228 | if (ret) |
1170 | goto prepare_write_failed; | 1229 | goto failure; |
1171 | 1230 | ||
1172 | if (ext3_should_journal_data(inode)) { | 1231 | if (ext3_should_journal_data(inode)) { |
1173 | ret = walk_page_buffers(handle, page_buffers(page), | 1232 | ret = walk_page_buffers(handle, page_buffers(page), |
1174 | from, to, NULL, do_journal_get_write_access); | 1233 | from, to, NULL, do_journal_get_write_access); |
1234 | if (ret) | ||
1235 | /* fatal error, just put the handle and return */ | ||
1236 | journal_stop(handle); | ||
1175 | } | 1237 | } |
1176 | prepare_write_failed: | 1238 | return ret; |
1177 | if (ret) | 1239 | |
1178 | ext3_journal_stop(handle); | 1240 | failure: |
1241 | ret2 = ext3_prepare_failure(file, page, from, to); | ||
1242 | if (ret2 < 0) | ||
1243 | return ret2; | ||
1179 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) | 1244 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) |
1180 | goto retry; | 1245 | goto retry; |
1181 | out: | 1246 | /* retry number exceeded, or other error like -EDQUOT */ |
1182 | return ret; | 1247 | return ret; |
1183 | } | 1248 | } |
1184 | 1249 | ||
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 906731a20f1a..60d2f9dbdb00 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -552,6 +552,15 @@ static int htree_dirblock_to_tree(struct file *dir_file, | |||
552 | dir->i_sb->s_blocksize - | 552 | dir->i_sb->s_blocksize - |
553 | EXT3_DIR_REC_LEN(0)); | 553 | EXT3_DIR_REC_LEN(0)); |
554 | for (; de < top; de = ext3_next_entry(de)) { | 554 | for (; de < top; de = ext3_next_entry(de)) { |
555 | if (!ext3_check_dir_entry("htree_dirblock_to_tree", dir, de, bh, | ||
556 | (block<<EXT3_BLOCK_SIZE_BITS(dir->i_sb)) | ||
557 | +((char *)de - bh->b_data))) { | ||
558 | /* On error, skip the f_pos to the next block. */ | ||
559 | dir_file->f_pos = (dir_file->f_pos | | ||
560 | (dir->i_sb->s_blocksize - 1)) + 1; | ||
561 | brelse (bh); | ||
562 | return count; | ||
563 | } | ||
555 | ext3fs_dirhash(de->name, de->name_len, hinfo); | 564 | ext3fs_dirhash(de->name, de->name_len, hinfo); |
556 | if ((hinfo->hash < start_hash) || | 565 | if ((hinfo->hash < start_hash) || |
557 | ((hinfo->hash == start_hash) && | 566 | ((hinfo->hash == start_hash) && |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index afc2d4f42d77..580b8a6ca979 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -436,7 +436,7 @@ static void ext3_put_super (struct super_block * sb) | |||
436 | return; | 436 | return; |
437 | } | 437 | } |
438 | 438 | ||
439 | static kmem_cache_t *ext3_inode_cachep; | 439 | static struct kmem_cache *ext3_inode_cachep; |
440 | 440 | ||
441 | /* | 441 | /* |
442 | * Called inside transaction, so use GFP_NOFS | 442 | * Called inside transaction, so use GFP_NOFS |
@@ -445,7 +445,7 @@ static struct inode *ext3_alloc_inode(struct super_block *sb) | |||
445 | { | 445 | { |
446 | struct ext3_inode_info *ei; | 446 | struct ext3_inode_info *ei; |
447 | 447 | ||
448 | ei = kmem_cache_alloc(ext3_inode_cachep, SLAB_NOFS); | 448 | ei = kmem_cache_alloc(ext3_inode_cachep, GFP_NOFS); |
449 | if (!ei) | 449 | if (!ei) |
450 | return NULL; | 450 | return NULL; |
451 | #ifdef CONFIG_EXT3_FS_POSIX_ACL | 451 | #ifdef CONFIG_EXT3_FS_POSIX_ACL |
@@ -462,7 +462,7 @@ static void ext3_destroy_inode(struct inode *inode) | |||
462 | kmem_cache_free(ext3_inode_cachep, EXT3_I(inode)); | 462 | kmem_cache_free(ext3_inode_cachep, EXT3_I(inode)); |
463 | } | 463 | } |
464 | 464 | ||
465 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 465 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
466 | { | 466 | { |
467 | struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; | 467 | struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; |
468 | 468 | ||
@@ -1264,6 +1264,12 @@ static void ext3_orphan_cleanup (struct super_block * sb, | |||
1264 | return; | 1264 | return; |
1265 | } | 1265 | } |
1266 | 1266 | ||
1267 | if (bdev_read_only(sb->s_bdev)) { | ||
1268 | printk(KERN_ERR "EXT3-fs: write access " | ||
1269 | "unavailable, skipping orphan cleanup.\n"); | ||
1270 | return; | ||
1271 | } | ||
1272 | |||
1267 | if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) { | 1273 | if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) { |
1268 | if (es->s_last_orphan) | 1274 | if (es->s_last_orphan) |
1269 | jbd_debug(1, "Errors on filesystem, " | 1275 | jbd_debug(1, "Errors on filesystem, " |
@@ -2387,6 +2393,7 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2387 | struct ext3_super_block *es = sbi->s_es; | 2393 | struct ext3_super_block *es = sbi->s_es; |
2388 | ext3_fsblk_t overhead; | 2394 | ext3_fsblk_t overhead; |
2389 | int i; | 2395 | int i; |
2396 | u64 fsid; | ||
2390 | 2397 | ||
2391 | if (test_opt (sb, MINIX_DF)) | 2398 | if (test_opt (sb, MINIX_DF)) |
2392 | overhead = 0; | 2399 | overhead = 0; |
@@ -2433,6 +2440,10 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2433 | buf->f_files = le32_to_cpu(es->s_inodes_count); | 2440 | buf->f_files = le32_to_cpu(es->s_inodes_count); |
2434 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); | 2441 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); |
2435 | buf->f_namelen = EXT3_NAME_LEN; | 2442 | buf->f_namelen = EXT3_NAME_LEN; |
2443 | fsid = le64_to_cpup((void *)es->s_uuid) ^ | ||
2444 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); | ||
2445 | buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL; | ||
2446 | buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL; | ||
2436 | return 0; | 2447 | return 0; |
2437 | } | 2448 | } |
2438 | 2449 | ||
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index f86f2482f01d..99857a400f4b 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c | |||
@@ -459,14 +459,11 @@ static void ext3_xattr_update_super_block(handle_t *handle, | |||
459 | if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR)) | 459 | if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR)) |
460 | return; | 460 | return; |
461 | 461 | ||
462 | lock_super(sb); | ||
463 | if (ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh) == 0) { | 462 | if (ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh) == 0) { |
464 | EXT3_SB(sb)->s_es->s_feature_compat |= | 463 | EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR); |
465 | cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR); | ||
466 | sb->s_dirt = 1; | 464 | sb->s_dirt = 1; |
467 | ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); | 465 | ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); |
468 | } | 466 | } |
469 | unlock_super(sb); | ||
470 | } | 467 | } |
471 | 468 | ||
472 | /* | 469 | /* |