Re: [Cluster-devel] [PATCH 03/12] xfs: Set allowed quota types

2014-10-08 Thread Jan Kara
On Tue 07-10-14 13:46:20, Andreas Dilger wrote:
 On Oct 7, 2014, at 1:29 PM, Jan Kara j...@suse.cz wrote:
  On Tue 07-10-14 07:30:28, Dave Chinner wrote:
  On Wed, Oct 01, 2014 at 09:31:25PM +0200, Jan Kara wrote:
  We support user, group, and project quotas. Tell VFS about it.
  
  CC: x...@oss.sgi.com
  CC: Dave Chinner da...@fromorbit.com
  Signed-off-by: Jan Kara j...@suse.cz
  ---
  fs/xfs/xfs_super.c | 2 ++
  1 file changed, 2 insertions(+)
  
  diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
  index b194652033cd..b32e998e8cbc 100644
  --- a/fs/xfs/xfs_super.c
  +++ b/fs/xfs/xfs_super.c
  @@ -1419,6 +1419,8 @@ xfs_fs_fill_super(
sb-s_export_op = xfs_export_operations;
  #ifdef CONFIG_XFS_QUOTA
sb-s_qcop = xfs_quotactl_operations;
  + sb-s_dquot.allowed_types = (1  USRQUOTA) | (1  GRPQUOTA) |
  + (1  PRJQUOTA);
  
  Would it be better to define masks for these rather than open
  coding these shifts everywhere?
   I can do that. Any suggestion for a name? I was thinking about it for a
  while and couldn't come up with anything satisfactory...
 
 Better to have QUOTA at the start, and TYPE in the name, so maybe:
 
 enum quota_types {
   QUOTA_TYPE_USR = 1  USRQUOTA,
   QUOTA_TYPE_GRP = 1  GRPQUOTA,
   QUOTA_TYPE_PRJ = 1  PRJQUOTA,
 };
 
 or maybe enum quota_type_mask or similar.
 
 I prefer named enums over #defines since this makes it more clear
 when declaring variables like allowed_types what valid values are
 instead of just int that someone might mistakenly set to USRQUOTA
 directly or something.
  OK, QUOTA_TYPE_USR etc. looks good. I'm not so sure about named enum. I'd
be fine with named enum for USRQUOTA, GRPQUOTA, etc. - i.e., types which
should have one of the named values but for a bitmask with arbitrary
combinations of flags it looks confusing to me (although technically
it would work).

Honza
-- 
Jan Kara j...@suse.cz
SUSE Labs, CR



Re: [Cluster-devel] [PATCH 1/1] GFS2: use _RET_IP_ instead of (unsigned long)__builtin_return_address(0)

2014-10-08 Thread Steven Whitehouse

Hi,

Apologies for taking so long - I've added this into the -nmw tree now. 
Thanks,


Steve.

On 03/10/14 19:15, Fabian Frederick wrote:

use macro definition

Signed-off-by: Fabian Frederick f...@skynet.be
---
  fs/gfs2/glock.c | 4 ++--
  fs/gfs2/glops.c | 2 +-
  fs/gfs2/trans.c | 2 +-
  3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 7f513b1..8f0c19d 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -811,7 +811,7 @@ void gfs2_holder_init(struct gfs2_glock *gl, unsigned int 
state, unsigned flags,
  {
INIT_LIST_HEAD(gh-gh_list);
gh-gh_gl = gl;
-   gh-gh_ip = (unsigned long)__builtin_return_address(0);
+   gh-gh_ip = _RET_IP_;
gh-gh_owner_pid = get_pid(task_pid(current));
gh-gh_state = state;
gh-gh_flags = flags;
@@ -835,7 +835,7 @@ void gfs2_holder_reinit(unsigned int state, unsigned flags, 
struct gfs2_holder *
gh-gh_state = state;
gh-gh_flags = flags;
gh-gh_iflags = 0;
-   gh-gh_ip = (unsigned long)__builtin_return_address(0);
+   gh-gh_ip = _RET_IP_;
if (gh-gh_owner_pid)
put_pid(gh-gh_owner_pid);
gh-gh_owner_pid = get_pid(task_pid(current));
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 2ffc67d..1cc0bba 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -93,7 +93,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
   * tr-alloced is not set since the transaction structure is
   * on the stack */
tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64));
-   tr.tr_ip = (unsigned long)__builtin_return_address(0);
+   tr.tr_ip = _RET_IP_;
sb_start_intwrite(sdp-sd_vfs);
if (gfs2_log_reserve(sdp, tr.tr_reserved)  0) {
sb_end_intwrite(sdp-sd_vfs);
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c
index 0546ab4..42bfd336 100644
--- a/fs/gfs2/trans.c
+++ b/fs/gfs2/trans.c
@@ -44,7 +44,7 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int 
blocks,
if (!tr)
return -ENOMEM;
  
-	tr-tr_ip = (unsigned long)__builtin_return_address(0);

+   tr-tr_ip = _RET_IP_;
tr-tr_blocks = blocks;
tr-tr_revokes = revokes;
tr-tr_reserved = 1;




[Cluster-devel] [PATCH 2/4] GFS2: Make rename not save dirent location

2014-10-08 Thread Steven Whitehouse
From: Bob Peterson rpete...@redhat.com

This patch fixes a regression in the patch GFS2: Remember directory
insert point, commit 2b47dad866d04f14c328f888ba5406057b8c7d33.
The problem had to do with the rename function: The function found
space for the new dirent, and remembered that location. But then the
old dirent was removed, which often moved the eligible location for
the renamed dirent. Putting the new dirent at the saved location
caused file system corruption.

This patch adds a new save_loc variable to struct gfs2_diradd.
If 1, the dirent location is saved. If 0, the dirent location is not
saved and the buffer_head is released as per previous behavior.

Signed-off-by: Bob Peterson rpete...@redhat.com
Signed-off-by: Steven Whitehouse swhit...@redhat.com

diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 1a349f9..5d4261f 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -2100,8 +2100,13 @@ int gfs2_diradd_alloc_required(struct inode *inode, 
const struct qstr *name,
}
if (IS_ERR(dent))
return PTR_ERR(dent);
-   da-bh = bh;
-   da-dent = dent;
+
+   if (da-save_loc) {
+   da-bh = bh;
+   da-dent = dent;
+   } else {
+   brelse(bh);
+   }
return 0;
 }
 
diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h
index 126c65d..e1b309c 100644
--- a/fs/gfs2/dir.h
+++ b/fs/gfs2/dir.h
@@ -23,6 +23,7 @@ struct gfs2_diradd {
unsigned nr_blocks;
struct gfs2_dirent *dent;
struct buffer_head *bh;
+   int save_loc;
 };
 
 extern struct inode *gfs2_dir_search(struct inode *dir,
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 9516f5c..fcf42ea 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -600,7 +600,7 @@ static int gfs2_create_inode(struct inode *dir, struct 
dentry *dentry,
int error, free_vfs_inode = 0;
u32 aflags = 0;
unsigned blocks = 1;
-   struct gfs2_diradd da = { .bh = NULL, };
+   struct gfs2_diradd da = { .bh = NULL, .save_loc = 1, };
 
if (!name-len || name-len  GFS2_FNAMESIZE)
return -ENAMETOOLONG;
@@ -900,7 +900,7 @@ static int gfs2_link(struct dentry *old_dentry, struct 
inode *dir,
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_holder ghs[2];
struct buffer_head *dibh;
-   struct gfs2_diradd da = { .bh = NULL, };
+   struct gfs2_diradd da = { .bh = NULL, .save_loc = 1, };
int error;
 
if (S_ISDIR(inode-i_mode))
@@ -1338,7 +1338,7 @@ static int gfs2_rename(struct inode *odir, struct dentry 
*odentry,
struct gfs2_rgrpd *nrgd;
unsigned int num_gh;
int dir_rename = 0;
-   struct gfs2_diradd da = { .nr_blocks = 0, };
+   struct gfs2_diradd da = { .nr_blocks = 0, .save_loc = 0, };
unsigned int x;
int error;
 
-- 
1.8.3.1



[Cluster-devel] GFS2: Pre-pull patch posting (merge window)

2014-10-08 Thread Steven Whitehouse
Hi,

Not a huge amount this time... just four patches. This time we have a couple
of bug fixes, one relating to bad i_goal values which are now ignored (i_goal
is basically a hint so it is safe to so this) and another relating to the
saving of the dirent location during rename. There is one performance
improvement, which is an optimisation in rgblk_free so that multiple block
deallocations will now be more efficient, and one clean up patch to use
_RET_IP_ rather than writing it out longhand,

Steve.




[Cluster-devel] [PATCH 3/4] GFS2: Use gfs2_rbm_incr in rgblk_free

2014-10-08 Thread Steven Whitehouse
From: Bob Peterson rpete...@redhat.com

This patch speeds up GFS2 unlink operations by using function
gfs2_rbm_incr rather than continuously calculating the rbm.

Signed-off-by: Bob Peterson rpete...@redhat.com
Signed-off-by: Steven Whitehouse swhit...@redhat.com

diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 55ef72d..7474c41 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -2097,7 +2097,7 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd 
*sdp, u64 bstart,
 u32 blen, unsigned char new_state)
 {
struct gfs2_rbm rbm;
-   struct gfs2_bitmap *bi;
+   struct gfs2_bitmap *bi, *bi_prev = NULL;
 
rbm.rgd = gfs2_blk2rgrpd(sdp, bstart, 1);
if (!rbm.rgd) {
@@ -2106,18 +2106,22 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd 
*sdp, u64 bstart,
return NULL;
}
 
+   gfs2_rbm_from_block(rbm, bstart);
while (blen--) {
-   gfs2_rbm_from_block(rbm, bstart);
bi = rbm_bi(rbm);
-   bstart++;
-   if (!bi-bi_clone) {
-   bi-bi_clone = kmalloc(bi-bi_bh-b_size,
-  GFP_NOFS | __GFP_NOFAIL);
-   memcpy(bi-bi_clone + bi-bi_offset,
-  bi-bi_bh-b_data + bi-bi_offset, bi-bi_len);
+   if (bi != bi_prev) {
+   if (!bi-bi_clone) {
+   bi-bi_clone = kmalloc(bi-bi_bh-b_size,
+ GFP_NOFS | __GFP_NOFAIL);
+   memcpy(bi-bi_clone + bi-bi_offset,
+  bi-bi_bh-b_data + bi-bi_offset,
+  bi-bi_len);
+   }
+   gfs2_trans_add_meta(rbm.rgd-rd_gl, bi-bi_bh);
+   bi_prev = bi;
}
-   gfs2_trans_add_meta(rbm.rgd-rd_gl, bi-bi_bh);
gfs2_setbit(rbm, false, new_state);
+   gfs2_rbm_incr(rbm);
}
 
return rbm.rgd;
-- 
1.8.3.1



[Cluster-devel] [GFS2 PATCH] GFS2: Block reservation doubling scheme

2014-10-08 Thread Bob Peterson
Hi,

Steve Whitehouse wrote:
| I'd much prefer to see an algorithm that is adaptive, rather than simply
| bumping up the default here. We do need to be able to cope with cases
| where the files are much smaller, and without adaptive sizing, we might
| land up creating small holes in the allocations, which would then cause
| problems for later allocations,

I took this to heart and came up with a new design. The idea is not unlike
the block reservation doubling schemes in other file systems. The results
are fantastic; much better than those gained by hard coding 64 blocks.
This is the best level of fragmentation I've ever achieved with this app:

EXTENT COUNT FOR OUTPUT FILES =  310103
EXTENT COUNT FOR OUTPUT FILES =  343990
EXTENT COUNT FOR OUTPUT FILES =  332818
EXTENT COUNT FOR OUTPUT FILES =  336852
EXTENT COUNT FOR OUTPUT FILES =  334820

Compare these results to counts without the patch:

EXTENT COUNT FOR OUTPUT FILES =  951813
EXTENT COUNT FOR OUTPUT FILES =  966978
EXTENT COUNT FOR OUTPUT FILES =  1065481

The only down side I see is that it makes the gfs2 inode structure bigger.
I also thought about changing the minimum reservation size to 16 blocks
rather than 32, since it's now adaptive, but before I did that, I'd have
to run some performance tests. What do you think?

Regards,

Bob Peterson
Red Hat File Systems

Patch text:

This patch introduces a new block reservation doubling scheme. If we
get to the end of a multi-block reservation, we probably did not
reserve enough blocks. So we double the size of the reservation for
next time. If we can't find any rgrps that match, we go back to the
default 32 blocks.

Signed-off-by: Bob Peterson rpete...@redhat.com 
---
 fs/gfs2/incore.h | 1 +
 fs/gfs2/main.c   | 2 ++
 fs/gfs2/rgrp.c   | 7 ++-
 fs/gfs2/rgrp.h   | 9 ++---
 4 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 39e7e99..f98fa37 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -398,6 +398,7 @@ struct gfs2_inode {
u32 i_diskflags;
u8 i_height;
u8 i_depth;
+   u32 i_rsrv_minblks; /* minimum blocks per reservation */
 };
 
 /*
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index 82b6ac8..2be2f98 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -29,6 +29,7 @@
 #include glock.h
 #include quota.h
 #include recovery.h
+#include rgrp.h
 #include dir.h
 
 struct workqueue_struct *gfs2_control_wq;
@@ -42,6 +43,7 @@ static void gfs2_init_inode_once(void *foo)
INIT_LIST_HEAD(ip-i_trunc_list);
ip-i_res = NULL;
ip-i_hash_cache = NULL;
+   ip-i_rsrv_minblks = RGRP_RSRV_MINBLKS;
 }
 
 static void gfs2_init_glock_once(void *foo)
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 7474c41..986c33f 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -1465,7 +1465,7 @@ static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct 
gfs2_inode *ip,
extlen = 1;
else {
extlen = max_t(u32, atomic_read(rs-rs_sizehint), ap-target);
-   extlen = clamp(extlen, RGRP_RSRV_MINBLKS, free_blocks);
+   extlen = clamp(extlen, ip-i_rsrv_minblks, free_blocks);
}
if ((rgd-rd_free_clone  rgd-rd_reserved) || (free_blocks  extlen))
return;
@@ -2000,6 +2000,7 @@ next_rgrp:
 * then this checks for some less likely conditions before
 * trying again.
 */
+   ip-i_rsrv_minblks = RGRP_RSRV_MINBLKS;
loops++;
/* Check that fs hasn't grown if writing to rindex */
if (ip == GFS2_I(sdp-sd_rindex)  !sdp-sd_rindex_uptodate) {
@@ -2195,6 +2196,10 @@ static void gfs2_adjust_reservation(struct gfs2_inode 
*ip,
trace_gfs2_rs(rs, TRACE_RS_CLAIM);
if (rs-rs_free  !ret)
goto out;
+   /* We used up our block reservation, so double the
+  minimum reservation size for the next write. */
+   if (ip-i_rsrv_minblks  RGRP_RSRV_MAXBLKS)
+   ip-i_rsrv_minblks = 1;
}
__rs_deltree(rs);
}
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index 5d8f085..d081cac 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
@@ -13,13 +13,8 @@
 #include linux/slab.h
 #include linux/uaccess.h
 
-/* Since each block in the file system is represented by two bits in the
- * bitmap, one 64-bit word in the bitmap will represent 32 blocks.
- * By reserving 32 blocks at a time, we can optimize / shortcut how we search
- * through the bitmaps by looking a word at a time.
- */
-#define RGRP_RSRV_MINBYTES 8
-#define RGRP_RSRV_MINBLKS ((u32)(RGRP_RSRV_MINBYTES * GFS2_NBBY))
+#define RGRP_RSRV_MINBLKS 32
+#define RGRP_RSRV_MAXBLKS 512
 
 struct gfs2_rgrpd;
 struct gfs2_sbd;



[Cluster-devel] GFS2: Pull request (merge window)

2014-10-08 Thread Steven Whitehouse
Hi,

Please consider pulling the following changes,

Steve.

-
The following changes since commit 37504a3be90b69438426d74ccf467a9fe192932b:

  Merge tag 'gfs2-fixes' of 
git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes (2014-09-16 
07:47:04 -0700)

are available in the git repository at:


  git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-nmw.git 
tags/gfs2-merge-window

for you to fetch changes up to d29c0afe4db72ceb72149c3894a6079674e9751f:

  GFS2: use _RET_IP_ instead of (unsigned long)__builtin_return_address(0) 
(2014-10-08 09:57:07 +0100)


This time we have a couple of bug fixes, one relating to bad i_goal values
which are now ignored (i_goal is basically a hint so it is safe to so this)
and another relating to the saving of the dirent location during rename.

There is one performance improvement, which is an optimisation in rgblk_free
so that multiple block deallocations will now be more efficient,
and one clean up patch to use _RET_IP_ rather than writing it out longhand.


Abhi Das (1):
  GFS2: fix bad inode i_goal values during block allocation

Bob Peterson (2):
  GFS2: Make rename not save dirent location
  GFS2: Use gfs2_rbm_incr in rgblk_free

Fabian Frederick (1):
  GFS2: use _RET_IP_ instead of (unsigned long)__builtin_return_address(0)

 fs/gfs2/dir.c   |  9 +++--
 fs/gfs2/dir.h   |  1 +
 fs/gfs2/glock.c |  4 ++--
 fs/gfs2/glops.c |  2 +-
 fs/gfs2/inode.c |  7 ---
 fs/gfs2/rgrp.c  | 30 +-
 fs/gfs2/rgrp.h  |  1 +
 fs/gfs2/trans.c |  2 +-
 8 files changed, 38 insertions(+), 18 deletions(-)



signature.asc
Description: This is a digitally signed message part


[Cluster-devel] [GFS2 PATCH] GFS2: Set of distributed preferences for rgrps

2014-10-08 Thread Bob Peterson
Hi,

This patch uses journal numbers to evenly distribute which node
prefers which resource groups for block allocations. This is to
help performance. The idea is to make each node in the cluster
prefer to use a certain subset of resource groups for its block
allocations. Other nodes use a different subset, thus minimizing
inter-node DLM communications.

GFS1 has a similar scheme, but with GFS1, each node starts out
using an initial section of the file system and works their way
forward. While this works for the most part, simultaneous writes
by different nodes can cause the heads to bounce on some devices.
Also, nodes tend to stray from their initial locations. With this
patch, the preferred resource groups are assigned in a round-robin
fashion.

Tests prove that this patch can be a major performance boost for
some applications. For example, using one particular application,
I posted these run times before applying this patch:

Run 1 time: 2hr 49min 39sec
Run 2 time: 2hr 57min 59sec
Run 3 time: 3hr 1min 10sec

With the patch applied the times are improved by almost a third:

Run 1 time: 2hr 7min 31sec
Run 2 time: 2hr 5min 49sec
Run 3 time: 2hr 5min 1sec
Run 4 time: 2hr 4min 35sec
Run 5 time: 2hr 5min 55sec

Regards,

Bob Peterson
Red Hat File Systems

Signed-off-by: Bob Peterson rpete...@redhat.com 
---
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index f98fa37..c9f4f4c 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -97,6 +97,7 @@ struct gfs2_rgrpd {
 #define GFS2_RDF_CHECK 0x1000 /* check for unlinked inodes */
 #define GFS2_RDF_UPTODATE  0x2000 /* rg is up to date */
 #define GFS2_RDF_ERROR 0x4000 /* error in rg */
+#define GFS2_RDF_PREFERRED 0x8000 /* This rgrp is preferred */
 #define GFS2_RDF_MASK  0xf000 /* mask for internal flags */
spinlock_t rd_rsspin;   /* protects reservation related vars */
struct rb_root rd_rstree;   /* multi-block reservation tree */
@@ -809,6 +810,7 @@ struct gfs2_sbd {
char sd_table_name[GFS2_FSNAME_LEN];
char sd_proto_name[GFS2_FSNAME_LEN];
 
+   int sd_nodes;
/* Debugging crud */
 
unsigned long sd_last_warning;
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c
index 641383a..5aeb03a 100644
--- a/fs/gfs2/lock_dlm.c
+++ b/fs/gfs2/lock_dlm.c
@@ -1113,6 +1113,8 @@ static void gdlm_recover_done(void *arg, struct dlm_slot 
*slots, int num_slots,
struct gfs2_sbd *sdp = arg;
struct lm_lockstruct *ls = sdp-sd_lockstruct;
 
+   BUG_ON(num_slots == 0);
+   sdp-sd_nodes = num_slots;
/* ensure the ls jid arrays are large enough */
set_recover_size(sdp, slots, num_slots);
 
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index d3eae24..bf3193f 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -134,6 +134,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
atomic_set(sdp-sd_log_freeze, 0);
atomic_set(sdp-sd_frozen_root, 0);
init_waitqueue_head(sdp-sd_frozen_root_wait);
+   sdp-sd_nodes = 1;
 
return sdp;
 }
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 986c33f..bd8bddc 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -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.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_flags = ~GFS2_RDF_UPTODATE;
+   rgd-rd_flags = ~(GFS2_RDF_UPTODATE | GFS2_RDF_PREFERRED);
if (rgd-rd_data  sdp-sd_max_rg_data)
sdp-sd_max_rg_data = rgd-rd_data;
spin_lock(sdp-sd_rindex_spin);
@@ -955,6 +955,36 @@ fail:
 }
 
 /**
+ * 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_nodes; 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
  * @ip: pointer to the rindex inode
  *
@@ -973,6 +1003,8 @@