aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/rgrp.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2012-10-31 06:37:10 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2012-11-07 08:33:17 -0500
commit9dbe9610b9df4efe0946299804ed46bb8f91dec2 (patch)
tree8d54797420ed9d0aef1c6bdd8f3b8dd5e9938d0a /fs/gfs2/rgrp.c
parentc9aecf73717f55e41ac11682a50bef8594547025 (diff)
GFS2: Add Orlov allocator
Just like ext3, this works on the root directory and any directory with the +T flag set. Also, just like ext3, any subdirectory created in one of the just mentioned cases will be allocated to a random resource group (GFS2 equivalent of a block group). If you are creating a set of directories, each of which will contain a job running on a different node, then by setting +T on the parent directory before creating the subdirectories, each will land up in a different resource group, and thus resource group contention between nodes will be kept to a minimum. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r--fs/gfs2/rgrp.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index bdf3e644baae..99a619788c65 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -16,6 +16,7 @@
16#include <linux/prefetch.h> 16#include <linux/prefetch.h>
17#include <linux/blkdev.h> 17#include <linux/blkdev.h>
18#include <linux/rbtree.h> 18#include <linux/rbtree.h>
19#include <linux/random.h>
19 20
20#include "gfs2.h" 21#include "gfs2.h"
21#include "incore.h" 22#include "incore.h"
@@ -1763,6 +1764,15 @@ static bool gfs2_rgrp_used_recently(const struct gfs2_blkreserv *rs,
1763 return tdiff > (msecs * 1000 * 1000); 1764 return tdiff > (msecs * 1000 * 1000);
1764} 1765}
1765 1766
1767static u32 gfs2_orlov_skip(const struct gfs2_inode *ip)
1768{
1769 const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1770 u32 skip;
1771
1772 get_random_bytes(&skip, sizeof(skip));
1773 return skip % sdp->sd_rgrps;
1774}
1775
1766static bool gfs2_select_rgrp(struct gfs2_rgrpd **pos, const struct gfs2_rgrpd *begin) 1776static bool gfs2_select_rgrp(struct gfs2_rgrpd **pos, const struct gfs2_rgrpd *begin)
1767{ 1777{
1768 struct gfs2_rgrpd *rgd = *pos; 1778 struct gfs2_rgrpd *rgd = *pos;
@@ -1784,7 +1794,7 @@ static bool gfs2_select_rgrp(struct gfs2_rgrpd **pos, const struct gfs2_rgrpd *b
1784 * Returns: errno 1794 * Returns: errno
1785 */ 1795 */
1786 1796
1787int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested) 1797int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested, u32 aflags)
1788{ 1798{
1789 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1799 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1790 struct gfs2_rgrpd *begin = NULL; 1800 struct gfs2_rgrpd *begin = NULL;
@@ -1792,6 +1802,7 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
1792 int error = 0, rg_locked, flags = 0; 1802 int error = 0, rg_locked, flags = 0;
1793 u64 last_unlinked = NO_BLOCK; 1803 u64 last_unlinked = NO_BLOCK;
1794 int loops = 0; 1804 int loops = 0;
1805 u32 skip = 0;
1795 1806
1796 if (sdp->sd_args.ar_rgrplvb) 1807 if (sdp->sd_args.ar_rgrplvb)
1797 flags |= GL_SKIP; 1808 flags |= GL_SKIP;
@@ -1805,6 +1816,8 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
1805 } else { 1816 } else {
1806 rs->rs_rbm.rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1); 1817 rs->rs_rbm.rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1);
1807 } 1818 }
1819 if (S_ISDIR(ip->i_inode.i_mode) && (aflags & GFS2_AF_ORLOV))
1820 skip = gfs2_orlov_skip(ip);
1808 if (rs->rs_rbm.rgd == NULL) 1821 if (rs->rs_rbm.rgd == NULL)
1809 return -EBADSLT; 1822 return -EBADSLT;
1810 1823
@@ -1813,6 +1826,8 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, u32 requested)
1813 1826
1814 if (!gfs2_glock_is_locked_by_me(rs->rs_rbm.rgd->rd_gl)) { 1827 if (!gfs2_glock_is_locked_by_me(rs->rs_rbm.rgd->rd_gl)) {
1815 rg_locked = 0; 1828 rg_locked = 0;
1829 if (skip && skip--)
1830 goto next_rgrp;
1816 if (!gfs2_rs_active(rs) && (loops < 2) && 1831 if (!gfs2_rs_active(rs) && (loops < 2) &&
1817 gfs2_rgrp_used_recently(rs, 1000) && 1832 gfs2_rgrp_used_recently(rs, 1000) &&
1818 gfs2_rgrp_congested(rs->rs_rbm.rgd, loops)) 1833 gfs2_rgrp_congested(rs->rs_rbm.rgd, loops))
@@ -1871,6 +1886,8 @@ next_rgrp:
1871 /* Find the next rgrp, and continue looking */ 1886 /* Find the next rgrp, and continue looking */
1872 if (gfs2_select_rgrp(&rs->rs_rbm.rgd, begin)) 1887 if (gfs2_select_rgrp(&rs->rs_rbm.rgd, begin))
1873 continue; 1888 continue;
1889 if (skip)
1890 continue;
1874 1891
1875 /* If we've scanned all the rgrps, but found no free blocks 1892 /* If we've scanned all the rgrps, but found no free blocks
1876 * then this checks for some less likely conditions before 1893 * then this checks for some less likely conditions before