aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/incore.h1
-rw-r--r--fs/gfs2/rgrp.c66
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 */
965static 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 */
1931static 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);