%patch
Index: linux.d/fs/reiserfs/tail_conversion.c
===================================================================
--- linux.d.orig/fs/reiserfs/tail_conversion.c  2003-12-03 19:38:26.000000000 -0500
+++ linux.d/fs/reiserfs/tail_conversion.c       2003-12-03 19:59:27.000000000 -0500
@@ -66,11 +66,11 @@
       set_ih_free_space (&ind_ih, 0); /* delete at nearest future */
        put_ih_item_len( &ind_ih, UNFM_P_SIZE );
       PATH_LAST_POSITION (path)++;
-       n_retval = reiserfs_insert_item (th, path, &end_key, &ind_ih,
+       n_retval = reiserfs_insert_item (th, path, &end_key, &ind_ih, inode,
                                        (char *)&unfm_ptr);
    } else {
       /* Paste into last indirect item of an object. */
-       n_retval = reiserfs_paste_into_item(th, path, &end_key,
+       n_retval = reiserfs_paste_into_item(th, path, &end_key, inode,
                                           (char *)&unfm_ptr, UNFM_P_SIZE);
    }
    if ( n_retval ) {
@@ -228,7 +228,7 @@
    set_cpu_key_k_type (&key, TYPE_DIRECT);
    key.key_length = 4;
    /* Insert tail as new direct item in the tree */
-    if ( reiserfs_insert_item(th, p_s_path, &key, &s_ih,
+    if ( reiserfs_insert_item(th, p_s_path, &key, &s_ih, p_s_inode,
                             tail ? tail : NULL) < 0 ) {
       /* No disk memory. So we can not convert last unformatted node
          to the direct item.  In this case we used to adjust
@@ -241,13 +241,15 @@
    }
    kunmap(page) ;

+    /* make sure to get the i_blocks changes from reiserfs_insert_item */
+    reiserfs_update_sd(th, p_s_inode);
+
    // note: we have now the same as in above direct2indirect
    // conversion: there are two keys which have matching first three
    // key components. They only differ by the fouhth one.

    /* We have inserted new direct item and must remove last
       unformatted node. */
-    p_s_inode->i_blocks += (p_s_sb->s_blocksize / 512);
    *p_c_mode = M_CUT;

    /* we store position of first direct item in the in-core inode */
Index: linux.d/fs/reiserfs/bitmap.c
===================================================================
--- linux.d.orig/fs/reiserfs/bitmap.c   2003-12-03 19:32:59.000000000 -0500
+++ linux.d/fs/reiserfs/bitmap.c        2003-12-03 19:59:27.000000000 -0500
@@ -10,6 +10,7 @@
#include <linux/errno.h>
#include <linux/locks.h>
#include <linux/kernel.h>
+#include <linux/quotaops.h>

#include <linux/reiserfs_fs.h>
#include <linux/reiserfs_fs_sb.h>
@@ -287,7 +288,8 @@
}

static void _reiserfs_free_block (struct reiserfs_transaction_handle *th,
-                         b_blocknr_t block)
+                                 struct inode *inode, b_blocknr_t block,
+                                 int for_unformatted)
{
    struct super_block * s = th->t_super;
    struct reiserfs_super_block * rs;
@@ -327,39 +329,55 @@
    set_sb_free_blocks( rs, sb_free_blocks(rs) + 1 );

    journal_mark_dirty (th, s, sbh);
+    if (for_unformatted) {
+#ifdef REISERQUOTA_DEBUG
+      printk(KERN_DEBUG "reiserquota: freeing block id=%u\n", inode->i_uid);
+#endif
+      DQUOT_FREE_BLOCK_NODIRTY(inode, 1);
+    }
+
}

void reiserfs_free_block (struct reiserfs_transaction_handle *th,
-                         unsigned long block) {
+                         struct inode *inode, unsigned long block,
+                         int for_unformatted)
+{
    struct super_block * s = th->t_super;

    RFALSE(!s, "vs-4061: trying to free block on nonexistent device");
    RFALSE(is_reusable (s, block, 1) == 0, "vs-4071: can not free such block");
    /* mark it before we clear it, just in case */
    journal_mark_freed(th, s, block) ;
-    _reiserfs_free_block(th, block) ;
+    _reiserfs_free_block(th, inode, block, for_unformatted) ;
}

/* preallocated blocks don't need to be run through journal_mark_freed */
void reiserfs_free_prealloc_block (struct reiserfs_transaction_handle *th,
-                          unsigned long block) {
+                         struct inode *inode,
+                          unsigned long block)
+{
    RFALSE(!th->t_super, "vs-4060: trying to free block on nonexistent device");
    RFALSE(is_reusable (th->t_super, block, 1) == 0, "vs-4070: can not free such block");
-    _reiserfs_free_block(th, block) ;
+    _reiserfs_free_block(th, inode, block, 1) ;
}

static void __discard_prealloc (struct reiserfs_transaction_handle * th,
                               struct inode * inode)
{
    unsigned long save = inode->u.reiserfs_i.i_prealloc_block ;
+    int dirty=0;
#ifdef CONFIG_REISERFS_CHECK
    if (inode->u.reiserfs_i.i_prealloc_count < 0)
       reiserfs_warning(th->t_super, "zam-4001:%s: inode has negative prealloc blocks count.\n", __FUNCTION__ );
#endif
    while (inode->u.reiserfs_i.i_prealloc_count > 0) {
-       reiserfs_free_prealloc_block(th,inode->u.reiserfs_i.i_prealloc_block);
+       reiserfs_free_prealloc_block(th, inode, inode->u.reiserfs_i.i_prealloc_block);
       inode->u.reiserfs_i.i_prealloc_block++;
       inode->u.reiserfs_i.i_prealloc_count --;
+       dirty = 1 ;
+    }
+    if (dirty) {
+       reiserfs_update_sd(th, inode) ;
    }
    inode->u.reiserfs_i.i_prealloc_block = save ;
    list_del (&(inode->u.reiserfs_i.i_prealloc_list));
@@ -773,6 +791,24 @@
    int nr_allocated = 0;

    determine_prealloc_size(hint);
+    if (!hint->formatted_node) {
+        int quota_ret;
+#ifdef REISERQUOTA_DEBUG
+       printk(KERN_DEBUG "reiserquota: allocating %d blocks id=%u\n", amount_needed, hint->inode->i_uid);
+#endif
+       quota_ret = DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode, amount_needed);
+       if (quota_ret)    /* Quota exceeded? */
+           return QUOTA_EXCEEDED;
+       if (hint->preallocate && hint->prealloc_size ) {
+#ifdef REISERQUOTA_DEBUG
+           printk(KERN_DEBUG "reiserquota: allocating (prealloc) %d blocks id=%u\n", hint->prealloc_size, hint->inode->i_uid);
+#endif
+           quota_ret = DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode, hint->prealloc_size);
+           if (quota_ret)
+               hint->preallocate=hint->prealloc_size=0;
+       }
+    }
+
    while((nr_allocated
         += allocate_without_wrapping_disk(hint, new_blocknrs + nr_allocated, start, finish,
                                         amount_needed - nr_allocated, hint->prealloc_size))
@@ -780,8 +816,14 @@

       /* not all blocks were successfully allocated yet*/
       if (second_pass) {      /* it was a second pass; we must free all blocks */
+           if (!hint->formatted_node) {
+#ifdef REISERQUOTA_DEBUG
+               printk(KERN_DEBUG "reiserquota: freeing (nospace) %d blocks id=%u\n", amount_needed + hint->prealloc_size - nr_allocated, hint->inode->i_uid);
+#endif
+               DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated);     /* Free not allocated blocks */
+           }
           while (nr_allocated --)
-               reiserfs_free_block(hint->th, new_blocknrs[nr_allocated]);
+               reiserfs_free_block(hint->th, hint->inode, new_blocknrs[nr_allocated], !hint->formatted_node);

           return NO_DISK_SPACE;
       } else {                /* refine search parameters for next pass */
@@ -791,6 +833,13 @@
           continue;
       }
    }
+    if ( !hint->formatted_node && amount_needed + hint->prealloc_size > nr_allocated + INODE_INFO(hint->inode)->i_prealloc_count) {
+    /* Some of preallocation blocks were not allocated */
+#ifdef REISERQUOTA_DEBUG
+       printk(KERN_DEBUG "reiserquota: freeing (failed prealloc) %d blocks id=%u\n", amount_needed + hint->prealloc_size - nr_allocated - INODE_INFO(hint->inode)->i_prealloc_count, hint->inode->i_uid);
+#endif
+       DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated - INODE_INFO(hint->inode)->i_prealloc_count);
+    }
    return CARRY_ON;
}

@@ -859,7 +908,7 @@

    if (ret != CARRY_ON) {
       while (amount_needed ++ < initial_amount_needed) {
-           reiserfs_free_block(hint->th, *(--new_blocknrs));
+           reiserfs_free_block(hint->th, hint->inode, *(--new_blocknrs), 1);
       }
    }
    return ret;
Index: linux.d/fs/reiserfs/stree.c
===================================================================
--- linux.d.orig/fs/reiserfs/stree.c    2003-12-03 19:38:26.000000000 -0500
+++ linux.d/fs/reiserfs/stree.c 2003-12-03 20:03:02.000000000 -0500
@@ -60,6 +60,7 @@
#include <linux/pagemap.h>
#include <linux/reiserfs_fs.h>
#include <linux/smp_lock.h>
+#include <linux/quotaops.h>

/* Does the buffer contain a disk block which is in the tree. */
inline int B_IS_IN_TREE (const struct buffer_head * p_s_bh)
@@ -71,9 +72,6 @@
  return ( B_LEVEL (p_s_bh) != FREE_LEVEL );
}

-
-
-
inline void copy_short_key (void * to, const void * from)
{
    memcpy (to, from, SHORT_KEY_SIZE);
@@ -1126,8 +1124,7 @@
               tmp = get_block_num(p_n_unfm_pointer,0);
               put_block_num(p_n_unfm_pointer, 0, 0);
               journal_mark_dirty (th, p_s_sb, p_s_bh);
-               inode->i_blocks -= p_s_sb->s_blocksize / 512;
-               reiserfs_free_block(th, tmp);
+               reiserfs_free_block(th, inode, tmp, 1);
               /* In case of big fragmentation it is possible that each block
                  freed will cause dirtying of one more bitmap and then we will
                  quickly overflow our transaction space. This is a
@@ -1169,8 +1166,7 @@
    }
}

-
-/* Calculate bytes number which will be deleted or cutted in the balance. */
+/* Calculate number of bytes which will be deleted or cut during balance */
int calc_deleted_bytes_number(
    struct  tree_balance  * p_s_tb,
    char                    c_mode
@@ -1181,14 +1177,14 @@
    if ( is_statdata_le_ih (p_le_ih) )
       return 0;

+    n_del_size = ( c_mode == M_DELETE ) ? ih_item_len(p_le_ih) : -p_s_tb->insert_size[0];
    if ( is_direntry_le_ih (p_le_ih) ) {
       // return EMPTY_DIR_SIZE; /* We delete emty directoris only. */
       // we can't use EMPTY_DIR_SIZE, as old format dirs have a different
       // empty size.  ick. FIXME, is this right?
       //
-       return ih_item_len(p_le_ih);
+       return n_del_size ;
    }
-    n_del_size = ( c_mode == M_DELETE ) ? ih_item_len(p_le_ih) : -p_s_tb->insert_size[0];

    if ( is_indirect_le_ih (p_le_ih) )
       n_del_size = (n_del_size/UNFM_P_SIZE)*
@@ -1222,17 +1218,46 @@
       item [--i] = 0;
}

+#ifdef REISERQUOTA_DEBUG
+char key2type(struct key *ih)
+{
+  if (is_direntry_le_key(2, ih))
+    return 'd';
+  if (is_direct_le_key(2, ih))
+    return 'D';
+  if (is_indirect_le_key(2, ih))
+    return 'i';
+  if (is_statdata_le_key(2, ih))
+    return 's';
+  return 'u';
+}
+
+char head2type(struct item_head *ih)
+{
+  if (is_direntry_le_ih(ih))
+    return 'd';
+  if (is_direct_le_ih(ih))
+    return 'D';
+  if (is_indirect_le_ih(ih))
+    return 'i';
+  if (is_statdata_le_ih(ih))
+    return 's';
+  return 'u';
+}
+#endif

/* Delete object item. */
int reiserfs_delete_item (struct reiserfs_transaction_handle *th,
                         struct path * p_s_path, /* Path to the deleted item. */
                         const struct cpu_key * p_s_item_key, /* Key to search for the deleted item.  */
-                         struct inode * p_s_inode,/* inode is here just to update i_blocks */
+                         struct inode * p_s_inode,/* inode is here just to update i_blocks and quotas */
                         struct buffer_head  * p_s_un_bh)    /* NULL or unformatted node pointer.    */
{
    struct super_block * p_s_sb = p_s_inode->i_sb;
    struct tree_balance   s_del_balance;
    struct item_head      s_ih;
+    struct item_head      *q_ih;
+    int                          quota_cut_bytes;
    int                   n_ret_value,
       n_del_size,
       n_removed;
@@ -1282,6 +1307,22 @@

    // reiserfs_delete_item returns item length when success
    n_ret_value = calc_deleted_bytes_number(&s_del_balance, M_DELETE);
+    q_ih = get_ih(p_s_path) ;
+    quota_cut_bytes = ih_item_len(q_ih) ;
+
+    /* hack so the quota code doesn't have to guess if the file
+    ** has a tail.  On tail insert, we allocate quota for 1 unformatted node.
+    ** We test the offset because the tail might have been
+    ** split into multiple items, and we only want to decrement for
+    ** the unfm node once
+    */
+    if (!S_ISLNK (p_s_inode->i_mode) && is_direct_le_ih(q_ih)) {
+        if ((le_ih_k_offset(q_ih) & (p_s_sb->s_blocksize - 1)) == 1) {
+            quota_cut_bytes = p_s_sb->s_blocksize + UNFM_P_SIZE;
+        } else {
+           quota_cut_bytes = 0 ;
+       }
+    }

    if ( p_s_un_bh )  {
       int off;
@@ -1313,10 +1354,14 @@
       memcpy(data + off,
              B_I_PITEM(PATH_PLAST_BUFFER(p_s_path), &s_ih), n_ret_value);
    }
-
    /* Perform balancing after all resources have been collected at once. */
    do_balance(&s_del_balance, NULL, NULL, M_DELETE);

+#ifdef REISERQUOTA_DEBUG
+    printk(KERN_DEBUG "reiserquota delete_item(): freeing %u, id=%u type=%c\n", quota_cut_bytes, p_s_inode->i_uid, head2type(&s_ih));
+#endif
+    DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
+
    /* Return deleted body length */
    return n_ret_value;
}
@@ -1341,14 +1386,16 @@

/* this deletes item which never gets split */
void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th,
+                                struct inode *inode,
                                struct key * key)
{
    struct tree_balance tb;
    INITIALIZE_PATH (path);
-    int item_len;
+    int item_len = 0;
    int tb_init = 0 ;
    struct cpu_key cpu_key;
    int retval;
+    int quota_cut_bytes = 0;

    le_key2cpu_key (&cpu_key, key);

@@ -1372,6 +1419,7 @@
           item_len = ih_item_len( PATH_PITEM_HEAD(&path) );
           init_tb_struct (th, &tb, th->t_super, &path, - (IH_SIZE + item_len));
       }
+       quota_cut_bytes = ih_item_len(PATH_PITEM_HEAD(&path)) ;

       retval = fix_nodes (M_DELETE, &tb, NULL, 0);
       if (retval == REPEAT_SEARCH) {
@@ -1381,6 +1429,12 @@

       if (retval == CARRY_ON) {
           do_balance (&tb, 0, 0, M_DELETE);
+           if (inode) {        /* Should we count quota for item? (we don't count quotas for save-links) */
+#ifdef REISERQUOTA_DEBUG
+               printk(KERN_DEBUG "reiserquota delete_solid_item(): freeing %u id=%u type=%c\n", quota_cut_bytes, inode->i_uid, key2type(key));
+#endif
+               DQUOT_FREE_SPACE_NODIRTY(inode, quota_cut_bytes);
+           }
           break;
       }

@@ -1413,7 +1467,7 @@
      }
/* USE_INODE_GENERATION_COUNTER */
#endif
-    reiserfs_delete_solid_item (th, INODE_PKEY (inode));
+    reiserfs_delete_solid_item (th, inode, INODE_PKEY (inode));
}


@@ -1532,6 +1586,7 @@
       structure by using the init_tb_struct and fix_nodes functions.
       After that we can make tree balancing. */
    struct tree_balance s_cut_balance;
+    struct item_head *p_le_ih;
    loff_t tail_pos = 0;
    int n_cut_size = 0,        /* Amount to be cut. */
       n_ret_value = CARRY_ON,
@@ -1539,6 +1594,7 @@
       n_is_inode_locked = 0;
    char                c_mode;            /* Mode of the balance. */
    int retval2 = -1;
+    int quota_cut_bytes;


    init_tb_struct(th, &s_cut_balance, p_s_inode->i_sb, p_s_path, n_cut_size);
@@ -1630,23 +1686,27 @@
    RFALSE( c_mode == M_PASTE || c_mode == M_INSERT, "illegal mode");

    /* Calculate number of bytes that need to be cut from the item. */
+    quota_cut_bytes = ( c_mode == M_DELETE ) ? ih_item_len(get_ih(p_s_path)) : -s_cut_balance.insert_size[0];
    if (retval2 == -1)
       n_ret_value = calc_deleted_bytes_number(&s_cut_balance, c_mode);
    else
       n_ret_value = retval2;
-
-    if ( c_mode == M_DELETE ) {
-       struct item_head * p_le_ih = PATH_PITEM_HEAD (s_cut_balance.tb_path);
-
-       if ( is_direct_le_ih (p_le_ih) && (le_ih_k_offset (p_le_ih) & (p_s_sb->s_blocksize - 1)) == 1 ) {
-           /* we delete first part of tail which was stored in direct
-               item(s) */
+
+
+    /* For direct items, we only change the quota when deleting the last
+    ** item.
+    */
+    p_le_ih = PATH_PITEM_HEAD (s_cut_balance.tb_path);
+    if (!S_ISLNK (p_s_inode->i_mode) && is_direct_le_ih(p_le_ih)) {
+        if (c_mode == M_DELETE &&
+          (le_ih_k_offset (p_le_ih) & (p_s_sb->s_blocksize - 1)) == 1 ) {
           // FIXME: this is to keep 3.5 happy
           p_s_inode->u.reiserfs_i.i_first_direct_byte = U32_MAX;
-           p_s_inode->i_blocks -= p_s_sb->s_blocksize / 512;
+           quota_cut_bytes = p_s_sb->s_blocksize + UNFM_P_SIZE ;
+        } else {
+           quota_cut_bytes = 0 ;
       }
    }
-
#ifdef CONFIG_REISERFS_CHECK
    if (n_is_inode_locked) {
       struct item_head * le_ih = PATH_PITEM_HEAD (s_cut_balance.tb_path);
@@ -1682,6 +1742,10 @@
       p_s_inode->u.reiserfs_i.i_flags &= ~i_pack_on_close_mask;
       unmap_buffers(page, tail_pos);
    }
+#ifdef REISERQUOTA_DEBUG
+    printk(KERN_DEBUG "reiserquota cut_from_item(): freeing %u id=%u type=%c\n", quota_cut_bytes, p_s_inode->i_uid, '?');
+#endif
+    DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
    return n_ret_value;
}

@@ -1693,8 +1757,8 @@

    set_le_key_k_offset (KEY_FORMAT_3_5, INODE_PKEY (inode), DOT_OFFSET);
    set_le_key_k_type (KEY_FORMAT_3_5, INODE_PKEY (inode), TYPE_DIRENTRY);
-    reiserfs_delete_solid_item (th, INODE_PKEY (inode));
-
+    reiserfs_delete_solid_item (th, inode, INODE_PKEY (inode));
+    reiserfs_update_sd(th, inode) ;
    set_le_key_k_offset (KEY_FORMAT_3_5, INODE_PKEY (inode), SD_OFFSET);
    set_le_key_k_type (KEY_FORMAT_3_5, INODE_PKEY (inode), TYPE_STAT_DATA);
}
@@ -1859,18 +1923,37 @@
int reiserfs_paste_into_item (struct reiserfs_transaction_handle *th,
                             struct path         * p_s_search_path,    /* Path to the pasted item.          */
                             const struct cpu_key      * p_s_key,              /* Key to search for the needed item.*/
+                             struct inode        * inode,              /* Inode item belongs to */
                             const char          * p_c_body,           /* Pointer to the bytes to paste.    */
                             int                   n_pasted_size)      /* Size of pasted bytes.             */
{
    struct tree_balance s_paste_balance;
    int                 retval;
+    int                        fs_gen;
+
+    fs_gen = get_generation(inode->i_sb) ;

+#ifdef REISERQUOTA_DEBUG
+    printk(KERN_DEBUG "reiserquota paste_into_item(): allocating %u id=%u type=%c\n", n_pasted_size, inode->i_uid, key2type(&(p_s_key->on_disk_key)));
+#endif
+
+    if (DQUOT_ALLOC_SPACE_NODIRTY(inode, n_pasted_size)) {
+       pathrelse(p_s_search_path);
+       return -EDQUOT;
+    }
    init_tb_struct(th, &s_paste_balance, th->t_super, p_s_search_path, n_pasted_size);
#ifdef DISPLACE_NEW_PACKING_LOCALITIES
    s_paste_balance.key = p_s_key->on_disk_key;
#endif
-
-    while ( (retval = fix_nodes(M_PASTE, &s_paste_balance, NULL, p_c_body)) == REPEAT_SEARCH ) {
+
+    /* DQUOT_* can schedule, must check before the fix_nodes */
+    if (fs_changed(fs_gen, inode->i_sb)) {
+       goto search_again;
+    }
+
+    while ((retval = fix_nodes(M_PASTE, &s_paste_balance, NULL, p_c_body)) ==
+REPEAT_SEARCH ) {
+search_again:
       /* file system changed while we were in the fix_nodes */
       PROC_INFO_INC( th -> t_super, paste_into_item_restarted );
       retval = search_for_position_by_key (th->t_super, p_s_key, p_s_search_path);
@@ -1899,6 +1982,10 @@
error_out:
    /* this also releases the path */
    unfix_nodes(&s_paste_balance);
+#ifdef REISERQUOTA_DEBUG
+    printk(KERN_DEBUG "reiserquota paste_into_item(): freeing %u id=%u type=%c\n", n_pasted_size, inode->i_uid, key2type(&(p_s_key->on_disk_key)));
+#endif
+    DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size);
    return retval ;
}

@@ -1908,23 +1995,45 @@
                        struct path         *  p_s_path,         /* Path to the inserteded item.         */
                        const struct cpu_key      * key,
                        struct item_head    *  p_s_ih,           /* Pointer to the item header to insert.*/
+                        struct inode        * inode,
                        const char          *  p_c_body)         /* Pointer to the bytes to insert.      */
{
    struct tree_balance s_ins_balance;
    int                 retval;
+    int fs_gen = 0 ;
+    int quota_bytes = 0 ;

+    if (inode) {      /* Do we count quotas for item? */
+       fs_gen = get_generation(inode->i_sb);
+       quota_bytes = ih_item_len(p_s_ih);
+
+       /* hack so the quota code doesn't have to guess if the file has
+        ** a tail, links are always tails, so there's no guessing needed
+        */
+       if (!S_ISLNK (inode->i_mode) && is_direct_le_ih(p_s_ih)) {
+           quota_bytes = inode->i_sb->s_blocksize + UNFM_P_SIZE ;
+       }
+#ifdef REISERQUOTA_DEBUG
+       printk(KERN_DEBUG "reiserquota insert_item(): allocating %u id=%u type=%c\n", quota_bytes, inode->i_uid, head2type(p_s_ih));
+#endif
+       /* We can't dirty inode here. It would be immediately written but
+        * appropriate stat item isn't inserted yet... */
+       if (DQUOT_ALLOC_SPACE_NODIRTY(inode, quota_bytes)) {
+           pathrelse(p_s_path);
+           return -EDQUOT;
+       }
+    }
    init_tb_struct(th, &s_ins_balance, th->t_super, p_s_path, IH_SIZE + ih_item_len(p_s_ih));
#ifdef DISPLACE_NEW_PACKING_LOCALITIES
    s_ins_balance.key = key->on_disk_key;
#endif
-
-    /*
-    if (p_c_body == 0)
-      n_zeros_num = ih_item_len(p_s_ih);
-    */
-    //    le_key2cpu_key (&key, &(p_s_ih->ih_key));
+    /* DQUOT_* can schedule, must check to be sure calling fix_nodes is safe */
+    if (inode && fs_changed(fs_gen, inode->i_sb)) {
+       goto search_again;
+    }

    while ( (retval = fix_nodes(M_INSERT, &s_ins_balance, p_s_ih, p_c_body)) == REPEAT_SEARCH) {
+search_again:
       /* file system changed while we were in the fix_nodes */
       PROC_INFO_INC( th -> t_super, insert_item_restarted );
       retval = search_item (th->t_super, key, p_s_path);
@@ -1939,7 +2048,7 @@
           goto error_out;
       }
    }
-
+
    /* make balancing after all resources will be collected at a time */
    if ( retval == CARRY_ON ) {
       do_balance (&s_ins_balance, p_s_ih, p_c_body, M_INSERT);
@@ -1950,6 +2059,11 @@
error_out:
    /* also releases the path */
    unfix_nodes(&s_ins_balance);
+#ifdef REISERQUOTA_DEBUG
+    printk(KERN_DEBUG "reiserquota insert_item(): freeing %u id=%u type=%c\n", quota_bytes, inode->i_uid, head2type(p_s_ih));
+#endif
+    if (inode)
+       DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes) ;
    return retval;
}

Index: linux.d/fs/reiserfs/namei.c
===================================================================
--- linux.d.orig/fs/reiserfs/namei.c    2003-12-03 19:38:26.000000000 -0500
+++ linux.d/fs/reiserfs/namei.c 2003-12-03 19:59:27.000000000 -0500
@@ -7,6 +7,7 @@
#include <linux/bitops.h>
#include <linux/reiserfs_fs.h>
#include <linux/smp_lock.h>
+#include <linux/quotaops.h>

#define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { i->i_nlink++; if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; }
#define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) i->i_nlink--;
@@ -469,7 +470,7 @@
    }

    /* perform the insertion of the entry that we have prepared */
-    retval = reiserfs_paste_into_item (th, &path, &entry_key, buffer, paste_size);
+    retval = reiserfs_paste_into_item (th, &path, &entry_key, dir, buffer, paste_size);
    if (buffer != small_buf)
       reiserfs_kfree (buffer, buflen, dir->i_sb);
    if (retval) {
@@ -478,7 +479,6 @@
    }

    dir->i_size += paste_size;
-    dir->i_blocks = ((dir->i_size + 511) >> 9);
    dir->i_mtime = dir->i_ctime = CURRENT_TIME;
    if (!S_ISDIR (inode->i_mode) && visible)
       // reiserfs_mkdir or reiserfs_rename will do that by itself
@@ -494,7 +494,9 @@
** inserted into the tree yet.
*/
static int drop_new_inode(struct inode *inode) {
+    DQUOT_DROP(inode);
    make_bad_inode(inode) ;
+    inode->i_flags |= S_NOQUOTA;
    iput(inode) ;
    return 0 ;
}
@@ -518,6 +520,11 @@
    } else
        inode->i_gid = current->fsgid;

+    DQUOT_INIT(inode);
+    if (DQUOT_ALLOC_INODE(inode)) {
+        drop_new_inode(inode);
+       return -EDQUOT;
+    }
    return 0 ;
}

@@ -749,7 +756,6 @@

    DEC_DIR_INODE_NLINK(dir)
    dir->i_size -= (DEH_SIZE + de.de_entrylen);
-    dir->i_blocks = ((dir->i_size + 511) >> 9);
    reiserfs_update_sd (&th, dir);

    /* prevent empty directory from getting lost */
@@ -834,7 +840,6 @@
    reiserfs_update_sd (&th, inode);

    dir->i_size -= (de.de_entrylen + DEH_SIZE);
-    dir->i_blocks = ((dir->i_size + 511) >> 9);
    dir->i_ctime = dir->i_mtime = CURRENT_TIME;
    reiserfs_update_sd (&th, dir);

@@ -1244,7 +1249,6 @@
       reiserfs_warning ((&th)->t_super, "vs-7060: reiserfs_rename: couldn't not cut old name. Fsck later?\n");

    old_dir->i_size -= DEH_SIZE + old_de.de_entrylen;
-    old_dir->i_blocks = ((old_dir->i_size + 511) >> 9);

    reiserfs_update_sd (&th, old_dir);
    reiserfs_update_sd (&th, new_dir);
Index: linux.d/fs/reiserfs/super.c
===================================================================
--- linux.d.orig/fs/reiserfs/super.c    2003-12-03 19:38:26.000000000 -0500
+++ linux.d/fs/reiserfs/super.c 2003-12-03 19:59:27.000000000 -0500
@@ -109,7 +109,7 @@
     /* we are going to do one balancing */
     journal_begin (&th, s, JOURNAL_PER_BALANCE_CNT);

-     reiserfs_delete_solid_item (&th, key);
+     reiserfs_delete_solid_item (&th, NULL, key);
     if (oid_free)
        /* removals are protected by direct items */
        reiserfs_release_objectid (&th, le32_to_cpu (key->k_objectid));
@@ -295,8 +295,8 @@
    /* body of "save" link */
    link = INODE_PKEY (inode)->k_dir_id;

-    /* put "save" link inot tree */
-    retval = reiserfs_insert_item (th, &path, &key, &ih, (char *)&link);
+    /* put "save" link inot tree, don't charge quota to anyone */
+    retval = reiserfs_insert_item (th, &path, &key, &ih, NULL, (char *)&link);
    if (retval) {
       if (retval != -ENOSPC)
           reiserfs_warning (inode->i_sb, "vs-2120: add_save_link: insert_item returned %d\n",
@@ -338,7 +338,8 @@
          ( inode -> u.reiserfs_i.i_flags & i_link_saved_truncate_mask ) ) ||
        ( !truncate &&
          ( inode -> u.reiserfs_i.i_flags & i_link_saved_unlink_mask ) ) )
-       reiserfs_delete_solid_item (&th, &key);
+       /* don't take quota bytes from anywhere */
+       reiserfs_delete_solid_item (&th, NULL, &key);
    if (!truncate) {
       reiserfs_release_objectid (&th, inode->i_ino);
       inode -> u.reiserfs_i.i_flags &= ~i_link_saved_unlink_mask;
@@ -636,6 +637,9 @@
               {"resize", 'r', 0, 0, 0},
               {"attrs", 0, 0, 1<<REISERFS_ATTRS, 0},
               {"noattrs", 0, 0, 0, 1<<REISERFS_ATTRS},
+               {"usrquota", 0, 0, 0, 0},
+               {"grpquota", 0, 0, 0, 0},
+
               {NULL, 0, 0, 0, 0}
    };

Index: linux.d/fs/reiserfs/file.c
===================================================================
--- linux.d.orig/fs/reiserfs/file.c     2003-12-03 19:38:26.000000000 -0500
+++ linux.d/fs/reiserfs/file.c  2003-12-03 19:59:27.000000000 -0500
@@ -6,6 +6,7 @@
#include <linux/sched.h>
#include <linux/reiserfs_fs.h>
#include <linux/smp_lock.h>
+#include <linux/quotaops.h>

/*
** We pack the tails of files on file close, not at the time they are written.
@@ -92,7 +93,9 @@
static int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
    struct inode *inode = dentry->d_inode ;
    int error ;
-    if (attr->ia_valid & ATTR_SIZE) {
+    unsigned int ia_valid = attr->ia_valid ;
+
+    if (ia_valid & ATTR_SIZE) {
       /* version 2 items will be caught by the s_maxbytes check
       ** done for us in vmtruncate
       */
@@ -131,9 +134,14 @@
           return -EINVAL;

    error = inode_change_ok(inode, attr) ;
-    if (!error)
-        inode_setattr(inode, attr) ;
+    if (!error) {
+       if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
+           (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
+               error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;

+       if (!error)
+           error = inode_setattr(inode, attr) ;
+    }
    return error ;
}

Index: linux.d/fs/reiserfs/fix_node.c
===================================================================
--- linux.d.orig/fs/reiserfs/fix_node.c 2003-12-03 19:38:26.000000000 -0500
+++ linux.d/fs/reiserfs/fix_node.c      2003-12-03 19:59:27.000000000 -0500
@@ -795,8 +795,9 @@
  else /* If we have enough already then there is nothing to do. */
    return CARRY_ON;

-  if ( reiserfs_new_form_blocknrs (p_s_tb, a_n_blocknrs,
-                                   n_amount_needed) == NO_DISK_SPACE )
+  /* No need to check quota - is not allocated for blocks used for formatted nodes */
+  if (reiserfs_new_form_blocknrs (p_s_tb, a_n_blocknrs,
+                                   n_amount_needed) == NO_DISK_SPACE)
    return NO_DISK_SPACE;

  /* for each blocknumber we just got, get a buffer and stick it on FEB */
@@ -2519,7 +2520,7 @@
           /* de-allocated block which was not used by balancing and
               bforget about buffer for it */
           brelse (tb->FEB[i]);
-           reiserfs_free_block (tb->transaction_handle, blocknr);
+           reiserfs_free_block (tb->transaction_handle, NULL, blocknr, 0);
       }
       if (tb->used[i]) {
           /* release used as new nodes including a new root */
Index: linux.d/fs/reiserfs/inode.c
===================================================================
--- linux.d.orig/fs/reiserfs/inode.c    2003-12-03 19:43:20.000000000 -0500
+++ linux.d/fs/reiserfs/inode.c 2003-12-03 20:03:02.000000000 -0500
@@ -4,9 +4,11 @@

#include <linux/config.h>
#include <linux/sched.h>
+#include <linux/fs.h>
#include <linux/reiserfs_fs.h>
#include <linux/locks.h>
#include <linux/smp_lock.h>
+#include <linux/quotaops.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>

@@ -35,6 +37,7 @@

    lock_kernel() ;

+    DQUOT_FREE_INODE(inode);
    /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */
    if (INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */
       down (&inode->i_sem);
@@ -681,7 +684,7 @@

       repeat = _allocate_block(th, block, inode, &allocated_block_nr, &path, create);

-       if (repeat == NO_DISK_SPACE) {
+       if (repeat == NO_DISK_SPACE || repeat == QUOTA_EXCEEDED) {
           /* restart the transaction to give the journal a chance to free
           ** some blocks.  releases the path, so we have to go back to
           ** research if we succeed on the second try
@@ -693,10 +696,13 @@
           restart_transaction(th, inode, &path, jbegin_count) ;
           repeat = _allocate_block(th, block, inode, &allocated_block_nr, NULL, create);

-           if (repeat != NO_DISK_SPACE) {
+           if (repeat != NO_DISK_SPACE && repeat != QUOTA_EXCEEDED) {
               goto research ;
           }
-           retval = -ENOSPC;
+           if (repeat == QUOTA_EXCEEDED)
+               retval = -EDQUOT;
+           else
+               retval = -ENOSPC;
           goto failure;
       }

@@ -722,7 +728,6 @@
           put_block_num(item, pos_in_item, allocated_block_nr) ;
            unfm_ptr = allocated_block_nr;
           journal_mark_dirty (th, inode->i_sb, bh);
-           inode->i_blocks += (inode->i_sb->s_blocksize / 512) ;
           reiserfs_update_sd(th, inode) ;
       }
       set_block_dev_mapped(bh_result, unfm_ptr, inode);
@@ -780,13 +785,11 @@
           set_cpu_key_k_offset (&tmp_key, 1);
           PATH_LAST_POSITION(&path) ++;

-           retval = reiserfs_insert_item (th, &path, &tmp_key, &tmp_ih, (char *)&unp);
+           retval = reiserfs_insert_item (th, &path, &tmp_key, &tmp_ih, inode, (char *)&unp);
           if (retval) {
-               reiserfs_free_block (th, allocated_block_nr);
-               goto failure; // retval == -ENOSPC or -EIO or -EEXIST
+               reiserfs_free_block (th, inode, allocated_block_nr, 1);
+               goto failure; // retval == -ENOSPC, -EDQUOT or -EIO or -EEXIST
           }
-           if (unp)
-               inode->i_blocks += inode->i_sb->s_blocksize / 512;
           //mark_tail_converted (inode);
       } else if (is_direct_le_ih (ih)) {
           /* direct item has to be converted */
@@ -824,7 +827,7 @@
                           th = reiserfs_persistent_transaction(inode->i_sb,3);
                       }
                       if (!IS_ERR(th)) {
-                           reiserfs_free_block (th, allocated_block_nr);
+                           reiserfs_free_block(th,inode,allocated_block_nr,1);
                       }

                   }
@@ -835,7 +838,7 @@
           retval = direct2indirect (th, inode, &path, unbh, tail_offset);
           if (retval) {
               reiserfs_unmap_buffer(unbh);
-               reiserfs_free_block (th, allocated_block_nr);
+               reiserfs_free_block (th, inode, allocated_block_nr, 1);
               goto failure;
           }

@@ -917,18 +920,16 @@
                  only have space for one block */
               blocks_needed=max_to_insert?max_to_insert:1;
           }
-           retval = reiserfs_paste_into_item (th, &path, &tmp_key, (char *)un, UNFM_P_SIZE * blocks_needed);
+           retval = reiserfs_paste_into_item (th, &path, &tmp_key, inode, (char *)un, UNFM_P_SIZE * blocks_needed);

           if (blocks_needed != 1)
                kfree(un);

           if (retval) {
-               reiserfs_free_block (th, allocated_block_nr);
+               reiserfs_free_block (th, inode, allocated_block_nr, 1);
               goto failure;
           }
-           if (done) {
-               inode->i_blocks += inode->i_sb->s_blocksize / 512;
-           } else {
+           if (!done) {
               /* We need to mark new file size in case this function will be
                  interrupted/aborted later on. And we may do this only for
                  holes. */
@@ -970,7 +971,7 @@
                             "%K should not be found\n", &key);
           retval = -EEXIST;
           if (allocated_block_nr)
-               reiserfs_free_block (th, allocated_block_nr);
+               reiserfs_free_block (th, inode, allocated_block_nr, 1);
           pathrelse(&path) ;
           goto failure;
       }
@@ -1006,6 +1007,58 @@
}


+/* Compute real number of used bytes by file
+ * Following three functions can go away when we'll have enough space in stat item
+ */
+static int real_space_diff(struct inode *inode, int sd_size)
+{
+    int bytes;
+    loff_t blocksize = inode->i_sb->s_blocksize ;
+
+    if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode))
+        return sd_size ;
+
+    /* End of file is also in full block with indirect reference, so round
+    ** up to the next block.
+    **
+    ** there is just no way to know if the tail is actually packed
+    ** on the file, so we have to assume it isn't.  When we pack the
+    ** tail, we add 4 bytes to pretend there really is an unformatted
+    ** node pointer
+    */
+    bytes = ((inode->i_size + (blocksize-1)) >> inode->i_sb->s_blocksize_bits) * UNFM_P_SIZE + sd_size;
+    return bytes ;
+}
+
+static inline loff_t to_real_used_space(struct inode *inode, ulong blocks,
+                                        int sd_size)
+{
+    if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) {
+        return inode->i_size + (loff_t)(real_space_diff(inode, sd_size)) ;
+    }
+    return ((loff_t)real_space_diff(inode, sd_size)) + (((loff_t)blocks) << 9);
+}
+
+/* Compute number of blocks used by file in ReiserFS counting */
+static inline ulong to_fake_used_blocks(struct inode *inode, int sd_size)
+{
+    loff_t bytes = inode_get_bytes(inode) ;
+    loff_t real_space = real_space_diff(inode, sd_size) ;
+
+    /* keeps fsck and non-quota versions of reiserfs happy */
+    if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) {
+        bytes += (loff_t)511 ;
+    }
+
+    /* files from before the quota patch might i_blocks such that
+    ** bytes < real_space.  Deal with that here to prevent it from
+    ** going negative.
+    */
+    if (bytes < real_space)
+        return 0 ;
+    return (bytes - real_space) >> 9;
+}
+
//
// BAD: new directories have stat data of new type and all other items
// of old type. Version stored in the inode says about body items, so
@@ -1061,6 +1114,14 @@

        rdev = sd_v1_rdev(sd);
       inode->u.reiserfs_i.i_first_direct_byte = sd_v1_first_direct_byte(sd);
+       /* an early bug in the quota code can give us an odd number for the
+       ** block count.  This is incorrect, fix it here.
+       */
+       if (inode->i_blocks & 1) {
+           inode->i_blocks++ ;
+       }
+       inode_set_bytes(inode, to_real_used_space(inode, inode->i_blocks,
+                                                 SD_V1_SIZE));
       /* nopack is initially zero for v1 objects. For v2 objects,
          nopack is initialised from sd_attrs */
       inode->u.reiserfs_i.i_flags &= ~i_nopack_mask;
@@ -1090,6 +1151,8 @@
            set_inode_item_key_version (inode, KEY_FORMAT_3_6);

        set_inode_sd_version (inode, STAT_DATA_V2);
+       inode_set_bytes(inode, to_real_used_space(inode, inode->i_blocks,
+                                                 SD_V2_SIZE));
       /* read persistent inode attributes from sd and initalise
          generic inode flags from them */
       inode -> u.reiserfs_i.i_attrs = sd_v2_attrs( sd );
@@ -1129,7 +1192,7 @@
    set_sd_v2_mtime(sd_v2, inode->i_mtime );
    set_sd_v2_atime(sd_v2, inode->i_atime );
    set_sd_v2_ctime(sd_v2, inode->i_ctime );
-    set_sd_v2_blocks(sd_v2, inode->i_blocks );
+    set_sd_v2_blocks(sd_v2, to_fake_used_blocks(inode, SD_V2_SIZE));
    if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
        set_sd_v2_rdev(sd_v2, inode->i_rdev );
    else
@@ -1157,7 +1220,7 @@
    if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
        set_sd_v1_rdev(sd_v1, inode->i_rdev );
    else
-        set_sd_v1_blocks(sd_v1, inode->i_blocks );
+        set_sd_v1_blocks(sd_v1, to_fake_used_blocks(inode, SD_V1_SIZE));

    // Sigh. i_first_direct_byte is back
    set_sd_v1_first_direct_byte(sd_v1, inode->u.reiserfs_i.i_first_direct_byte);
@@ -1537,6 +1600,7 @@
/* stat data of new object is inserted already, this inserts the item
   containing "." and ".." entries */
static int reiserfs_new_directory (struct reiserfs_transaction_handle *th,
+                                  struct inode *inode,
                                  struct item_head * ih, struct path * path,
                                  const struct inode * dir)
{
@@ -1581,13 +1645,14 @@
    }

    /* insert item, that is empty directory item */
-    return reiserfs_insert_item (th, path, &key, ih, body);
+    return reiserfs_insert_item (th, path, &key, ih, inode, body);
}


/* stat data of object has been inserted, this inserts the item
   containing the body of symlink */
static int reiserfs_new_symlink (struct reiserfs_transaction_handle *th,
+                                struct inode *inode,   /* Inode of symlink */
                                struct item_head * ih,
                                struct path * path, const char * symname, int item_len)
{
@@ -1617,7 +1682,7 @@
    }

    /* insert item, that is body of symlink */
-    return reiserfs_insert_item (th, path, &key, ih, symname);
+    return reiserfs_insert_item (th, path, &key, ih, inode, symname);
}


@@ -1691,7 +1756,8 @@

    inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
    inode->i_size = i_size;
-    inode->i_blocks = (inode->i_size + 511) >> 9;
+    inode->i_blocks = 0;
+    inode->i_bytes = 0;
    inode->u.reiserfs_i.i_first_direct_byte = S_ISLNK(mode) ? 1 :
      U32_MAX/*NO_BYTES_IN_DIRECT_ITEM*/;

@@ -1752,7 +1818,7 @@
    if (dir->u.reiserfs_i.new_packing_locality)
       th->displace_new_blocks = 1;
#endif
-    retval = reiserfs_insert_item (th, &path_to_key, &key, &ih, (char *)(&sd));
+    retval = reiserfs_insert_item (th, &path_to_key, &key, &ih, inode, (char *)(&sd));
    if (retval) {
       reiserfs_check_path(&path_to_key) ;
       err = retval;
@@ -1765,14 +1831,14 @@
#endif
    if (S_ISDIR(mode)) {
       /* insert item with "." and ".." */
-       retval = reiserfs_new_directory (th, &ih, &path_to_key, dir);
+       retval = reiserfs_new_directory (th, inode, &ih, &path_to_key, dir);
    }

    if (S_ISLNK(mode)) {
       /* insert body of symlink */
       if (!old_format_only (sb))
           i_size = ROUND_UP(i_size);
-       retval = reiserfs_new_symlink (th, &ih, &path_to_key, symname, i_size);
+       retval = reiserfs_new_symlink (th, inode, &ih, &path_to_key, symname, i_size);
    }
    if (retval) {
       err = retval;
@@ -1792,6 +1858,9 @@

    /* dquot_drop must be done outside a transaction */
    journal_end(th, th->t_super, th->t_blocks_allocated) ;
+    DQUOT_FREE_INODE(inode);
+    DQUOT_DROP(inode);
+    inode->i_flags |= S_NOQUOTA;
    make_bad_inode(inode);

out_inserted_sd:
Index: linux.d/fs/reiserfs/do_balan.c
===================================================================
--- linux.d.orig/fs/reiserfs/do_balan.c 2003-12-03 19:38:26.000000000 -0500
+++ linux.d/fs/reiserfs/do_balan.c      2003-12-03 19:59:27.000000000 -0500
@@ -1239,7 +1239,7 @@
           if (buffer_dirty (tb->thrown[i]))
             reiserfs_warning (tb->tb_sb, "free_thrown deals with dirty buffer %ld\n", blocknr);
           brelse(tb->thrown[i]) ; /* incremented in store_thrown */
-           reiserfs_free_block (tb->transaction_handle, blocknr);
+           reiserfs_free_block (tb->transaction_handle, NULL, blocknr, 0);
       }
    }
}
@@ -1255,7 +1255,7 @@
        BUG();
    // mark_buffer_clean (bh);
    /* reiserfs_free_block is no longer schedule safe
-    reiserfs_free_block (tb->transaction_handle, tb->tb_sb, bh->b_blocknr);
+    reiserfs_free_block (tb->transaction_handle, NULL, tb->tb_sb, bh->b_blocknr, 0);
    */

    store_thrown (tb, bh);
Index: linux.d/include/linux/reiserfs_fs.h
===================================================================
--- linux.d.orig/include/linux/reiserfs_fs.h    2003-12-03 19:38:26.000000000 -0500
+++ linux.d/include/linux/reiserfs_fs.h 2003-12-03 19:59:27.000000000 -0500
@@ -266,6 +266,7 @@
#define NO_DISK_SPACE -3
#define NO_BALANCING_NEEDED  (-4)
#define NO_MORE_UNUSED_CONTIGUOUS_BLOCKS (-5)
+#define QUOTA_EXCEEDED -6

typedef unsigned long b_blocknr_t;
typedef __u32 unp_t;
@@ -1932,11 +1933,13 @@
int reiserfs_insert_item (struct reiserfs_transaction_handle *th,
                         struct path * path,
                         const struct cpu_key * key,
-                         struct item_head * ih, const char * body);
+                         struct item_head * ih,
+                         struct inode *inode, const char * body);

int reiserfs_paste_into_item (struct reiserfs_transaction_handle *th,
                             struct path * path,
                             const struct cpu_key * key,
+                             struct inode *inode,
                             const char * body, int paste_size);

int reiserfs_cut_from_item (struct reiserfs_transaction_handle *th,
@@ -1953,7 +1956,7 @@
                         struct buffer_head  * p_s_un_bh);

void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th,
-                                                                struct key * key);
+                                struct inode *inode, struct key * key);
void reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inode * p_s_inode);
void reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
                          struct  inode * p_s_inode, struct page *,
@@ -2090,7 +2093,7 @@
extern struct inode_operations reiserfs_file_inode_operations;
extern struct file_operations reiserfs_file_operations;
extern struct address_space_operations reiserfs_address_space_operations ;
-int get_new_buffer (struct reiserfs_transaction_handle *th, struct buffer_head *,
+int get_new_buffer (struct reiserfs_transaction_handle *th, struct inode *, struct buffer_head *,
                   struct buffer_head **, struct path *);


@@ -2204,7 +2207,7 @@

int reiserfs_parse_alloc_options (struct super_block *, char *);
int is_reusable (struct super_block * s, unsigned long block, int bit_value);
-void reiserfs_free_block (struct reiserfs_transaction_handle *th, unsigned long);
+void reiserfs_free_block (struct reiserfs_transaction_handle *th, struct inode *inode, unsigned long, int);
int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *, b_blocknr_t * , int, int);
extern inline int reiserfs_new_form_blocknrs (struct tree_balance * tb,
                                             b_blocknr_t *new_blocknrs, int amount_needed)