aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
authorAndrew Price <anprice@redhat.com>2014-11-12 12:24:03 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2014-11-14 09:14:30 -0500
commit9c9f1159a54c6163dd0b9d2085985d3c98dad11f (patch)
treed65c967f3dc7d604a73b020ed80a13839c6548b9 /fs/gfs2
parent1a8550332a7f0111306b6b34e44a7c696ef68c4d (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.c66
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
800static long gfs2_fallocate(struct file *file, int mode, loff_t offset, 800static 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
858retry: 840retry:
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
903out_trans_fail: 885out_trans_fail:
904 gfs2_inplace_release(ip); 886 gfs2_inplace_release(ip);
905out_qunlock: 887out_qunlock:
906 gfs2_quota_unlock(ip); 888 gfs2_quota_unlock(ip);
889 return error;
890}
891
892static 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);
927out_putw:
928 put_write_access(inode);
907out_unlock: 929out_unlock:
908 gfs2_glock_dq(&gh); 930 gfs2_glock_dq(&gh);
909out_uninit: 931out_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