]> Pileus Git - ~andy/linux/blobdiff - fs/reiserfs/inode.c
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
[~andy/linux] / fs / reiserfs / inode.c
index 0048cc16a6a8c5e6d54ebd1d9dd16f29f1d310ea..ad62bdbb451ee77f1cfcee9be8cae70537168667 100644 (file)
@@ -30,7 +30,6 @@ void reiserfs_evict_inode(struct inode *inode)
            JOURNAL_PER_BALANCE_CNT * 2 +
            2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb);
        struct reiserfs_transaction_handle th;
-       int depth;
        int err;
 
        if (!inode->i_nlink && !is_bad_inode(inode))
@@ -40,12 +39,13 @@ void reiserfs_evict_inode(struct inode *inode)
        if (inode->i_nlink)
                goto no_delete;
 
-       depth = reiserfs_write_lock_once(inode->i_sb);
-
        /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */
        if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) {  /* also handles bad_inode case */
+
                reiserfs_delete_xattrs(inode);
 
+               reiserfs_write_lock(inode->i_sb);
+
                if (journal_begin(&th, inode->i_sb, jbegin_count))
                        goto out;
                reiserfs_update_inode_transaction(inode);
@@ -57,8 +57,11 @@ void reiserfs_evict_inode(struct inode *inode)
                /* Do quota update inside a transaction for journaled quotas. We must do that
                 * after delete_object so that quota updates go into the same transaction as
                 * stat data deletion */
-               if (!err) 
+               if (!err) {
+                       int depth = reiserfs_write_unlock_nested(inode->i_sb);
                        dquot_free_inode(inode);
+                       reiserfs_write_lock_nested(inode->i_sb, depth);
+               }
 
                if (journal_end(&th, inode->i_sb, jbegin_count))
                        goto out;
@@ -72,12 +75,12 @@ void reiserfs_evict_inode(struct inode *inode)
                /* all items of file are deleted, so we can remove "save" link */
                remove_save_link(inode, 0 /* not truncate */ ); /* we can't do anything
                                                                 * about an error here */
+out:
+               reiserfs_write_unlock(inode->i_sb);
        } else {
                /* no object items are in the tree */
                ;
        }
-      out:
-       reiserfs_write_unlock_once(inode->i_sb, depth);
        clear_inode(inode);     /* note this must go after the journal_end to prevent deadlock */
        dquot_drop(inode);
        inode->i_blocks = 0;
@@ -610,7 +613,6 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
        __le32 *item;
        int done;
        int fs_gen;
-       int lock_depth;
        struct reiserfs_transaction_handle *th = NULL;
        /* space reserved in transaction batch:
           . 3 balancings in direct->indirect conversion
@@ -626,11 +628,11 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
        loff_t new_offset =
            (((loff_t) block) << inode->i_sb->s_blocksize_bits) + 1;
 
-       lock_depth = reiserfs_write_lock_once(inode->i_sb);
+       reiserfs_write_lock(inode->i_sb);
        version = get_inode_item_key_version(inode);
 
        if (!file_capable(inode, block)) {
-               reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+               reiserfs_write_unlock(inode->i_sb);
                return -EFBIG;
        }
 
@@ -642,7 +644,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
                /* find number of block-th logical block of the file */
                ret = _get_block_create_0(inode, block, bh_result,
                                          create | GET_BLOCK_READ_DIRECT);
-               reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+               reiserfs_write_unlock(inode->i_sb);
                return ret;
        }
        /*
@@ -760,7 +762,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
                if (!dangle && th)
                        retval = reiserfs_end_persistent_transaction(th);
 
-               reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+               reiserfs_write_unlock(inode->i_sb);
 
                /* the item was found, so new blocks were not added to the file
                 ** there is no need to make sure the inode is updated with this
@@ -1011,11 +1013,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
                 * long time.  reschedule if needed and also release the write
                 * lock for others.
                 */
-               if (need_resched()) {
-                       reiserfs_write_unlock_once(inode->i_sb, lock_depth);
-                       schedule();
-                       lock_depth = reiserfs_write_lock_once(inode->i_sb);
-               }
+               reiserfs_cond_resched(inode->i_sb);
 
                retval = search_for_position_by_key(inode->i_sb, &key, &path);
                if (retval == IO_ERROR) {
@@ -1050,7 +1048,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
                        retval = err;
        }
 
-       reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+       reiserfs_write_unlock(inode->i_sb);
        reiserfs_check_path(&path);
        return retval;
 }
@@ -1509,14 +1507,15 @@ struct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key)
 {
        struct inode *inode;
        struct reiserfs_iget_args args;
+       int depth;
 
        args.objectid = key->on_disk_key.k_objectid;
        args.dirid = key->on_disk_key.k_dir_id;
-       reiserfs_write_unlock(s);
+       depth = reiserfs_write_unlock_nested(s);
        inode = iget5_locked(s, key->on_disk_key.k_objectid,
                             reiserfs_find_actor, reiserfs_init_locked_inode,
                             (void *)(&args));
-       reiserfs_write_lock(s);
+       reiserfs_write_lock_nested(s, depth);
        if (!inode)
                return ERR_PTR(-ENOMEM);
 
@@ -1772,7 +1771,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
                       struct inode *inode,
                       struct reiserfs_security_handle *security)
 {
-       struct super_block *sb;
+       struct super_block *sb = dir->i_sb;
        struct reiserfs_iget_args args;
        INITIALIZE_PATH(path_to_key);
        struct cpu_key key;
@@ -1780,12 +1779,13 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
        struct stat_data sd;
        int retval;
        int err;
+       int depth;
 
        BUG_ON(!th->t_trans_id);
 
-       reiserfs_write_unlock(inode->i_sb);
+       depth = reiserfs_write_unlock_nested(sb);
        err = dquot_alloc_inode(inode);
-       reiserfs_write_lock(inode->i_sb);
+       reiserfs_write_lock_nested(sb, depth);
        if (err)
                goto out_end_trans;
        if (!dir->i_nlink) {
@@ -1793,8 +1793,6 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
                goto out_bad_inode;
        }
 
-       sb = dir->i_sb;
-
        /* item head of new item */
        ih.ih_key.k_dir_id = reiserfs_choose_packing(dir);
        ih.ih_key.k_objectid = cpu_to_le32(reiserfs_get_unused_objectid(th));
@@ -1812,10 +1810,10 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
        memcpy(INODE_PKEY(inode), &(ih.ih_key), KEY_SIZE);
        args.dirid = le32_to_cpu(ih.ih_key.k_dir_id);
 
-       reiserfs_write_unlock(inode->i_sb);
+       depth = reiserfs_write_unlock_nested(inode->i_sb);
        err = insert_inode_locked4(inode, args.objectid,
                             reiserfs_find_actor, &args);
-       reiserfs_write_lock(inode->i_sb);
+       reiserfs_write_lock_nested(inode->i_sb, depth);
        if (err) {
                err = -EINVAL;
                goto out_bad_inode;
@@ -1941,7 +1939,9 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
        }
 
        if (reiserfs_posixacl(inode->i_sb)) {
+               reiserfs_write_unlock(inode->i_sb);
                retval = reiserfs_inherit_default_acl(th, dir, dentry, inode);
+               reiserfs_write_lock(inode->i_sb);
                if (retval) {
                        err = retval;
                        reiserfs_check_path(&path_to_key);
@@ -1956,7 +1956,9 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
                inode->i_flags |= S_PRIVATE;
 
        if (security->name) {
+               reiserfs_write_unlock(inode->i_sb);
                retval = reiserfs_security_write(th, inode, security);
+               reiserfs_write_lock(inode->i_sb);
                if (retval) {
                        err = retval;
                        reiserfs_check_path(&path_to_key);
@@ -1982,14 +1984,16 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
        INODE_PKEY(inode)->k_objectid = 0;
 
        /* Quota change must be inside a transaction for journaling */
+       depth = reiserfs_write_unlock_nested(inode->i_sb);
        dquot_free_inode(inode);
+       reiserfs_write_lock_nested(inode->i_sb, depth);
 
       out_end_trans:
        journal_end(th, th->t_super, th->t_blocks_allocated);
-       reiserfs_write_unlock(inode->i_sb);
        /* Drop can be outside and it needs more credits so it's better to have it outside */
+       depth = reiserfs_write_unlock_nested(inode->i_sb);
        dquot_drop(inode);
-       reiserfs_write_lock(inode->i_sb);
+       reiserfs_write_lock_nested(inode->i_sb, depth);
        inode->i_flags |= S_NOQUOTA;
        make_bad_inode(inode);
 
@@ -2103,9 +2107,8 @@ int reiserfs_truncate_file(struct inode *inode, int update_timestamps)
        int error;
        struct buffer_head *bh = NULL;
        int err2;
-       int lock_depth;
 
-       lock_depth = reiserfs_write_lock_once(inode->i_sb);
+       reiserfs_write_lock(inode->i_sb);
 
        if (inode->i_size > 0) {
                error = grab_tail_page(inode, &page, &bh);
@@ -2174,7 +2177,7 @@ int reiserfs_truncate_file(struct inode *inode, int update_timestamps)
                page_cache_release(page);
        }
 
-       reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+       reiserfs_write_unlock(inode->i_sb);
 
        return 0;
       out:
@@ -2183,7 +2186,7 @@ int reiserfs_truncate_file(struct inode *inode, int update_timestamps)
                page_cache_release(page);
        }
 
-       reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+       reiserfs_write_unlock(inode->i_sb);
 
        return error;
 }
@@ -2648,10 +2651,11 @@ int __reiserfs_write_begin(struct page *page, unsigned from, unsigned len)
        struct inode *inode = page->mapping->host;
        int ret;
        int old_ref = 0;
+       int depth;
 
-       reiserfs_write_unlock(inode->i_sb);
+       depth = reiserfs_write_unlock_nested(inode->i_sb);
        reiserfs_wait_on_write_block(inode->i_sb);
-       reiserfs_write_lock(inode->i_sb);
+       reiserfs_write_lock_nested(inode->i_sb, depth);
 
        fix_tail_page_for_writing(page);
        if (reiserfs_transaction_running(inode->i_sb)) {
@@ -2708,7 +2712,6 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
        int update_sd = 0;
        struct reiserfs_transaction_handle *th;
        unsigned start;
-       int lock_depth = 0;
        bool locked = false;
 
        if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND)
@@ -2737,7 +2740,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
         */
        if (pos + copied > inode->i_size) {
                struct reiserfs_transaction_handle myth;
-               lock_depth = reiserfs_write_lock_once(inode->i_sb);
+               reiserfs_write_lock(inode->i_sb);
                locked = true;
                /* If the file have grown beyond the border where it
                   can have a tail, unmark it as needing a tail
@@ -2768,7 +2771,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
        }
        if (th) {
                if (!locked) {
-                       lock_depth = reiserfs_write_lock_once(inode->i_sb);
+                       reiserfs_write_lock(inode->i_sb);
                        locked = true;
                }
                if (!update_sd)
@@ -2780,7 +2783,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
 
       out:
        if (locked)
-               reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+               reiserfs_write_unlock(inode->i_sb);
        unlock_page(page);
        page_cache_release(page);
 
@@ -2790,7 +2793,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
        return ret == 0 ? copied : ret;
 
       journal_error:
-       reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+       reiserfs_write_unlock(inode->i_sb);
        locked = false;
        if (th) {
                if (!update_sd)
@@ -2808,10 +2811,11 @@ int reiserfs_commit_write(struct file *f, struct page *page,
        int ret = 0;
        int update_sd = 0;
        struct reiserfs_transaction_handle *th = NULL;
+       int depth;
 
-       reiserfs_write_unlock(inode->i_sb);
+       depth = reiserfs_write_unlock_nested(inode->i_sb);
        reiserfs_wait_on_write_block(inode->i_sb);
-       reiserfs_write_lock(inode->i_sb);
+       reiserfs_write_lock_nested(inode->i_sb, depth);
 
        if (reiserfs_transaction_running(inode->i_sb)) {
                th = current->journal_info;
@@ -3110,7 +3114,6 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
 {
        struct inode *inode = dentry->d_inode;
        unsigned int ia_valid;
-       int depth;
        int error;
 
        error = inode_change_ok(inode, attr);
@@ -3122,13 +3125,14 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
 
        if (is_quota_modification(inode, attr))
                dquot_initialize(inode);
-       depth = reiserfs_write_lock_once(inode->i_sb);
+       reiserfs_write_lock(inode->i_sb);
        if (attr->ia_valid & ATTR_SIZE) {
                /* version 2 items will be caught by the s_maxbytes check
                 ** done for us in vmtruncate
                 */
                if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
                    attr->ia_size > MAX_NON_LFS) {
+                       reiserfs_write_unlock(inode->i_sb);
                        error = -EFBIG;
                        goto out;
                }
@@ -3150,8 +3154,10 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
                                if (err)
                                        error = err;
                        }
-                       if (error)
+                       if (error) {
+                               reiserfs_write_unlock(inode->i_sb);
                                goto out;
+                       }
                        /*
                         * file size is changed, ctime and mtime are
                         * to be updated
@@ -3159,6 +3165,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
                        attr->ia_valid |= (ATTR_MTIME | ATTR_CTIME);
                }
        }
+       reiserfs_write_unlock(inode->i_sb);
 
        if ((((attr->ia_valid & ATTR_UID) && (from_kuid(&init_user_ns, attr->ia_uid) & ~0xffff)) ||
             ((attr->ia_valid & ATTR_GID) && (from_kgid(&init_user_ns, attr->ia_gid) & ~0xffff))) &&
@@ -3183,14 +3190,16 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
                        return error;
 
                /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */
+               reiserfs_write_lock(inode->i_sb);
                error = journal_begin(&th, inode->i_sb, jbegin_count);
+               reiserfs_write_unlock(inode->i_sb);
                if (error)
                        goto out;
-               reiserfs_write_unlock_once(inode->i_sb, depth);
                error = dquot_transfer(inode, attr);
-               depth = reiserfs_write_lock_once(inode->i_sb);
+               reiserfs_write_lock(inode->i_sb);
                if (error) {
                        journal_end(&th, inode->i_sb, jbegin_count);
+                       reiserfs_write_unlock(inode->i_sb);
                        goto out;
                }
 
@@ -3202,17 +3211,11 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
                        inode->i_gid = attr->ia_gid;
                mark_inode_dirty(inode);
                error = journal_end(&th, inode->i_sb, jbegin_count);
+               reiserfs_write_unlock(inode->i_sb);
                if (error)
                        goto out;
        }
 
-       /*
-        * Relax the lock here, as it might truncate the
-        * inode pages and wait for inode pages locks.
-        * To release such page lock, the owner needs the
-        * reiserfs lock
-        */
-       reiserfs_write_unlock_once(inode->i_sb, depth);
        if ((attr->ia_valid & ATTR_SIZE) &&
            attr->ia_size != i_size_read(inode)) {
                error = inode_newsize_ok(inode, attr->ia_size);
@@ -3226,16 +3229,13 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
                setattr_copy(inode, attr);
                mark_inode_dirty(inode);
        }
-       depth = reiserfs_write_lock_once(inode->i_sb);
 
        if (!error && reiserfs_posixacl(inode->i_sb)) {
                if (attr->ia_valid & ATTR_MODE)
                        error = reiserfs_acl_chmod(inode);
        }
 
-      out:
-       reiserfs_write_unlock_once(inode->i_sb, depth);
-
+out:
        return error;
 }