diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/incore.h | 1 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 66 |
2 files changed, 62 insertions, 5 deletions
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 39e7e9959b74..1b899187be5a 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -97,6 +97,7 @@ struct gfs2_rgrpd { | |||
97 | #define GFS2_RDF_CHECK 0x10000000 /* check for unlinked inodes */ | 97 | #define GFS2_RDF_CHECK 0x10000000 /* check for unlinked inodes */ |
98 | #define GFS2_RDF_UPTODATE 0x20000000 /* rg is up to date */ | 98 | #define GFS2_RDF_UPTODATE 0x20000000 /* rg is up to date */ |
99 | #define GFS2_RDF_ERROR 0x40000000 /* error in rg */ | 99 | #define GFS2_RDF_ERROR 0x40000000 /* error in rg */ |
100 | #define GFS2_RDF_PREFERRED 0x80000000 /* This rgrp is preferred */ | ||
100 | #define GFS2_RDF_MASK 0xf0000000 /* mask for internal flags */ | 101 | #define GFS2_RDF_MASK 0xf0000000 /* mask for internal flags */ |
101 | spinlock_t rd_rsspin; /* protects reservation related vars */ | 102 | spinlock_t rd_rsspin; /* protects reservation related vars */ |
102 | struct rb_root rd_rstree; /* multi-block reservation tree */ | 103 | struct rb_root rd_rstree; /* multi-block reservation tree */ |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 7474c413ffd1..f4e4a0c5babe 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -936,7 +936,7 @@ static int read_rindex_entry(struct gfs2_inode *ip) | |||
936 | rgd->rd_gl->gl_vm.start = rgd->rd_addr * bsize; | 936 | rgd->rd_gl->gl_vm.start = rgd->rd_addr * bsize; |
937 | rgd->rd_gl->gl_vm.end = rgd->rd_gl->gl_vm.start + (rgd->rd_length * bsize) - 1; | 937 | rgd->rd_gl->gl_vm.end = rgd->rd_gl->gl_vm.start + (rgd->rd_length * bsize) - 1; |
938 | rgd->rd_rgl = (struct gfs2_rgrp_lvb *)rgd->rd_gl->gl_lksb.sb_lvbptr; | 938 | rgd->rd_rgl = (struct gfs2_rgrp_lvb *)rgd->rd_gl->gl_lksb.sb_lvbptr; |
939 | rgd->rd_flags &= ~GFS2_RDF_UPTODATE; | 939 | rgd->rd_flags &= ~(GFS2_RDF_UPTODATE | GFS2_RDF_PREFERRED); |
940 | if (rgd->rd_data > sdp->sd_max_rg_data) | 940 | if (rgd->rd_data > sdp->sd_max_rg_data) |
941 | sdp->sd_max_rg_data = rgd->rd_data; | 941 | sdp->sd_max_rg_data = rgd->rd_data; |
942 | spin_lock(&sdp->sd_rindex_spin); | 942 | spin_lock(&sdp->sd_rindex_spin); |
@@ -955,6 +955,36 @@ fail: | |||
955 | } | 955 | } |
956 | 956 | ||
957 | /** | 957 | /** |
958 | * set_rgrp_preferences - Run all the rgrps, selecting some we prefer to use | ||
959 | * @sdp: the GFS2 superblock | ||
960 | * | ||
961 | * The purpose of this function is to select a subset of the resource groups | ||
962 | * and mark them as PREFERRED. We do it in such a way that each node prefers | ||
963 | * to use a unique set of rgrps to minimize glock contention. | ||
964 | */ | ||
965 | static void set_rgrp_preferences(struct gfs2_sbd *sdp) | ||
966 | { | ||
967 | struct gfs2_rgrpd *rgd, *first; | ||
968 | int i; | ||
969 | |||
970 | /* Skip an initial number of rgrps, based on this node's journal ID. | ||
971 | That should start each node out on its own set. */ | ||
972 | rgd = gfs2_rgrpd_get_first(sdp); | ||
973 | for (i = 0; i < sdp->sd_lockstruct.ls_jid; i++) | ||
974 | rgd = gfs2_rgrpd_get_next(rgd); | ||
975 | first = rgd; | ||
976 | |||
977 | do { | ||
978 | rgd->rd_flags |= GFS2_RDF_PREFERRED; | ||
979 | for (i = 0; i < sdp->sd_journals; i++) { | ||
980 | rgd = gfs2_rgrpd_get_next(rgd); | ||
981 | if (rgd == first) | ||
982 | break; | ||
983 | } | ||
984 | } while (rgd != first); | ||
985 | } | ||
986 | |||
987 | /** | ||
958 | * gfs2_ri_update - Pull in a new resource index from the disk | 988 | * gfs2_ri_update - Pull in a new resource index from the disk |
959 | * @ip: pointer to the rindex inode | 989 | * @ip: pointer to the rindex inode |
960 | * | 990 | * |
@@ -973,6 +1003,8 @@ static int gfs2_ri_update(struct gfs2_inode *ip) | |||
973 | if (error < 0) | 1003 | if (error < 0) |
974 | return error; | 1004 | return error; |
975 | 1005 | ||
1006 | set_rgrp_preferences(sdp); | ||
1007 | |||
976 | sdp->sd_rindex_uptodate = 1; | 1008 | sdp->sd_rindex_uptodate = 1; |
977 | return 0; | 1009 | return 0; |
978 | } | 1010 | } |
@@ -1891,6 +1923,25 @@ static bool gfs2_select_rgrp(struct gfs2_rgrpd **pos, const struct gfs2_rgrpd *b | |||
1891 | } | 1923 | } |
1892 | 1924 | ||
1893 | /** | 1925 | /** |
1926 | * fast_to_acquire - determine if a resource group will be fast to acquire | ||
1927 | * | ||
1928 | * If this is one of our preferred rgrps, it should be quicker to acquire, | ||
1929 | * because we tried to set ourselves up as dlm lock master. | ||
1930 | */ | ||
1931 | static inline int fast_to_acquire(struct gfs2_rgrpd *rgd) | ||
1932 | { | ||
1933 | struct gfs2_glock *gl = rgd->rd_gl; | ||
1934 | |||
1935 | if (gl->gl_state != LM_ST_UNLOCKED && list_empty(&gl->gl_holders) && | ||
1936 | !test_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags) && | ||
1937 | !test_bit(GLF_DEMOTE, &gl->gl_flags)) | ||
1938 | return 1; | ||
1939 | if (rgd->rd_flags & GFS2_RDF_PREFERRED) | ||
1940 | return 1; | ||
1941 | return 0; | ||
1942 | } | ||
1943 | |||
1944 | /** | ||
1894 | * gfs2_inplace_reserve - Reserve space in the filesystem | 1945 | * gfs2_inplace_reserve - Reserve space in the filesystem |
1895 | * @ip: the inode to reserve space for | 1946 | * @ip: the inode to reserve space for |
1896 | * @ap: the allocation parameters | 1947 | * @ap: the allocation parameters |
@@ -1932,10 +1983,15 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *a | |||
1932 | rg_locked = 0; | 1983 | rg_locked = 0; |
1933 | if (skip && skip--) | 1984 | if (skip && skip--) |
1934 | goto next_rgrp; | 1985 | goto next_rgrp; |
1935 | if (!gfs2_rs_active(rs) && (loops < 2) && | 1986 | if (!gfs2_rs_active(rs)) { |
1936 | gfs2_rgrp_used_recently(rs, 1000) && | 1987 | if (loops == 0 && |
1937 | gfs2_rgrp_congested(rs->rs_rbm.rgd, loops)) | 1988 | !fast_to_acquire(rs->rs_rbm.rgd)) |
1938 | goto next_rgrp; | 1989 | goto next_rgrp; |
1990 | if ((loops < 2) && | ||
1991 | gfs2_rgrp_used_recently(rs, 1000) && | ||
1992 | gfs2_rgrp_congested(rs->rs_rbm.rgd, loops)) | ||
1993 | goto next_rgrp; | ||
1994 | } | ||
1939 | error = gfs2_glock_nq_init(rs->rs_rbm.rgd->rd_gl, | 1995 | error = gfs2_glock_nq_init(rs->rs_rbm.rgd->rd_gl, |
1940 | LM_ST_EXCLUSIVE, flags, | 1996 | LM_ST_EXCLUSIVE, flags, |
1941 | &rs->rs_rgd_gh); | 1997 | &rs->rs_rgd_gh); |