VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / fs / ext3 / xattr.c
index 97b74fe..b6c382c 100644 (file)
@@ -59,6 +59,7 @@
 #include <linux/mbcache.h>
 #include <linux/quotaops.h>
 #include <linux/rwsem.h>
+#include <linux/vs_dlimit.h>
 #include "xattr.h"
 #include "acl.h"
 
@@ -761,8 +762,12 @@ ext3_xattr_set_handle2(handle_t *handle, struct inode *inode,
                                   the inode. */
                                ea_bdebug(new_bh, "reusing block");
 
+                               error = -ENOSPC;
+                               if (DLIMIT_ALLOC_BLOCK(sb, inode->i_xid, 1))
+                                       goto cleanup;
                                error = -EDQUOT;
                                if (DQUOT_ALLOC_BLOCK(inode, 1)) {
+                                       DLIMIT_FREE_BLOCK(sb, inode->i_xid, 1);
                                        unlock_buffer(new_bh);
                                        journal_release_buffer(handle, new_bh,
                                                               credits);
@@ -786,8 +791,8 @@ ext3_xattr_set_handle2(handle_t *handle, struct inode *inode,
                                        EXT3_SB(sb)->s_es->s_first_data_block) +
                                EXT3_I(inode)->i_block_group *
                                EXT3_BLOCKS_PER_GROUP(sb);
-                       int block = ext3_new_block(handle,
-                               inode, goal, 0, 0, &error);
+                       int block = ext3_new_block(handle, inode, goal,
+                                                  NULL, NULL, &error);
                        if (error)
                                goto cleanup;
                        ea_idebug(inode, "creating block %d", block);
@@ -848,6 +853,7 @@ getblk_failed:
                        /* Decrement the refcount only. */
                        HDR(old_bh)->h_refcount = cpu_to_le32(
                                le32_to_cpu(HDR(old_bh)->h_refcount) - 1);
+                       DLIMIT_FREE_BLOCK(sb, inode->i_xid, 1);
                        DQUOT_FREE_BLOCK(inode, 1);
                        ext3_journal_dirty_metadata(handle, old_bh);
                        ea_bdebug(old_bh, "refcount now=%d",
@@ -875,8 +881,9 @@ ext3_xattr_set(struct inode *inode, int name_index, const char *name,
               const void *value, size_t value_len, int flags)
 {
        handle_t *handle;
-       int error;
+       int error, retries = 0;
 
+retry:
        handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS);
        if (IS_ERR(handle)) {
                error = PTR_ERR(handle);
@@ -886,6 +893,9 @@ ext3_xattr_set(struct inode *inode, int name_index, const char *name,
                error = ext3_xattr_set_handle(handle, inode, name_index, name,
                                              value, value_len, flags);
                error2 = ext3_journal_stop(handle);
+               if (error == -ENOSPC &&
+                   ext3_should_retry_alloc(inode->i_sb, &retries))
+                       goto retry;
                if (error == 0)
                        error = error2;
        }
@@ -935,6 +945,7 @@ ext3_xattr_delete_inode(handle_t *handle, struct inode *inode)
                ext3_journal_dirty_metadata(handle, bh);
                if (IS_SYNC(inode))
                        handle->h_sync = 1;
+               DLIMIT_FREE_BLOCK(inode->i_sb, inode->i_xid, 1);
                DQUOT_FREE_BLOCK(inode, 1);
        }
        ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1);