nfsd4: use list_move in move_to_confirmed
[safe/jmp/linux-2.6] / fs / reiserfs / inode.c
index 6114050..dc2c65e 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/smp_lock.h>
 #include <linux/pagemap.h>
 #include <linux/highmem.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 #include <linux/buffer_head.h>
@@ -31,11 +32,15 @@ void reiserfs_delete_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 (!is_bad_inode(inode))
+               dquot_initialize(inode);
+
        truncate_inode_pages(&inode->i_data, 0);
 
-       reiserfs_write_lock(inode->i_sb);
+       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 */
@@ -53,7 +58,7 @@ void reiserfs_delete_inode(struct inode *inode)
                 * after delete_object so that quota updates go into the same transaction as
                 * stat data deletion */
                if (!err) 
-                       vfs_dq_free_inode(inode);
+                       dquot_free_inode(inode);
 
                if (journal_end(&th, inode->i_sb, jbegin_count))
                        goto out;
@@ -74,7 +79,7 @@ void reiserfs_delete_inode(struct inode *inode)
       out:
        clear_inode(inode);     /* note this must go after the journal_end to prevent deadlock */
        inode->i_blocks = 0;
-       reiserfs_write_unlock(inode->i_sb);
+       reiserfs_write_unlock_once(inode->i_sb, depth);
 }
 
 static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid,
@@ -251,7 +256,6 @@ static int _get_block_create_0(struct inode *inode, sector_t block,
        struct cpu_key key;
        struct buffer_head *bh;
        struct item_head *ih, tmp_ih;
-       int fs_gen;
        b_blocknr_t blocknr;
        char *p = NULL;
        int chars;
@@ -265,7 +269,6 @@ static int _get_block_create_0(struct inode *inode, sector_t block,
                     (loff_t) block * inode->i_sb->s_blocksize + 1, TYPE_ANY,
                     3);
 
-      research:
        result = search_for_position_by_key(inode->i_sb, &key, &path);
        if (result != POSITION_FOUND) {
                pathrelse(&path);
@@ -340,7 +343,6 @@ static int _get_block_create_0(struct inode *inode, sector_t block,
        }
        // read file tail into part of page
        offset = (cpu_key_k_offset(&key) - 1) & (PAGE_CACHE_SIZE - 1);
-       fs_gen = get_generation(inode->i_sb);
        copy_item_head(&tmp_ih, ih);
 
        /* we only want to kmap if we are reading the tail into the page.
@@ -348,13 +350,9 @@ static int _get_block_create_0(struct inode *inode, sector_t block,
         ** sure we need to.  But, this means the item might move if
         ** kmap schedules
         */
-       if (!p) {
+       if (!p)
                p = (char *)kmap(bh_result->b_page);
-               if (fs_changed(fs_gen, inode->i_sb)
-                   && item_moved(&tmp_ih, &path)) {
-                       goto research;
-               }
-       }
+
        p += offset;
        memset(p, 0, inode->i_sb->s_blocksize);
        do {
@@ -939,7 +937,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
                        if (blocks_needed == 1) {
                                un = &unf_single;
                        } else {
-                               un = kzalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_ATOMIC);      // We need to avoid scheduling.
+                               un = kzalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_NOFS);
                                if (!un) {
                                        un = &unf_single;
                                        blocks_needed = 1;
@@ -1503,9 +1501,11 @@ struct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key)
 
        args.objectid = key->on_disk_key.k_objectid;
        args.dirid = key->on_disk_key.k_dir_id;
+       reiserfs_write_unlock(s);
        inode = iget5_locked(s, key->on_disk_key.k_objectid,
                             reiserfs_find_actor, reiserfs_init_locked_inode,
                             (void *)(&args));
+       reiserfs_write_lock(s);
        if (!inode)
                return ERR_PTR(-ENOMEM);
 
@@ -1619,7 +1619,7 @@ int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp,
 ** to properly mark inodes for datasync and such, but only actually
 ** does something when called for a synchronous update.
 */
-int reiserfs_write_inode(struct inode *inode, int do_sync)
+int reiserfs_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
        struct reiserfs_transaction_handle th;
        int jbegin_count = 1;
@@ -1631,7 +1631,7 @@ int reiserfs_write_inode(struct inode *inode, int do_sync)
         ** inode needs to reach disk for safety, and they can safely be
         ** ignored because the altered inode has already been logged.
         */
-       if (do_sync && !(current->flags & PF_MEMALLOC)) {
+       if (wbc->sync_mode == WB_SYNC_ALL && !(current->flags & PF_MEMALLOC)) {
                reiserfs_write_lock(inode->i_sb);
                if (!journal_begin(&th, inode->i_sb, jbegin_count)) {
                        reiserfs_update_sd(&th, inode);
@@ -1769,10 +1769,10 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
 
        BUG_ON(!th->t_trans_id);
 
-       if (vfs_dq_alloc_inode(inode)) {
-               err = -EDQUOT;
+       dquot_initialize(inode);
+       err = dquot_alloc_inode(inode);
+       if (err)
                goto out_end_trans;
-       }
        if (!dir->i_nlink) {
                err = -EPERM;
                goto out_bad_inode;
@@ -1963,12 +1963,12 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
        INODE_PKEY(inode)->k_objectid = 0;
 
        /* Quota change must be inside a transaction for journaling */
-       vfs_dq_free_inode(inode);
+       dquot_free_inode(inode);
 
       out_end_trans:
        journal_end(th, th->t_super, th->t_blocks_allocated);
        /* Drop can be outside and it needs more credits so it's better to have it outside */
-       vfs_dq_drop(inode);
+       dquot_drop(inode);
        inode->i_flags |= S_NOQUOTA;
        make_bad_inode(inode);
 
@@ -2545,6 +2545,12 @@ static int reiserfs_writepage(struct page *page, struct writeback_control *wbc)
        return reiserfs_write_full_page(page, wbc);
 }
 
+static void reiserfs_truncate_failed_write(struct inode *inode)
+{
+       truncate_inode_pages(inode->i_mapping, inode->i_size);
+       reiserfs_truncate_file(inode, 0);
+}
+
 static int reiserfs_write_begin(struct file *file,
                                struct address_space *mapping,
                                loff_t pos, unsigned len, unsigned flags,
@@ -2611,6 +2617,8 @@ static int reiserfs_write_begin(struct file *file,
        if (ret) {
                unlock_page(page);
                page_cache_release(page);
+               /* Truncate allocated blocks */
+               reiserfs_truncate_failed_write(inode);
        }
        return ret;
 }
@@ -2681,6 +2689,8 @@ 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)
                pos ++;
@@ -2706,10 +2716,10 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
         ** transaction tracking stuff when the size changes.  So, we have
         ** to do the i_size updates here.
         */
-       pos += copied;
-       if (pos > inode->i_size) {
+       if (pos + copied > inode->i_size) {
                struct reiserfs_transaction_handle myth;
-               reiserfs_write_lock(inode->i_sb);
+               lock_depth = reiserfs_write_lock_once(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
                   packing */
@@ -2720,12 +2730,11 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
                        REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
 
                ret = journal_begin(&myth, inode->i_sb, 1);
-               if (ret) {
-                       reiserfs_write_unlock(inode->i_sb);
+               if (ret)
                        goto journal_error;
-               }
+
                reiserfs_update_inode_transaction(inode);
-               inode->i_size = pos;
+               inode->i_size = pos + copied;
                /*
                 * this will just nest into our transaction.  It's important
                 * to use mark_inode_dirty so the inode gets pushed around on the
@@ -2735,34 +2744,40 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
                reiserfs_update_sd(&myth, inode);
                update_sd = 1;
                ret = journal_end(&myth, inode->i_sb, 1);
-               reiserfs_write_unlock(inode->i_sb);
                if (ret)
                        goto journal_error;
        }
        if (th) {
-               reiserfs_write_lock(inode->i_sb);
+               if (!locked) {
+                       lock_depth = reiserfs_write_lock_once(inode->i_sb);
+                       locked = true;
+               }
                if (!update_sd)
                        mark_inode_dirty(inode);
                ret = reiserfs_end_persistent_transaction(th);
-               reiserfs_write_unlock(inode->i_sb);
                if (ret)
                        goto out;
        }
 
       out:
+       if (locked)
+               reiserfs_write_unlock_once(inode->i_sb, lock_depth);
        unlock_page(page);
        page_cache_release(page);
+
+       if (pos + len > inode->i_size)
+               reiserfs_truncate_failed_write(inode);
+
        return ret == 0 ? copied : ret;
 
       journal_error:
+       reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+       locked = false;
        if (th) {
-               reiserfs_write_lock(inode->i_sb);
                if (!update_sd)
                        reiserfs_update_sd(th, inode);
                ret = reiserfs_end_persistent_transaction(th);
-               reiserfs_write_unlock(inode->i_sb);
        }
-
        goto out;
 }
 
@@ -2790,7 +2805,6 @@ int reiserfs_commit_write(struct file *f, struct page *page,
         */
        if (pos > inode->i_size) {
                struct reiserfs_transaction_handle myth;
-               reiserfs_write_lock(inode->i_sb);
                /* If the file have grown beyond the border where it
                   can have a tail, unmark it as needing a tail
                   packing */
@@ -2801,10 +2815,9 @@ int reiserfs_commit_write(struct file *f, struct page *page,
                        REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
 
                ret = journal_begin(&myth, inode->i_sb, 1);
-               if (ret) {
-                       reiserfs_write_unlock(inode->i_sb);
+               if (ret)
                        goto journal_error;
-               }
+
                reiserfs_update_inode_transaction(inode);
                inode->i_size = pos;
                /*
@@ -2816,16 +2829,13 @@ int reiserfs_commit_write(struct file *f, struct page *page,
                reiserfs_update_sd(&myth, inode);
                update_sd = 1;
                ret = journal_end(&myth, inode->i_sb, 1);
-               reiserfs_write_unlock(inode->i_sb);
                if (ret)
                        goto journal_error;
        }
        if (th) {
-               reiserfs_write_lock(inode->i_sb);
                if (!update_sd)
                        mark_inode_dirty(inode);
                ret = reiserfs_end_persistent_transaction(th);
-               reiserfs_write_unlock(inode->i_sb);
                if (ret)
                        goto out;
        }
@@ -2835,11 +2845,9 @@ int reiserfs_commit_write(struct file *f, struct page *page,
 
       journal_error:
        if (th) {
-               reiserfs_write_lock(inode->i_sb);
                if (!update_sd)
                        reiserfs_update_sd(th, inode);
                ret = reiserfs_end_persistent_transaction(th);
-               reiserfs_write_unlock(inode->i_sb);
        }
 
        return ret;
@@ -3060,14 +3068,17 @@ static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb,
 int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
 {
        struct inode *inode = dentry->d_inode;
-       int error;
        unsigned int ia_valid;
+       int depth;
+       int error;
 
        /* must be turned off for recursive notify_change calls */
        ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);
 
-       reiserfs_write_lock(inode->i_sb);
+       depth = reiserfs_write_lock_once(inode->i_sb);
        if (attr->ia_valid & ATTR_SIZE) {
+               dquot_initialize(inode);
+
                /* version 2 items will be caught by the s_maxbytes check
                 ** done for us in vmtruncate
                 */
@@ -3129,8 +3140,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
                                                  jbegin_count);
                                if (error)
                                        goto out;
-                               error =
-                                   vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
+                               error = dquot_transfer(inode, attr);
                                if (error) {
                                        journal_end(&th, inode->i_sb,
                                                    jbegin_count);
@@ -3147,8 +3157,17 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
                                    journal_end(&th, inode->i_sb, jbegin_count);
                        }
                }
-               if (!error)
+               if (!error) {
+                       /*
+                        * 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);
                        error = inode_setattr(inode, attr);
+                       depth = reiserfs_write_lock_once(inode->i_sb);
+               }
        }
 
        if (!error && reiserfs_posixacl(inode->i_sb)) {
@@ -3157,7 +3176,8 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
        }
 
       out:
-       reiserfs_write_unlock(inode->i_sb);
+       reiserfs_write_unlock_once(inode->i_sb, depth);
+
        return error;
 }