aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/rgrp.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r--fs/gfs2/rgrp.c71
1 files changed, 51 insertions, 20 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 6b6cc096756a..f6e05d63e8ab 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -860,22 +860,36 @@ fail:
860} 860}
861 861
862/** 862/**
863 * gfs2_alloc_get - get the struct gfs2_alloc structure for an inode 863 * gfs2_qadata_get - get the struct gfs2_qadata structure for an inode
864 * @ip: the incore GFS2 inode structure 864 * @ip: the incore GFS2 inode structure
865 * 865 *
866 * Returns: the struct gfs2_alloc 866 * Returns: the struct gfs2_qadata
867 */ 867 */
868 868
869struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip) 869struct gfs2_qadata *gfs2_qadata_get(struct gfs2_inode *ip)
870{ 870{
871 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 871 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
872 int error; 872 int error;
873 BUG_ON(ip->i_alloc != NULL); 873 BUG_ON(ip->i_qadata != NULL);
874 ip->i_alloc = kzalloc(sizeof(struct gfs2_alloc), GFP_NOFS); 874 ip->i_qadata = kzalloc(sizeof(struct gfs2_qadata), GFP_NOFS);
875 error = gfs2_rindex_update(sdp); 875 error = gfs2_rindex_update(sdp);
876 if (error) 876 if (error)
877 fs_warn(sdp, "rindex update returns %d\n", error); 877 fs_warn(sdp, "rindex update returns %d\n", error);
878 return ip->i_alloc; 878 return ip->i_qadata;
879}
880
881/**
882 * gfs2_blkrsv_get - get the struct gfs2_blkreserv structure for an inode
883 * @ip: the incore GFS2 inode structure
884 *
885 * Returns: the struct gfs2_qadata
886 */
887
888static struct gfs2_blkreserv *gfs2_blkrsv_get(struct gfs2_inode *ip)
889{
890 BUG_ON(ip->i_res != NULL);
891 ip->i_res = kzalloc(sizeof(struct gfs2_blkreserv), GFP_NOFS);
892 return ip->i_res;
879} 893}
880 894
881/** 895/**
@@ -890,11 +904,11 @@ struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip)
890 904
891static int try_rgrp_fit(const struct gfs2_rgrpd *rgd, const struct gfs2_inode *ip) 905static int try_rgrp_fit(const struct gfs2_rgrpd *rgd, const struct gfs2_inode *ip)
892{ 906{
893 const struct gfs2_alloc *al = ip->i_alloc; 907 const struct gfs2_blkreserv *rs = ip->i_res;
894 908
895 if (rgd->rd_flags & (GFS2_RGF_NOALLOC | GFS2_RDF_ERROR)) 909 if (rgd->rd_flags & (GFS2_RGF_NOALLOC | GFS2_RDF_ERROR))
896 return 0; 910 return 0;
897 if (rgd->rd_free_clone >= al->al_requested) 911 if (rgd->rd_free_clone >= rs->rs_requested)
898 return 1; 912 return 1;
899 return 0; 913 return 0;
900} 914}
@@ -982,7 +996,7 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
982{ 996{
983 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 997 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
984 struct gfs2_rgrpd *rgd, *begin = NULL; 998 struct gfs2_rgrpd *rgd, *begin = NULL;
985 struct gfs2_alloc *al = ip->i_alloc; 999 struct gfs2_blkreserv *rs = ip->i_res;
986 int error, rg_locked, flags = LM_FLAG_TRY; 1000 int error, rg_locked, flags = LM_FLAG_TRY;
987 int loops = 0; 1001 int loops = 0;
988 1002
@@ -1002,7 +1016,7 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1002 error = 0; 1016 error = 0;
1003 } else { 1017 } else {
1004 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 1018 error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE,
1005 flags, &al->al_rgd_gh); 1019 flags, &rs->rs_rgd_gh);
1006 } 1020 }
1007 switch (error) { 1021 switch (error) {
1008 case 0: 1022 case 0:
@@ -1013,7 +1027,7 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1013 if (rgd->rd_flags & GFS2_RDF_CHECK) 1027 if (rgd->rd_flags & GFS2_RDF_CHECK)
1014 try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); 1028 try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr);
1015 if (!rg_locked) 1029 if (!rg_locked)
1016 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1030 gfs2_glock_dq_uninit(&rs->rs_rgd_gh);
1017 /* fall through */ 1031 /* fall through */
1018 case GLR_TRYFAILED: 1032 case GLR_TRYFAILED:
1019 rgd = gfs2_rgrpd_get_next(rgd); 1033 rgd = gfs2_rgrpd_get_next(rgd);
@@ -1030,6 +1044,13 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1030 return -ENOSPC; 1044 return -ENOSPC;
1031} 1045}
1032 1046
1047static void gfs2_blkrsv_put(struct gfs2_inode *ip)
1048{
1049 BUG_ON(ip->i_res == NULL);
1050 kfree(ip->i_res);
1051 ip->i_res = NULL;
1052}
1053
1033/** 1054/**
1034 * gfs2_inplace_reserve - Reserve space in the filesystem 1055 * gfs2_inplace_reserve - Reserve space in the filesystem
1035 * @ip: the inode to reserve space for 1056 * @ip: the inode to reserve space for
@@ -1037,16 +1058,23 @@ static int get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1037 * Returns: errno 1058 * Returns: errno
1038 */ 1059 */
1039 1060
1040int gfs2_inplace_reserve(struct gfs2_inode *ip) 1061int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
1041{ 1062{
1042 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1063 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1043 struct gfs2_alloc *al = ip->i_alloc; 1064 struct gfs2_blkreserv *rs;
1044 int error = 0; 1065 int error = 0;
1045 u64 last_unlinked = NO_BLOCK; 1066 u64 last_unlinked = NO_BLOCK;
1046 int tries = 0; 1067 int tries = 0;
1047 1068
1048 if (gfs2_assert_warn(sdp, al->al_requested)) 1069 rs = gfs2_blkrsv_get(ip);
1049 return -EINVAL; 1070 if (!rs)
1071 return -ENOMEM;
1072
1073 rs->rs_requested = requested;
1074 if (gfs2_assert_warn(sdp, requested)) {
1075 error = -EINVAL;
1076 goto out;
1077 }
1050 1078
1051 do { 1079 do {
1052 error = get_local_rgrp(ip, &last_unlinked); 1080 error = get_local_rgrp(ip, &last_unlinked);
@@ -1063,6 +1091,9 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip)
1063 gfs2_log_flush(sdp, NULL); 1091 gfs2_log_flush(sdp, NULL);
1064 } while (tries++ < 3); 1092 } while (tries++ < 3);
1065 1093
1094out:
1095 if (error)
1096 gfs2_blkrsv_put(ip);
1066 return error; 1097 return error;
1067} 1098}
1068 1099
@@ -1075,10 +1106,11 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip)
1075 1106
1076void gfs2_inplace_release(struct gfs2_inode *ip) 1107void gfs2_inplace_release(struct gfs2_inode *ip)
1077{ 1108{
1078 struct gfs2_alloc *al = ip->i_alloc; 1109 struct gfs2_blkreserv *rs = ip->i_res;
1079 1110
1080 if (al->al_rgd_gh.gh_gl) 1111 gfs2_blkrsv_put(ip);
1081 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1112 if (rs->rs_rgd_gh.gh_gl)
1113 gfs2_glock_dq_uninit(&rs->rs_rgd_gh);
1082} 1114}
1083 1115
1084/** 1116/**
@@ -1338,7 +1370,6 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *ndata,
1338{ 1370{
1339 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1371 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1340 struct buffer_head *dibh; 1372 struct buffer_head *dibh;
1341 struct gfs2_alloc *al = ip->i_alloc;
1342 struct gfs2_rgrpd *rgd; 1373 struct gfs2_rgrpd *rgd;
1343 u32 goal, extlen, blk; /* block, within the rgrp scope */ 1374 u32 goal, extlen, blk; /* block, within the rgrp scope */
1344 u64 block; /* block, within the file system scope */ 1375 u64 block; /* block, within the file system scope */
@@ -1348,7 +1379,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *ndata,
1348 /* Only happens if there is a bug in gfs2, return something distinctive 1379 /* Only happens if there is a bug in gfs2, return something distinctive
1349 * to ensure that it is noticed. 1380 * to ensure that it is noticed.
1350 */ 1381 */
1351 if (al == NULL) 1382 if (ip->i_res == NULL)
1352 return -ECANCELED; 1383 return -ECANCELED;
1353 1384
1354 rgd = ip->i_rgd; 1385 rgd = ip->i_rgd;