diff options
Diffstat (limited to 'fs/gfs2/rgrp.c')
| -rw-r--r-- | fs/gfs2/rgrp.c | 108 |
1 files changed, 12 insertions, 96 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 3401628d742b..2d90fb253505 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
| @@ -371,11 +371,6 @@ static void clear_rgrpdi(struct gfs2_sbd *sdp) | |||
| 371 | 371 | ||
| 372 | spin_lock(&sdp->sd_rindex_spin); | 372 | spin_lock(&sdp->sd_rindex_spin); |
| 373 | sdp->sd_rindex_forward = NULL; | 373 | sdp->sd_rindex_forward = NULL; |
| 374 | head = &sdp->sd_rindex_recent_list; | ||
| 375 | while (!list_empty(head)) { | ||
| 376 | rgd = list_entry(head->next, struct gfs2_rgrpd, rd_recent); | ||
| 377 | list_del(&rgd->rd_recent); | ||
| 378 | } | ||
| 379 | spin_unlock(&sdp->sd_rindex_spin); | 374 | spin_unlock(&sdp->sd_rindex_spin); |
| 380 | 375 | ||
| 381 | head = &sdp->sd_rindex_list; | 376 | head = &sdp->sd_rindex_list; |
| @@ -945,107 +940,30 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) | |||
| 945 | } | 940 | } |
| 946 | 941 | ||
| 947 | /** | 942 | /** |
| 948 | * recent_rgrp_first - get first RG from "recent" list | ||
| 949 | * @sdp: The GFS2 superblock | ||
| 950 | * @rglast: address of the rgrp used last | ||
| 951 | * | ||
| 952 | * Returns: The first rgrp in the recent list | ||
| 953 | */ | ||
| 954 | |||
| 955 | static struct gfs2_rgrpd *recent_rgrp_first(struct gfs2_sbd *sdp, | ||
| 956 | u64 rglast) | ||
| 957 | { | ||
| 958 | struct gfs2_rgrpd *rgd; | ||
| 959 | |||
| 960 | spin_lock(&sdp->sd_rindex_spin); | ||
| 961 | |||
| 962 | if (rglast) { | ||
| 963 | list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) { | ||
| 964 | if (rgrp_contains_block(rgd, rglast)) | ||
| 965 | goto out; | ||
| 966 | } | ||
| 967 | } | ||
| 968 | rgd = NULL; | ||
| 969 | if (!list_empty(&sdp->sd_rindex_recent_list)) | ||
| 970 | rgd = list_entry(sdp->sd_rindex_recent_list.next, | ||
| 971 | struct gfs2_rgrpd, rd_recent); | ||
| 972 | out: | ||
| 973 | spin_unlock(&sdp->sd_rindex_spin); | ||
| 974 | return rgd; | ||
| 975 | } | ||
| 976 | |||
| 977 | /** | ||
| 978 | * recent_rgrp_next - get next RG from "recent" list | 943 | * recent_rgrp_next - get next RG from "recent" list |
| 979 | * @cur_rgd: current rgrp | 944 | * @cur_rgd: current rgrp |
| 980 | * @remove: | ||
| 981 | * | 945 | * |
| 982 | * Returns: The next rgrp in the recent list | 946 | * Returns: The next rgrp in the recent list |
| 983 | */ | 947 | */ |
| 984 | 948 | ||
| 985 | static struct gfs2_rgrpd *recent_rgrp_next(struct gfs2_rgrpd *cur_rgd, | 949 | static struct gfs2_rgrpd *recent_rgrp_next(struct gfs2_rgrpd *cur_rgd) |
| 986 | int remove) | ||
| 987 | { | 950 | { |
| 988 | struct gfs2_sbd *sdp = cur_rgd->rd_sbd; | 951 | struct gfs2_sbd *sdp = cur_rgd->rd_sbd; |
| 989 | struct list_head *head; | 952 | struct list_head *head; |
| 990 | struct gfs2_rgrpd *rgd; | 953 | struct gfs2_rgrpd *rgd; |
| 991 | 954 | ||
| 992 | spin_lock(&sdp->sd_rindex_spin); | 955 | spin_lock(&sdp->sd_rindex_spin); |
| 993 | 956 | head = &sdp->sd_rindex_mru_list; | |
| 994 | head = &sdp->sd_rindex_recent_list; | 957 | if (unlikely(cur_rgd->rd_list_mru.next == head)) { |
| 995 | 958 | spin_unlock(&sdp->sd_rindex_spin); | |
| 996 | list_for_each_entry(rgd, head, rd_recent) { | 959 | return NULL; |
| 997 | if (rgd == cur_rgd) { | ||
| 998 | if (cur_rgd->rd_recent.next != head) | ||
| 999 | rgd = list_entry(cur_rgd->rd_recent.next, | ||
| 1000 | struct gfs2_rgrpd, rd_recent); | ||
| 1001 | else | ||
| 1002 | rgd = NULL; | ||
| 1003 | |||
| 1004 | if (remove) | ||
| 1005 | list_del(&cur_rgd->rd_recent); | ||
| 1006 | |||
| 1007 | goto out; | ||
| 1008 | } | ||
| 1009 | } | 960 | } |
| 1010 | 961 | rgd = list_entry(cur_rgd->rd_list_mru.next, struct gfs2_rgrpd, rd_list_mru); | |
| 1011 | rgd = NULL; | ||
| 1012 | if (!list_empty(head)) | ||
| 1013 | rgd = list_entry(head->next, struct gfs2_rgrpd, rd_recent); | ||
| 1014 | |||
| 1015 | out: | ||
| 1016 | spin_unlock(&sdp->sd_rindex_spin); | 962 | spin_unlock(&sdp->sd_rindex_spin); |
| 1017 | return rgd; | 963 | return rgd; |
| 1018 | } | 964 | } |
| 1019 | 965 | ||
| 1020 | /** | 966 | /** |
| 1021 | * recent_rgrp_add - add an RG to tail of "recent" list | ||
| 1022 | * @new_rgd: The rgrp to add | ||
| 1023 | * | ||
| 1024 | */ | ||
| 1025 | |||
| 1026 | static void recent_rgrp_add(struct gfs2_rgrpd *new_rgd) | ||
| 1027 | { | ||
| 1028 | struct gfs2_sbd *sdp = new_rgd->rd_sbd; | ||
| 1029 | struct gfs2_rgrpd *rgd; | ||
| 1030 | unsigned int count = 0; | ||
| 1031 | unsigned int max = sdp->sd_rgrps / gfs2_jindex_size(sdp); | ||
| 1032 | |||
| 1033 | spin_lock(&sdp->sd_rindex_spin); | ||
| 1034 | |||
| 1035 | list_for_each_entry(rgd, &sdp->sd_rindex_recent_list, rd_recent) { | ||
| 1036 | if (rgd == new_rgd) | ||
| 1037 | goto out; | ||
| 1038 | |||
| 1039 | if (++count >= max) | ||
| 1040 | goto out; | ||
| 1041 | } | ||
| 1042 | list_add_tail(&new_rgd->rd_recent, &sdp->sd_rindex_recent_list); | ||
| 1043 | |||
| 1044 | out: | ||
| 1045 | spin_unlock(&sdp->sd_rindex_spin); | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | /** | ||
| 1049 | * forward_rgrp_get - get an rgrp to try next from full list | 967 | * forward_rgrp_get - get an rgrp to try next from full list |
| 1050 | * @sdp: The GFS2 superblock | 968 | * @sdp: The GFS2 superblock |
| 1051 | * | 969 | * |
| @@ -1112,9 +1030,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | |||
| 1112 | int loops = 0; | 1030 | int loops = 0; |
| 1113 | int error, rg_locked; | 1031 | int error, rg_locked; |
| 1114 | 1032 | ||
| 1115 | /* Try recently successful rgrps */ | 1033 | rgd = gfs2_blk2rgrpd(sdp, ip->i_goal); |
| 1116 | |||
| 1117 | rgd = recent_rgrp_first(sdp, ip->i_goal); | ||
| 1118 | 1034 | ||
| 1119 | while (rgd) { | 1035 | while (rgd) { |
| 1120 | rg_locked = 0; | 1036 | rg_locked = 0; |
| @@ -1136,11 +1052,9 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | |||
| 1136 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | 1052 | gfs2_glock_dq_uninit(&al->al_rgd_gh); |
| 1137 | if (inode) | 1053 | if (inode) |
| 1138 | return inode; | 1054 | return inode; |
| 1139 | rgd = recent_rgrp_next(rgd, 1); | 1055 | /* fall through */ |
| 1140 | break; | ||
| 1141 | |||
| 1142 | case GLR_TRYFAILED: | 1056 | case GLR_TRYFAILED: |
| 1143 | rgd = recent_rgrp_next(rgd, 0); | 1057 | rgd = recent_rgrp_next(rgd); |
| 1144 | break; | 1058 | break; |
| 1145 | 1059 | ||
| 1146 | default: | 1060 | default: |
| @@ -1199,7 +1113,9 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | |||
| 1199 | 1113 | ||
| 1200 | out: | 1114 | out: |
| 1201 | if (begin) { | 1115 | if (begin) { |
| 1202 | recent_rgrp_add(rgd); | 1116 | spin_lock(&sdp->sd_rindex_spin); |
| 1117 | list_move(&rgd->rd_list_mru, &sdp->sd_rindex_mru_list); | ||
| 1118 | spin_unlock(&sdp->sd_rindex_spin); | ||
| 1203 | rgd = gfs2_rgrpd_get_next(rgd); | 1119 | rgd = gfs2_rgrpd_get_next(rgd); |
| 1204 | if (!rgd) | 1120 | if (!rgd) |
| 1205 | rgd = gfs2_rgrpd_get_first(sdp); | 1121 | rgd = gfs2_rgrpd_get_first(sdp); |
