diff options
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r-- | fs/gfs2/rgrp.c | 71 |
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 | ||
869 | struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip) | 869 | struct 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 | |||
888 | static 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 | ||
891 | static int try_rgrp_fit(const struct gfs2_rgrpd *rgd, const struct gfs2_inode *ip) | 905 | static 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 | ||
1047 | static 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 | ||
1040 | int gfs2_inplace_reserve(struct gfs2_inode *ip) | 1061 | int 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 | ||
1094 | out: | ||
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 | ||
1076 | void gfs2_inplace_release(struct gfs2_inode *ip) | 1107 | void 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; |