diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/gfs2/file.c | 70 |
1 files changed, 47 insertions, 23 deletions
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index c569adbc1431..4d3108792172 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -765,22 +765,30 @@ out: | |||
765 | brelse(dibh); | 765 | brelse(dibh); |
766 | return error; | 766 | return error; |
767 | } | 767 | } |
768 | 768 | /** | |
769 | static void calc_max_reserv(struct gfs2_inode *ip, loff_t max, loff_t *len, | 769 | * calc_max_reserv() - Reverse of write_calc_reserv. Given a number of |
770 | unsigned int *data_blocks, unsigned int *ind_blocks) | 770 | * blocks, determine how many bytes can be written. |
771 | * @ip: The inode in question. | ||
772 | * @len: Max cap of bytes. What we return in *len must be <= this. | ||
773 | * @data_blocks: Compute and return the number of data blocks needed | ||
774 | * @ind_blocks: Compute and return the number of indirect blocks needed | ||
775 | * @max_blocks: The total blocks available to work with. | ||
776 | * | ||
777 | * Returns: void, but @len, @data_blocks and @ind_blocks are filled in. | ||
778 | */ | ||
779 | static void calc_max_reserv(struct gfs2_inode *ip, loff_t *len, | ||
780 | unsigned int *data_blocks, unsigned int *ind_blocks, | ||
781 | unsigned int max_blocks) | ||
771 | { | 782 | { |
783 | loff_t max = *len; | ||
772 | const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 784 | const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
773 | unsigned int max_blocks = ip->i_rgd->rd_free_clone; | ||
774 | unsigned int tmp, max_data = max_blocks - 3 * (sdp->sd_max_height - 1); | 785 | unsigned int tmp, max_data = max_blocks - 3 * (sdp->sd_max_height - 1); |
775 | 786 | ||
776 | for (tmp = max_data; tmp > sdp->sd_diptrs;) { | 787 | for (tmp = max_data; tmp > sdp->sd_diptrs;) { |
777 | tmp = DIV_ROUND_UP(tmp, sdp->sd_inptrs); | 788 | tmp = DIV_ROUND_UP(tmp, sdp->sd_inptrs); |
778 | max_data -= tmp; | 789 | max_data -= tmp; |
779 | } | 790 | } |
780 | /* This calculation isn't the exact reverse of gfs2_write_calc_reserve, | 791 | |
781 | so it might end up with fewer data blocks */ | ||
782 | if (max_data <= *data_blocks) | ||
783 | return; | ||
784 | *data_blocks = max_data; | 792 | *data_blocks = max_data; |
785 | *ind_blocks = max_blocks - max_data; | 793 | *ind_blocks = max_blocks - max_data; |
786 | *len = ((loff_t)max_data - 3) << sdp->sd_sb.sb_bsize_shift; | 794 | *len = ((loff_t)max_data - 3) << sdp->sd_sb.sb_bsize_shift; |
@@ -797,7 +805,7 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t | |||
797 | struct gfs2_inode *ip = GFS2_I(inode); | 805 | struct gfs2_inode *ip = GFS2_I(inode); |
798 | struct gfs2_alloc_parms ap = { .aflags = 0, }; | 806 | struct gfs2_alloc_parms ap = { .aflags = 0, }; |
799 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; | 807 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; |
800 | loff_t bytes, max_bytes; | 808 | loff_t bytes, max_bytes, max_blks = UINT_MAX; |
801 | int error; | 809 | int error; |
802 | const loff_t pos = offset; | 810 | const loff_t pos = offset; |
803 | const loff_t count = len; | 811 | const loff_t count = len; |
@@ -819,6 +827,9 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t | |||
819 | 827 | ||
820 | gfs2_size_hint(file, offset, len); | 828 | gfs2_size_hint(file, offset, len); |
821 | 829 | ||
830 | gfs2_write_calc_reserv(ip, PAGE_SIZE, &data_blocks, &ind_blocks); | ||
831 | ap.min_target = data_blocks + ind_blocks; | ||
832 | |||
822 | while (len > 0) { | 833 | while (len > 0) { |
823 | if (len < bytes) | 834 | if (len < bytes) |
824 | bytes = len; | 835 | bytes = len; |
@@ -827,28 +838,41 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t | |||
827 | offset += bytes; | 838 | offset += bytes; |
828 | continue; | 839 | continue; |
829 | } | 840 | } |
830 | retry: | 841 | |
842 | /* We need to determine how many bytes we can actually | ||
843 | * fallocate without exceeding quota or going over the | ||
844 | * end of the fs. We start off optimistically by assuming | ||
845 | * we can write max_bytes */ | ||
846 | max_bytes = (len > max_chunk_size) ? max_chunk_size : len; | ||
847 | |||
848 | /* Since max_bytes is most likely a theoretical max, we | ||
849 | * calculate a more realistic 'bytes' to serve as a good | ||
850 | * starting point for the number of bytes we may be able | ||
851 | * to write */ | ||
831 | gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks); | 852 | gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks); |
832 | ap.target = data_blocks + ind_blocks; | 853 | ap.target = data_blocks + ind_blocks; |
833 | 854 | ||
834 | error = gfs2_quota_lock_check(ip, &ap); | 855 | error = gfs2_quota_lock_check(ip, &ap); |
835 | if (error) | 856 | if (error) |
836 | return error; | 857 | return error; |
858 | /* ap.allowed tells us how many blocks quota will allow | ||
859 | * us to write. Check if this reduces max_blks */ | ||
860 | if (ap.allowed && ap.allowed < max_blks) | ||
861 | max_blks = ap.allowed; | ||
862 | |||
837 | error = gfs2_inplace_reserve(ip, &ap); | 863 | error = gfs2_inplace_reserve(ip, &ap); |
838 | if (error) { | 864 | if (error) |
839 | if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) { | ||
840 | bytes >>= 1; | ||
841 | bytes &= bsize_mask; | ||
842 | if (bytes == 0) | ||
843 | bytes = sdp->sd_sb.sb_bsize; | ||
844 | gfs2_quota_unlock(ip); | ||
845 | goto retry; | ||
846 | } | ||
847 | goto out_qunlock; | 865 | goto out_qunlock; |
848 | } | 866 | |
849 | max_bytes = bytes; | 867 | /* check if the selected rgrp limits our max_blks further */ |
850 | calc_max_reserv(ip, (len > max_chunk_size)? max_chunk_size: len, | 868 | if (ap.allowed && ap.allowed < max_blks) |
851 | &max_bytes, &data_blocks, &ind_blocks); | 869 | max_blks = ap.allowed; |
870 | |||
871 | /* Almost done. Calculate bytes that can be written using | ||
872 | * max_blks. We also recompute max_bytes, data_blocks and | ||
873 | * ind_blocks */ | ||
874 | calc_max_reserv(ip, &max_bytes, &data_blocks, | ||
875 | &ind_blocks, max_blks); | ||
852 | 876 | ||
853 | rblocks = RES_DINODE + ind_blocks + RES_STATFS + RES_QUOTA + | 877 | rblocks = RES_DINODE + ind_blocks + RES_STATFS + RES_QUOTA + |
854 | RES_RG_HDR + gfs2_rg_blocks(ip, data_blocks + ind_blocks); | 878 | RES_RG_HDR + gfs2_rg_blocks(ip, data_blocks + ind_blocks); |