Skip to content

Commit

Permalink
dquot: cleanup space allocation / freeing routines
Browse files Browse the repository at this point in the history
Get rid of the alloc_space, free_space, reserve_space, claim_space and
release_rsv dquot operations - they are always called from the filesystem
and if a filesystem really needs their own (which none currently does)
it can just call into it's own routine directly.

Move shared logic into the common __dquot_alloc_space,
dquot_claim_space_nodirty and __dquot_free_space low-level methods,
and rationalize the wrappers around it to move as much as possible
code into the common block for CONFIG_QUOTA vs not.  Also rename
all these helpers to be named dquot_* instead of vfs_dq_*.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jan Kara <jack@suse.cz>
  • Loading branch information
Christoph Hellwig authored and jankara committed Mar 4, 2010
1 parent 49792c8 commit 5dd4056
Show file tree
Hide file tree
Showing 29 changed files with 258 additions and 383 deletions.
6 changes: 1 addition & 5 deletions Documentation/filesystems/Locking
Original file line number Diff line number Diff line change
Expand Up @@ -462,9 +462,7 @@ in sys_read() and friends.
prototypes:
int (*initialize) (struct inode *, int);
int (*drop) (struct inode *);
int (*alloc_space) (struct inode *, qsize_t, int);
int (*alloc_inode) (const struct inode *, unsigned long);
int (*free_space) (struct inode *, qsize_t);
int (*free_inode) (const struct inode *, unsigned long);
int (*transfer) (struct inode *, struct iattr *);
int (*write_dquot) (struct dquot *);
Expand All @@ -481,9 +479,7 @@ What filesystem should expect from the generic quota functions:
FS recursion Held locks when called
initialize: yes maybe dqonoff_sem
drop: yes -
alloc_space: ->mark_dirty() -
alloc_inode: ->mark_dirty() -
free_space: ->mark_dirty() -
free_inode: ->mark_dirty() -
transfer: yes -
write_dquot: yes dqonoff_sem or dqptr_sem
Expand All @@ -495,7 +491,7 @@ write_info: yes dqonoff_sem
FS recursion means calling ->quota_read() and ->quota_write() from superblock
operations.

->alloc_space(), ->alloc_inode(), ->free_space(), ->free_inode() are called
->alloc_inode(), ->free_inode() are called
only directly by the filesystem and do not call any fs functions only
the ->mark_dirty() operation.

Expand Down
12 changes: 7 additions & 5 deletions fs/ext2/balloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ void ext2_free_blocks (struct inode * inode, unsigned long block,
error_return:
brelse(bitmap_bh);
release_blocks(sb, freed);
vfs_dq_free_block(inode, freed);
dquot_free_block(inode, freed);
}

/**
Expand Down Expand Up @@ -1236,6 +1236,7 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal,
unsigned short windowsz = 0;
unsigned long ngroups;
unsigned long num = *count;
int ret;

*errp = -ENOSPC;
sb = inode->i_sb;
Expand All @@ -1247,8 +1248,9 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal,
/*
* Check quota for allocation of this block.
*/
if (vfs_dq_alloc_block(inode, num)) {
*errp = -EDQUOT;
ret = dquot_alloc_block(inode, num);
if (ret) {
*errp = ret;
return 0;
}

Expand Down Expand Up @@ -1409,7 +1411,7 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal,

*errp = 0;
brelse(bitmap_bh);
vfs_dq_free_block(inode, *count-num);
dquot_free_block(inode, *count-num);
*count = num;
return ret_block;

Expand All @@ -1420,7 +1422,7 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal,
* Undo the block allocation
*/
if (!performed_allocation)
vfs_dq_free_block(inode, *count);
dquot_free_block(inode, *count);
brelse(bitmap_bh);
return 0;
}
Expand Down
10 changes: 5 additions & 5 deletions fs/ext2/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -644,8 +644,8 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
the inode. */
ea_bdebug(new_bh, "reusing block");

error = -EDQUOT;
if (vfs_dq_alloc_block(inode, 1)) {
error = dquot_alloc_block(inode, 1);
if (error) {
unlock_buffer(new_bh);
goto cleanup;
}
Expand Down Expand Up @@ -702,7 +702,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
* as if nothing happened and cleanup the unused block */
if (error && error != -ENOSPC) {
if (new_bh && new_bh != old_bh)
vfs_dq_free_block(inode, 1);
dquot_free_block(inode, 1);
goto cleanup;
}
} else
Expand Down Expand Up @@ -734,7 +734,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
le32_add_cpu(&HDR(old_bh)->h_refcount, -1);
if (ce)
mb_cache_entry_release(ce);
vfs_dq_free_block(inode, 1);
dquot_free_block(inode, 1);
mark_buffer_dirty(old_bh);
ea_bdebug(old_bh, "refcount now=%d",
le32_to_cpu(HDR(old_bh)->h_refcount));
Expand Down Expand Up @@ -797,7 +797,7 @@ ext2_xattr_delete_inode(struct inode *inode)
mark_buffer_dirty(bh);
if (IS_SYNC(inode))
sync_dirty_buffer(bh);
vfs_dq_free_block(inode, 1);
dquot_free_block(inode, 1);
}
EXT2_I(inode)->i_file_acl = 0;

Expand Down
11 changes: 6 additions & 5 deletions fs/ext3/balloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ void ext3_free_blocks(handle_t *handle, struct inode *inode,
}
ext3_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks);
if (dquot_freed_blocks)
vfs_dq_free_block(inode, dquot_freed_blocks);
dquot_free_block(inode, dquot_freed_blocks);
return;
}

Expand Down Expand Up @@ -1502,8 +1502,9 @@ ext3_fsblk_t ext3_new_blocks(handle_t *handle, struct inode *inode,
/*
* Check quota for allocation of this block.
*/
if (vfs_dq_alloc_block(inode, num)) {
*errp = -EDQUOT;
err = dquot_alloc_block(inode, num);
if (err) {
*errp = err;
return 0;
}

Expand Down Expand Up @@ -1713,7 +1714,7 @@ ext3_fsblk_t ext3_new_blocks(handle_t *handle, struct inode *inode,

*errp = 0;
brelse(bitmap_bh);
vfs_dq_free_block(inode, *count-num);
dquot_free_block(inode, *count-num);
*count = num;
return ret_block;

Expand All @@ -1728,7 +1729,7 @@ ext3_fsblk_t ext3_new_blocks(handle_t *handle, struct inode *inode,
* Undo the block allocation
*/
if (!performed_allocation)
vfs_dq_free_block(inode, *count);
dquot_free_block(inode, *count);
brelse(bitmap_bh);
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion fs/ext3/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -3336,7 +3336,7 @@ int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode)
* i_size has been changed by generic_commit_write() and we thus need
* to include the updated inode in the current transaction.
*
* Also, vfs_dq_alloc_space() will always dirty the inode when blocks
* Also, dquot_alloc_space() will always dirty the inode when blocks
* are allocated to the file.
*
* If the inode is marked synchronous, we don't honour that here - doing
Expand Down
2 changes: 0 additions & 2 deletions fs/ext3/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -752,9 +752,7 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type,
static const struct dquot_operations ext3_quota_operations = {
.initialize = dquot_initialize,
.drop = dquot_drop,
.alloc_space = dquot_alloc_space,
.alloc_inode = dquot_alloc_inode,
.free_space = dquot_free_space,
.free_inode = dquot_free_inode,
.transfer = dquot_transfer,
.write_dquot = ext3_write_dquot,
Expand Down
8 changes: 4 additions & 4 deletions fs/ext3/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ ext3_xattr_release_block(handle_t *handle, struct inode *inode,
error = ext3_journal_dirty_metadata(handle, bh);
if (IS_SYNC(inode))
handle->h_sync = 1;
vfs_dq_free_block(inode, 1);
dquot_free_block(inode, 1);
ea_bdebug(bh, "refcount now=%d; releasing",
le32_to_cpu(BHDR(bh)->h_refcount));
if (ce)
Expand Down Expand Up @@ -775,8 +775,8 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode,
else {
/* The old block is released after updating
the inode. */
error = -EDQUOT;
if (vfs_dq_alloc_block(inode, 1))
error = dquot_alloc_block(inode, 1);
if (error)
goto cleanup;
error = ext3_journal_get_write_access(handle,
new_bh);
Expand Down Expand Up @@ -850,7 +850,7 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode,
return error;

cleanup_dquot:
vfs_dq_free_block(inode, 1);
dquot_free_block(inode, 1);
goto cleanup;

bad_block:
Expand Down
20 changes: 11 additions & 9 deletions fs/ext4/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1093,9 +1093,9 @@ void ext4_da_update_reserve_space(struct inode *inode,

/* Update quota subsystem */
if (quota_claim) {
vfs_dq_claim_block(inode, used);
dquot_claim_block(inode, used);
if (mdb_free)
vfs_dq_release_reservation_block(inode, mdb_free);
dquot_release_reservation_block(inode, mdb_free);
} else {
/*
* We did fallocate with an offset that is already delayed
Expand All @@ -1106,8 +1106,8 @@ void ext4_da_update_reserve_space(struct inode *inode,
* that
*/
if (allocated_meta_blocks)
vfs_dq_claim_block(inode, allocated_meta_blocks);
vfs_dq_release_reservation_block(inode, mdb_free + used);
dquot_claim_block(inode, allocated_meta_blocks);
dquot_release_reservation_block(inode, mdb_free + used);
}

/*
Expand Down Expand Up @@ -1836,6 +1836,7 @@ static int ext4_da_reserve_space(struct inode *inode, sector_t lblock)
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
struct ext4_inode_info *ei = EXT4_I(inode);
unsigned long md_needed, md_reserved;
int ret;

/*
* recalculate the amount of metadata blocks to reserve
Expand All @@ -1853,11 +1854,12 @@ static int ext4_da_reserve_space(struct inode *inode, sector_t lblock)
* later. Real quota accounting is done at pages writeout
* time.
*/
if (vfs_dq_reserve_block(inode, md_needed + 1))
return -EDQUOT;
ret = dquot_reserve_block(inode, md_needed + 1);
if (ret)
return ret;

if (ext4_claim_free_blocks(sbi, md_needed + 1)) {
vfs_dq_release_reservation_block(inode, md_needed + 1);
dquot_release_reservation_block(inode, md_needed + 1);
if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
yield();
goto repeat;
Expand Down Expand Up @@ -1914,7 +1916,7 @@ static void ext4_da_release_space(struct inode *inode, int to_free)

spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);

vfs_dq_release_reservation_block(inode, to_free);
dquot_release_reservation_block(inode, to_free);
}

static void ext4_da_page_release_reservation(struct page *page,
Expand Down Expand Up @@ -5641,7 +5643,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
* i_size has been changed by generic_commit_write() and we thus need
* to include the updated inode in the current transaction.
*
* Also, vfs_dq_alloc_block() will always dirty the inode when blocks
* Also, dquot_alloc_block() will always dirty the inode when blocks
* are allocated to the file.
*
* If the inode is marked synchronous, we don't honour that here - doing
Expand Down
6 changes: 3 additions & 3 deletions fs/ext4/mballoc.c
Original file line number Diff line number Diff line change
Expand Up @@ -4254,7 +4254,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
return 0;
}
reserv_blks = ar->len;
while (ar->len && vfs_dq_alloc_block(ar->inode, ar->len)) {
while (ar->len && dquot_alloc_block(ar->inode, ar->len)) {
ar->flags |= EXT4_MB_HINT_NOPREALLOC;
ar->len--;
}
Expand Down Expand Up @@ -4331,7 +4331,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
kmem_cache_free(ext4_ac_cachep, ac);
out1:
if (inquota && ar->len < inquota)
vfs_dq_free_block(ar->inode, inquota - ar->len);
dquot_free_block(ar->inode, inquota - ar->len);
out3:
if (!ar->len) {
if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag)
Expand Down Expand Up @@ -4646,7 +4646,7 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
sb->s_dirt = 1;
error_return:
if (freed)
vfs_dq_free_block(inode, freed);
dquot_free_block(inode, freed);
brelse(bitmap_bh);
ext4_std_error(sb, err);
if (ac)
Expand Down
5 changes: 0 additions & 5 deletions fs/ext4/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1014,15 +1014,10 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
static const struct dquot_operations ext4_quota_operations = {
.initialize = dquot_initialize,
.drop = dquot_drop,
.alloc_space = dquot_alloc_space,
.reserve_space = dquot_reserve_space,
.claim_space = dquot_claim_space,
.release_rsv = dquot_release_reserved_space,
#ifdef CONFIG_QUOTA
.get_reserved_space = ext4_get_reserved_space,
#endif
.alloc_inode = dquot_alloc_inode,
.free_space = dquot_free_space,
.free_inode = dquot_free_inode,
.transfer = dquot_transfer,
.write_dquot = ext4_write_dquot,
Expand Down
8 changes: 4 additions & 4 deletions fs/ext4/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
error = ext4_handle_dirty_metadata(handle, inode, bh);
if (IS_SYNC(inode))
ext4_handle_sync(handle);
vfs_dq_free_block(inode, 1);
dquot_free_block(inode, 1);
ea_bdebug(bh, "refcount now=%d; releasing",
le32_to_cpu(BHDR(bh)->h_refcount));
if (ce)
Expand Down Expand Up @@ -787,8 +787,8 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
else {
/* The old block is released after updating
the inode. */
error = -EDQUOT;
if (vfs_dq_alloc_block(inode, 1))
error = dquot_alloc_block(inode, 1);
if (error)
goto cleanup;
error = ext4_journal_get_write_access(handle,
new_bh);
Expand Down Expand Up @@ -876,7 +876,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
return error;

cleanup_dquot:
vfs_dq_free_block(inode, 1);
dquot_free_block(inode, 1);
goto cleanup;

bad_block:
Expand Down
Loading

0 comments on commit 5dd4056

Please sign in to comment.