diff options
Diffstat (limited to 'fs/reiserfs')
| -rw-r--r-- | fs/reiserfs/bitmap.c | 3 | ||||
| -rw-r--r-- | fs/reiserfs/inode.c | 26 | ||||
| -rw-r--r-- | fs/reiserfs/ioctl.c | 3 | ||||
| -rw-r--r-- | fs/reiserfs/journal.c | 20 | ||||
| -rw-r--r-- | fs/reiserfs/lock.c | 9 | ||||
| -rw-r--r-- | fs/reiserfs/namei.c | 7 | ||||
| -rw-r--r-- | fs/reiserfs/xattr.c | 38 | ||||
| -rw-r--r-- | fs/reiserfs/xattr_acl.c | 2 |
8 files changed, 87 insertions, 21 deletions
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 685495707181..65c872761177 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c | |||
| @@ -1277,7 +1277,10 @@ int reiserfs_init_bitmap_cache(struct super_block *sb) | |||
| 1277 | struct reiserfs_bitmap_info *bitmap; | 1277 | struct reiserfs_bitmap_info *bitmap; |
| 1278 | unsigned int bmap_nr = reiserfs_bmap_count(sb); | 1278 | unsigned int bmap_nr = reiserfs_bmap_count(sb); |
| 1279 | 1279 | ||
| 1280 | /* Avoid lock recursion in fault case */ | ||
| 1281 | reiserfs_write_unlock(sb); | ||
| 1280 | bitmap = vmalloc(sizeof(*bitmap) * bmap_nr); | 1282 | bitmap = vmalloc(sizeof(*bitmap) * bmap_nr); |
| 1283 | reiserfs_write_lock(sb); | ||
| 1281 | if (bitmap == NULL) | 1284 | if (bitmap == NULL) |
| 1282 | return -ENOMEM; | 1285 | return -ENOMEM; |
| 1283 | 1286 | ||
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 290ae38fca8a..2df0f5c7c60b 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
| @@ -31,11 +31,12 @@ void reiserfs_delete_inode(struct inode *inode) | |||
| 31 | JOURNAL_PER_BALANCE_CNT * 2 + | 31 | JOURNAL_PER_BALANCE_CNT * 2 + |
| 32 | 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb); | 32 | 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb); |
| 33 | struct reiserfs_transaction_handle th; | 33 | struct reiserfs_transaction_handle th; |
| 34 | int depth; | ||
| 34 | int err; | 35 | int err; |
| 35 | 36 | ||
| 36 | truncate_inode_pages(&inode->i_data, 0); | 37 | truncate_inode_pages(&inode->i_data, 0); |
| 37 | 38 | ||
| 38 | reiserfs_write_lock(inode->i_sb); | 39 | depth = reiserfs_write_lock_once(inode->i_sb); |
| 39 | 40 | ||
| 40 | /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ | 41 | /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ |
| 41 | if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ | 42 | if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ |
| @@ -74,7 +75,7 @@ void reiserfs_delete_inode(struct inode *inode) | |||
| 74 | out: | 75 | out: |
| 75 | clear_inode(inode); /* note this must go after the journal_end to prevent deadlock */ | 76 | clear_inode(inode); /* note this must go after the journal_end to prevent deadlock */ |
| 76 | inode->i_blocks = 0; | 77 | inode->i_blocks = 0; |
| 77 | reiserfs_write_unlock(inode->i_sb); | 78 | reiserfs_write_unlock_once(inode->i_sb, depth); |
| 78 | } | 79 | } |
| 79 | 80 | ||
| 80 | static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid, | 81 | static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid, |
| @@ -1496,9 +1497,11 @@ struct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key) | |||
| 1496 | 1497 | ||
| 1497 | args.objectid = key->on_disk_key.k_objectid; | 1498 | args.objectid = key->on_disk_key.k_objectid; |
| 1498 | args.dirid = key->on_disk_key.k_dir_id; | 1499 | args.dirid = key->on_disk_key.k_dir_id; |
| 1500 | reiserfs_write_unlock(s); | ||
| 1499 | inode = iget5_locked(s, key->on_disk_key.k_objectid, | 1501 | inode = iget5_locked(s, key->on_disk_key.k_objectid, |
| 1500 | reiserfs_find_actor, reiserfs_init_locked_inode, | 1502 | reiserfs_find_actor, reiserfs_init_locked_inode, |
| 1501 | (void *)(&args)); | 1503 | (void *)(&args)); |
| 1504 | reiserfs_write_lock(s); | ||
| 1502 | if (!inode) | 1505 | if (!inode) |
| 1503 | return ERR_PTR(-ENOMEM); | 1506 | return ERR_PTR(-ENOMEM); |
| 1504 | 1507 | ||
| @@ -3061,13 +3064,14 @@ static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb, | |||
| 3061 | int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | 3064 | int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) |
| 3062 | { | 3065 | { |
| 3063 | struct inode *inode = dentry->d_inode; | 3066 | struct inode *inode = dentry->d_inode; |
| 3064 | int error; | ||
| 3065 | unsigned int ia_valid; | 3067 | unsigned int ia_valid; |
| 3068 | int depth; | ||
| 3069 | int error; | ||
| 3066 | 3070 | ||
| 3067 | /* must be turned off for recursive notify_change calls */ | 3071 | /* must be turned off for recursive notify_change calls */ |
| 3068 | ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); | 3072 | ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); |
| 3069 | 3073 | ||
| 3070 | reiserfs_write_lock(inode->i_sb); | 3074 | depth = reiserfs_write_lock_once(inode->i_sb); |
| 3071 | if (attr->ia_valid & ATTR_SIZE) { | 3075 | if (attr->ia_valid & ATTR_SIZE) { |
| 3072 | /* version 2 items will be caught by the s_maxbytes check | 3076 | /* version 2 items will be caught by the s_maxbytes check |
| 3073 | ** done for us in vmtruncate | 3077 | ** done for us in vmtruncate |
| @@ -3148,8 +3152,17 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 3148 | journal_end(&th, inode->i_sb, jbegin_count); | 3152 | journal_end(&th, inode->i_sb, jbegin_count); |
| 3149 | } | 3153 | } |
| 3150 | } | 3154 | } |
| 3151 | if (!error) | 3155 | if (!error) { |
| 3156 | /* | ||
| 3157 | * Relax the lock here, as it might truncate the | ||
| 3158 | * inode pages and wait for inode pages locks. | ||
| 3159 | * To release such page lock, the owner needs the | ||
| 3160 | * reiserfs lock | ||
| 3161 | */ | ||
| 3162 | reiserfs_write_unlock_once(inode->i_sb, depth); | ||
| 3152 | error = inode_setattr(inode, attr); | 3163 | error = inode_setattr(inode, attr); |
| 3164 | depth = reiserfs_write_lock_once(inode->i_sb); | ||
| 3165 | } | ||
| 3153 | } | 3166 | } |
| 3154 | 3167 | ||
| 3155 | if (!error && reiserfs_posixacl(inode->i_sb)) { | 3168 | if (!error && reiserfs_posixacl(inode->i_sb)) { |
| @@ -3158,7 +3171,8 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 3158 | } | 3171 | } |
| 3159 | 3172 | ||
| 3160 | out: | 3173 | out: |
| 3161 | reiserfs_write_unlock(inode->i_sb); | 3174 | reiserfs_write_unlock_once(inode->i_sb, depth); |
| 3175 | |||
| 3162 | return error; | 3176 | return error; |
| 3163 | } | 3177 | } |
| 3164 | 3178 | ||
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index ace77451ceb1..f53505de0712 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c | |||
| @@ -104,9 +104,10 @@ setflags_out: | |||
| 104 | err = put_user(inode->i_generation, (int __user *)arg); | 104 | err = put_user(inode->i_generation, (int __user *)arg); |
| 105 | break; | 105 | break; |
| 106 | case REISERFS_IOC_SETVERSION: | 106 | case REISERFS_IOC_SETVERSION: |
| 107 | if (!is_owner_or_cap(inode)) | 107 | if (!is_owner_or_cap(inode)) { |
| 108 | err = -EPERM; | 108 | err = -EPERM; |
| 109 | break; | 109 | break; |
| 110 | } | ||
| 110 | err = mnt_want_write(filp->f_path.mnt); | 111 | err = mnt_want_write(filp->f_path.mnt); |
| 111 | if (err) | 112 | if (err) |
| 112 | break; | 113 | break; |
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 2f8a7e7b8dab..ba98546fabbd 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
| @@ -2009,10 +2009,11 @@ static int do_journal_release(struct reiserfs_transaction_handle *th, | |||
| 2009 | destroy_workqueue(commit_wq); | 2009 | destroy_workqueue(commit_wq); |
| 2010 | commit_wq = NULL; | 2010 | commit_wq = NULL; |
| 2011 | } | 2011 | } |
| 2012 | reiserfs_write_lock(sb); | ||
| 2013 | 2012 | ||
| 2014 | free_journal_ram(sb); | 2013 | free_journal_ram(sb); |
| 2015 | 2014 | ||
| 2015 | reiserfs_write_lock(sb); | ||
| 2016 | |||
| 2016 | return 0; | 2017 | return 0; |
| 2017 | } | 2018 | } |
| 2018 | 2019 | ||
| @@ -2758,11 +2759,18 @@ int journal_init(struct super_block *sb, const char *j_dev_name, | |||
| 2758 | struct reiserfs_journal *journal; | 2759 | struct reiserfs_journal *journal; |
| 2759 | struct reiserfs_journal_list *jl; | 2760 | struct reiserfs_journal_list *jl; |
| 2760 | char b[BDEVNAME_SIZE]; | 2761 | char b[BDEVNAME_SIZE]; |
| 2762 | int ret; | ||
| 2761 | 2763 | ||
| 2764 | /* | ||
| 2765 | * Unlock here to avoid various RECLAIM-FS-ON <-> IN-RECLAIM-FS | ||
| 2766 | * dependency inversion warnings. | ||
| 2767 | */ | ||
| 2768 | reiserfs_write_unlock(sb); | ||
| 2762 | journal = SB_JOURNAL(sb) = vmalloc(sizeof(struct reiserfs_journal)); | 2769 | journal = SB_JOURNAL(sb) = vmalloc(sizeof(struct reiserfs_journal)); |
| 2763 | if (!journal) { | 2770 | if (!journal) { |
| 2764 | reiserfs_warning(sb, "journal-1256", | 2771 | reiserfs_warning(sb, "journal-1256", |
| 2765 | "unable to get memory for journal structure"); | 2772 | "unable to get memory for journal structure"); |
| 2773 | reiserfs_write_lock(sb); | ||
| 2766 | return 1; | 2774 | return 1; |
| 2767 | } | 2775 | } |
| 2768 | memset(journal, 0, sizeof(struct reiserfs_journal)); | 2776 | memset(journal, 0, sizeof(struct reiserfs_journal)); |
| @@ -2771,10 +2779,12 @@ int journal_init(struct super_block *sb, const char *j_dev_name, | |||
| 2771 | INIT_LIST_HEAD(&journal->j_working_list); | 2779 | INIT_LIST_HEAD(&journal->j_working_list); |
| 2772 | INIT_LIST_HEAD(&journal->j_journal_list); | 2780 | INIT_LIST_HEAD(&journal->j_journal_list); |
| 2773 | journal->j_persistent_trans = 0; | 2781 | journal->j_persistent_trans = 0; |
| 2774 | if (reiserfs_allocate_list_bitmaps(sb, | 2782 | ret = reiserfs_allocate_list_bitmaps(sb, journal->j_list_bitmap, |
| 2775 | journal->j_list_bitmap, | 2783 | reiserfs_bmap_count(sb)); |
| 2776 | reiserfs_bmap_count(sb))) | 2784 | reiserfs_write_lock(sb); |
| 2785 | if (ret) | ||
| 2777 | goto free_and_return; | 2786 | goto free_and_return; |
| 2787 | |||
| 2778 | allocate_bitmap_nodes(sb); | 2788 | allocate_bitmap_nodes(sb); |
| 2779 | 2789 | ||
| 2780 | /* reserved for journal area support */ | 2790 | /* reserved for journal area support */ |
| @@ -2903,7 +2913,9 @@ int journal_init(struct super_block *sb, const char *j_dev_name, | |||
| 2903 | journal->j_mount_id = 10; | 2913 | journal->j_mount_id = 10; |
| 2904 | journal->j_state = 0; | 2914 | journal->j_state = 0; |
| 2905 | atomic_set(&(journal->j_jlock), 0); | 2915 | atomic_set(&(journal->j_jlock), 0); |
| 2916 | reiserfs_write_unlock(sb); | ||
| 2906 | journal->j_cnode_free_list = allocate_cnodes(num_cnodes); | 2917 | journal->j_cnode_free_list = allocate_cnodes(num_cnodes); |
| 2918 | reiserfs_write_lock(sb); | ||
| 2907 | journal->j_cnode_free_orig = journal->j_cnode_free_list; | 2919 | journal->j_cnode_free_orig = journal->j_cnode_free_list; |
| 2908 | journal->j_cnode_free = journal->j_cnode_free_list ? num_cnodes : 0; | 2920 | journal->j_cnode_free = journal->j_cnode_free_list ? num_cnodes : 0; |
| 2909 | journal->j_cnode_used = 0; | 2921 | journal->j_cnode_used = 0; |
diff --git a/fs/reiserfs/lock.c b/fs/reiserfs/lock.c index ee2cfc0fd8a7..b87aa2c1afc1 100644 --- a/fs/reiserfs/lock.c +++ b/fs/reiserfs/lock.c | |||
| @@ -86,3 +86,12 @@ void reiserfs_check_lock_depth(struct super_block *sb, char *caller) | |||
| 86 | reiserfs_panic(sb, "%s called without kernel lock held %d", | 86 | reiserfs_panic(sb, "%s called without kernel lock held %d", |
| 87 | caller); | 87 | caller); |
| 88 | } | 88 | } |
| 89 | |||
| 90 | #ifdef CONFIG_REISERFS_CHECK | ||
| 91 | void reiserfs_lock_check_recursive(struct super_block *sb) | ||
| 92 | { | ||
| 93 | struct reiserfs_sb_info *sb_i = REISERFS_SB(sb); | ||
| 94 | |||
| 95 | WARN_ONCE((sb_i->lock_depth > 0), "Unwanted recursive reiserfs lock!\n"); | ||
| 96 | } | ||
| 97 | #endif | ||
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index e296ff72a6cc..9d4dcf0b07cb 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
| @@ -921,6 +921,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 921 | struct reiserfs_transaction_handle th; | 921 | struct reiserfs_transaction_handle th; |
| 922 | int jbegin_count; | 922 | int jbegin_count; |
| 923 | unsigned long savelink; | 923 | unsigned long savelink; |
| 924 | int depth; | ||
| 924 | 925 | ||
| 925 | inode = dentry->d_inode; | 926 | inode = dentry->d_inode; |
| 926 | 927 | ||
| @@ -932,7 +933,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 932 | JOURNAL_PER_BALANCE_CNT * 2 + 2 + | 933 | JOURNAL_PER_BALANCE_CNT * 2 + 2 + |
| 933 | 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); | 934 | 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); |
| 934 | 935 | ||
| 935 | reiserfs_write_lock(dir->i_sb); | 936 | depth = reiserfs_write_lock_once(dir->i_sb); |
| 936 | retval = journal_begin(&th, dir->i_sb, jbegin_count); | 937 | retval = journal_begin(&th, dir->i_sb, jbegin_count); |
| 937 | if (retval) | 938 | if (retval) |
| 938 | goto out_unlink; | 939 | goto out_unlink; |
| @@ -993,7 +994,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 993 | 994 | ||
| 994 | retval = journal_end(&th, dir->i_sb, jbegin_count); | 995 | retval = journal_end(&th, dir->i_sb, jbegin_count); |
| 995 | reiserfs_check_path(&path); | 996 | reiserfs_check_path(&path); |
| 996 | reiserfs_write_unlock(dir->i_sb); | 997 | reiserfs_write_unlock_once(dir->i_sb, depth); |
| 997 | return retval; | 998 | return retval; |
| 998 | 999 | ||
| 999 | end_unlink: | 1000 | end_unlink: |
| @@ -1003,7 +1004,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 1003 | if (err) | 1004 | if (err) |
| 1004 | retval = err; | 1005 | retval = err; |
| 1005 | out_unlink: | 1006 | out_unlink: |
| 1006 | reiserfs_write_unlock(dir->i_sb); | 1007 | reiserfs_write_unlock_once(dir->i_sb, depth); |
| 1007 | return retval; | 1008 | return retval; |
| 1008 | } | 1009 | } |
| 1009 | 1010 | ||
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 8c7033a8b67e..81f09fab8ae4 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
| @@ -83,7 +83,8 @@ static int xattr_unlink(struct inode *dir, struct dentry *dentry) | |||
| 83 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); | 83 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); |
| 84 | vfs_dq_init(dir); | 84 | vfs_dq_init(dir); |
| 85 | 85 | ||
| 86 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); | 86 | reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex, |
| 87 | I_MUTEX_CHILD, dir->i_sb); | ||
| 87 | error = dir->i_op->unlink(dir, dentry); | 88 | error = dir->i_op->unlink(dir, dentry); |
| 88 | mutex_unlock(&dentry->d_inode->i_mutex); | 89 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 89 | 90 | ||
| @@ -98,7 +99,8 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 98 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); | 99 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); |
| 99 | vfs_dq_init(dir); | 100 | vfs_dq_init(dir); |
| 100 | 101 | ||
| 101 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); | 102 | reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex, |
| 103 | I_MUTEX_CHILD, dir->i_sb); | ||
| 102 | dentry_unhash(dentry); | 104 | dentry_unhash(dentry); |
| 103 | error = dir->i_op->rmdir(dir, dentry); | 105 | error = dir->i_op->rmdir(dir, dentry); |
| 104 | if (!error) | 106 | if (!error) |
| @@ -235,16 +237,22 @@ static int reiserfs_for_each_xattr(struct inode *inode, | |||
| 235 | if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) | 237 | if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) |
| 236 | return 0; | 238 | return 0; |
| 237 | 239 | ||
| 240 | reiserfs_write_unlock(inode->i_sb); | ||
| 238 | dir = open_xa_dir(inode, XATTR_REPLACE); | 241 | dir = open_xa_dir(inode, XATTR_REPLACE); |
| 239 | if (IS_ERR(dir)) { | 242 | if (IS_ERR(dir)) { |
| 240 | err = PTR_ERR(dir); | 243 | err = PTR_ERR(dir); |
| 244 | reiserfs_write_lock(inode->i_sb); | ||
| 241 | goto out; | 245 | goto out; |
| 242 | } else if (!dir->d_inode) { | 246 | } else if (!dir->d_inode) { |
| 243 | err = 0; | 247 | err = 0; |
| 248 | reiserfs_write_lock(inode->i_sb); | ||
| 244 | goto out_dir; | 249 | goto out_dir; |
| 245 | } | 250 | } |
| 246 | 251 | ||
| 247 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); | 252 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); |
| 253 | |||
| 254 | reiserfs_write_lock(inode->i_sb); | ||
| 255 | |||
| 248 | buf.xadir = dir; | 256 | buf.xadir = dir; |
| 249 | err = reiserfs_readdir_dentry(dir, &buf, fill_with_dentries, &pos); | 257 | err = reiserfs_readdir_dentry(dir, &buf, fill_with_dentries, &pos); |
| 250 | while ((err == 0 || err == -ENOSPC) && buf.count) { | 258 | while ((err == 0 || err == -ENOSPC) && buf.count) { |
| @@ -283,8 +291,9 @@ static int reiserfs_for_each_xattr(struct inode *inode, | |||
| 283 | err = journal_begin(&th, inode->i_sb, blocks); | 291 | err = journal_begin(&th, inode->i_sb, blocks); |
| 284 | if (!err) { | 292 | if (!err) { |
| 285 | int jerror; | 293 | int jerror; |
| 286 | mutex_lock_nested(&dir->d_parent->d_inode->i_mutex, | 294 | reiserfs_mutex_lock_nested_safe( |
| 287 | I_MUTEX_XATTR); | 295 | &dir->d_parent->d_inode->i_mutex, |
| 296 | I_MUTEX_XATTR, inode->i_sb); | ||
| 288 | err = action(dir, data); | 297 | err = action(dir, data); |
| 289 | jerror = journal_end(&th, inode->i_sb, blocks); | 298 | jerror = journal_end(&th, inode->i_sb, blocks); |
| 290 | mutex_unlock(&dir->d_parent->d_inode->i_mutex); | 299 | mutex_unlock(&dir->d_parent->d_inode->i_mutex); |
| @@ -443,7 +452,9 @@ static int lookup_and_delete_xattr(struct inode *inode, const char *name) | |||
| 443 | } | 452 | } |
| 444 | 453 | ||
| 445 | if (dentry->d_inode) { | 454 | if (dentry->d_inode) { |
| 455 | reiserfs_write_lock(inode->i_sb); | ||
| 446 | err = xattr_unlink(xadir->d_inode, dentry); | 456 | err = xattr_unlink(xadir->d_inode, dentry); |
| 457 | reiserfs_write_unlock(inode->i_sb); | ||
| 447 | update_ctime(inode); | 458 | update_ctime(inode); |
| 448 | } | 459 | } |
| 449 | 460 | ||
| @@ -477,15 +488,24 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, | |||
| 477 | if (get_inode_sd_version(inode) == STAT_DATA_V1) | 488 | if (get_inode_sd_version(inode) == STAT_DATA_V1) |
| 478 | return -EOPNOTSUPP; | 489 | return -EOPNOTSUPP; |
| 479 | 490 | ||
| 480 | if (!buffer) | 491 | reiserfs_write_unlock(inode->i_sb); |
| 481 | return lookup_and_delete_xattr(inode, name); | 492 | |
| 493 | if (!buffer) { | ||
| 494 | err = lookup_and_delete_xattr(inode, name); | ||
| 495 | reiserfs_write_lock(inode->i_sb); | ||
| 496 | return err; | ||
| 497 | } | ||
| 482 | 498 | ||
| 483 | dentry = xattr_lookup(inode, name, flags); | 499 | dentry = xattr_lookup(inode, name, flags); |
| 484 | if (IS_ERR(dentry)) | 500 | if (IS_ERR(dentry)) { |
| 501 | reiserfs_write_lock(inode->i_sb); | ||
| 485 | return PTR_ERR(dentry); | 502 | return PTR_ERR(dentry); |
| 503 | } | ||
| 486 | 504 | ||
| 487 | down_write(&REISERFS_I(inode)->i_xattr_sem); | 505 | down_write(&REISERFS_I(inode)->i_xattr_sem); |
| 488 | 506 | ||
| 507 | reiserfs_write_lock(inode->i_sb); | ||
| 508 | |||
| 489 | xahash = xattr_hash(buffer, buffer_size); | 509 | xahash = xattr_hash(buffer, buffer_size); |
| 490 | while (buffer_pos < buffer_size || buffer_pos == 0) { | 510 | while (buffer_pos < buffer_size || buffer_pos == 0) { |
| 491 | size_t chunk; | 511 | size_t chunk; |
| @@ -540,8 +560,12 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, | |||
| 540 | .ia_size = buffer_size, | 560 | .ia_size = buffer_size, |
| 541 | .ia_valid = ATTR_SIZE | ATTR_CTIME, | 561 | .ia_valid = ATTR_SIZE | ATTR_CTIME, |
| 542 | }; | 562 | }; |
| 563 | |||
| 564 | reiserfs_write_unlock(inode->i_sb); | ||
| 543 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); | 565 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); |
| 544 | down_write(&dentry->d_inode->i_alloc_sem); | 566 | down_write(&dentry->d_inode->i_alloc_sem); |
| 567 | reiserfs_write_lock(inode->i_sb); | ||
| 568 | |||
| 545 | err = reiserfs_setattr(dentry, &newattrs); | 569 | err = reiserfs_setattr(dentry, &newattrs); |
| 546 | up_write(&dentry->d_inode->i_alloc_sem); | 570 | up_write(&dentry->d_inode->i_alloc_sem); |
| 547 | mutex_unlock(&dentry->d_inode->i_mutex); | 571 | mutex_unlock(&dentry->d_inode->i_mutex); |
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index cc32e6ada67b..dd20a7883f0f 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c | |||
| @@ -455,7 +455,9 @@ int reiserfs_acl_chmod(struct inode *inode) | |||
| 455 | return 0; | 455 | return 0; |
| 456 | } | 456 | } |
| 457 | 457 | ||
| 458 | reiserfs_write_unlock(inode->i_sb); | ||
| 458 | acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); | 459 | acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); |
| 460 | reiserfs_write_lock(inode->i_sb); | ||
| 459 | if (!acl) | 461 | if (!acl) |
| 460 | return 0; | 462 | return 0; |
| 461 | if (IS_ERR(acl)) | 463 | if (IS_ERR(acl)) |
