Commit 446a7461 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] reiserfs: quota support

From: Chris Mason <mason@suse.com>

ReiserFS support for quotas.  Originally from Jan Kara
parent 30304fc9
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/reiserfs_fs_sb.h> #include <linux/reiserfs_fs_sb.h>
#include <linux/reiserfs_fs_i.h> #include <linux/reiserfs_fs_i.h>
#include <linux/quotaops.h>
#define PREALLOCATION_SIZE 9 #define PREALLOCATION_SIZE 9
...@@ -281,7 +282,8 @@ static int scan_bitmap (struct reiserfs_transaction_handle *th, ...@@ -281,7 +282,8 @@ static int scan_bitmap (struct reiserfs_transaction_handle *th,
} }
static void _reiserfs_free_block (struct reiserfs_transaction_handle *th, 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 super_block * s = th->t_super;
struct reiserfs_super_block * rs; struct reiserfs_super_block * rs;
...@@ -323,11 +325,13 @@ static void _reiserfs_free_block (struct reiserfs_transaction_handle *th, ...@@ -323,11 +325,13 @@ static void _reiserfs_free_block (struct reiserfs_transaction_handle *th,
set_sb_free_blocks( rs, sb_free_blocks(rs) + 1 ); set_sb_free_blocks( rs, sb_free_blocks(rs) + 1 );
journal_mark_dirty (th, s, sbh); journal_mark_dirty (th, s, sbh);
s->s_dirt = 1; if (for_unformatted)
DQUOT_FREE_BLOCK_NODIRTY(inode, 1);
} }
void reiserfs_free_block (struct reiserfs_transaction_handle *th, 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 super_block * s = th->t_super;
...@@ -335,42 +339,46 @@ void reiserfs_free_block (struct reiserfs_transaction_handle *th, ...@@ -335,42 +339,46 @@ void reiserfs_free_block (struct reiserfs_transaction_handle *th,
RFALSE(is_reusable (s, block, 1) == 0, "vs-4071: can not free such block"); RFALSE(is_reusable (s, block, 1) == 0, "vs-4071: can not free such block");
/* mark it before we clear it, just in case */ /* mark it before we clear it, just in case */
journal_mark_freed(th, s, block) ; 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 */ /* preallocated blocks don't need to be run through journal_mark_freed */
void reiserfs_free_prealloc_block (struct reiserfs_transaction_handle *th, void reiserfs_free_prealloc_block (struct reiserfs_transaction_handle *th,
b_blocknr_t block) { struct inode *inode, b_blocknr_t block) {
RFALSE(!th->t_super, "vs-4060: trying to free block on nonexistent device"); 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"); 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, static void __discard_prealloc (struct reiserfs_transaction_handle * th,
struct reiserfs_inode_info *ei) struct reiserfs_inode_info *ei)
{ {
unsigned long save = ei->i_prealloc_block ; unsigned long save = ei->i_prealloc_block ;
int dirty = 0;
struct inode *inode = &ei->vfs_inode;
#ifdef CONFIG_REISERFS_CHECK #ifdef CONFIG_REISERFS_CHECK
if (ei->i_prealloc_count < 0) if (ei->i_prealloc_count < 0)
reiserfs_warning("zam-4001:%s: inode has negative prealloc blocks count.\n", __FUNCTION__ ); reiserfs_warning("zam-4001:%s: inode has negative prealloc blocks count.\n", __FUNCTION__ );
#endif #endif
while (ei->i_prealloc_count > 0) { while (ei->i_prealloc_count > 0) {
reiserfs_free_prealloc_block(th,ei->i_prealloc_block); reiserfs_free_prealloc_block(th, inode, ei->i_prealloc_block);
ei->i_prealloc_block++; ei->i_prealloc_block++;
ei->i_prealloc_count --; ei->i_prealloc_count --;
dirty = 1;
} }
if (dirty)
reiserfs_update_sd(th, inode);
ei->i_prealloc_block = save; ei->i_prealloc_block = save;
list_del_init(&(ei->i_prealloc_list)); list_del_init(&(ei->i_prealloc_list));
} }
/* FIXME: It should be inline function */ /* FIXME: It should be inline function */
void reiserfs_discard_prealloc (struct reiserfs_transaction_handle *th, void reiserfs_discard_prealloc (struct reiserfs_transaction_handle *th,
struct inode * inode) struct inode *inode)
{ {
struct reiserfs_inode_info *ei = REISERFS_I(inode); struct reiserfs_inode_info *ei = REISERFS_I(inode);
if (ei->i_prealloc_count) { if (ei->i_prealloc_count)
__discard_prealloc(th, ei); __discard_prealloc(th, ei);
}
} }
void reiserfs_discard_all_prealloc (struct reiserfs_transaction_handle *th) void reiserfs_discard_all_prealloc (struct reiserfs_transaction_handle *th)
...@@ -772,6 +780,24 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start ...@@ -772,6 +780,24 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
int nr_allocated = 0; int nr_allocated = 0;
determine_prealloc_size(hint); 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 while((nr_allocated
+= allocate_without_wrapping_disk(hint, new_blocknrs + nr_allocated, start, finish, += allocate_without_wrapping_disk(hint, new_blocknrs + nr_allocated, start, finish,
amount_needed - nr_allocated, hint->prealloc_size)) amount_needed - nr_allocated, hint->prealloc_size))
...@@ -779,8 +805,14 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start ...@@ -779,8 +805,14 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
/* not all blocks were successfully allocated yet*/ /* not all blocks were successfully allocated yet*/
if (second_pass) { /* it was a second pass; we must free all blocks */ 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 --) 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; return NO_DISK_SPACE;
} else { /* refine search parameters for next pass */ } else { /* refine search parameters for next pass */
...@@ -789,7 +821,19 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start ...@@ -789,7 +821,19 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
start = 0; start = 0;
continue; continue;
} }
} }
if ( !hint->formatted_node &&
amount_needed + hint->prealloc_size >
nr_allocated + REISERFS_I(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 -
REISERFS_I(hint->inode)->i_prealloc_count);
}
return CARRY_ON; return CARRY_ON;
} }
...@@ -858,7 +902,7 @@ int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *hint, ...@@ -858,7 +902,7 @@ int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *hint,
if (ret != CARRY_ON) { if (ret != CARRY_ON) {
while (amount_needed ++ < initial_amount_needed) { 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; return ret;
......
...@@ -1234,7 +1234,7 @@ static void free_thrown(struct tree_balance *tb) { ...@@ -1234,7 +1234,7 @@ static void free_thrown(struct tree_balance *tb) {
if (buffer_dirty (tb->thrown[i])) if (buffer_dirty (tb->thrown[i]))
printk ("free_thrown deals with dirty buffer %d\n", blocknr); printk ("free_thrown deals with dirty buffer %d\n", blocknr);
brelse(tb->thrown[i]) ; /* incremented in store_thrown */ brelse(tb->thrown[i]) ; /* incremented in store_thrown */
reiserfs_free_block (tb->transaction_handle, blocknr); reiserfs_free_block (tb->transaction_handle, NULL, blocknr, 0);
} }
} }
} }
...@@ -1247,10 +1247,6 @@ void reiserfs_invalidate_buffer (struct tree_balance * tb, struct buffer_head * ...@@ -1247,10 +1247,6 @@ void reiserfs_invalidate_buffer (struct tree_balance * tb, struct buffer_head *
set_blkh_nr_item( blkh, 0 ); set_blkh_nr_item( blkh, 0 );
clear_buffer_dirty(bh); clear_buffer_dirty(bh);
/* reiserfs_free_block is no longer schedule safe
reiserfs_free_block (tb->transaction_handle, tb->tb_sb, bh->b_blocknr);
*/
store_thrown (tb, bh); store_thrown (tb, bh);
} }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/writeback.h> #include <linux/writeback.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/quotaops.h>
/* /*
** We pack the tails of files on file close, not at the time they are written. ** We pack the tails of files on file close, not at the time they are written.
...@@ -274,7 +275,7 @@ int reiserfs_allocate_blocks_for_region( ...@@ -274,7 +275,7 @@ int reiserfs_allocate_blocks_for_region(
/* Ok, there is existing indirect item already. Need to append it */ /* Ok, there is existing indirect item already. Need to append it */
/* Calculate position past inserted item */ /* Calculate position past inserted item */
make_cpu_key( &key, inode, le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key)) + op_bytes_number(ih, inode->i_sb->s_blocksize), TYPE_INDIRECT, 3); make_cpu_key( &key, inode, le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key)) + op_bytes_number(ih, inode->i_sb->s_blocksize), TYPE_INDIRECT, 3);
res = reiserfs_paste_into_item( th, &path, &key, (char *)zeros, UNFM_P_SIZE*to_paste); res = reiserfs_paste_into_item( th, &path, &key, inode, (char *)zeros, UNFM_P_SIZE*to_paste);
if ( res ) { if ( res ) {
kfree(zeros); kfree(zeros);
goto error_exit_free_blocks; goto error_exit_free_blocks;
...@@ -304,7 +305,7 @@ int reiserfs_allocate_blocks_for_region( ...@@ -304,7 +305,7 @@ int reiserfs_allocate_blocks_for_region(
kfree(zeros); kfree(zeros);
goto error_exit_free_blocks; goto error_exit_free_blocks;
} }
res = reiserfs_insert_item( th, &path, &key, &ins_ih, (char *)zeros); res = reiserfs_insert_item( th, &path, &key, &ins_ih, inode, (char *)zeros);
} else { } else {
reiserfs_panic(inode->i_sb, "green-9011: Unexpected key type %K\n", &key); reiserfs_panic(inode->i_sb, "green-9011: Unexpected key type %K\n", &key);
} }
...@@ -421,7 +422,7 @@ int reiserfs_allocate_blocks_for_region( ...@@ -421,7 +422,7 @@ int reiserfs_allocate_blocks_for_region(
// position. We do not need to recalculate path as it should // position. We do not need to recalculate path as it should
// already point to correct place. // already point to correct place.
make_cpu_key( &key, inode, le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key)) + op_bytes_number(ih, inode->i_sb->s_blocksize), TYPE_INDIRECT, 3); make_cpu_key( &key, inode, le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key)) + op_bytes_number(ih, inode->i_sb->s_blocksize), TYPE_INDIRECT, 3);
res = reiserfs_paste_into_item( th, &path, &key, (char *)(allocated_blocks+curr_block), UNFM_P_SIZE*(blocks_to_allocate-curr_block)); res = reiserfs_paste_into_item( th, &path, &key, inode, (char *)(allocated_blocks+curr_block), UNFM_P_SIZE*(blocks_to_allocate-curr_block));
if ( res ) { if ( res ) {
goto error_exit_free_blocks; goto error_exit_free_blocks;
} }
...@@ -452,7 +453,7 @@ int reiserfs_allocate_blocks_for_region( ...@@ -452,7 +453,7 @@ int reiserfs_allocate_blocks_for_region(
goto error_exit_free_blocks; goto error_exit_free_blocks;
} }
/* Insert item into the tree with the data as its body */ /* Insert item into the tree with the data as its body */
res = reiserfs_insert_item( th, &path, &key, &ins_ih, (char *)(allocated_blocks+curr_block)); res = reiserfs_insert_item( th, &path, &key, &ins_ih, inode, (char *)(allocated_blocks+curr_block));
} else { } else {
reiserfs_panic(inode->i_sb, "green-9010: unexpected item type for key %K\n",&key); reiserfs_panic(inode->i_sb, "green-9010: unexpected item type for key %K\n",&key);
} }
...@@ -462,7 +463,6 @@ int reiserfs_allocate_blocks_for_region( ...@@ -462,7 +463,6 @@ int reiserfs_allocate_blocks_for_region(
// unless we return an error, they are also responsible for logging // unless we return an error, they are also responsible for logging
// the inode. // the inode.
// //
inode->i_blocks += blocks_to_allocate << (inode->i_blkbits - 9);
pathrelse(&path); pathrelse(&path);
reiserfs_write_unlock(inode->i_sb); reiserfs_write_unlock(inode->i_sb);
...@@ -508,7 +508,7 @@ int reiserfs_allocate_blocks_for_region( ...@@ -508,7 +508,7 @@ int reiserfs_allocate_blocks_for_region(
pathrelse(&path); pathrelse(&path);
// free blocks // free blocks
for( i = 0; i < blocks_to_allocate; i++ ) for( i = 0; i < blocks_to_allocate; i++ )
reiserfs_free_block(th, le32_to_cpu(allocated_blocks[i])); reiserfs_free_block(th, inode, le32_to_cpu(allocated_blocks[i]), 1);
error_exit: error_exit:
reiserfs_update_sd(th, inode); // update any changes we made to blk count reiserfs_update_sd(th, inode); // update any changes we made to blk count
......
...@@ -795,8 +795,9 @@ static int get_empty_nodes( ...@@ -795,8 +795,9 @@ static int get_empty_nodes(
else /* If we have enough already then there is nothing to do. */ else /* If we have enough already then there is nothing to do. */
return CARRY_ON; return CARRY_ON;
if ( reiserfs_new_form_blocknrs (p_s_tb, a_n_blocknrs, /* No need to check quota - is not allocated for blocks used for formatted nodes */
n_amount_needed) == NO_DISK_SPACE ) if (reiserfs_new_form_blocknrs (p_s_tb, a_n_blocknrs,
n_amount_needed) == NO_DISK_SPACE)
return NO_DISK_SPACE; return NO_DISK_SPACE;
/* for each blocknumber we just got, get a buffer and stick it on FEB */ /* for each blocknumber we just got, get a buffer and stick it on FEB */
...@@ -2492,7 +2493,7 @@ void unfix_nodes (struct tree_balance * tb) ...@@ -2492,7 +2493,7 @@ void unfix_nodes (struct tree_balance * tb)
/* de-allocated block which was not used by balancing and /* de-allocated block which was not used by balancing and
bforget about buffer for it */ bforget about buffer for it */
brelse (tb->FEB[i]); brelse (tb->FEB[i]);
reiserfs_free_block (tb->transaction_handle, blocknr); reiserfs_free_block (tb->transaction_handle, NULL, blocknr, 0);
} }
if (tb->used[i]) { if (tb->used[i]) {
/* release used as new nodes including a new root */ /* release used as new nodes including a new root */
......
This diff is collapsed.
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/reiserfs_acl.h> #include <linux/reiserfs_acl.h>
#include <linux/reiserfs_xattr.h> #include <linux/reiserfs_xattr.h>
#include <linux/smp_lock.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 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--; #define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) i->i_nlink--;
...@@ -519,7 +520,7 @@ static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct in ...@@ -519,7 +520,7 @@ static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct in
} }
/* perform the insertion of the entry that we have prepared */ /* 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) if (buffer != small_buf)
reiserfs_kfree (buffer, buflen, dir->i_sb); reiserfs_kfree (buffer, buflen, dir->i_sb);
if (retval) { if (retval) {
...@@ -528,7 +529,6 @@ static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct in ...@@ -528,7 +529,6 @@ static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct in
} }
dir->i_size += paste_size; dir->i_size += paste_size;
dir->i_blocks = ((dir->i_size + 511) >> 9);
dir->i_mtime = dir->i_ctime = CURRENT_TIME; dir->i_mtime = dir->i_ctime = CURRENT_TIME;
if (!S_ISDIR (inode->i_mode) && visible) if (!S_ISDIR (inode->i_mode) && visible)
// reiserfs_mkdir or reiserfs_rename will do that by itself // reiserfs_mkdir or reiserfs_rename will do that by itself
...@@ -544,7 +544,9 @@ static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct in ...@@ -544,7 +544,9 @@ static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct in
** inserted into the tree yet. ** inserted into the tree yet.
*/ */
static int drop_new_inode(struct inode *inode) { static int drop_new_inode(struct inode *inode) {
DQUOT_DROP(inode);
make_bad_inode(inode) ; make_bad_inode(inode) ;
inode->i_flags |= S_NOQUOTA;
iput(inode) ; iput(inode) ;
return 0 ; return 0 ;
} }
...@@ -570,6 +572,11 @@ static int new_inode_init(struct inode *inode, struct inode *dir, int mode) { ...@@ -570,6 +572,11 @@ static int new_inode_init(struct inode *inode, struct inode *dir, int mode) {
} else { } else {
inode->i_gid = current->fsgid; inode->i_gid = current->fsgid;
} }
DQUOT_INIT(inode);
if (DQUOT_ALLOC_INODE(inode)) {
drop_new_inode(inode);
return -EDQUOT;
}
return 0 ; return 0 ;
} }
...@@ -836,7 +843,6 @@ static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry) ...@@ -836,7 +843,6 @@ static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry)
DEC_DIR_INODE_NLINK(dir) DEC_DIR_INODE_NLINK(dir)
dir->i_size -= (DEH_SIZE + de.de_entrylen); dir->i_size -= (DEH_SIZE + de.de_entrylen);
dir->i_blocks = ((dir->i_size + 511) >> 9);
reiserfs_update_sd (&th, dir); reiserfs_update_sd (&th, dir);
/* prevent empty directory from getting lost */ /* prevent empty directory from getting lost */
...@@ -919,7 +925,6 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry) ...@@ -919,7 +925,6 @@ static int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
reiserfs_update_sd (&th, inode); reiserfs_update_sd (&th, inode);
dir->i_size -= (de.de_entrylen + DEH_SIZE); dir->i_size -= (de.de_entrylen + DEH_SIZE);
dir->i_blocks = ((dir->i_size + 511) >> 9);
dir->i_ctime = dir->i_mtime = CURRENT_TIME; dir->i_ctime = dir->i_mtime = CURRENT_TIME;
reiserfs_update_sd (&th, dir); reiserfs_update_sd (&th, dir);
...@@ -1335,7 +1340,6 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry, ...@@ -1335,7 +1340,6 @@ static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,
reiserfs_warning ("vs-7060: reiserfs_rename: couldn't not cut old name. Fsck later?\n"); reiserfs_warning ("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_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, old_dir);
reiserfs_update_sd (&th, new_dir); reiserfs_update_sd (&th, new_dir);
......
This diff is collapsed.
...@@ -115,7 +115,7 @@ static void remove_save_link_only (struct super_block * s, struct key * key, int ...@@ -115,7 +115,7 @@ static void remove_save_link_only (struct super_block * s, struct key * key, int
/* we are going to do one balancing */ /* we are going to do one balancing */
journal_begin (&th, s, JOURNAL_PER_BALANCE_CNT); journal_begin (&th, s, JOURNAL_PER_BALANCE_CNT);
reiserfs_delete_solid_item (&th, key); reiserfs_delete_solid_item (&th, NULL, key);
if (oid_free) if (oid_free)
/* removals are protected by direct items */ /* removals are protected by direct items */
reiserfs_release_objectid (&th, le32_to_cpu (key->k_objectid)); reiserfs_release_objectid (&th, le32_to_cpu (key->k_objectid));
...@@ -301,8 +301,8 @@ void add_save_link (struct reiserfs_transaction_handle * th, ...@@ -301,8 +301,8 @@ void add_save_link (struct reiserfs_transaction_handle * th,
/* body of "save" link */ /* body of "save" link */
link = INODE_PKEY (inode)->k_dir_id; link = INODE_PKEY (inode)->k_dir_id;
/* put "save" link inot tree */ /* put "save" link inot tree, don't charge quota to anyone */
retval = reiserfs_insert_item (th, &path, &key, &ih, (char *)&link); retval = reiserfs_insert_item (th, &path, &key, &ih, NULL, (char *)&link);
if (retval) { if (retval) {
if (retval != -ENOSPC) if (retval != -ENOSPC)
reiserfs_warning ("vs-2120: add_save_link: insert_item returned %d\n", reiserfs_warning ("vs-2120: add_save_link: insert_item returned %d\n",
...@@ -344,7 +344,8 @@ void remove_save_link (struct inode * inode, int truncate) ...@@ -344,7 +344,8 @@ void remove_save_link (struct inode * inode, int truncate)
( REISERFS_I(inode) -> i_flags & i_link_saved_truncate_mask ) ) || ( REISERFS_I(inode) -> i_flags & i_link_saved_truncate_mask ) ) ||
( !truncate && ( !truncate &&
( REISERFS_I(inode) -> i_flags & i_link_saved_unlink_mask ) ) ) ( REISERFS_I(inode) -> 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) { if (!truncate) {
reiserfs_release_objectid (&th, inode->i_ino); reiserfs_release_objectid (&th, inode->i_ino);
REISERFS_I(inode) -> i_flags &= ~i_link_saved_unlink_mask; REISERFS_I(inode) -> i_flags &= ~i_link_saved_unlink_mask;
...@@ -714,6 +715,8 @@ static int reiserfs_parse_options (struct super_block * s, char * options, /* st ...@@ -714,6 +715,8 @@ static int reiserfs_parse_options (struct super_block * s, char * options, /* st
{"jdev", 'j', 0, 0, 0}, {"jdev", 'j', 0, 0, 0},
{"nolargeio", 'w', 0, 0, 0}, {"nolargeio", 'w', 0, 0, 0},
{"commit", 'c', 0, 0, 0}, {"commit", 'c', 0, 0, 0},
{"usrquota", 0, 0, 0, 0},
{"grpquota", 0, 0, 0, 0},
{NULL, 0, 0, 0, 0} {NULL, 0, 0, 0, 0}
}; };
......
...@@ -66,11 +66,11 @@ int direct2indirect (struct reiserfs_transaction_handle *th, struct inode * inod ...@@ -66,11 +66,11 @@ int direct2indirect (struct reiserfs_transaction_handle *th, struct inode * inod
set_ih_free_space (&ind_ih, 0); /* delete at nearest future */ set_ih_free_space (&ind_ih, 0); /* delete at nearest future */
put_ih_item_len( &ind_ih, UNFM_P_SIZE ); put_ih_item_len( &ind_ih, UNFM_P_SIZE );
PATH_LAST_POSITION (path)++; 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); (char *)&unfm_ptr);
} else { } else {
/* Paste into last indirect item of an object. */ /* 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); (char *)&unfm_ptr, UNFM_P_SIZE);
} }
if ( n_retval ) { if ( n_retval ) {
...@@ -274,7 +274,7 @@ int indirect2direct (struct reiserfs_transaction_handle *th, ...@@ -274,7 +274,7 @@ int indirect2direct (struct reiserfs_transaction_handle *th,
set_cpu_key_k_type (&key, TYPE_DIRECT); set_cpu_key_k_type (&key, TYPE_DIRECT);
key.key_length = 4; key.key_length = 4;
/* Insert tail as new direct item in the tree */ /* 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 ) { tail ? tail : NULL) < 0 ) {
/* No disk memory. So we can not convert last unformatted node /* No disk memory. So we can not convert last unformatted node
to the direct item. In this case we used to adjust to the direct item. In this case we used to adjust
...@@ -292,13 +292,15 @@ int indirect2direct (struct reiserfs_transaction_handle *th, ...@@ -292,13 +292,15 @@ int indirect2direct (struct reiserfs_transaction_handle *th,
*/ */
unmap_buffers(page, pos1) ; unmap_buffers(page, pos1) ;
/* 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 // note: we have now the same as in above direct2indirect
// conversion: there are two keys which have matching first three // conversion: there are two keys which have matching first three
// key components. They only differ by the fouhth one. // key components. They only differ by the fouhth one.
/* We have inserted new direct item and must remove last /* We have inserted new direct item and must remove last
unformatted node. */ unformatted node. */
p_s_inode->i_blocks += (p_s_sb->s_blocksize / 512);
*p_c_mode = M_CUT; *p_c_mode = M_CUT;
/* we store position of first direct item in the in-core inode */ /* we store position of first direct item in the in-core inode */
......
...@@ -268,6 +268,7 @@ int is_reiserfs_jr (struct reiserfs_super_block * rs); ...@@ -268,6 +268,7 @@ int is_reiserfs_jr (struct reiserfs_super_block * rs);
#define NO_DISK_SPACE -3 #define NO_DISK_SPACE -3
#define NO_BALANCING_NEEDED (-4) #define NO_BALANCING_NEEDED (-4)
#define NO_MORE_UNUSED_CONTIGUOUS_BLOCKS (-5) #define NO_MORE_UNUSED_CONTIGUOUS_BLOCKS (-5)
#define QUOTA_EXCEEDED -6
typedef __u32 b_blocknr_t; typedef __u32 b_blocknr_t;
typedef __u32 unp_t; typedef __u32 unp_t;
...@@ -1238,7 +1239,6 @@ excessive effort to avoid disturbing the precious VFS code.:-( The ...@@ -1238,7 +1239,6 @@ excessive effort to avoid disturbing the precious VFS code.:-( The
gods only know how we are going to SMP the code that uses them. gods only know how we are going to SMP the code that uses them.
znodes are the way! */ znodes are the way! */
struct path { struct path {
int path_length; /* Length of the array above. */ int path_length; /* Length of the array above. */
struct path_element path_elements[EXTENDED_MAX_HEIGHT]; /* Array of the path elements. */ struct path_element path_elements[EXTENDED_MAX_HEIGHT]; /* Array of the path elements. */
...@@ -1889,11 +1889,13 @@ void pathrelse_and_restore (struct super_block *s, struct path * p_s_search_path ...@@ -1889,11 +1889,13 @@ void pathrelse_and_restore (struct super_block *s, struct path * p_s_search_path
int reiserfs_insert_item (struct reiserfs_transaction_handle *th, int reiserfs_insert_item (struct reiserfs_transaction_handle *th,
struct path * path, struct path * path,
const struct cpu_key * key, 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, int reiserfs_paste_into_item (struct reiserfs_transaction_handle *th,
struct path * path, struct path * path,
const struct cpu_key * key, const struct cpu_key * key,
struct inode *inode,
const char * body, int paste_size); const char * body, int paste_size);
int reiserfs_cut_from_item (struct reiserfs_transaction_handle *th, int reiserfs_cut_from_item (struct reiserfs_transaction_handle *th,
...@@ -1910,7 +1912,7 @@ int reiserfs_delete_item (struct reiserfs_transaction_handle *th, ...@@ -1910,7 +1912,7 @@ int reiserfs_delete_item (struct reiserfs_transaction_handle *th,
struct buffer_head * p_s_un_bh); struct buffer_head * p_s_un_bh);
void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th, 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_delete_object (struct reiserfs_transaction_handle *th, struct inode * p_s_inode);
void reiserfs_do_truncate (struct reiserfs_transaction_handle *th, void reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
struct inode * p_s_inode, struct page *, struct inode * p_s_inode, struct page *,
...@@ -1955,8 +1957,18 @@ int reiserfs_new_inode (struct reiserfs_transaction_handle *th, ...@@ -1955,8 +1957,18 @@ int reiserfs_new_inode (struct reiserfs_transaction_handle *th,
struct inode * dir, int mode, struct inode * dir, int mode,
const char * symname, loff_t i_size, const char * symname, loff_t i_size,
struct dentry *dentry, struct inode *inode); struct dentry *dentry, struct inode *inode);
int reiserfs_sync_inode (struct reiserfs_transaction_handle *th, struct inode * inode);
void reiserfs_update_sd (struct reiserfs_transaction_handle *th, struct inode * inode); int reiserfs_sync_inode (struct reiserfs_transaction_handle *th,
struct inode * inode);
void reiserfs_update_sd_size (struct reiserfs_transaction_handle *th,
struct inode * inode, loff_t size);
static inline void reiserfs_update_sd(struct reiserfs_transaction_handle *th,
struct inode *inode)
{
reiserfs_update_sd_size(th, inode, inode->i_size) ;
}
void sd_attrs_to_i_attrs( __u16 sd_attrs, struct inode *inode ); void sd_attrs_to_i_attrs( __u16 sd_attrs, struct inode *inode );
void i_attrs_to_sd_attrs( struct inode *inode, __u16 *sd_attrs ); void i_attrs_to_sd_attrs( struct inode *inode, __u16 *sd_attrs );
...@@ -2139,7 +2151,7 @@ typedef struct __reiserfs_blocknr_hint reiserfs_blocknr_hint_t; ...@@ -2139,7 +2151,7 @@ typedef struct __reiserfs_blocknr_hint reiserfs_blocknr_hint_t;
int reiserfs_parse_alloc_options (struct super_block *, char *); int reiserfs_parse_alloc_options (struct super_block *, char *);
int is_reusable (struct super_block * s, b_blocknr_t block, int bit_value); int is_reusable (struct super_block * s, b_blocknr_t block, int bit_value);
void reiserfs_free_block (struct reiserfs_transaction_handle *th, b_blocknr_t); void reiserfs_free_block (struct reiserfs_transaction_handle *th, struct inode *, b_blocknr_t, int for_unformatted);
int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *, b_blocknr_t * , int, 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, extern inline int reiserfs_new_form_blocknrs (struct tree_balance * tb,
b_blocknr_t *new_blocknrs, int amount_needed) b_blocknr_t *new_blocknrs, int amount_needed)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment