Skip to content

Commit

Permalink
ext4: Convert to generic reserved quota's space management.
Browse files Browse the repository at this point in the history
commit a9e7f44 upstream.

This patch also fixes write vs chown race condition.

Acked-by: "Theodore Ts'o" <tytso@mit.edu>
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Dmitry Monakhov authored and Greg Kroah-Hartman committed Jan 6, 2010
1 parent c169e13 commit 8227f06
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 10 deletions.
6 changes: 5 additions & 1 deletion fs/ext4/ext4.h
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,10 @@ struct ext4_inode_info {
__u16 i_extra_isize;

spinlock_t i_block_reservation_lock;
#ifdef CONFIG_QUOTA
/* quota space reservation, managed internally by quota code */
qsize_t i_reserved_quota;
#endif

/* completed async DIOs that might need unwritten extents handling */
struct list_head i_aio_dio_complete_list;
Expand Down Expand Up @@ -1439,7 +1443,7 @@ extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks);
extern int ext4_block_truncate_page(handle_t *handle,
struct address_space *mapping, loff_t from);
extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
extern qsize_t ext4_get_reserved_space(struct inode *inode);
extern qsize_t *ext4_get_reserved_space(struct inode *inode);
extern int flush_aio_dio_completed_IO(struct inode *inode);
/* ioctl.c */
extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
Expand Down
16 changes: 7 additions & 9 deletions fs/ext4/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1046,17 +1046,12 @@ static int ext4_ind_get_blocks(handle_t *handle, struct inode *inode,
return err;
}

qsize_t ext4_get_reserved_space(struct inode *inode)
#ifdef CONFIG_QUOTA
qsize_t *ext4_get_reserved_space(struct inode *inode)
{
unsigned long long total;

spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
total = EXT4_I(inode)->i_reserved_data_blocks +
EXT4_I(inode)->i_reserved_meta_blocks;
spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);

return (total << inode->i_blkbits);
return &EXT4_I(inode)->i_reserved_quota;
}
#endif
/*
* Calculate the number of metadata blocks need to reserve
* to allocate @blocks for non extent file based file
Expand Down Expand Up @@ -4840,6 +4835,9 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;
inode->i_size = ext4_isize(raw_inode);
ei->i_disksize = inode->i_size;
#ifdef CONFIG_QUOTA
ei->i_reserved_quota = 0;
#endif
inode->i_generation = le32_to_cpu(raw_inode->i_generation);
ei->i_block_group = iloc.block_group;
ei->i_last_alloc_group = ~0;
Expand Down
5 changes: 5 additions & 0 deletions fs/ext4/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,9 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
ei->i_allocated_meta_blocks = 0;
ei->i_delalloc_reserved_flag = 0;
spin_lock_init(&(ei->i_block_reservation_lock));
#ifdef CONFIG_QUOTA
ei->i_reserved_quota = 0;
#endif
INIT_LIST_HEAD(&ei->i_aio_dio_complete_list);
ei->cur_aio_dio = NULL;
ei->i_sync_tid = 0;
Expand Down Expand Up @@ -1008,7 +1011,9 @@ static struct dquot_operations ext4_quota_operations = {
.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,
Expand Down

0 comments on commit 8227f06

Please sign in to comment.