#include <linux/reiserfs_fs.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.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)
return ( B_LEVEL (p_s_bh) != FREE_LEVEL );
}
-
-
-
inline void copy_short_key (void * to, const void * from)
{
memcpy (to, from, SHORT_KEY_SIZE);
if (cpu_key_k_offset (key1) > cpu_key_k_offset (key2))
return 1;
- reiserfs_warning ("comp_cpu_keys: type are compared for %K and %K\n",
+ reiserfs_warning (NULL, "comp_cpu_keys: type are compared for %K and %K",
key1, key2);
if (cpu_key_k_type (key1) < cpu_key_k_type (key2))
blkh = (struct block_head *)buf;
if ( blkh_level(blkh) != DISK_LEAF_NODE_LEVEL) {
- printk ("is_leaf: this should be caught earlier\n");
+ reiserfs_warning (NULL, "is_leaf: this should be caught earlier");
return 0;
}
nr = blkh_nr_item(blkh);
if (nr < 1 || nr > ((blocksize - BLKH_SIZE) / (IH_SIZE + MIN_ITEM_LEN))) {
/* item number is too big or too small */
- reiserfs_warning ("is_leaf: nr_item seems wrong: %z\n", bh);
+ reiserfs_warning (NULL, "is_leaf: nr_item seems wrong: %z", bh);
return 0;
}
ih = (struct item_head *)(buf + BLKH_SIZE) + nr - 1;
used_space = BLKH_SIZE + IH_SIZE * nr + (blocksize - ih_location (ih));
if (used_space != blocksize - blkh_free_space(blkh)) {
/* free space does not match to calculated amount of use space */
- reiserfs_warning ("is_leaf: free space seems wrong: %z\n", bh);
+ reiserfs_warning (NULL, "is_leaf: free space seems wrong: %z", bh);
return 0;
}
prev_location = blocksize;
for (i = 0; i < nr; i ++, ih ++) {
if ( le_ih_k_type(ih) == TYPE_ANY) {
- reiserfs_warning ("is_leaf: wrong item type for item %h\n",ih);
+ reiserfs_warning (NULL, "is_leaf: wrong item type for item %h",ih);
return 0;
}
if (ih_location (ih) >= blocksize || ih_location (ih) < IH_SIZE * nr) {
- reiserfs_warning ("is_leaf: item location seems wrong: %h\n", ih);
+ reiserfs_warning (NULL, "is_leaf: item location seems wrong: %h", ih);
return 0;
}
if (ih_item_len (ih) < 1 || ih_item_len (ih) > MAX_ITEM_LEN (blocksize)) {
- reiserfs_warning ("is_leaf: item length seems wrong: %h\n", ih);
+ reiserfs_warning (NULL, "is_leaf: item length seems wrong: %h", ih);
return 0;
}
if (prev_location - ih_location (ih) != ih_item_len (ih)) {
- reiserfs_warning ("is_leaf: item location seems wrong (second one): %h\n", ih);
+ reiserfs_warning (NULL, "is_leaf: item location seems wrong (second one): %h", ih);
return 0;
}
prev_location = ih_location (ih);
nr = blkh_level(blkh);
if (nr <= DISK_LEAF_NODE_LEVEL || nr > MAX_HEIGHT) {
/* this level is not possible for internal nodes */
- printk ("is_internal: this should be caught earlier\n");
+ reiserfs_warning (NULL, "is_internal: this should be caught earlier");
return 0;
}
nr = blkh_nr_item(blkh);
if (nr > (blocksize - BLKH_SIZE - DC_SIZE) / (KEY_SIZE + DC_SIZE)) {
/* for internal which is not root we might check min number of keys */
- reiserfs_warning ("is_internal: number of key seems wrong: %z\n", bh);
+ reiserfs_warning (NULL, "is_internal: number of key seems wrong: %z", bh);
return 0;
}
used_space = BLKH_SIZE + KEY_SIZE * nr + DC_SIZE * (nr + 1);
if (used_space != blocksize - blkh_free_space(blkh)) {
- reiserfs_warning ("is_internal: free space seems wrong: %z\n", bh);
+ reiserfs_warning (NULL, "is_internal: free space seems wrong: %z", bh);
return 0;
}
static int is_tree_node (struct buffer_head * bh, int level)
{
if (B_LEVEL (bh) != level) {
- printk ("is_tree_node: node level %d does not match to the expected one %d\n",
+ reiserfs_warning (NULL, "is_tree_node: node level %d does not match to the expected one %d",
B_LEVEL (bh), level);
return 0;
}
#ifdef CONFIG_REISERFS_CHECK
if ( !(++n_repeat_counter % 50000) )
- reiserfs_warning ("PAP-5100: search_by_key: %s:"
+ reiserfs_warning (p_s_sb, "PAP-5100: search_by_key: %s:"
"there were %d iterations of while loop "
- "looking for key %K\n",
+ "looking for key %K",
current->comm, n_repeat_counter, p_s_key);
#endif
// make sure, that the node contents look like a node of
// certain level
if (!is_tree_node (p_s_bh, expected_level)) {
- reiserfs_warning ("vs-5150: search_by_key: "
- "invalid format found in block %ld. Fsck?\n",
+ reiserfs_warning (p_s_sb, "vs-5150: search_by_key: "
+ "invalid format found in block %ld. Fsck?",
p_s_bh->b_blocknr);
pathrelse (p_s_search_path);
return IO_ERROR;
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);
if ( item_moved (&s_ih, p_s_path) ) {
need_research = 1;
break ;
}
}
-
-/* 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
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)*
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;
if (n_ret_value == IO_ERROR)
break;
if (n_ret_value == FILE_NOT_FOUND) {
- reiserfs_warning ("vs-5340: reiserfs_delete_item: "
- "no items of the file %K found\n", p_s_item_key);
+ reiserfs_warning (p_s_sb, "vs-5340: reiserfs_delete_item: "
+ "no items of the file %K found", p_s_item_key);
break;
}
} /* while (1) */
// 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;
B_I_PITEM(PATH_PLAST_BUFFER(p_s_path), &s_ih), n_ret_value);
kunmap_atomic(data, KM_USER0);
}
-
/* Perform balancing after all resources have been collected at once. */
do_balance(&s_del_balance, NULL, NULL, M_DELETE);
+#ifdef REISERQUOTA_DEBUG
+ reiserfs_debug (p_s_sb, "reiserquota delete_item(): freeing %u, id=%u type=%c", 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;
}
/* 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);
while (1) {
retval = search_item (th->t_super, &cpu_key, &path);
if (retval == IO_ERROR) {
- reiserfs_warning ("vs-5350: reiserfs_delete_solid_item: "
- "i/o failure occurred trying to delete %K\n", &cpu_key);
+ reiserfs_warning (th->t_super,
+ "vs-5350: reiserfs_delete_solid_item: "
+ "i/o failure occurred trying to delete %K",
+ &cpu_key);
break;
}
if (retval != ITEM_FOUND) {
// No need for a warning, if there is just no free space to insert '..' item into the newly-created subdir
if ( !( (unsigned long long) GET_HASH_VALUE (le_key_k_offset (le_key_version (key), key)) == 0 && \
(unsigned long long) GET_GENERATION_NUMBER (le_key_k_offset (le_key_version (key), key)) == 1 ) )
- reiserfs_warning ("vs-5355: reiserfs_delete_solid_item: %k not found", key);
+ reiserfs_warning (th->t_super, "vs-5355: reiserfs_delete_solid_item: %k not found", key);
break;
}
if (!tb_init) {
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) {
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
+ reiserfs_debug (th->t_super, "reiserquota delete_solid_item(): freeing %u id=%u type=%c", quota_cut_bytes, inode->i_uid, key2type(key));
+#endif
+ DQUOT_FREE_SPACE_NODIRTY(inode, quota_cut_bytes);
+ }
break;
}
// IO_ERROR, NO_DISK_SPACE, etc
- reiserfs_warning ("vs-5360: reiserfs_delete_solid_item: "
- "could not delete %K due to fix_nodes failure\n", &cpu_key);
+ reiserfs_warning (th->t_super, "vs-5360: reiserfs_delete_solid_item: "
+ "could not delete %K due to fix_nodes failure", &cpu_key);
unfix_nodes (&tb);
break;
}
}
/* USE_INODE_GENERATION_COUNTER */
#endif
- reiserfs_delete_solid_item (th, INODE_PKEY (inode));
+ reiserfs_delete_solid_item (th, inode, INODE_PKEY (inode));
}
tail_len -= removed;
set_cpu_key_k_offset (&tail_key, cpu_key_k_offset (&tail_key) - removed);
}
- printk ("indirect_to_direct_roll_back: indirect_to_direct conversion has been rolled back due to lack of disk space\n");
+ reiserfs_warning (inode->i_sb, "indirect_to_direct_roll_back: indirect_to_direct conversion has been rolled back due to lack of disk space");
//mark_file_without_tail (inode);
mark_inode_dirty (inode);
}
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;
int n_cut_size = 0, /* Amount to be cut. */
n_ret_value = CARRY_ON,
n_removed = 0, /* Number of the removed unformatted nodes. */
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);
if (n_ret_value == POSITION_FOUND)
continue;
- reiserfs_warning ("PAP-5610: reiserfs_cut_from_item: item %K not found\n", p_s_item_key);
+ reiserfs_warning (p_s_sb, "PAP-5610: reiserfs_cut_from_item: item %K not found", p_s_item_key);
unfix_nodes (&s_cut_balance);
return (n_ret_value == IO_ERROR) ? -EIO : -ENOENT;
} /* while */
indirect_to_direct_roll_back (th, p_s_inode, p_s_path);
}
if (n_ret_value == NO_DISK_SPACE)
- reiserfs_warning ("NO_DISK_SPACE");
+ reiserfs_warning (p_s_sb, "NO_DISK_SPACE");
unfix_nodes (&s_cut_balance);
return -EIO;
}
RFALSE( c_mode == M_PASTE || c_mode == M_INSERT, "invalid 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
REISERFS_I(p_s_inode)->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);
*/
REISERFS_I(p_s_inode)->i_flags &= ~i_pack_on_close_mask ;
}
+#ifdef REISERQUOTA_DEBUG
+ reiserfs_debug (p_s_inode->i_sb, "reiserquota cut_from_item(): freeing %u id=%u type=%c", quota_cut_bytes, p_s_inode->i_uid, '?');
+#endif
+ DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
return n_ret_value;
}
-
static void truncate_directory (struct reiserfs_transaction_handle *th, struct inode * inode)
{
if (inode->i_nlink)
- reiserfs_warning ("vs-5655: truncate_directory: link count != 0\n");
+ reiserfs_warning (inode->i_sb,
+ "vs-5655: truncate_directory: link count != 0");
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);
}
retval = search_for_position_by_key(p_s_inode->i_sb, &s_item_key, &s_search_path);
if (retval == IO_ERROR) {
- reiserfs_warning ("vs-5657: reiserfs_do_truncate: "
- "i/o failure occurred trying to truncate %K\n", &s_item_key);
+ reiserfs_warning (p_s_inode->i_sb, "vs-5657: reiserfs_do_truncate: "
+ "i/o failure occurred trying to truncate %K", &s_item_key);
return;
}
if (retval == POSITION_FOUND || retval == FILE_NOT_FOUND) {
pathrelse (&s_search_path);
- reiserfs_warning ("PAP-5660: reiserfs_do_truncate: "
- "wrong result %d of search for %K\n", retval, &s_item_key);
+ reiserfs_warning (p_s_inode->i_sb, "PAP-5660: reiserfs_do_truncate: "
+ "wrong result %d of search for %K", retval, &s_item_key);
return;
}
/* Cut or delete file item. */
n_deleted = reiserfs_cut_from_item(th, &s_search_path, &s_item_key, p_s_inode, page, n_new_file_size);
if (n_deleted < 0) {
- reiserfs_warning ("vs-5665: reiserfs_do_truncate: reiserfs_cut_from_item failed");
+ reiserfs_warning (p_s_inode->i_sb, "vs-5665: reiserfs_do_truncate: reiserfs_cut_from_item failed");
reiserfs_check_path(&s_search_path) ;
return;
}
search_for_position_by_key(p_s_inode->i_sb, &s_item_key, &s_search_path) == POSITION_FOUND ) ;
RFALSE( n_file_size > ROUND_UP (n_new_file_size),
- "PAP-5680: truncate did not finish: new_file_size %Ld, current %Ld, oid %d\n",
+ "PAP-5680: truncate did not finish: new_file_size %Ld, current %Ld, oid %d",
n_new_file_size, n_file_size, s_item_key.on_disk_key.k_objectid);
update_and_out:
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
+ reiserfs_debug (inode->i_sb, "reiserquota paste_into_item(): allocating %u id=%u type=%c", 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);
goto error_out ;
}
if (retval == POSITION_FOUND) {
- reiserfs_warning ("PAP-5710: reiserfs_paste_into_item: entry or pasted byte (%K) exists\n", p_s_key);
+ reiserfs_warning (inode->i_sb, "PAP-5710: reiserfs_paste_into_item: entry or pasted byte (%K) exists", p_s_key);
retval = -EEXIST ;
goto error_out ;
}
error_out:
/* this also releases the path */
unfix_nodes(&s_paste_balance);
+#ifdef REISERQUOTA_DEBUG
+ reiserfs_debug (inode->i_sb, "reiserquota paste_into_item(): freeing %u id=%u type=%c", n_pasted_size, inode->i_uid, key2type(&(p_s_key->on_disk_key)));
+#endif
+ DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size);
return retval ;
}
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
+ reiserfs_debug (inode->i_sb, "reiserquota insert_item(): allocating %u id=%u type=%c", 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);
goto error_out ;
}
if (retval == ITEM_FOUND) {
- reiserfs_warning ("PAP-5760: reiserfs_insert_item: "
- "key %K already exists in the tree\n", key);
+ reiserfs_warning (th->t_super, "PAP-5760: reiserfs_insert_item: "
+ "key %K already exists in the tree", key);
retval = -EEXIST ;
goto error_out;
}
error_out:
/* also releases the path */
unfix_nodes(&s_ins_balance);
+#ifdef REISERQUOTA_DEBUG
+ reiserfs_debug (th->t_super, "reiserquota insert_item(): freeing %u id=%u type=%c", quota_bytes, inode->i_uid, head2type(p_s_ih));
+#endif
+ if (inode)
+ DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes) ;
return retval;
}