|
@@ -936,7 +936,7 @@ static int read_rindex_entry(struct gfs2_inode *ip)
|
|
rgd->rd_gl->gl_vm.start = rgd->rd_addr * bsize;
|
|
rgd->rd_gl->gl_vm.start = rgd->rd_addr * bsize;
|
|
rgd->rd_gl->gl_vm.end = rgd->rd_gl->gl_vm.start + (rgd->rd_length * bsize) - 1;
|
|
rgd->rd_gl->gl_vm.end = rgd->rd_gl->gl_vm.start + (rgd->rd_length * bsize) - 1;
|
|
rgd->rd_rgl = (struct gfs2_rgrp_lvb *)rgd->rd_gl->gl_lksb.sb_lvbptr;
|
|
rgd->rd_rgl = (struct gfs2_rgrp_lvb *)rgd->rd_gl->gl_lksb.sb_lvbptr;
|
|
- rgd->rd_flags &= ~GFS2_RDF_UPTODATE;
|
|
|
|
|
|
+ rgd->rd_flags &= ~(GFS2_RDF_UPTODATE | GFS2_RDF_PREFERRED);
|
|
if (rgd->rd_data > sdp->sd_max_rg_data)
|
|
if (rgd->rd_data > sdp->sd_max_rg_data)
|
|
sdp->sd_max_rg_data = rgd->rd_data;
|
|
sdp->sd_max_rg_data = rgd->rd_data;
|
|
spin_lock(&sdp->sd_rindex_spin);
|
|
spin_lock(&sdp->sd_rindex_spin);
|
|
@@ -954,6 +954,36 @@ fail:
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * set_rgrp_preferences - Run all the rgrps, selecting some we prefer to use
|
|
|
|
+ * @sdp: the GFS2 superblock
|
|
|
|
+ *
|
|
|
|
+ * The purpose of this function is to select a subset of the resource groups
|
|
|
|
+ * and mark them as PREFERRED. We do it in such a way that each node prefers
|
|
|
|
+ * to use a unique set of rgrps to minimize glock contention.
|
|
|
|
+ */
|
|
|
|
+static void set_rgrp_preferences(struct gfs2_sbd *sdp)
|
|
|
|
+{
|
|
|
|
+ struct gfs2_rgrpd *rgd, *first;
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ /* Skip an initial number of rgrps, based on this node's journal ID.
|
|
|
|
+ That should start each node out on its own set. */
|
|
|
|
+ rgd = gfs2_rgrpd_get_first(sdp);
|
|
|
|
+ for (i = 0; i < sdp->sd_lockstruct.ls_jid; i++)
|
|
|
|
+ rgd = gfs2_rgrpd_get_next(rgd);
|
|
|
|
+ first = rgd;
|
|
|
|
+
|
|
|
|
+ do {
|
|
|
|
+ rgd->rd_flags |= GFS2_RDF_PREFERRED;
|
|
|
|
+ for (i = 0; i < sdp->sd_journals; i++) {
|
|
|
|
+ rgd = gfs2_rgrpd_get_next(rgd);
|
|
|
|
+ if (rgd == first)
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ } while (rgd != first);
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* gfs2_ri_update - Pull in a new resource index from the disk
|
|
* gfs2_ri_update - Pull in a new resource index from the disk
|
|
* @ip: pointer to the rindex inode
|
|
* @ip: pointer to the rindex inode
|
|
@@ -973,6 +1003,8 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
|
|
if (error < 0)
|
|
if (error < 0)
|
|
return error;
|
|
return error;
|
|
|
|
|
|
|
|
+ set_rgrp_preferences(sdp);
|
|
|
|
+
|
|
sdp->sd_rindex_uptodate = 1;
|
|
sdp->sd_rindex_uptodate = 1;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -1890,6 +1922,25 @@ static bool gfs2_select_rgrp(struct gfs2_rgrpd **pos, const struct gfs2_rgrpd *b
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * fast_to_acquire - determine if a resource group will be fast to acquire
|
|
|
|
+ *
|
|
|
|
+ * If this is one of our preferred rgrps, it should be quicker to acquire,
|
|
|
|
+ * because we tried to set ourselves up as dlm lock master.
|
|
|
|
+ */
|
|
|
|
+static inline int fast_to_acquire(struct gfs2_rgrpd *rgd)
|
|
|
|
+{
|
|
|
|
+ struct gfs2_glock *gl = rgd->rd_gl;
|
|
|
|
+
|
|
|
|
+ if (gl->gl_state != LM_ST_UNLOCKED && list_empty(&gl->gl_holders) &&
|
|
|
|
+ !test_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags) &&
|
|
|
|
+ !test_bit(GLF_DEMOTE, &gl->gl_flags))
|
|
|
|
+ return 1;
|
|
|
|
+ if (rgd->rd_flags & GFS2_RDF_PREFERRED)
|
|
|
|
+ return 1;
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* gfs2_inplace_reserve - Reserve space in the filesystem
|
|
* gfs2_inplace_reserve - Reserve space in the filesystem
|
|
* @ip: the inode to reserve space for
|
|
* @ip: the inode to reserve space for
|
|
@@ -1932,10 +1983,15 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, const struct gfs2_alloc_parms *a
|
|
rg_locked = 0;
|
|
rg_locked = 0;
|
|
if (skip && skip--)
|
|
if (skip && skip--)
|
|
goto next_rgrp;
|
|
goto next_rgrp;
|
|
- if (!gfs2_rs_active(rs) && (loops < 2) &&
|
|
|
|
- gfs2_rgrp_used_recently(rs, 1000) &&
|
|
|
|
- gfs2_rgrp_congested(rs->rs_rbm.rgd, loops))
|
|
|
|
- goto next_rgrp;
|
|
|
|
|
|
+ if (!gfs2_rs_active(rs)) {
|
|
|
|
+ if (loops == 0 &&
|
|
|
|
+ !fast_to_acquire(rs->rs_rbm.rgd))
|
|
|
|
+ goto next_rgrp;
|
|
|
|
+ if ((loops < 2) &&
|
|
|
|
+ gfs2_rgrp_used_recently(rs, 1000) &&
|
|
|
|
+ gfs2_rgrp_congested(rs->rs_rbm.rgd, loops))
|
|
|
|
+ goto next_rgrp;
|
|
|
|
+ }
|
|
error = gfs2_glock_nq_init(rs->rs_rbm.rgd->rd_gl,
|
|
error = gfs2_glock_nq_init(rs->rs_rbm.rgd->rd_gl,
|
|
LM_ST_EXCLUSIVE, flags,
|
|
LM_ST_EXCLUSIVE, flags,
|
|
&rs->rs_rgd_gh);
|
|
&rs->rs_rgd_gh);
|