nfsd4: implement reclaim_complete
[safe/jmp/linux-2.6] / fs / ext4 / inode.c
index c717a74..81d6054 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/bio.h>
 #include <linux/workqueue.h>
 #include <linux/kernel.h>
+#include <linux/slab.h>
 
 #include "ext4_jbd2.h"
 #include "xattr.h"
@@ -171,6 +172,9 @@ void ext4_delete_inode(struct inode *inode)
        handle_t *handle;
        int err;
 
+       if (!is_bad_inode(inode))
+               dquot_initialize(inode);
+
        if (ext4_should_order_data(inode))
                ext4_begin_ordered_truncate(inode, 0);
        truncate_inode_pages(&inode->i_data, 0);
@@ -1032,7 +1036,7 @@ static int ext4_indirect_calc_metadata_amount(struct inode *inode,
                                              sector_t lblock)
 {
        struct ext4_inode_info *ei = EXT4_I(inode);
-       int dind_mask = EXT4_ADDR_PER_BLOCK(inode->i_sb) - 1;
+       sector_t dind_mask = ~((sector_t)EXT4_ADDR_PER_BLOCK(inode->i_sb) - 1);
        int blk_bits;
 
        if (lblock < EXT4_NDIR_BLOCKS)
@@ -1047,7 +1051,7 @@ static int ext4_indirect_calc_metadata_amount(struct inode *inode,
        }
        ei->i_da_metadata_calc_last_lblock = lblock & dind_mask;
        ei->i_da_metadata_calc_len = 1;
-       blk_bits = roundup_pow_of_two(lblock + 1);
+       blk_bits = order_base_2(lblock);
        return (blk_bits / EXT4_ADDR_PER_BLOCK_BITS(inode->i_sb)) + 1;
 }
 
@@ -1108,9 +1112,9 @@ void ext4_da_update_reserve_space(struct inode *inode,
 
        /* Update quota subsystem */
        if (quota_claim) {
-               vfs_dq_claim_block(inode, used);
+               dquot_claim_block(inode, used);
                if (mdb_free)
-                       vfs_dq_release_reservation_block(inode, mdb_free);
+                       dquot_release_reservation_block(inode, mdb_free);
        } else {
                /*
                 * We did fallocate with an offset that is already delayed
@@ -1121,8 +1125,8 @@ void ext4_da_update_reserve_space(struct inode *inode,
                 * that
                 */
                if (allocated_meta_blocks)
-                       vfs_dq_claim_block(inode, allocated_meta_blocks);
-               vfs_dq_release_reservation_block(inode, mdb_free + used);
+                       dquot_claim_block(inode, allocated_meta_blocks);
+               dquot_release_reservation_block(inode, mdb_free + used);
        }
 
        /*
@@ -1857,6 +1861,7 @@ static int ext4_da_reserve_space(struct inode *inode, sector_t lblock)
        struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
        struct ext4_inode_info *ei = EXT4_I(inode);
        unsigned long md_needed, md_reserved;
+       int ret;
 
        /*
         * recalculate the amount of metadata blocks to reserve
@@ -1875,11 +1880,12 @@ repeat:
         * later. Real quota accounting is done at pages writeout
         * time.
         */
-       if (vfs_dq_reserve_block(inode, md_needed + 1))
-               return -EDQUOT;
+       ret = dquot_reserve_block(inode, md_needed + 1);
+       if (ret)
+               return ret;
 
        if (ext4_claim_free_blocks(sbi, md_needed + 1)) {
-               vfs_dq_release_reservation_block(inode, md_needed + 1);
+               dquot_release_reservation_block(inode, md_needed + 1);
                if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
                        yield();
                        goto repeat;
@@ -1936,7 +1942,7 @@ static void ext4_da_release_space(struct inode *inode, int to_free)
 
        spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
 
-       vfs_dq_release_reservation_block(inode, to_free);
+       dquot_release_reservation_block(inode, to_free);
 }
 
 static void ext4_da_page_release_reservation(struct page *page,
@@ -2157,17 +2163,16 @@ static void ext4_da_block_invalidatepages(struct mpage_da_data *mpd,
                        break;
                for (i = 0; i < nr_pages; i++) {
                        struct page *page = pvec.pages[i];
-                       index = page->index;
-                       if (index > end)
+                       if (page->index > end)
                                break;
-                       index++;
-
                        BUG_ON(!PageLocked(page));
                        BUG_ON(PageWriteback(page));
                        block_invalidatepage(page, 0);
                        ClearPageUptodate(page);
                        unlock_page(page);
                }
+               index = pvec.pages[nr_pages - 1]->index + 1;
+               pagevec_release(&pvec);
        }
        return;
 }
@@ -5349,7 +5354,7 @@ out_brelse:
  * `stuff()' is running, and the new i_size will be lost.  Plus the inode
  * will no longer be on the superblock's dirty inode list.
  */
-int ext4_write_inode(struct inode *inode, int wait)
+int ext4_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
        int err;
 
@@ -5363,17 +5368,17 @@ int ext4_write_inode(struct inode *inode, int wait)
                        return -EIO;
                }
 
-               if (!wait)
+               if (wbc->sync_mode != WB_SYNC_ALL)
                        return 0;
 
                err = ext4_force_commit(inode->i_sb);
        } else {
                struct ext4_iloc iloc;
 
-               err = ext4_get_inode_loc(inode, &iloc);
+               err = __ext4_get_inode_loc(inode, &iloc, 0);
                if (err)
                        return err;
-               if (wait)
+               if (wbc->sync_mode == WB_SYNC_ALL)
                        sync_dirty_buffer(iloc.bh);
                if (buffer_req(iloc.bh) && !buffer_uptodate(iloc.bh)) {
                        ext4_error(inode->i_sb, "IO error syncing inode, "
@@ -5381,6 +5386,7 @@ int ext4_write_inode(struct inode *inode, int wait)
                                   (unsigned long long)iloc.bh->b_blocknr);
                        err = -EIO;
                }
+               brelse(iloc.bh);
        }
        return err;
 }
@@ -5419,6 +5425,8 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
        if (error)
                return error;
 
+       if (ia_valid & ATTR_SIZE)
+               dquot_initialize(inode);
        if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
                (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
                handle_t *handle;
@@ -5431,7 +5439,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
                        error = PTR_ERR(handle);
                        goto err_out;
                }
-               error = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
+               error = dquot_transfer(inode, attr);
                if (error) {
                        ext4_journal_stop(handle);
                        return error;
@@ -5817,7 +5825,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
  * i_size has been changed by generic_commit_write() and we thus need
  * to include the updated inode in the current transaction.
  *
- * Also, vfs_dq_alloc_block() will always dirty the inode when blocks
+ * Also, dquot_alloc_block() will always dirty the inode when blocks
  * are allocated to the file.
  *
  * If the inode is marked synchronous, we don't honour that here - doing