aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3
diff options
context:
space:
mode:
authorAnton Altaparmakov <aia21@cantab.net>2006-01-19 11:39:33 -0500
committerAnton Altaparmakov <aia21@cantab.net>2006-01-19 11:39:33 -0500
commit944d79559d154c12becde0dab327016cf438f46c (patch)
tree50c101806f4d3b6585222dda060559eb4f3e005a /fs/ext3
parentd087e4bdd24ebe3ae3d0b265b6573ec901af4b4b (diff)
parent0f36b018b2e314d45af86449f1a97facb1fbe300 (diff)
Merge branch 'master' of /usr/src/ntfs-2.6/
Diffstat (limited to 'fs/ext3')
-rw-r--r--fs/ext3/acl.c11
-rw-r--r--fs/ext3/balloc.c3
-rw-r--r--fs/ext3/bitmap.c8
-rw-r--r--fs/ext3/bitmap.h8
-rw-r--r--fs/ext3/ialloc.c7
-rw-r--r--fs/ext3/ioctl.c1
-rw-r--r--fs/ext3/namei.c7
-rw-r--r--fs/ext3/resize.c32
-rw-r--r--fs/ext3/super.c60
-rw-r--r--fs/ext3/xattr.c6
-rw-r--r--fs/ext3/xattr_trusted.c5
-rw-r--r--fs/ext3/xattr_user.c15
12 files changed, 85 insertions, 78 deletions
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index 3ac38266fc9e..47a9da2dfb4f 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -7,6 +7,7 @@
7#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/sched.h> 8#include <linux/sched.h>
9#include <linux/slab.h> 9#include <linux/slab.h>
10#include <linux/capability.h>
10#include <linux/fs.h> 11#include <linux/fs.h>
11#include <linux/ext3_jbd.h> 12#include <linux/ext3_jbd.h>
12#include <linux/ext3_fs.h> 13#include <linux/ext3_fs.h>
@@ -152,7 +153,7 @@ ext3_iset_acl(struct inode *inode, struct posix_acl **i_acl,
152/* 153/*
153 * Inode operation get_posix_acl(). 154 * Inode operation get_posix_acl().
154 * 155 *
155 * inode->i_sem: don't care 156 * inode->i_mutex: don't care
156 */ 157 */
157static struct posix_acl * 158static struct posix_acl *
158ext3_get_acl(struct inode *inode, int type) 159ext3_get_acl(struct inode *inode, int type)
@@ -216,7 +217,7 @@ ext3_get_acl(struct inode *inode, int type)
216/* 217/*
217 * Set the access or default ACL of an inode. 218 * Set the access or default ACL of an inode.
218 * 219 *
219 * inode->i_sem: down unless called from ext3_new_inode 220 * inode->i_mutex: down unless called from ext3_new_inode
220 */ 221 */
221static int 222static int
222ext3_set_acl(handle_t *handle, struct inode *inode, int type, 223ext3_set_acl(handle_t *handle, struct inode *inode, int type,
@@ -306,8 +307,8 @@ ext3_permission(struct inode *inode, int mask, struct nameidata *nd)
306/* 307/*
307 * Initialize the ACLs of a new inode. Called from ext3_new_inode. 308 * Initialize the ACLs of a new inode. Called from ext3_new_inode.
308 * 309 *
309 * dir->i_sem: down 310 * dir->i_mutex: down
310 * inode->i_sem: up (access to inode is still exclusive) 311 * inode->i_mutex: up (access to inode is still exclusive)
311 */ 312 */
312int 313int
313ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) 314ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
@@ -368,7 +369,7 @@ cleanup:
368 * for directories) are added. There are no more bits available in the 369 * for directories) are added. There are no more bits available in the
369 * file mode. 370 * file mode.
370 * 371 *
371 * inode->i_sem: down 372 * inode->i_mutex: down
372 */ 373 */
373int 374int
374ext3_acl_chmod(struct inode *inode) 375ext3_acl_chmod(struct inode *inode)
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index ae1148c24c53..6250fcdf14a1 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/config.h> 14#include <linux/config.h>
15#include <linux/time.h> 15#include <linux/time.h>
16#include <linux/capability.h>
16#include <linux/fs.h> 17#include <linux/fs.h>
17#include <linux/jbd.h> 18#include <linux/jbd.h>
18#include <linux/ext3_fs.h> 19#include <linux/ext3_fs.h>
@@ -20,8 +21,6 @@
20#include <linux/quotaops.h> 21#include <linux/quotaops.h>
21#include <linux/buffer_head.h> 22#include <linux/buffer_head.h>
22 23
23#include "bitmap.h"
24
25/* 24/*
26 * balloc.c contains the blocks allocation and deallocation routines 25 * balloc.c contains the blocks allocation and deallocation routines
27 */ 26 */
diff --git a/fs/ext3/bitmap.c b/fs/ext3/bitmap.c
index 5b4ba3e246e6..cb16b4c5d5df 100644
--- a/fs/ext3/bitmap.c
+++ b/fs/ext3/bitmap.c
@@ -7,8 +7,11 @@
7 * Universite Pierre et Marie Curie (Paris VI) 7 * Universite Pierre et Marie Curie (Paris VI)
8 */ 8 */
9 9
10#ifdef EXT3FS_DEBUG
11
10#include <linux/buffer_head.h> 12#include <linux/buffer_head.h>
11#include "bitmap.h" 13
14#include "ext3_fs.h"
12 15
13static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; 16static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
14 17
@@ -24,3 +27,6 @@ unsigned long ext3_count_free (struct buffer_head * map, unsigned int numchars)
24 nibblemap[(map->b_data[i] >> 4) & 0xf]; 27 nibblemap[(map->b_data[i] >> 4) & 0xf];
25 return (sum); 28 return (sum);
26} 29}
30
31#endif /* EXT3FS_DEBUG */
32
diff --git a/fs/ext3/bitmap.h b/fs/ext3/bitmap.h
deleted file mode 100644
index 6ee503a6bb4e..000000000000
--- a/fs/ext3/bitmap.h
+++ /dev/null
@@ -1,8 +0,0 @@
1/* linux/fs/ext3/bitmap.c
2 *
3 * Copyright (C) 2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6*/
7
8extern unsigned long ext3_count_free (struct buffer_head *, unsigned int );
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index 9e4a24376210..dc826464f313 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -26,7 +26,6 @@
26 26
27#include <asm/byteorder.h> 27#include <asm/byteorder.h>
28 28
29#include "bitmap.h"
30#include "xattr.h" 29#include "xattr.h"
31#include "acl.h" 30#include "acl.h"
32 31
@@ -651,7 +650,7 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino)
651 /* Error cases - e2fsck has already cleaned up for us */ 650 /* Error cases - e2fsck has already cleaned up for us */
652 if (ino > max_ino) { 651 if (ino > max_ino) {
653 ext3_warning(sb, __FUNCTION__, 652 ext3_warning(sb, __FUNCTION__,
654 "bad orphan ino %lu! e2fsck was run?\n", ino); 653 "bad orphan ino %lu! e2fsck was run?", ino);
655 goto out; 654 goto out;
656 } 655 }
657 656
@@ -660,7 +659,7 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino)
660 bitmap_bh = read_inode_bitmap(sb, block_group); 659 bitmap_bh = read_inode_bitmap(sb, block_group);
661 if (!bitmap_bh) { 660 if (!bitmap_bh) {
662 ext3_warning(sb, __FUNCTION__, 661 ext3_warning(sb, __FUNCTION__,
663 "inode bitmap error for orphan %lu\n", ino); 662 "inode bitmap error for orphan %lu", ino);
664 goto out; 663 goto out;
665 } 664 }
666 665
@@ -672,7 +671,7 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino)
672 !(inode = iget(sb, ino)) || is_bad_inode(inode) || 671 !(inode = iget(sb, ino)) || is_bad_inode(inode) ||
673 NEXT_ORPHAN(inode) > max_ino) { 672 NEXT_ORPHAN(inode) > max_ino) {
674 ext3_warning(sb, __FUNCTION__, 673 ext3_warning(sb, __FUNCTION__,
675 "bad orphan inode %lu! e2fsck was run?\n", ino); 674 "bad orphan inode %lu! e2fsck was run?", ino);
676 printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n", 675 printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n",
677 bit, (unsigned long long)bitmap_bh->b_blocknr, 676 bit, (unsigned long long)bitmap_bh->b_blocknr,
678 ext3_test_bit(bit, bitmap_bh->b_data)); 677 ext3_test_bit(bit, bitmap_bh->b_data));
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
index 706d68608381..556cd5510078 100644
--- a/fs/ext3/ioctl.c
+++ b/fs/ext3/ioctl.c
@@ -9,6 +9,7 @@
9 9
10#include <linux/fs.h> 10#include <linux/fs.h>
11#include <linux/jbd.h> 11#include <linux/jbd.h>
12#include <linux/capability.h>
12#include <linux/ext3_fs.h> 13#include <linux/ext3_fs.h>
13#include <linux/ext3_jbd.h> 14#include <linux/ext3_jbd.h>
14#include <linux/time.h> 15#include <linux/time.h>
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index b3c690a3b54a..8bd8ac077704 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -1005,10 +1005,7 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, str
1005 if (!inode) 1005 if (!inode)
1006 return ERR_PTR(-EACCES); 1006 return ERR_PTR(-EACCES);
1007 } 1007 }
1008 if (inode) 1008 return d_splice_alias(inode, dentry);
1009 return d_splice_alias(inode, dentry);
1010 d_add(dentry, inode);
1011 return NULL;
1012} 1009}
1013 1010
1014 1011
@@ -1476,7 +1473,7 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry,
1476 if (levels && (dx_get_count(frames->entries) == 1473 if (levels && (dx_get_count(frames->entries) ==
1477 dx_get_limit(frames->entries))) { 1474 dx_get_limit(frames->entries))) {
1478 ext3_warning(sb, __FUNCTION__, 1475 ext3_warning(sb, __FUNCTION__,
1479 "Directory index full!\n"); 1476 "Directory index full!");
1480 err = -ENOSPC; 1477 err = -ENOSPC;
1481 goto cleanup; 1478 goto cleanup;
1482 } 1479 }
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 6104ad310507..1041dab6de2f 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -31,7 +31,7 @@ static int verify_group_input(struct super_block *sb,
31 unsigned start = le32_to_cpu(es->s_blocks_count); 31 unsigned start = le32_to_cpu(es->s_blocks_count);
32 unsigned end = start + input->blocks_count; 32 unsigned end = start + input->blocks_count;
33 unsigned group = input->group; 33 unsigned group = input->group;
34 unsigned itend = input->inode_table + EXT3_SB(sb)->s_itb_per_group; 34 unsigned itend = input->inode_table + sbi->s_itb_per_group;
35 unsigned overhead = ext3_bg_has_super(sb, group) ? 35 unsigned overhead = ext3_bg_has_super(sb, group) ?
36 (1 + ext3_bg_num_gdb(sb, group) + 36 (1 + ext3_bg_num_gdb(sb, group) +
37 le16_to_cpu(es->s_reserved_gdt_blocks)) : 0; 37 le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
@@ -340,7 +340,7 @@ static int verify_reserved_gdb(struct super_block *sb,
340 while ((grp = ext3_list_backups(sb, &three, &five, &seven)) < end) { 340 while ((grp = ext3_list_backups(sb, &three, &five, &seven)) < end) {
341 if (le32_to_cpu(*p++) != grp * EXT3_BLOCKS_PER_GROUP(sb) + blk){ 341 if (le32_to_cpu(*p++) != grp * EXT3_BLOCKS_PER_GROUP(sb) + blk){
342 ext3_warning(sb, __FUNCTION__, 342 ext3_warning(sb, __FUNCTION__,
343 "reserved GDT %ld missing grp %d (%ld)\n", 343 "reserved GDT %ld missing grp %d (%ld)",
344 blk, grp, 344 blk, grp,
345 grp * EXT3_BLOCKS_PER_GROUP(sb) + blk); 345 grp * EXT3_BLOCKS_PER_GROUP(sb) + blk);
346 return -EINVAL; 346 return -EINVAL;
@@ -393,7 +393,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
393 if (EXT3_SB(sb)->s_sbh->b_blocknr != 393 if (EXT3_SB(sb)->s_sbh->b_blocknr !=
394 le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) { 394 le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) {
395 ext3_warning(sb, __FUNCTION__, 395 ext3_warning(sb, __FUNCTION__,
396 "won't resize using backup superblock at %llu\n", 396 "won't resize using backup superblock at %llu",
397 (unsigned long long)EXT3_SB(sb)->s_sbh->b_blocknr); 397 (unsigned long long)EXT3_SB(sb)->s_sbh->b_blocknr);
398 return -EPERM; 398 return -EPERM;
399 } 399 }
@@ -417,7 +417,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
417 data = (__u32 *)dind->b_data; 417 data = (__u32 *)dind->b_data;
418 if (le32_to_cpu(data[gdb_num % EXT3_ADDR_PER_BLOCK(sb)]) != gdblock) { 418 if (le32_to_cpu(data[gdb_num % EXT3_ADDR_PER_BLOCK(sb)]) != gdblock) {
419 ext3_warning(sb, __FUNCTION__, 419 ext3_warning(sb, __FUNCTION__,
420 "new group %u GDT block %lu not reserved\n", 420 "new group %u GDT block %lu not reserved",
421 input->group, gdblock); 421 input->group, gdblock);
422 err = -EINVAL; 422 err = -EINVAL;
423 goto exit_dind; 423 goto exit_dind;
@@ -540,7 +540,7 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode,
540 for (res = 0; res < reserved_gdb; res++, blk++) { 540 for (res = 0; res < reserved_gdb; res++, blk++) {
541 if (le32_to_cpu(*data) != blk) { 541 if (le32_to_cpu(*data) != blk) {
542 ext3_warning(sb, __FUNCTION__, 542 ext3_warning(sb, __FUNCTION__,
543 "reserved block %lu not at offset %ld\n", 543 "reserved block %lu not at offset %ld",
544 blk, (long)(data - (__u32 *)dind->b_data)); 544 blk, (long)(data - (__u32 *)dind->b_data));
545 err = -EINVAL; 545 err = -EINVAL;
546 goto exit_bh; 546 goto exit_bh;
@@ -683,7 +683,7 @@ exit_err:
683 if (err) { 683 if (err) {
684 ext3_warning(sb, __FUNCTION__, 684 ext3_warning(sb, __FUNCTION__,
685 "can't update backup for group %d (err %d), " 685 "can't update backup for group %d (err %d), "
686 "forcing fsck on next reboot\n", group, err); 686 "forcing fsck on next reboot", group, err);
687 sbi->s_mount_state &= ~EXT3_VALID_FS; 687 sbi->s_mount_state &= ~EXT3_VALID_FS;
688 sbi->s_es->s_state &= ~cpu_to_le16(EXT3_VALID_FS); 688 sbi->s_es->s_state &= ~cpu_to_le16(EXT3_VALID_FS);
689 mark_buffer_dirty(sbi->s_sbh); 689 mark_buffer_dirty(sbi->s_sbh);
@@ -722,7 +722,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
722 if (gdb_off == 0 && !EXT3_HAS_RO_COMPAT_FEATURE(sb, 722 if (gdb_off == 0 && !EXT3_HAS_RO_COMPAT_FEATURE(sb,
723 EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER)) { 723 EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
724 ext3_warning(sb, __FUNCTION__, 724 ext3_warning(sb, __FUNCTION__,
725 "Can't resize non-sparse filesystem further\n"); 725 "Can't resize non-sparse filesystem further");
726 return -EPERM; 726 return -EPERM;
727 } 727 }
728 728
@@ -730,13 +730,13 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
730 if (!EXT3_HAS_COMPAT_FEATURE(sb, 730 if (!EXT3_HAS_COMPAT_FEATURE(sb,
731 EXT3_FEATURE_COMPAT_RESIZE_INODE)){ 731 EXT3_FEATURE_COMPAT_RESIZE_INODE)){
732 ext3_warning(sb, __FUNCTION__, 732 ext3_warning(sb, __FUNCTION__,
733 "No reserved GDT blocks, can't resize\n"); 733 "No reserved GDT blocks, can't resize");
734 return -EPERM; 734 return -EPERM;
735 } 735 }
736 inode = iget(sb, EXT3_RESIZE_INO); 736 inode = iget(sb, EXT3_RESIZE_INO);
737 if (!inode || is_bad_inode(inode)) { 737 if (!inode || is_bad_inode(inode)) {
738 ext3_warning(sb, __FUNCTION__, 738 ext3_warning(sb, __FUNCTION__,
739 "Error opening resize inode\n"); 739 "Error opening resize inode");
740 iput(inode); 740 iput(inode);
741 return -ENOENT; 741 return -ENOENT;
742 } 742 }
@@ -764,9 +764,9 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
764 } 764 }
765 765
766 lock_super(sb); 766 lock_super(sb);
767 if (input->group != EXT3_SB(sb)->s_groups_count) { 767 if (input->group != sbi->s_groups_count) {
768 ext3_warning(sb, __FUNCTION__, 768 ext3_warning(sb, __FUNCTION__,
769 "multiple resizers run on filesystem!\n"); 769 "multiple resizers run on filesystem!");
770 err = -EBUSY; 770 err = -EBUSY;
771 goto exit_journal; 771 goto exit_journal;
772 } 772 }
@@ -799,7 +799,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
799 * data. So we need to be careful to set all of the relevant 799 * data. So we need to be careful to set all of the relevant
800 * group descriptor data etc. *before* we enable the group. 800 * group descriptor data etc. *before* we enable the group.
801 * 801 *
802 * The key field here is EXT3_SB(sb)->s_groups_count: as long as 802 * The key field here is sbi->s_groups_count: as long as
803 * that retains its old value, nobody is going to access the new 803 * that retains its old value, nobody is going to access the new
804 * group. 804 * group.
805 * 805 *
@@ -859,7 +859,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
859 smp_wmb(); 859 smp_wmb();
860 860
861 /* Update the global fs size fields */ 861 /* Update the global fs size fields */
862 EXT3_SB(sb)->s_groups_count++; 862 sbi->s_groups_count++;
863 863
864 ext3_journal_dirty_metadata(handle, primary); 864 ext3_journal_dirty_metadata(handle, primary);
865 865
@@ -874,7 +874,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
874 percpu_counter_mod(&sbi->s_freeinodes_counter, 874 percpu_counter_mod(&sbi->s_freeinodes_counter,
875 EXT3_INODES_PER_GROUP(sb)); 875 EXT3_INODES_PER_GROUP(sb));
876 876
877 ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); 877 ext3_journal_dirty_metadata(handle, sbi->s_sbh);
878 sb->s_dirt = 1; 878 sb->s_dirt = 1;
879 879
880exit_journal: 880exit_journal:
@@ -937,7 +937,7 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es,
937 937
938 if (last == 0) { 938 if (last == 0) {
939 ext3_warning(sb, __FUNCTION__, 939 ext3_warning(sb, __FUNCTION__,
940 "need to use ext2online to resize further\n"); 940 "need to use ext2online to resize further");
941 return -EPERM; 941 return -EPERM;
942 } 942 }
943 943
@@ -973,7 +973,7 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es,
973 lock_super(sb); 973 lock_super(sb);
974 if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) { 974 if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) {
975 ext3_warning(sb, __FUNCTION__, 975 ext3_warning(sb, __FUNCTION__,
976 "multiple resizers run on filesystem!\n"); 976 "multiple resizers run on filesystem!");
977 err = -EBUSY; 977 err = -EBUSY;
978 goto exit_put; 978 goto exit_put;
979 } 979 }
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 4e6730622d90..56bf76586019 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -43,7 +43,8 @@
43#include "acl.h" 43#include "acl.h"
44#include "namei.h" 44#include "namei.h"
45 45
46static int ext3_load_journal(struct super_block *, struct ext3_super_block *); 46static int ext3_load_journal(struct super_block *, struct ext3_super_block *,
47 unsigned long journal_devnum);
47static int ext3_create_journal(struct super_block *, struct ext3_super_block *, 48static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
48 int); 49 int);
49static void ext3_commit_super (struct super_block * sb, 50static void ext3_commit_super (struct super_block * sb,
@@ -628,7 +629,7 @@ enum {
628 Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, 629 Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
629 Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, 630 Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
630 Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, 631 Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh,
631 Opt_commit, Opt_journal_update, Opt_journal_inum, 632 Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev,
632 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, 633 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
633 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, 634 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
634 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, 635 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
@@ -666,6 +667,7 @@ static match_table_t tokens = {
666 {Opt_commit, "commit=%u"}, 667 {Opt_commit, "commit=%u"},
667 {Opt_journal_update, "journal=update"}, 668 {Opt_journal_update, "journal=update"},
668 {Opt_journal_inum, "journal=%u"}, 669 {Opt_journal_inum, "journal=%u"},
670 {Opt_journal_dev, "journal_dev=%u"},
669 {Opt_abort, "abort"}, 671 {Opt_abort, "abort"},
670 {Opt_data_journal, "data=journal"}, 672 {Opt_data_journal, "data=journal"},
671 {Opt_data_ordered, "data=ordered"}, 673 {Opt_data_ordered, "data=ordered"},
@@ -705,8 +707,9 @@ static unsigned long get_sb_block(void **data)
705 return sb_block; 707 return sb_block;
706} 708}
707 709
708static int parse_options (char * options, struct super_block *sb, 710static int parse_options (char *options, struct super_block *sb,
709 unsigned long * inum, unsigned long *n_blocks_count, int is_remount) 711 unsigned long *inum, unsigned long *journal_devnum,
712 unsigned long *n_blocks_count, int is_remount)
710{ 713{
711 struct ext3_sb_info *sbi = EXT3_SB(sb); 714 struct ext3_sb_info *sbi = EXT3_SB(sb);
712 char * p; 715 char * p;
@@ -839,6 +842,16 @@ static int parse_options (char * options, struct super_block *sb,
839 return 0; 842 return 0;
840 *inum = option; 843 *inum = option;
841 break; 844 break;
845 case Opt_journal_dev:
846 if (is_remount) {
847 printk(KERN_ERR "EXT3-fs: cannot specify "
848 "journal on remount\n");
849 return 0;
850 }
851 if (match_int(&args[0], &option))
852 return 0;
853 *journal_devnum = option;
854 break;
842 case Opt_noload: 855 case Opt_noload:
843 set_opt (sbi->s_mount_opt, NOLOAD); 856 set_opt (sbi->s_mount_opt, NOLOAD);
844 break; 857 break;
@@ -1331,6 +1344,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1331 unsigned long logic_sb_block; 1344 unsigned long logic_sb_block;
1332 unsigned long offset = 0; 1345 unsigned long offset = 0;
1333 unsigned long journal_inum = 0; 1346 unsigned long journal_inum = 0;
1347 unsigned long journal_devnum = 0;
1334 unsigned long def_mount_opts; 1348 unsigned long def_mount_opts;
1335 struct inode *root; 1349 struct inode *root;
1336 int blocksize; 1350 int blocksize;
@@ -1411,7 +1425,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1411 1425
1412 set_opt(sbi->s_mount_opt, RESERVATION); 1426 set_opt(sbi->s_mount_opt, RESERVATION);
1413 1427
1414 if (!parse_options ((char *) data, sb, &journal_inum, NULL, 0)) 1428 if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum,
1429 NULL, 0))
1415 goto failed_mount; 1430 goto failed_mount;
1416 1431
1417 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | 1432 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
@@ -1622,7 +1637,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1622 */ 1637 */
1623 if (!test_opt(sb, NOLOAD) && 1638 if (!test_opt(sb, NOLOAD) &&
1624 EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) { 1639 EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
1625 if (ext3_load_journal(sb, es)) 1640 if (ext3_load_journal(sb, es, journal_devnum))
1626 goto failed_mount2; 1641 goto failed_mount2;
1627 } else if (journal_inum) { 1642 } else if (journal_inum) {
1628 if (ext3_create_journal(sb, es, journal_inum)) 1643 if (ext3_create_journal(sb, es, journal_inum))
@@ -1902,15 +1917,24 @@ out_bdev:
1902 return NULL; 1917 return NULL;
1903} 1918}
1904 1919
1905static int ext3_load_journal(struct super_block * sb, 1920static int ext3_load_journal(struct super_block *sb,
1906 struct ext3_super_block * es) 1921 struct ext3_super_block *es,
1922 unsigned long journal_devnum)
1907{ 1923{
1908 journal_t *journal; 1924 journal_t *journal;
1909 int journal_inum = le32_to_cpu(es->s_journal_inum); 1925 int journal_inum = le32_to_cpu(es->s_journal_inum);
1910 dev_t journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev)); 1926 dev_t journal_dev;
1911 int err = 0; 1927 int err = 0;
1912 int really_read_only; 1928 int really_read_only;
1913 1929
1930 if (journal_devnum &&
1931 journal_devnum != le32_to_cpu(es->s_journal_dev)) {
1932 printk(KERN_INFO "EXT3-fs: external journal device major/minor "
1933 "numbers have changed\n");
1934 journal_dev = new_decode_dev(journal_devnum);
1935 } else
1936 journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
1937
1914 really_read_only = bdev_read_only(sb->s_bdev); 1938 really_read_only = bdev_read_only(sb->s_bdev);
1915 1939
1916 /* 1940 /*
@@ -1969,6 +1993,16 @@ static int ext3_load_journal(struct super_block * sb,
1969 1993
1970 EXT3_SB(sb)->s_journal = journal; 1994 EXT3_SB(sb)->s_journal = journal;
1971 ext3_clear_journal_err(sb, es); 1995 ext3_clear_journal_err(sb, es);
1996
1997 if (journal_devnum &&
1998 journal_devnum != le32_to_cpu(es->s_journal_dev)) {
1999 es->s_journal_dev = cpu_to_le32(journal_devnum);
2000 sb->s_dirt = 1;
2001
2002 /* Make sure we flush the recovery flag to disk. */
2003 ext3_commit_super(sb, es, 1);
2004 }
2005
1972 return 0; 2006 return 0;
1973} 2007}
1974 2008
@@ -2116,7 +2150,7 @@ int ext3_force_commit(struct super_block *sb)
2116 2150
2117static void ext3_write_super (struct super_block * sb) 2151static void ext3_write_super (struct super_block * sb)
2118{ 2152{
2119 if (down_trylock(&sb->s_lock) == 0) 2153 if (mutex_trylock(&sb->s_lock) != 0)
2120 BUG(); 2154 BUG();
2121 sb->s_dirt = 0; 2155 sb->s_dirt = 0;
2122} 2156}
@@ -2197,7 +2231,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
2197 /* 2231 /*
2198 * Allow the "check" option to be passed as a remount option. 2232 * Allow the "check" option to be passed as a remount option.
2199 */ 2233 */
2200 if (!parse_options(data, sb, NULL, &n_blocks_count, 1)) { 2234 if (!parse_options(data, sb, NULL, NULL, &n_blocks_count, 1)) {
2201 err = -EINVAL; 2235 err = -EINVAL;
2202 goto restore_opts; 2236 goto restore_opts;
2203 } 2237 }
@@ -2567,7 +2601,7 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type,
2567 struct buffer_head *bh; 2601 struct buffer_head *bh;
2568 handle_t *handle = journal_current_handle(); 2602 handle_t *handle = journal_current_handle();
2569 2603
2570 down(&inode->i_sem); 2604 mutex_lock(&inode->i_mutex);
2571 while (towrite > 0) { 2605 while (towrite > 0) {
2572 tocopy = sb->s_blocksize - offset < towrite ? 2606 tocopy = sb->s_blocksize - offset < towrite ?
2573 sb->s_blocksize - offset : towrite; 2607 sb->s_blocksize - offset : towrite;
@@ -2610,7 +2644,7 @@ out:
2610 inode->i_version++; 2644 inode->i_version++;
2611 inode->i_mtime = inode->i_ctime = CURRENT_TIME; 2645 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
2612 ext3_mark_inode_dirty(handle, inode); 2646 ext3_mark_inode_dirty(handle, inode);
2613 up(&inode->i_sem); 2647 mutex_unlock(&inode->i_mutex);
2614 return len - towrite; 2648 return len - towrite;
2615} 2649}
2616 2650
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 430de9f63be3..e8d60bf6b7df 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -140,7 +140,7 @@ ext3_xattr_handler(int name_index)
140/* 140/*
141 * Inode operation listxattr() 141 * Inode operation listxattr()
142 * 142 *
143 * dentry->d_inode->i_sem: don't care 143 * dentry->d_inode->i_mutex: don't care
144 */ 144 */
145ssize_t 145ssize_t
146ext3_listxattr(struct dentry *dentry, char *buffer, size_t size) 146ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
@@ -946,10 +946,6 @@ ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
946 }; 946 };
947 int error; 947 int error;
948 948
949 if (IS_RDONLY(inode))
950 return -EROFS;
951 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
952 return -EPERM;
953 if (!name) 949 if (!name)
954 return -EINVAL; 950 return -EINVAL;
955 if (strlen(name) > 255) 951 if (strlen(name) > 255)
diff --git a/fs/ext3/xattr_trusted.c b/fs/ext3/xattr_trusted.c
index f68bfd1cf519..86d91f1186dc 100644
--- a/fs/ext3/xattr_trusted.c
+++ b/fs/ext3/xattr_trusted.c
@@ -7,6 +7,7 @@
7 7
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/string.h> 9#include <linux/string.h>
10#include <linux/capability.h>
10#include <linux/fs.h> 11#include <linux/fs.h>
11#include <linux/smp_lock.h> 12#include <linux/smp_lock.h>
12#include <linux/ext3_jbd.h> 13#include <linux/ext3_jbd.h>
@@ -39,8 +40,6 @@ ext3_xattr_trusted_get(struct inode *inode, const char *name,
39{ 40{
40 if (strcmp(name, "") == 0) 41 if (strcmp(name, "") == 0)
41 return -EINVAL; 42 return -EINVAL;
42 if (!capable(CAP_SYS_ADMIN))
43 return -EPERM;
44 return ext3_xattr_get(inode, EXT3_XATTR_INDEX_TRUSTED, name, 43 return ext3_xattr_get(inode, EXT3_XATTR_INDEX_TRUSTED, name,
45 buffer, size); 44 buffer, size);
46} 45}
@@ -51,8 +50,6 @@ ext3_xattr_trusted_set(struct inode *inode, const char *name,
51{ 50{
52 if (strcmp(name, "") == 0) 51 if (strcmp(name, "") == 0)
53 return -EINVAL; 52 return -EINVAL;
54 if (!capable(CAP_SYS_ADMIN))
55 return -EPERM;
56 return ext3_xattr_set(inode, EXT3_XATTR_INDEX_TRUSTED, name, 53 return ext3_xattr_set(inode, EXT3_XATTR_INDEX_TRUSTED, name,
57 value, size, flags); 54 value, size, flags);
58} 55}
diff --git a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c
index e907cae7a07c..a85a0a17c4fd 100644
--- a/fs/ext3/xattr_user.c
+++ b/fs/ext3/xattr_user.c
@@ -37,16 +37,10 @@ static int
37ext3_xattr_user_get(struct inode *inode, const char *name, 37ext3_xattr_user_get(struct inode *inode, const char *name,
38 void *buffer, size_t size) 38 void *buffer, size_t size)
39{ 39{
40 int error;
41
42 if (strcmp(name, "") == 0) 40 if (strcmp(name, "") == 0)
43 return -EINVAL; 41 return -EINVAL;
44 if (!test_opt(inode->i_sb, XATTR_USER)) 42 if (!test_opt(inode->i_sb, XATTR_USER))
45 return -EOPNOTSUPP; 43 return -EOPNOTSUPP;
46 error = permission(inode, MAY_READ, NULL);
47 if (error)
48 return error;
49
50 return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name, buffer, size); 44 return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name, buffer, size);
51} 45}
52 46
@@ -54,19 +48,10 @@ static int
54ext3_xattr_user_set(struct inode *inode, const char *name, 48ext3_xattr_user_set(struct inode *inode, const char *name,
55 const void *value, size_t size, int flags) 49 const void *value, size_t size, int flags)
56{ 50{
57 int error;
58
59 if (strcmp(name, "") == 0) 51 if (strcmp(name, "") == 0)
60 return -EINVAL; 52 return -EINVAL;
61 if (!test_opt(inode->i_sb, XATTR_USER)) 53 if (!test_opt(inode->i_sb, XATTR_USER))
62 return -EOPNOTSUPP; 54 return -EOPNOTSUPP;
63 if ( !S_ISREG(inode->i_mode) &&
64 (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
65 return -EPERM;
66 error = permission(inode, MAY_WRITE, NULL);
67 if (error)
68 return error;
69
70 return ext3_xattr_set(inode, EXT3_XATTR_INDEX_USER, name, 55 return ext3_xattr_set(inode, EXT3_XATTR_INDEX_USER, name,
71 value, size, flags); 56 value, size, flags);
72} 57}