reiserfs: Relax lock before open xattr dir in reiserfs_xattr_set_handle()
[deliverable/linux.git] / fs / reiserfs / xattr.c
index 6925b835a43b6f2f94e8a4217180b2e8d1735ab7..78a3f246295c04541db0589c1eba4c2aea88f6ed 100644 (file)
@@ -234,16 +234,22 @@ static int reiserfs_for_each_xattr(struct inode *inode,
        if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1)
                return 0;
 
+       reiserfs_write_unlock(inode->i_sb);
        dir = open_xa_dir(inode, XATTR_REPLACE);
        if (IS_ERR(dir)) {
                err = PTR_ERR(dir);
+               reiserfs_write_lock(inode->i_sb);
                goto out;
        } else if (!dir->d_inode) {
                err = 0;
+               reiserfs_write_lock(inode->i_sb);
                goto out_dir;
        }
 
        mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR);
+
+       reiserfs_write_lock(inode->i_sb);
+
        buf.xadir = dir;
        err = reiserfs_readdir_dentry(dir, &buf, fill_with_dentries, &pos);
        while ((err == 0 || err == -ENOSPC) && buf.count) {
@@ -479,11 +485,16 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th,
        if (!buffer)
                return lookup_and_delete_xattr(inode, name);
 
+       reiserfs_write_unlock(inode->i_sb);
        dentry = xattr_lookup(inode, name, flags);
-       if (IS_ERR(dentry))
+       if (IS_ERR(dentry)) {
+               reiserfs_write_lock(inode->i_sb);
                return PTR_ERR(dentry);
+       }
 
-       down_write(&REISERFS_I(inode)->i_xattr_sem);
+       down_read(&REISERFS_I(inode)->i_xattr_sem);
+
+       reiserfs_write_lock(inode->i_sb);
 
        xahash = xattr_hash(buffer, buffer_size);
        while (buffer_pos < buffer_size || buffer_pos == 0) {
@@ -975,7 +986,7 @@ int reiserfs_lookup_privroot(struct super_block *s)
        int err = 0;
 
        /* If we don't have the privroot located yet - go find it */
-       mutex_lock(&s->s_root->d_inode->i_mutex);
+       reiserfs_mutex_lock_safe(&s->s_root->d_inode->i_mutex, s);
        dentry = lookup_one_len(PRIVROOT_NAME, s->s_root,
                                strlen(PRIVROOT_NAME));
        if (!IS_ERR(dentry)) {
@@ -1004,14 +1015,14 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags)
                goto error;
 
        if (!privroot->d_inode && !(mount_flags & MS_RDONLY)) {
-               mutex_lock(&s->s_root->d_inode->i_mutex);
+               reiserfs_mutex_lock_safe(&s->s_root->d_inode->i_mutex, s);
                err = create_privroot(REISERFS_SB(s)->priv_root);
                mutex_unlock(&s->s_root->d_inode->i_mutex);
        }
 
        if (privroot->d_inode) {
                s->s_xattr = reiserfs_xattr_handlers;
-               mutex_lock(&privroot->d_inode->i_mutex);
+               reiserfs_mutex_lock_safe(&privroot->d_inode->i_mutex, s);
                if (!REISERFS_SB(s)->xattr_root) {
                        struct dentry *dentry;
                        dentry = lookup_one_len(XAROOT_NAME, privroot,
This page took 0.025943 seconds and 5 git commands to generate.