diff options
author | Andrew Price <anprice@redhat.com> | 2014-11-12 12:24:03 -0500 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2014-11-14 09:14:30 -0500 |
commit | 9c9f1159a54c6163dd0b9d2085985d3c98dad11f (patch) | |
tree | d65c967f3dc7d604a73b020ed80a13839c6548b9 /fs/gfs2 | |
parent | 1a8550332a7f0111306b6b34e44a7c696ef68c4d (diff) |
GFS2: Use inode_newsize_ok and get_write_access in fallocate
gfs2_fallocate wasn't checking inode_newsize_ok nor get_write_access.
Split out the context setup and inode locking pieces into a separate
function to make it more clear and add these missing calls.
inode_newsize_ok is called conditional on FALLOC_FL_KEEP_SIZE as there
is no need to enforce a file size limit if it isn't going to change.
Signed-off-by: Andrew Price <anprice@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/file.c | 66 |
1 files changed, 44 insertions, 22 deletions
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 5ebe56831794..3786579dd348 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -797,8 +797,7 @@ static void calc_max_reserv(struct gfs2_inode *ip, loff_t max, loff_t *len, | |||
797 | } | 797 | } |
798 | } | 798 | } |
799 | 799 | ||
800 | static long gfs2_fallocate(struct file *file, int mode, loff_t offset, | 800 | static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t len) |
801 | loff_t len) | ||
802 | { | 801 | { |
803 | struct inode *inode = file_inode(file); | 802 | struct inode *inode = file_inode(file); |
804 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 803 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
@@ -812,14 +811,9 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, | |||
812 | loff_t bsize_mask = ~((loff_t)sdp->sd_sb.sb_bsize - 1); | 811 | loff_t bsize_mask = ~((loff_t)sdp->sd_sb.sb_bsize - 1); |
813 | loff_t next = (offset + len - 1) >> sdp->sd_sb.sb_bsize_shift; | 812 | loff_t next = (offset + len - 1) >> sdp->sd_sb.sb_bsize_shift; |
814 | loff_t max_chunk_size = UINT_MAX & bsize_mask; | 813 | loff_t max_chunk_size = UINT_MAX & bsize_mask; |
815 | struct gfs2_holder gh; | ||
816 | 814 | ||
817 | next = (next + 1) << sdp->sd_sb.sb_bsize_shift; | 815 | next = (next + 1) << sdp->sd_sb.sb_bsize_shift; |
818 | 816 | ||
819 | /* We only support the FALLOC_FL_KEEP_SIZE mode */ | ||
820 | if (mode & ~FALLOC_FL_KEEP_SIZE) | ||
821 | return -EOPNOTSUPP; | ||
822 | |||
823 | offset &= bsize_mask; | 817 | offset &= bsize_mask; |
824 | 818 | ||
825 | len = next - offset; | 819 | len = next - offset; |
@@ -830,17 +824,6 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, | |||
830 | if (bytes == 0) | 824 | if (bytes == 0) |
831 | bytes = sdp->sd_sb.sb_bsize; | 825 | bytes = sdp->sd_sb.sb_bsize; |
832 | 826 | ||
833 | error = gfs2_rs_alloc(ip); | ||
834 | if (error) | ||
835 | return error; | ||
836 | |||
837 | mutex_lock(&inode->i_mutex); | ||
838 | |||
839 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | ||
840 | error = gfs2_glock_nq(&gh); | ||
841 | if (unlikely(error)) | ||
842 | goto out_uninit; | ||
843 | |||
844 | gfs2_size_hint(file, offset, len); | 827 | gfs2_size_hint(file, offset, len); |
845 | 828 | ||
846 | while (len > 0) { | 829 | while (len > 0) { |
@@ -853,8 +836,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, | |||
853 | } | 836 | } |
854 | error = gfs2_quota_lock_check(ip); | 837 | error = gfs2_quota_lock_check(ip); |
855 | if (error) | 838 | if (error) |
856 | goto out_unlock; | 839 | return error; |
857 | |||
858 | retry: | 840 | retry: |
859 | gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks); | 841 | gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks); |
860 | 842 | ||
@@ -898,18 +880,58 @@ retry: | |||
898 | 880 | ||
899 | if (error == 0) | 881 | if (error == 0) |
900 | error = generic_write_sync(file, pos, count); | 882 | error = generic_write_sync(file, pos, count); |
901 | goto out_unlock; | 883 | return error; |
902 | 884 | ||
903 | out_trans_fail: | 885 | out_trans_fail: |
904 | gfs2_inplace_release(ip); | 886 | gfs2_inplace_release(ip); |
905 | out_qunlock: | 887 | out_qunlock: |
906 | gfs2_quota_unlock(ip); | 888 | gfs2_quota_unlock(ip); |
889 | return error; | ||
890 | } | ||
891 | |||
892 | static long gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t len) | ||
893 | { | ||
894 | struct inode *inode = file_inode(file); | ||
895 | struct gfs2_inode *ip = GFS2_I(inode); | ||
896 | struct gfs2_holder gh; | ||
897 | int ret; | ||
898 | |||
899 | if (mode & ~FALLOC_FL_KEEP_SIZE) | ||
900 | return -EOPNOTSUPP; | ||
901 | |||
902 | mutex_lock(&inode->i_mutex); | ||
903 | |||
904 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | ||
905 | ret = gfs2_glock_nq(&gh); | ||
906 | if (ret) | ||
907 | goto out_uninit; | ||
908 | |||
909 | if (!(mode & FALLOC_FL_KEEP_SIZE) && | ||
910 | (offset + len) > inode->i_size) { | ||
911 | ret = inode_newsize_ok(inode, offset + len); | ||
912 | if (ret) | ||
913 | goto out_unlock; | ||
914 | } | ||
915 | |||
916 | ret = get_write_access(inode); | ||
917 | if (ret) | ||
918 | goto out_unlock; | ||
919 | |||
920 | ret = gfs2_rs_alloc(ip); | ||
921 | if (ret) | ||
922 | goto out_putw; | ||
923 | |||
924 | ret = __gfs2_fallocate(file, mode, offset, len); | ||
925 | if (ret) | ||
926 | gfs2_rs_deltree(ip->i_res); | ||
927 | out_putw: | ||
928 | put_write_access(inode); | ||
907 | out_unlock: | 929 | out_unlock: |
908 | gfs2_glock_dq(&gh); | 930 | gfs2_glock_dq(&gh); |
909 | out_uninit: | 931 | out_uninit: |
910 | gfs2_holder_uninit(&gh); | 932 | gfs2_holder_uninit(&gh); |
911 | mutex_unlock(&inode->i_mutex); | 933 | mutex_unlock(&inode->i_mutex); |
912 | return error; | 934 | return ret; |
913 | } | 935 | } |
914 | 936 | ||
915 | #ifdef CONFIG_GFS2_FS_LOCKING_DLM | 937 | #ifdef CONFIG_GFS2_FS_LOCKING_DLM |