diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext4/balloc.c | 57 | ||||
-rw-r--r-- | fs/ext4/ext4.h | 3 |
2 files changed, 17 insertions, 43 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index b9821be709bd..e28203ec45bd 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -589,8 +589,15 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, | |||
589 | return; | 589 | return; |
590 | } | 590 | } |
591 | 591 | ||
592 | int ext4_claim_free_blocks(struct ext4_sb_info *sbi, | 592 | /** |
593 | s64 nblocks) | 593 | * ext4_has_free_blocks() |
594 | * @sbi: in-core super block structure. | ||
595 | * @nblocks: number of needed blocks | ||
596 | * | ||
597 | * Check if filesystem has nblocks free & available for allocation. | ||
598 | * On success return 1, return 0 on failure. | ||
599 | */ | ||
600 | int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks) | ||
594 | { | 601 | { |
595 | s64 free_blocks, dirty_blocks; | 602 | s64 free_blocks, dirty_blocks; |
596 | s64 root_blocks = 0; | 603 | s64 root_blocks = 0; |
@@ -620,53 +627,21 @@ int ext4_claim_free_blocks(struct ext4_sb_info *sbi, | |||
620 | */ | 627 | */ |
621 | if (free_blocks < ((root_blocks + nblocks) + dirty_blocks)) | 628 | if (free_blocks < ((root_blocks + nblocks) + dirty_blocks)) |
622 | /* we don't have free space */ | 629 | /* we don't have free space */ |
623 | return -ENOSPC; | 630 | return 0; |
624 | 631 | ||
625 | /* Add the blocks to nblocks */ | 632 | return 1; |
626 | percpu_counter_add(dbc, nblocks); | ||
627 | return 0; | ||
628 | } | 633 | } |
629 | 634 | ||
630 | /** | 635 | int ext4_claim_free_blocks(struct ext4_sb_info *sbi, |
631 | * ext4_has_free_blocks() | ||
632 | * @sbi: in-core super block structure. | ||
633 | * @nblocks: number of neeed blocks | ||
634 | * | ||
635 | * Check if filesystem has free blocks available for allocation. | ||
636 | * Return the number of blocks avaible for allocation for this request | ||
637 | * On success, return nblocks | ||
638 | */ | ||
639 | ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi, | ||
640 | s64 nblocks) | 636 | s64 nblocks) |
641 | { | 637 | { |
642 | s64 free_blocks, dirty_blocks; | 638 | if (ext4_has_free_blocks(sbi, nblocks)) { |
643 | s64 root_blocks = 0; | 639 | percpu_counter_add(&sbi->s_dirtyblocks_counter, nblocks); |
644 | struct percpu_counter *fbc = &sbi->s_freeblocks_counter; | ||
645 | struct percpu_counter *dbc = &sbi->s_dirtyblocks_counter; | ||
646 | |||
647 | free_blocks = percpu_counter_read_positive(fbc); | ||
648 | dirty_blocks = percpu_counter_read_positive(dbc); | ||
649 | |||
650 | if (!capable(CAP_SYS_RESOURCE) && | ||
651 | sbi->s_resuid != current->fsuid && | ||
652 | (sbi->s_resgid == 0 || !in_group_p(sbi->s_resgid))) | ||
653 | root_blocks = ext4_r_blocks_count(sbi->s_es); | ||
654 | |||
655 | if (free_blocks - (nblocks + root_blocks + dirty_blocks) < | ||
656 | EXT4_FREEBLOCKS_WATERMARK) { | ||
657 | free_blocks = percpu_counter_sum(fbc); | ||
658 | dirty_blocks = percpu_counter_sum(dbc); | ||
659 | } | ||
660 | if (free_blocks <= (root_blocks + dirty_blocks)) | ||
661 | /* we don't have free space */ | ||
662 | return 0; | 640 | return 0; |
663 | 641 | } else | |
664 | if (free_blocks - (root_blocks + dirty_blocks) < nblocks) | 642 | return -ENOSPC; |
665 | return free_blocks - (root_blocks + dirty_blocks); | ||
666 | return nblocks; | ||
667 | } | 643 | } |
668 | 644 | ||
669 | |||
670 | /** | 645 | /** |
671 | * ext4_should_retry_alloc() | 646 | * ext4_should_retry_alloc() |
672 | * @sb: super block | 647 | * @sb: super block |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 4880cc3e6727..b0537c827024 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -1003,8 +1003,7 @@ extern ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, | |||
1003 | ext4_lblk_t iblock, ext4_fsblk_t goal, | 1003 | ext4_lblk_t iblock, ext4_fsblk_t goal, |
1004 | unsigned long *count, int *errp); | 1004 | unsigned long *count, int *errp); |
1005 | extern int ext4_claim_free_blocks(struct ext4_sb_info *sbi, s64 nblocks); | 1005 | extern int ext4_claim_free_blocks(struct ext4_sb_info *sbi, s64 nblocks); |
1006 | extern ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi, | 1006 | extern int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks); |
1007 | s64 nblocks); | ||
1008 | extern void ext4_free_blocks(handle_t *handle, struct inode *inode, | 1007 | extern void ext4_free_blocks(handle_t *handle, struct inode *inode, |
1009 | ext4_fsblk_t block, unsigned long count, int metadata); | 1008 | ext4_fsblk_t block, unsigned long count, int metadata); |
1010 | extern void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, | 1009 | extern void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, |