xref: /openbmc/linux/fs/gfs2/rgrp.c (revision ecc23d0a422a3118fcf6e4f0a46e17a6c2047b02)
17336d0e6SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2b3b94faaSDavid Teigland /*
3b3b94faaSDavid Teigland  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
4fe6c991cSBob Peterson  * Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
5b3b94faaSDavid Teigland  */
6b3b94faaSDavid Teigland 
7d77d1b58SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8d77d1b58SJoe Perches 
9b3b94faaSDavid Teigland #include <linux/slab.h>
10b3b94faaSDavid Teigland #include <linux/spinlock.h>
11b3b94faaSDavid Teigland #include <linux/completion.h>
12b3b94faaSDavid Teigland #include <linux/buffer_head.h>
13f42faf4fSSteven Whitehouse #include <linux/fs.h>
145c676f6dSSteven Whitehouse #include <linux/gfs2_ondisk.h>
151f466a47SBob Peterson #include <linux/prefetch.h>
16f15ab561SSteven Whitehouse #include <linux/blkdev.h>
177c9ca621SBob Peterson #include <linux/rbtree.h>
189dbe9610SSteven Whitehouse #include <linux/random.h>
19b3b94faaSDavid Teigland 
20b3b94faaSDavid Teigland #include "gfs2.h"
215c676f6dSSteven Whitehouse #include "incore.h"
22b3b94faaSDavid Teigland #include "glock.h"
23b3b94faaSDavid Teigland #include "glops.h"
24b3b94faaSDavid Teigland #include "lops.h"
25b3b94faaSDavid Teigland #include "meta_io.h"
26b3b94faaSDavid Teigland #include "quota.h"
27b3b94faaSDavid Teigland #include "rgrp.h"
28b3b94faaSDavid Teigland #include "super.h"
29b3b94faaSDavid Teigland #include "trans.h"
305c676f6dSSteven Whitehouse #include "util.h"
31172e045aSBenjamin Marzinski #include "log.h"
32c8cdf479SSteven Whitehouse #include "inode.h"
3363997775SSteven Whitehouse #include "trace_gfs2.h"
34850d2d91SAndrew Price #include "dir.h"
35b3b94faaSDavid Teigland 
362c1e52aaSSteven Whitehouse #define BFITNOENT ((u32)~0)
376760bdcdSBob Peterson #define NO_BLOCK ((u64)~0)
3888c8ab1fSSteven Whitehouse 
39c65b76b8SAndreas Gruenbacher struct gfs2_rbm {
40c65b76b8SAndreas Gruenbacher 	struct gfs2_rgrpd *rgd;
41c65b76b8SAndreas Gruenbacher 	u32 offset;		/* The offset is bitmap relative */
42c65b76b8SAndreas Gruenbacher 	int bii;		/* Bitmap index */
43c65b76b8SAndreas Gruenbacher };
44c65b76b8SAndreas Gruenbacher 
rbm_bi(const struct gfs2_rbm * rbm)45c65b76b8SAndreas Gruenbacher static inline struct gfs2_bitmap *rbm_bi(const struct gfs2_rbm *rbm)
46c65b76b8SAndreas Gruenbacher {
47c65b76b8SAndreas Gruenbacher 	return rbm->rgd->rd_bits + rbm->bii;
48c65b76b8SAndreas Gruenbacher }
49c65b76b8SAndreas Gruenbacher 
gfs2_rbm_to_block(const struct gfs2_rbm * rbm)50c65b76b8SAndreas Gruenbacher static inline u64 gfs2_rbm_to_block(const struct gfs2_rbm *rbm)
51c65b76b8SAndreas Gruenbacher {
52c65b76b8SAndreas Gruenbacher 	BUG_ON(rbm->offset >= rbm->rgd->rd_data);
53c65b76b8SAndreas Gruenbacher 	return rbm->rgd->rd_data0 + (rbm_bi(rbm)->bi_start * GFS2_NBBY) +
54c65b76b8SAndreas Gruenbacher 		rbm->offset;
55c65b76b8SAndreas Gruenbacher }
56c65b76b8SAndreas Gruenbacher 
5788c8ab1fSSteven Whitehouse /*
5888c8ab1fSSteven Whitehouse  * These routines are used by the resource group routines (rgrp.c)
5988c8ab1fSSteven Whitehouse  * to keep track of block allocation.  Each block is represented by two
60feaa7bbaSSteven Whitehouse  * bits.  So, each byte represents GFS2_NBBY (i.e. 4) blocks.
61feaa7bbaSSteven Whitehouse  *
62feaa7bbaSSteven Whitehouse  * 0 = Free
63feaa7bbaSSteven Whitehouse  * 1 = Used (not metadata)
64feaa7bbaSSteven Whitehouse  * 2 = Unlinked (still in use) inode
65feaa7bbaSSteven Whitehouse  * 3 = Used (metadata)
6688c8ab1fSSteven Whitehouse  */
6788c8ab1fSSteven Whitehouse 
685ce13431SBob Peterson struct gfs2_extent {
695ce13431SBob Peterson 	struct gfs2_rbm rbm;
705ce13431SBob Peterson 	u32 len;
715ce13431SBob Peterson };
725ce13431SBob Peterson 
7388c8ab1fSSteven Whitehouse static const char valid_change[16] = {
7488c8ab1fSSteven Whitehouse 	        /* current */
75feaa7bbaSSteven Whitehouse 	/* n */ 0, 1, 1, 1,
7688c8ab1fSSteven Whitehouse 	/* e */ 1, 0, 0, 0,
77feaa7bbaSSteven Whitehouse 	/* w */ 0, 0, 0, 1,
7888c8ab1fSSteven Whitehouse 	        1, 0, 0, 0
7988c8ab1fSSteven Whitehouse };
8088c8ab1fSSteven Whitehouse 
815ce13431SBob Peterson static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 *minext,
823d39fcd1SAndreas Gruenbacher 			 struct gfs2_blkreserv *rs, bool nowrap);
83ff7f4cb4SSteven Whitehouse 
84ff7f4cb4SSteven Whitehouse 
8588c8ab1fSSteven Whitehouse /**
8688c8ab1fSSteven Whitehouse  * gfs2_setbit - Set a bit in the bitmaps
873e6339ddSSteven Whitehouse  * @rbm: The position of the bit to set
883e6339ddSSteven Whitehouse  * @do_clone: Also set the clone bitmap, if it exists
8988c8ab1fSSteven Whitehouse  * @new_state: the new state of the block
9088c8ab1fSSteven Whitehouse  *
9188c8ab1fSSteven Whitehouse  */
9288c8ab1fSSteven Whitehouse 
gfs2_setbit(const struct gfs2_rbm * rbm,bool do_clone,unsigned char new_state)933e6339ddSSteven Whitehouse static inline void gfs2_setbit(const struct gfs2_rbm *rbm, bool do_clone,
9406344b91SBob Peterson 			       unsigned char new_state)
9588c8ab1fSSteven Whitehouse {
96b45e41d7SSteven Whitehouse 	unsigned char *byte1, *byte2, *end, cur_state;
97e579ed4fSBob Peterson 	struct gfs2_bitmap *bi = rbm_bi(rbm);
98281b4952SAndreas Gruenbacher 	unsigned int buflen = bi->bi_bytes;
993e6339ddSSteven Whitehouse 	const unsigned int bit = (rbm->offset % GFS2_NBBY) * GFS2_BIT_SIZE;
10088c8ab1fSSteven Whitehouse 
101e579ed4fSBob Peterson 	byte1 = bi->bi_bh->b_data + bi->bi_offset + (rbm->offset / GFS2_NBBY);
102e579ed4fSBob Peterson 	end = bi->bi_bh->b_data + bi->bi_offset + buflen;
10388c8ab1fSSteven Whitehouse 
104b45e41d7SSteven Whitehouse 	BUG_ON(byte1 >= end);
10588c8ab1fSSteven Whitehouse 
106b45e41d7SSteven Whitehouse 	cur_state = (*byte1 >> bit) & GFS2_BIT_MASK;
10788c8ab1fSSteven Whitehouse 
108b45e41d7SSteven Whitehouse 	if (unlikely(!valid_change[new_state * 4 + cur_state])) {
109e54c78a2SBob Peterson 		struct gfs2_sbd *sdp = rbm->rgd->rd_sbd;
110e54c78a2SBob Peterson 
111e54c78a2SBob Peterson 		fs_warn(sdp, "buf_blk = 0x%x old_state=%d, new_state=%d\n",
112d77d1b58SJoe Perches 			rbm->offset, cur_state, new_state);
113e54c78a2SBob Peterson 		fs_warn(sdp, "rgrp=0x%llx bi_start=0x%x biblk: 0x%llx\n",
114e54c78a2SBob Peterson 			(unsigned long long)rbm->rgd->rd_addr, bi->bi_start,
115e54c78a2SBob Peterson 			(unsigned long long)bi->bi_bh->b_blocknr);
116281b4952SAndreas Gruenbacher 		fs_warn(sdp, "bi_offset=0x%x bi_bytes=0x%x block=0x%llx\n",
117281b4952SAndreas Gruenbacher 			bi->bi_offset, bi->bi_bytes,
118e54c78a2SBob Peterson 			(unsigned long long)gfs2_rbm_to_block(rbm));
11995c8e17fSBob Peterson 		dump_stack();
1203e6339ddSSteven Whitehouse 		gfs2_consist_rgrpd(rbm->rgd);
121b45e41d7SSteven Whitehouse 		return;
122b45e41d7SSteven Whitehouse 	}
123b45e41d7SSteven Whitehouse 	*byte1 ^= (cur_state ^ new_state) << bit;
124b45e41d7SSteven Whitehouse 
125e579ed4fSBob Peterson 	if (do_clone && bi->bi_clone) {
126e579ed4fSBob Peterson 		byte2 = bi->bi_clone + bi->bi_offset + (rbm->offset / GFS2_NBBY);
127b45e41d7SSteven Whitehouse 		cur_state = (*byte2 >> bit) & GFS2_BIT_MASK;
128b45e41d7SSteven Whitehouse 		*byte2 ^= (cur_state ^ new_state) << bit;
129b45e41d7SSteven Whitehouse 	}
13088c8ab1fSSteven Whitehouse }
13188c8ab1fSSteven Whitehouse 
13288c8ab1fSSteven Whitehouse /**
13388c8ab1fSSteven Whitehouse  * gfs2_testbit - test a bit in the bitmaps
134c04a2ef3SSteven Whitehouse  * @rbm: The bit to test
135dffe12a8SBob Peterson  * @use_clone: If true, test the clone bitmap, not the official bitmap.
136dffe12a8SBob Peterson  *
137dffe12a8SBob Peterson  * Some callers like gfs2_unaligned_extlen need to test the clone bitmaps,
138dffe12a8SBob Peterson  * not the "real" bitmaps, to avoid allocating recently freed blocks.
13988c8ab1fSSteven Whitehouse  *
140c04a2ef3SSteven Whitehouse  * Returns: The two bit block state of the requested bit
14188c8ab1fSSteven Whitehouse  */
14288c8ab1fSSteven Whitehouse 
gfs2_testbit(const struct gfs2_rbm * rbm,bool use_clone)143dffe12a8SBob Peterson static inline u8 gfs2_testbit(const struct gfs2_rbm *rbm, bool use_clone)
14488c8ab1fSSteven Whitehouse {
145e579ed4fSBob Peterson 	struct gfs2_bitmap *bi = rbm_bi(rbm);
146dffe12a8SBob Peterson 	const u8 *buffer;
147c04a2ef3SSteven Whitehouse 	const u8 *byte;
14888c8ab1fSSteven Whitehouse 	unsigned int bit;
14988c8ab1fSSteven Whitehouse 
150dffe12a8SBob Peterson 	if (use_clone && bi->bi_clone)
151dffe12a8SBob Peterson 		buffer = bi->bi_clone;
152dffe12a8SBob Peterson 	else
153dffe12a8SBob Peterson 		buffer = bi->bi_bh->b_data;
154dffe12a8SBob Peterson 	buffer += bi->bi_offset;
155c04a2ef3SSteven Whitehouse 	byte = buffer + (rbm->offset / GFS2_NBBY);
156c04a2ef3SSteven Whitehouse 	bit = (rbm->offset % GFS2_NBBY) * GFS2_BIT_SIZE;
15788c8ab1fSSteven Whitehouse 
158c04a2ef3SSteven Whitehouse 	return (*byte >> bit) & GFS2_BIT_MASK;
15988c8ab1fSSteven Whitehouse }
16088c8ab1fSSteven Whitehouse 
16188c8ab1fSSteven Whitehouse /**
162223b2b88SSteven Whitehouse  * gfs2_bit_search
163223b2b88SSteven Whitehouse  * @ptr: Pointer to bitmap data
164223b2b88SSteven Whitehouse  * @mask: Mask to use (normally 0x55555.... but adjusted for search start)
165223b2b88SSteven Whitehouse  * @state: The state we are searching for
166223b2b88SSteven Whitehouse  *
167223b2b88SSteven Whitehouse  * We xor the bitmap data with a patter which is the bitwise opposite
168223b2b88SSteven Whitehouse  * of what we are looking for, this gives rise to a pattern of ones
169223b2b88SSteven Whitehouse  * wherever there is a match. Since we have two bits per entry, we
170223b2b88SSteven Whitehouse  * take this pattern, shift it down by one place and then and it with
171223b2b88SSteven Whitehouse  * the original. All the even bit positions (0,2,4, etc) then represent
172223b2b88SSteven Whitehouse  * successful matches, so we mask with 0x55555..... to remove the unwanted
173223b2b88SSteven Whitehouse  * odd bit positions.
174223b2b88SSteven Whitehouse  *
175223b2b88SSteven Whitehouse  * This allows searching of a whole u64 at once (32 blocks) with a
176223b2b88SSteven Whitehouse  * single test (on 64 bit arches).
177223b2b88SSteven Whitehouse  */
178223b2b88SSteven Whitehouse 
gfs2_bit_search(const __le64 * ptr,u64 mask,u8 state)179223b2b88SSteven Whitehouse static inline u64 gfs2_bit_search(const __le64 *ptr, u64 mask, u8 state)
180223b2b88SSteven Whitehouse {
181223b2b88SSteven Whitehouse 	u64 tmp;
182223b2b88SSteven Whitehouse 	static const u64 search[] = {
183075ac448SHannes Eder 		[0] = 0xffffffffffffffffULL,
184075ac448SHannes Eder 		[1] = 0xaaaaaaaaaaaaaaaaULL,
185075ac448SHannes Eder 		[2] = 0x5555555555555555ULL,
186075ac448SHannes Eder 		[3] = 0x0000000000000000ULL,
187223b2b88SSteven Whitehouse 	};
188223b2b88SSteven Whitehouse 	tmp = le64_to_cpu(*ptr) ^ search[state];
189223b2b88SSteven Whitehouse 	tmp &= (tmp >> 1);
190223b2b88SSteven Whitehouse 	tmp &= mask;
191223b2b88SSteven Whitehouse 	return tmp;
192223b2b88SSteven Whitehouse }
193223b2b88SSteven Whitehouse 
194223b2b88SSteven Whitehouse /**
1958e2e0047SBob Peterson  * rs_cmp - multi-block reservation range compare
196c65b76b8SAndreas Gruenbacher  * @start: start of the new reservation
1978e2e0047SBob Peterson  * @len: number of blocks in the new reservation
1988e2e0047SBob Peterson  * @rs: existing reservation to compare against
1998e2e0047SBob Peterson  *
2008e2e0047SBob Peterson  * returns: 1 if the block range is beyond the reach of the reservation
2018e2e0047SBob Peterson  *         -1 if the block range is before the start of the reservation
2028e2e0047SBob Peterson  *          0 if the block range overlaps with the reservation
2038e2e0047SBob Peterson  */
rs_cmp(u64 start,u32 len,struct gfs2_blkreserv * rs)204c65b76b8SAndreas Gruenbacher static inline int rs_cmp(u64 start, u32 len, struct gfs2_blkreserv *rs)
2058e2e0047SBob Peterson {
20607974d2aSAndreas Gruenbacher 	if (start >= rs->rs_start + rs->rs_requested)
2078e2e0047SBob Peterson 		return 1;
208c65b76b8SAndreas Gruenbacher 	if (rs->rs_start >= start + len)
2098e2e0047SBob Peterson 		return -1;
2108e2e0047SBob Peterson 	return 0;
2118e2e0047SBob Peterson }
2128e2e0047SBob Peterson 
2138e2e0047SBob Peterson /**
21488c8ab1fSSteven Whitehouse  * gfs2_bitfit - Search an rgrp's bitmap buffer to find a bit-pair representing
21588c8ab1fSSteven Whitehouse  *       a block in a given allocation state.
216886b1416SBob Peterson  * @buf: the buffer that holds the bitmaps
217223b2b88SSteven Whitehouse  * @len: the length (in bytes) of the buffer
21888c8ab1fSSteven Whitehouse  * @goal: start search at this block's bit-pair (within @buffer)
219223b2b88SSteven Whitehouse  * @state: GFS2_BLKST_XXX the state of the block we're looking for.
22088c8ab1fSSteven Whitehouse  *
22188c8ab1fSSteven Whitehouse  * Scope of @goal and returned block number is only within this bitmap buffer,
22288c8ab1fSSteven Whitehouse  * not entire rgrp or filesystem.  @buffer will be offset from the actual
223223b2b88SSteven Whitehouse  * beginning of a bitmap block buffer, skipping any header structures, but
224223b2b88SSteven Whitehouse  * headers are always a multiple of 64 bits long so that the buffer is
225223b2b88SSteven Whitehouse  * always aligned to a 64 bit boundary.
226223b2b88SSteven Whitehouse  *
227223b2b88SSteven Whitehouse  * The size of the buffer is in bytes, but is it assumed that it is
228fd589a8fSAnand Gadiyar  * always ok to read a complete multiple of 64 bits at the end
229223b2b88SSteven Whitehouse  * of the block in case the end is no aligned to a natural boundary.
23088c8ab1fSSteven Whitehouse  *
23188c8ab1fSSteven Whitehouse  * Return: the block number (bitmap buffer scope) that was found
23288c8ab1fSSteven Whitehouse  */
23388c8ab1fSSteven Whitehouse 
gfs2_bitfit(const u8 * buf,const unsigned int len,u32 goal,u8 state)23402ab1721SHannes Eder static u32 gfs2_bitfit(const u8 *buf, const unsigned int len,
23502ab1721SHannes Eder 		       u32 goal, u8 state)
23688c8ab1fSSteven Whitehouse {
237223b2b88SSteven Whitehouse 	u32 spoint = (goal << 1) & ((8*sizeof(u64)) - 1);
238223b2b88SSteven Whitehouse 	const __le64 *ptr = ((__le64 *)buf) + (goal >> 5);
239223b2b88SSteven Whitehouse 	const __le64 *end = (__le64 *)(buf + ALIGN(len, sizeof(u64)));
240223b2b88SSteven Whitehouse 	u64 tmp;
241075ac448SHannes Eder 	u64 mask = 0x5555555555555555ULL;
242223b2b88SSteven Whitehouse 	u32 bit;
24388c8ab1fSSteven Whitehouse 
244223b2b88SSteven Whitehouse 	/* Mask off bits we don't care about at the start of the search */
245223b2b88SSteven Whitehouse 	mask <<= spoint;
246223b2b88SSteven Whitehouse 	tmp = gfs2_bit_search(ptr, mask, state);
247223b2b88SSteven Whitehouse 	ptr++;
248223b2b88SSteven Whitehouse 	while(tmp == 0 && ptr < end) {
249075ac448SHannes Eder 		tmp = gfs2_bit_search(ptr, 0x5555555555555555ULL, state);
250223b2b88SSteven Whitehouse 		ptr++;
2515fdc2eebSBob Peterson 	}
252223b2b88SSteven Whitehouse 	/* Mask off any bits which are more than len bytes from the start */
253223b2b88SSteven Whitehouse 	if (ptr == end && (len & (sizeof(u64) - 1)))
254223b2b88SSteven Whitehouse 		tmp &= (((u64)~0) >> (64 - 8*(len & (sizeof(u64) - 1))));
255223b2b88SSteven Whitehouse 	/* Didn't find anything, so return */
256223b2b88SSteven Whitehouse 	if (tmp == 0)
25788c8ab1fSSteven Whitehouse 		return BFITNOENT;
258223b2b88SSteven Whitehouse 	ptr--;
259d8bd504aSSteven Whitehouse 	bit = __ffs64(tmp);
260223b2b88SSteven Whitehouse 	bit /= 2;	/* two bits per entry in the bitmap */
261223b2b88SSteven Whitehouse 	return (((const unsigned char *)ptr - buf) * GFS2_NBBY) + bit;
26288c8ab1fSSteven Whitehouse }
26388c8ab1fSSteven Whitehouse 
26488c8ab1fSSteven Whitehouse /**
265ff7f4cb4SSteven Whitehouse  * gfs2_rbm_from_block - Set the rbm based upon rgd and block number
266ff7f4cb4SSteven Whitehouse  * @rbm: The rbm with rgd already set correctly
267ff7f4cb4SSteven Whitehouse  * @block: The block number (filesystem relative)
268ff7f4cb4SSteven Whitehouse  *
269ff7f4cb4SSteven Whitehouse  * This sets the bi and offset members of an rbm based on a
270ff7f4cb4SSteven Whitehouse  * resource group and a filesystem relative block number. The
271ff7f4cb4SSteven Whitehouse  * resource group must be set in the rbm on entry, the bi and
272ff7f4cb4SSteven Whitehouse  * offset members will be set by this function.
273ff7f4cb4SSteven Whitehouse  *
274ff7f4cb4SSteven Whitehouse  * Returns: 0 on success, or an error code
275ff7f4cb4SSteven Whitehouse  */
276ff7f4cb4SSteven Whitehouse 
gfs2_rbm_from_block(struct gfs2_rbm * rbm,u64 block)277ff7f4cb4SSteven Whitehouse static int gfs2_rbm_from_block(struct gfs2_rbm *rbm, u64 block)
278ff7f4cb4SSteven Whitehouse {
2793548fce1SAndreas Gruenbacher 	if (!rgrp_contains_block(rbm->rgd, block))
280ff7f4cb4SSteven Whitehouse 		return -E2BIG;
281e579ed4fSBob Peterson 	rbm->bii = 0;
2823548fce1SAndreas Gruenbacher 	rbm->offset = block - rbm->rgd->rd_data0;
283a68a0a35SBob Peterson 	/* Check if the block is within the first block */
284e579ed4fSBob Peterson 	if (rbm->offset < rbm_bi(rbm)->bi_blocks)
285a68a0a35SBob Peterson 		return 0;
286ff7f4cb4SSteven Whitehouse 
287a68a0a35SBob Peterson 	/* Adjust for the size diff between gfs2_meta_header and gfs2_rgrp */
288a68a0a35SBob Peterson 	rbm->offset += (sizeof(struct gfs2_rgrp) -
289a68a0a35SBob Peterson 			sizeof(struct gfs2_meta_header)) * GFS2_NBBY;
290e579ed4fSBob Peterson 	rbm->bii = rbm->offset / rbm->rgd->rd_sbd->sd_blocks_per_bitmap;
291e579ed4fSBob Peterson 	rbm->offset -= rbm->bii * rbm->rgd->rd_sbd->sd_blocks_per_bitmap;
292ff7f4cb4SSteven Whitehouse 	return 0;
293ff7f4cb4SSteven Whitehouse }
294ff7f4cb4SSteven Whitehouse 
295ff7f4cb4SSteven Whitehouse /**
2960eacdd16SAndreas Gruenbacher  * gfs2_rbm_add - add a number of blocks to an rbm
297149ed7f5SBob Peterson  * @rbm: The rbm with rgd already set correctly
2980eacdd16SAndreas Gruenbacher  * @blocks: The number of blocks to add to rpm
299149ed7f5SBob Peterson  *
3000eacdd16SAndreas Gruenbacher  * This function takes an existing rbm structure and adds a number of blocks to
3010eacdd16SAndreas Gruenbacher  * it.
302149ed7f5SBob Peterson  *
3030eacdd16SAndreas Gruenbacher  * Returns: True if the new rbm would point past the end of the rgrp.
304149ed7f5SBob Peterson  */
305149ed7f5SBob Peterson 
gfs2_rbm_add(struct gfs2_rbm * rbm,u32 blocks)3060eacdd16SAndreas Gruenbacher static bool gfs2_rbm_add(struct gfs2_rbm *rbm, u32 blocks)
307149ed7f5SBob Peterson {
3080eacdd16SAndreas Gruenbacher 	struct gfs2_rgrpd *rgd = rbm->rgd;
3090eacdd16SAndreas Gruenbacher 	struct gfs2_bitmap *bi = rgd->rd_bits + rbm->bii;
3100eacdd16SAndreas Gruenbacher 
3110eacdd16SAndreas Gruenbacher 	if (rbm->offset + blocks < bi->bi_blocks) {
3120eacdd16SAndreas Gruenbacher 		rbm->offset += blocks;
313149ed7f5SBob Peterson 		return false;
314149ed7f5SBob Peterson 	}
3150eacdd16SAndreas Gruenbacher 	blocks -= bi->bi_blocks - rbm->offset;
316149ed7f5SBob Peterson 
3170eacdd16SAndreas Gruenbacher 	for(;;) {
3180eacdd16SAndreas Gruenbacher 		bi++;
3190eacdd16SAndreas Gruenbacher 		if (bi == rgd->rd_bits + rgd->rd_length)
3200eacdd16SAndreas Gruenbacher 			return true;
3210eacdd16SAndreas Gruenbacher 		if (blocks < bi->bi_blocks) {
3220eacdd16SAndreas Gruenbacher 			rbm->offset = blocks;
3230eacdd16SAndreas Gruenbacher 			rbm->bii = bi - rgd->rd_bits;
324149ed7f5SBob Peterson 			return false;
325149ed7f5SBob Peterson 		}
3260eacdd16SAndreas Gruenbacher 		blocks -= bi->bi_blocks;
3270eacdd16SAndreas Gruenbacher 	}
3280eacdd16SAndreas Gruenbacher }
329149ed7f5SBob Peterson 
330149ed7f5SBob Peterson /**
331ff7f4cb4SSteven Whitehouse  * gfs2_unaligned_extlen - Look for free blocks which are not byte aligned
332ff7f4cb4SSteven Whitehouse  * @rbm: Position to search (value/result)
333ff7f4cb4SSteven Whitehouse  * @n_unaligned: Number of unaligned blocks to check
334ff7f4cb4SSteven Whitehouse  * @len: Decremented for each block found (terminate on zero)
335ff7f4cb4SSteven Whitehouse  *
336c65b76b8SAndreas Gruenbacher  * Returns: true if a non-free block is encountered or the end of the resource
337c65b76b8SAndreas Gruenbacher  *	    group is reached.
338ff7f4cb4SSteven Whitehouse  */
339ff7f4cb4SSteven Whitehouse 
gfs2_unaligned_extlen(struct gfs2_rbm * rbm,u32 n_unaligned,u32 * len)340ff7f4cb4SSteven Whitehouse static bool gfs2_unaligned_extlen(struct gfs2_rbm *rbm, u32 n_unaligned, u32 *len)
341ff7f4cb4SSteven Whitehouse {
342ff7f4cb4SSteven Whitehouse 	u32 n;
343ff7f4cb4SSteven Whitehouse 	u8 res;
344ff7f4cb4SSteven Whitehouse 
345ff7f4cb4SSteven Whitehouse 	for (n = 0; n < n_unaligned; n++) {
346dffe12a8SBob Peterson 		res = gfs2_testbit(rbm, true);
347ff7f4cb4SSteven Whitehouse 		if (res != GFS2_BLKST_FREE)
348ff7f4cb4SSteven Whitehouse 			return true;
349ff7f4cb4SSteven Whitehouse 		(*len)--;
350ff7f4cb4SSteven Whitehouse 		if (*len == 0)
351ff7f4cb4SSteven Whitehouse 			return true;
3520eacdd16SAndreas Gruenbacher 		if (gfs2_rbm_add(rbm, 1))
353ff7f4cb4SSteven Whitehouse 			return true;
354ff7f4cb4SSteven Whitehouse 	}
355ff7f4cb4SSteven Whitehouse 
356ff7f4cb4SSteven Whitehouse 	return false;
357ff7f4cb4SSteven Whitehouse }
358ff7f4cb4SSteven Whitehouse 
359ff7f4cb4SSteven Whitehouse /**
360ff7f4cb4SSteven Whitehouse  * gfs2_free_extlen - Return extent length of free blocks
36127ff6a0fSFabian Frederick  * @rrbm: Starting position
362ff7f4cb4SSteven Whitehouse  * @len: Max length to check
363ff7f4cb4SSteven Whitehouse  *
364ff7f4cb4SSteven Whitehouse  * Starting at the block specified by the rbm, see how many free blocks
365ff7f4cb4SSteven Whitehouse  * there are, not reading more than len blocks ahead. This can be done
366ff7f4cb4SSteven Whitehouse  * using memchr_inv when the blocks are byte aligned, but has to be done
367ff7f4cb4SSteven Whitehouse  * on a block by block basis in case of unaligned blocks. Also this
368ff7f4cb4SSteven Whitehouse  * function can cope with bitmap boundaries (although it must stop on
369ff7f4cb4SSteven Whitehouse  * a resource group boundary)
370ff7f4cb4SSteven Whitehouse  *
371ff7f4cb4SSteven Whitehouse  * Returns: Number of free blocks in the extent
372ff7f4cb4SSteven Whitehouse  */
373ff7f4cb4SSteven Whitehouse 
gfs2_free_extlen(const struct gfs2_rbm * rrbm,u32 len)374ff7f4cb4SSteven Whitehouse static u32 gfs2_free_extlen(const struct gfs2_rbm *rrbm, u32 len)
375ff7f4cb4SSteven Whitehouse {
376ff7f4cb4SSteven Whitehouse 	struct gfs2_rbm rbm = *rrbm;
377ff7f4cb4SSteven Whitehouse 	u32 n_unaligned = rbm.offset & 3;
378ff7f4cb4SSteven Whitehouse 	u32 size = len;
379ff7f4cb4SSteven Whitehouse 	u32 bytes;
380ff7f4cb4SSteven Whitehouse 	u32 chunk_size;
381ff7f4cb4SSteven Whitehouse 	u8 *ptr, *start, *end;
382ff7f4cb4SSteven Whitehouse 	u64 block;
383e579ed4fSBob Peterson 	struct gfs2_bitmap *bi;
384ff7f4cb4SSteven Whitehouse 
385ff7f4cb4SSteven Whitehouse 	if (n_unaligned &&
386ff7f4cb4SSteven Whitehouse 	    gfs2_unaligned_extlen(&rbm, 4 - n_unaligned, &len))
387ff7f4cb4SSteven Whitehouse 		goto out;
388ff7f4cb4SSteven Whitehouse 
3893701530aSBob Peterson 	n_unaligned = len & 3;
390ff7f4cb4SSteven Whitehouse 	/* Start is now byte aligned */
391ff7f4cb4SSteven Whitehouse 	while (len > 3) {
392e579ed4fSBob Peterson 		bi = rbm_bi(&rbm);
393e579ed4fSBob Peterson 		start = bi->bi_bh->b_data;
394e579ed4fSBob Peterson 		if (bi->bi_clone)
395e579ed4fSBob Peterson 			start = bi->bi_clone;
396e579ed4fSBob Peterson 		start += bi->bi_offset;
397281b4952SAndreas Gruenbacher 		end = start + bi->bi_bytes;
398ff7f4cb4SSteven Whitehouse 		BUG_ON(rbm.offset & 3);
399ff7f4cb4SSteven Whitehouse 		start += (rbm.offset / GFS2_NBBY);
400ff7f4cb4SSteven Whitehouse 		bytes = min_t(u32, len / GFS2_NBBY, (end - start));
401ff7f4cb4SSteven Whitehouse 		ptr = memchr_inv(start, 0, bytes);
402ff7f4cb4SSteven Whitehouse 		chunk_size = ((ptr == NULL) ? bytes : (ptr - start));
403ff7f4cb4SSteven Whitehouse 		chunk_size *= GFS2_NBBY;
404ff7f4cb4SSteven Whitehouse 		BUG_ON(len < chunk_size);
405ff7f4cb4SSteven Whitehouse 		len -= chunk_size;
406ff7f4cb4SSteven Whitehouse 		block = gfs2_rbm_to_block(&rbm);
40715bd50adSBob Peterson 		if (gfs2_rbm_from_block(&rbm, block + chunk_size)) {
40815bd50adSBob Peterson 			n_unaligned = 0;
409ff7f4cb4SSteven Whitehouse 			break;
41015bd50adSBob Peterson 		}
41115bd50adSBob Peterson 		if (ptr) {
41215bd50adSBob Peterson 			n_unaligned = 3;
41315bd50adSBob Peterson 			break;
41415bd50adSBob Peterson 		}
415ff7f4cb4SSteven Whitehouse 		n_unaligned = len & 3;
416ff7f4cb4SSteven Whitehouse 	}
417ff7f4cb4SSteven Whitehouse 
418ff7f4cb4SSteven Whitehouse 	/* Deal with any bits left over at the end */
419ff7f4cb4SSteven Whitehouse 	if (n_unaligned)
420ff7f4cb4SSteven Whitehouse 		gfs2_unaligned_extlen(&rbm, n_unaligned, &len);
421ff7f4cb4SSteven Whitehouse out:
422ff7f4cb4SSteven Whitehouse 	return size - len;
423ff7f4cb4SSteven Whitehouse }
424ff7f4cb4SSteven Whitehouse 
425ff7f4cb4SSteven Whitehouse /**
42688c8ab1fSSteven Whitehouse  * gfs2_bitcount - count the number of bits in a certain state
427886b1416SBob Peterson  * @rgd: the resource group descriptor
42888c8ab1fSSteven Whitehouse  * @buffer: the buffer that holds the bitmaps
42988c8ab1fSSteven Whitehouse  * @buflen: the length (in bytes) of the buffer
43088c8ab1fSSteven Whitehouse  * @state: the state of the block we're looking for
43188c8ab1fSSteven Whitehouse  *
43288c8ab1fSSteven Whitehouse  * Returns: The number of bits
43388c8ab1fSSteven Whitehouse  */
43488c8ab1fSSteven Whitehouse 
gfs2_bitcount(struct gfs2_rgrpd * rgd,const u8 * buffer,unsigned int buflen,u8 state)435110acf38SSteven Whitehouse static u32 gfs2_bitcount(struct gfs2_rgrpd *rgd, const u8 *buffer,
436110acf38SSteven Whitehouse 			 unsigned int buflen, u8 state)
43788c8ab1fSSteven Whitehouse {
438110acf38SSteven Whitehouse 	const u8 *byte = buffer;
439110acf38SSteven Whitehouse 	const u8 *end = buffer + buflen;
440110acf38SSteven Whitehouse 	const u8 state1 = state << 2;
441110acf38SSteven Whitehouse 	const u8 state2 = state << 4;
442110acf38SSteven Whitehouse 	const u8 state3 = state << 6;
443cd915493SSteven Whitehouse 	u32 count = 0;
44488c8ab1fSSteven Whitehouse 
44588c8ab1fSSteven Whitehouse 	for (; byte < end; byte++) {
44688c8ab1fSSteven Whitehouse 		if (((*byte) & 0x03) == state)
44788c8ab1fSSteven Whitehouse 			count++;
44888c8ab1fSSteven Whitehouse 		if (((*byte) & 0x0C) == state1)
44988c8ab1fSSteven Whitehouse 			count++;
45088c8ab1fSSteven Whitehouse 		if (((*byte) & 0x30) == state2)
45188c8ab1fSSteven Whitehouse 			count++;
45288c8ab1fSSteven Whitehouse 		if (((*byte) & 0xC0) == state3)
45388c8ab1fSSteven Whitehouse 			count++;
45488c8ab1fSSteven Whitehouse 	}
45588c8ab1fSSteven Whitehouse 
45688c8ab1fSSteven Whitehouse 	return count;
45788c8ab1fSSteven Whitehouse }
45888c8ab1fSSteven Whitehouse 
459b3b94faaSDavid Teigland /**
460b3b94faaSDavid Teigland  * gfs2_rgrp_verify - Verify that a resource group is consistent
461b3b94faaSDavid Teigland  * @rgd: the rgrp
462b3b94faaSDavid Teigland  *
463b3b94faaSDavid Teigland  */
464b3b94faaSDavid Teigland 
gfs2_rgrp_verify(struct gfs2_rgrpd * rgd)465b3b94faaSDavid Teigland void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd)
466b3b94faaSDavid Teigland {
467b3b94faaSDavid Teigland 	struct gfs2_sbd *sdp = rgd->rd_sbd;
468b3b94faaSDavid Teigland 	struct gfs2_bitmap *bi = NULL;
469bb8d8a6fSSteven Whitehouse 	u32 length = rgd->rd_length;
470cd915493SSteven Whitehouse 	u32 count[4], tmp;
471b3b94faaSDavid Teigland 	int buf, x;
472b3b94faaSDavid Teigland 
473cd915493SSteven Whitehouse 	memset(count, 0, 4 * sizeof(u32));
474b3b94faaSDavid Teigland 
475b3b94faaSDavid Teigland 	/* Count # blocks in each of 4 possible allocation states */
476b3b94faaSDavid Teigland 	for (buf = 0; buf < length; buf++) {
477b3b94faaSDavid Teigland 		bi = rgd->rd_bits + buf;
478b3b94faaSDavid Teigland 		for (x = 0; x < 4; x++)
479b3b94faaSDavid Teigland 			count[x] += gfs2_bitcount(rgd,
480b3b94faaSDavid Teigland 						  bi->bi_bh->b_data +
481b3b94faaSDavid Teigland 						  bi->bi_offset,
482281b4952SAndreas Gruenbacher 						  bi->bi_bytes, x);
483b3b94faaSDavid Teigland 	}
484b3b94faaSDavid Teigland 
485cfc8b549SSteven Whitehouse 	if (count[0] != rgd->rd_free) {
4868dc88ac6SAndreas Gruenbacher 		gfs2_lm(sdp, "free data mismatch:  %u != %u\n",
487cfc8b549SSteven Whitehouse 			count[0], rgd->rd_free);
4888dc88ac6SAndreas Gruenbacher 		gfs2_consist_rgrpd(rgd);
489b3b94faaSDavid Teigland 		return;
490b3b94faaSDavid Teigland 	}
491b3b94faaSDavid Teigland 
49273f74948SSteven Whitehouse 	tmp = rgd->rd_data - rgd->rd_free - rgd->rd_dinodes;
4936b946170SBenjamin Marzinski 	if (count[1] != tmp) {
4948dc88ac6SAndreas Gruenbacher 		gfs2_lm(sdp, "used data mismatch:  %u != %u\n",
495b3b94faaSDavid Teigland 			count[1], tmp);
4968dc88ac6SAndreas Gruenbacher 		gfs2_consist_rgrpd(rgd);
497b3b94faaSDavid Teigland 		return;
498b3b94faaSDavid Teigland 	}
499b3b94faaSDavid Teigland 
5006b946170SBenjamin Marzinski 	if (count[2] + count[3] != rgd->rd_dinodes) {
5018dc88ac6SAndreas Gruenbacher 		gfs2_lm(sdp, "used metadata mismatch:  %u != %u\n",
5026b946170SBenjamin Marzinski 			count[2] + count[3], rgd->rd_dinodes);
5038dc88ac6SAndreas Gruenbacher 		gfs2_consist_rgrpd(rgd);
504b3b94faaSDavid Teigland 		return;
505b3b94faaSDavid Teigland 	}
506b3b94faaSDavid Teigland }
507b3b94faaSDavid Teigland 
508b3b94faaSDavid Teigland /**
509b3b94faaSDavid Teigland  * gfs2_blk2rgrpd - Find resource group for a given data/meta block number
510b3b94faaSDavid Teigland  * @sdp: The GFS2 superblock
511886b1416SBob Peterson  * @blk: The data block number
512886b1416SBob Peterson  * @exact: True if this needs to be an exact match
513b3b94faaSDavid Teigland  *
51490bcab99SSteven Whitehouse  * The @exact argument should be set to true by most callers. The exception
51590bcab99SSteven Whitehouse  * is when we need to match blocks which are not represented by the rgrp
51690bcab99SSteven Whitehouse  * bitmap, but which are part of the rgrp (i.e. padding blocks) which are
51790bcab99SSteven Whitehouse  * there for alignment purposes. Another way of looking at it is that @exact
51890bcab99SSteven Whitehouse  * matches only valid data/metadata blocks, but with @exact false, it will
51990bcab99SSteven Whitehouse  * match any block within the extent of the rgrp.
52090bcab99SSteven Whitehouse  *
521b3b94faaSDavid Teigland  * Returns: The resource group, or NULL if not found
522b3b94faaSDavid Teigland  */
523b3b94faaSDavid Teigland 
gfs2_blk2rgrpd(struct gfs2_sbd * sdp,u64 blk,bool exact)52466fc061bSSteven Whitehouse struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk, bool exact)
525b3b94faaSDavid Teigland {
52666fc061bSSteven Whitehouse 	struct rb_node *n, *next;
527f75bbfb4SSteven Whitehouse 	struct gfs2_rgrpd *cur;
528b3b94faaSDavid Teigland 
529b3b94faaSDavid Teigland 	spin_lock(&sdp->sd_rindex_spin);
53066fc061bSSteven Whitehouse 	n = sdp->sd_rindex_tree.rb_node;
53166fc061bSSteven Whitehouse 	while (n) {
53266fc061bSSteven Whitehouse 		cur = rb_entry(n, struct gfs2_rgrpd, rd_node);
53366fc061bSSteven Whitehouse 		next = NULL;
5347c9ca621SBob Peterson 		if (blk < cur->rd_addr)
53566fc061bSSteven Whitehouse 			next = n->rb_left;
536f75bbfb4SSteven Whitehouse 		else if (blk >= cur->rd_data0 + cur->rd_data)
53766fc061bSSteven Whitehouse 			next = n->rb_right;
53866fc061bSSteven Whitehouse 		if (next == NULL) {
539b3b94faaSDavid Teigland 			spin_unlock(&sdp->sd_rindex_spin);
54066fc061bSSteven Whitehouse 			if (exact) {
54166fc061bSSteven Whitehouse 				if (blk < cur->rd_addr)
54266fc061bSSteven Whitehouse 					return NULL;
54366fc061bSSteven Whitehouse 				if (blk >= cur->rd_data0 + cur->rd_data)
54466fc061bSSteven Whitehouse 					return NULL;
54566fc061bSSteven Whitehouse 			}
5467c9ca621SBob Peterson 			return cur;
547b3b94faaSDavid Teigland 		}
54866fc061bSSteven Whitehouse 		n = next;
549b3b94faaSDavid Teigland 	}
550b3b94faaSDavid Teigland 	spin_unlock(&sdp->sd_rindex_spin);
551b3b94faaSDavid Teigland 
552b3b94faaSDavid Teigland 	return NULL;
553b3b94faaSDavid Teigland }
554b3b94faaSDavid Teigland 
555b3b94faaSDavid Teigland /**
556b3b94faaSDavid Teigland  * gfs2_rgrpd_get_first - get the first Resource Group in the filesystem
557b3b94faaSDavid Teigland  * @sdp: The GFS2 superblock
558b3b94faaSDavid Teigland  *
559b3b94faaSDavid Teigland  * Returns: The first rgrp in the filesystem
560b3b94faaSDavid Teigland  */
561b3b94faaSDavid Teigland 
gfs2_rgrpd_get_first(struct gfs2_sbd * sdp)562b3b94faaSDavid Teigland struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp)
563b3b94faaSDavid Teigland {
5647c9ca621SBob Peterson 	const struct rb_node *n;
5657c9ca621SBob Peterson 	struct gfs2_rgrpd *rgd;
5667c9ca621SBob Peterson 
5678339ee54SSteven Whitehouse 	spin_lock(&sdp->sd_rindex_spin);
5687c9ca621SBob Peterson 	n = rb_first(&sdp->sd_rindex_tree);
5697c9ca621SBob Peterson 	rgd = rb_entry(n, struct gfs2_rgrpd, rd_node);
5708339ee54SSteven Whitehouse 	spin_unlock(&sdp->sd_rindex_spin);
5717c9ca621SBob Peterson 
5727c9ca621SBob Peterson 	return rgd;
573b3b94faaSDavid Teigland }
574b3b94faaSDavid Teigland 
575b3b94faaSDavid Teigland /**
576b3b94faaSDavid Teigland  * gfs2_rgrpd_get_next - get the next RG
577886b1416SBob Peterson  * @rgd: the resource group descriptor
578b3b94faaSDavid Teigland  *
579b3b94faaSDavid Teigland  * Returns: The next rgrp
580b3b94faaSDavid Teigland  */
581b3b94faaSDavid Teigland 
gfs2_rgrpd_get_next(struct gfs2_rgrpd * rgd)582b3b94faaSDavid Teigland struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd)
583b3b94faaSDavid Teigland {
5847c9ca621SBob Peterson 	struct gfs2_sbd *sdp = rgd->rd_sbd;
5857c9ca621SBob Peterson 	const struct rb_node *n;
5867c9ca621SBob Peterson 
5877c9ca621SBob Peterson 	spin_lock(&sdp->sd_rindex_spin);
5887c9ca621SBob Peterson 	n = rb_next(&rgd->rd_node);
5897c9ca621SBob Peterson 	if (n == NULL)
5907c9ca621SBob Peterson 		n = rb_first(&sdp->sd_rindex_tree);
5917c9ca621SBob Peterson 
5927c9ca621SBob Peterson 	if (unlikely(&rgd->rd_node == n)) {
5937c9ca621SBob Peterson 		spin_unlock(&sdp->sd_rindex_spin);
594b3b94faaSDavid Teigland 		return NULL;
5957c9ca621SBob Peterson 	}
5967c9ca621SBob Peterson 	rgd = rb_entry(n, struct gfs2_rgrpd, rd_node);
5977c9ca621SBob Peterson 	spin_unlock(&sdp->sd_rindex_spin);
5987c9ca621SBob Peterson 	return rgd;
599b3b94faaSDavid Teigland }
600b3b94faaSDavid Teigland 
check_and_update_goal(struct gfs2_inode * ip)60100a158beSAbhi Das void check_and_update_goal(struct gfs2_inode *ip)
60200a158beSAbhi Das {
60300a158beSAbhi Das 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
60400a158beSAbhi Das 	if (!ip->i_goal || gfs2_blk2rgrpd(sdp, ip->i_goal, 1) == NULL)
60500a158beSAbhi Das 		ip->i_goal = ip->i_no_addr;
60600a158beSAbhi Das }
60700a158beSAbhi Das 
gfs2_free_clones(struct gfs2_rgrpd * rgd)6088339ee54SSteven Whitehouse void gfs2_free_clones(struct gfs2_rgrpd *rgd)
6098339ee54SSteven Whitehouse {
6108339ee54SSteven Whitehouse 	int x;
6118339ee54SSteven Whitehouse 
6128339ee54SSteven Whitehouse 	for (x = 0; x < rgd->rd_length; x++) {
6138339ee54SSteven Whitehouse 		struct gfs2_bitmap *bi = rgd->rd_bits + x;
6148339ee54SSteven Whitehouse 		kfree(bi->bi_clone);
6158339ee54SSteven Whitehouse 		bi->bi_clone = NULL;
6168339ee54SSteven Whitehouse 	}
6178339ee54SSteven Whitehouse }
6188339ee54SSteven Whitehouse 
dump_rs(struct seq_file * seq,const struct gfs2_blkreserv * rs,const char * fs_id_buf)6193792ce97SBob Peterson static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs,
6203792ce97SBob Peterson 		    const char *fs_id_buf)
6218e2e0047SBob Peterson {
622f85c10e2SBob Peterson 	struct gfs2_inode *ip = container_of(rs, struct gfs2_inode, i_res);
623f85c10e2SBob Peterson 
624c65b76b8SAndreas Gruenbacher 	gfs2_print_dbg(seq, "%s  B: n:%llu s:%llu f:%u\n",
625c65b76b8SAndreas Gruenbacher 		       fs_id_buf,
626f85c10e2SBob Peterson 		       (unsigned long long)ip->i_no_addr,
627c65b76b8SAndreas Gruenbacher 		       (unsigned long long)rs->rs_start,
62807974d2aSAndreas Gruenbacher 		       rs->rs_requested);
6298e2e0047SBob Peterson }
6308e2e0047SBob Peterson 
6310a305e49SBob Peterson /**
6328e2e0047SBob Peterson  * __rs_deltree - remove a multi-block reservation from the rgd tree
6338e2e0047SBob Peterson  * @rs: The reservation to remove
6348e2e0047SBob Peterson  *
6358e2e0047SBob Peterson  */
__rs_deltree(struct gfs2_blkreserv * rs)63620095218SBob Peterson static void __rs_deltree(struct gfs2_blkreserv *rs)
6378e2e0047SBob Peterson {
6388e2e0047SBob Peterson 	struct gfs2_rgrpd *rgd;
6398e2e0047SBob Peterson 
6408e2e0047SBob Peterson 	if (!gfs2_rs_active(rs))
6418e2e0047SBob Peterson 		return;
6428e2e0047SBob Peterson 
643c65b76b8SAndreas Gruenbacher 	rgd = rs->rs_rgd;
6449e733d39SSteven Whitehouse 	trace_gfs2_rs(rs, TRACE_RS_TREEDEL);
6458e2e0047SBob Peterson 	rb_erase(&rs->rs_node, &rgd->rd_rstree);
64624d634e8SMichel Lespinasse 	RB_CLEAR_NODE(&rs->rs_node);
6478e2e0047SBob Peterson 
64807974d2aSAndreas Gruenbacher 	if (rs->rs_requested) {
64907974d2aSAndreas Gruenbacher 		/* return requested blocks to the rgrp */
65007974d2aSAndreas Gruenbacher 		BUG_ON(rs->rs_rgd->rd_requested < rs->rs_requested);
65107974d2aSAndreas Gruenbacher 		rs->rs_rgd->rd_requested -= rs->rs_requested;
652a12c6fa1SAndreas Gruenbacher 
6535ea5050cSBob Peterson 		/* The rgrp extent failure point is likely not to increase;
6545ea5050cSBob Peterson 		   it will only do so if the freed blocks are somehow
6555ea5050cSBob Peterson 		   contiguous with a span of free blocks that follows. Still,
6565ea5050cSBob Peterson 		   it will force the number to be recalculated later. */
65707974d2aSAndreas Gruenbacher 		rgd->rd_extfail_pt += rs->rs_requested;
65807974d2aSAndreas Gruenbacher 		rs->rs_requested = 0;
6598e2e0047SBob Peterson 	}
6608e2e0047SBob Peterson }
6618e2e0047SBob Peterson 
6628e2e0047SBob Peterson /**
6638e2e0047SBob Peterson  * gfs2_rs_deltree - remove a multi-block reservation from the rgd tree
6648e2e0047SBob Peterson  * @rs: The reservation to remove
6658e2e0047SBob Peterson  *
6668e2e0047SBob Peterson  */
gfs2_rs_deltree(struct gfs2_blkreserv * rs)66720095218SBob Peterson void gfs2_rs_deltree(struct gfs2_blkreserv *rs)
6688e2e0047SBob Peterson {
6698e2e0047SBob Peterson 	struct gfs2_rgrpd *rgd;
6708e2e0047SBob Peterson 
671c65b76b8SAndreas Gruenbacher 	rgd = rs->rs_rgd;
6724a993fb1SSteven Whitehouse 	if (rgd) {
6738e2e0047SBob Peterson 		spin_lock(&rgd->rd_rsspin);
67420095218SBob Peterson 		__rs_deltree(rs);
67507974d2aSAndreas Gruenbacher 		BUG_ON(rs->rs_requested);
6768e2e0047SBob Peterson 		spin_unlock(&rgd->rd_rsspin);
6778e2e0047SBob Peterson 	}
6784a993fb1SSteven Whitehouse }
6798e2e0047SBob Peterson 
6808e2e0047SBob Peterson /**
6811595548fSAndreas Gruenbacher  * gfs2_rs_delete - delete a multi-block reservation
6820a305e49SBob Peterson  * @ip: The inode for this reservation
6830a305e49SBob Peterson  *
6840a305e49SBob Peterson  */
gfs2_rs_delete(struct gfs2_inode * ip)6857336905aSAndreas Gruenbacher void gfs2_rs_delete(struct gfs2_inode *ip)
6860a305e49SBob Peterson {
6877336905aSAndreas Gruenbacher 	struct inode *inode = &ip->i_inode;
6887336905aSAndreas Gruenbacher 
6890a305e49SBob Peterson 	down_write(&ip->i_rw_mutex);
6907336905aSAndreas Gruenbacher 	if (atomic_read(&inode->i_writecount) <= 1)
691a097dc7eSBob Peterson 		gfs2_rs_deltree(&ip->i_res);
6920a305e49SBob Peterson 	up_write(&ip->i_rw_mutex);
6930a305e49SBob Peterson }
6940a305e49SBob Peterson 
6958e2e0047SBob Peterson /**
6968e2e0047SBob Peterson  * return_all_reservations - return all reserved blocks back to the rgrp.
6978e2e0047SBob Peterson  * @rgd: the rgrp that needs its space back
6988e2e0047SBob Peterson  *
6998e2e0047SBob Peterson  * We previously reserved a bunch of blocks for allocation. Now we need to
7008e2e0047SBob Peterson  * give them back. This leave the reservation structures in tact, but removes
7018e2e0047SBob Peterson  * all of their corresponding "no-fly zones".
7028e2e0047SBob Peterson  */
return_all_reservations(struct gfs2_rgrpd * rgd)7038e2e0047SBob Peterson static void return_all_reservations(struct gfs2_rgrpd *rgd)
7048e2e0047SBob Peterson {
7058e2e0047SBob Peterson 	struct rb_node *n;
7068e2e0047SBob Peterson 	struct gfs2_blkreserv *rs;
7078e2e0047SBob Peterson 
7088e2e0047SBob Peterson 	spin_lock(&rgd->rd_rsspin);
7098e2e0047SBob Peterson 	while ((n = rb_first(&rgd->rd_rstree))) {
7108e2e0047SBob Peterson 		rs = rb_entry(n, struct gfs2_blkreserv, rs_node);
71120095218SBob Peterson 		__rs_deltree(rs);
7128e2e0047SBob Peterson 	}
7138e2e0047SBob Peterson 	spin_unlock(&rgd->rd_rsspin);
7148e2e0047SBob Peterson }
7158e2e0047SBob Peterson 
gfs2_clear_rgrpd(struct gfs2_sbd * sdp)7168339ee54SSteven Whitehouse void gfs2_clear_rgrpd(struct gfs2_sbd *sdp)
717b3b94faaSDavid Teigland {
7187c9ca621SBob Peterson 	struct rb_node *n;
719b3b94faaSDavid Teigland 	struct gfs2_rgrpd *rgd;
720b3b94faaSDavid Teigland 	struct gfs2_glock *gl;
721b3b94faaSDavid Teigland 
7227c9ca621SBob Peterson 	while ((n = rb_first(&sdp->sd_rindex_tree))) {
7237c9ca621SBob Peterson 		rgd = rb_entry(n, struct gfs2_rgrpd, rd_node);
724b3b94faaSDavid Teigland 		gl = rgd->rd_gl;
725b3b94faaSDavid Teigland 
7267c9ca621SBob Peterson 		rb_erase(n, &sdp->sd_rindex_tree);
727b3b94faaSDavid Teigland 
728b3b94faaSDavid Teigland 		if (gl) {
729b3422cacSBob Peterson 			if (gl->gl_state != LM_ST_UNLOCKED) {
730b3422cacSBob Peterson 				gfs2_glock_cb(gl, LM_ST_UNLOCKED);
731b3422cacSBob Peterson 				flush_delayed_work(&gl->gl_work);
732b3422cacSBob Peterson 			}
73310283ea5SAndreas Gruenbacher 			gfs2_rgrp_brelse(rgd);
734b3422cacSBob Peterson 			glock_clear_object(gl, rgd);
735b3b94faaSDavid Teigland 			gfs2_glock_put(gl);
736b3b94faaSDavid Teigland 		}
737b3b94faaSDavid Teigland 
7388339ee54SSteven Whitehouse 		gfs2_free_clones(rgd);
739d0f17d38SBob Peterson 		return_all_reservations(rgd);
740b3b94faaSDavid Teigland 		kfree(rgd->rd_bits);
74136e4ad03SBob Peterson 		rgd->rd_bits = NULL;
7426bdd9be6SBob Peterson 		kmem_cache_free(gfs2_rgrpd_cachep, rgd);
743b3b94faaSDavid Teigland 	}
744b3b94faaSDavid Teigland }
745b3b94faaSDavid Teigland 
746b3b94faaSDavid Teigland /**
747c551f66cSLee Jones  * compute_bitstructs - Compute the bitmap sizes
748b3b94faaSDavid Teigland  * @rgd: The resource group descriptor
749b3b94faaSDavid Teigland  *
750b3b94faaSDavid Teigland  * Calculates bitmap descriptors, one for each block that contains bitmap data
751b3b94faaSDavid Teigland  *
752b3b94faaSDavid Teigland  * Returns: errno
753b3b94faaSDavid Teigland  */
754b3b94faaSDavid Teigland 
compute_bitstructs(struct gfs2_rgrpd * rgd)755b3b94faaSDavid Teigland static int compute_bitstructs(struct gfs2_rgrpd *rgd)
756b3b94faaSDavid Teigland {
757b3b94faaSDavid Teigland 	struct gfs2_sbd *sdp = rgd->rd_sbd;
758b3b94faaSDavid Teigland 	struct gfs2_bitmap *bi;
759bb8d8a6fSSteven Whitehouse 	u32 length = rgd->rd_length; /* # blocks in hdr & bitmap */
760cd915493SSteven Whitehouse 	u32 bytes_left, bytes;
761b3b94faaSDavid Teigland 	int x;
762b3b94faaSDavid Teigland 
763feaa7bbaSSteven Whitehouse 	if (!length)
764feaa7bbaSSteven Whitehouse 		return -EINVAL;
765feaa7bbaSSteven Whitehouse 
766dd894be8SSteven Whitehouse 	rgd->rd_bits = kcalloc(length, sizeof(struct gfs2_bitmap), GFP_NOFS);
767b3b94faaSDavid Teigland 	if (!rgd->rd_bits)
768b3b94faaSDavid Teigland 		return -ENOMEM;
769b3b94faaSDavid Teigland 
770bb8d8a6fSSteven Whitehouse 	bytes_left = rgd->rd_bitbytes;
771b3b94faaSDavid Teigland 
772b3b94faaSDavid Teigland 	for (x = 0; x < length; x++) {
773b3b94faaSDavid Teigland 		bi = rgd->rd_bits + x;
774b3b94faaSDavid Teigland 
77560a0b8f9SSteven Whitehouse 		bi->bi_flags = 0;
776b3b94faaSDavid Teigland 		/* small rgrp; bitmap stored completely in header block */
777b3b94faaSDavid Teigland 		if (length == 1) {
778b3b94faaSDavid Teigland 			bytes = bytes_left;
779b3b94faaSDavid Teigland 			bi->bi_offset = sizeof(struct gfs2_rgrp);
780b3b94faaSDavid Teigland 			bi->bi_start = 0;
781281b4952SAndreas Gruenbacher 			bi->bi_bytes = bytes;
7827e230f57SBob Peterson 			bi->bi_blocks = bytes * GFS2_NBBY;
783b3b94faaSDavid Teigland 		/* header block */
784b3b94faaSDavid Teigland 		} else if (x == 0) {
785b3b94faaSDavid Teigland 			bytes = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_rgrp);
786b3b94faaSDavid Teigland 			bi->bi_offset = sizeof(struct gfs2_rgrp);
787b3b94faaSDavid Teigland 			bi->bi_start = 0;
788281b4952SAndreas Gruenbacher 			bi->bi_bytes = bytes;
7897e230f57SBob Peterson 			bi->bi_blocks = bytes * GFS2_NBBY;
790b3b94faaSDavid Teigland 		/* last block */
791b3b94faaSDavid Teigland 		} else if (x + 1 == length) {
792b3b94faaSDavid Teigland 			bytes = bytes_left;
793b3b94faaSDavid Teigland 			bi->bi_offset = sizeof(struct gfs2_meta_header);
794bb8d8a6fSSteven Whitehouse 			bi->bi_start = rgd->rd_bitbytes - bytes_left;
795281b4952SAndreas Gruenbacher 			bi->bi_bytes = bytes;
7967e230f57SBob Peterson 			bi->bi_blocks = bytes * GFS2_NBBY;
797b3b94faaSDavid Teigland 		/* other blocks */
798b3b94faaSDavid Teigland 		} else {
799568f4c96SSteven Whitehouse 			bytes = sdp->sd_sb.sb_bsize -
800568f4c96SSteven Whitehouse 				sizeof(struct gfs2_meta_header);
801b3b94faaSDavid Teigland 			bi->bi_offset = sizeof(struct gfs2_meta_header);
802bb8d8a6fSSteven Whitehouse 			bi->bi_start = rgd->rd_bitbytes - bytes_left;
803281b4952SAndreas Gruenbacher 			bi->bi_bytes = bytes;
8047e230f57SBob Peterson 			bi->bi_blocks = bytes * GFS2_NBBY;
805b3b94faaSDavid Teigland 		}
806b3b94faaSDavid Teigland 
807b3b94faaSDavid Teigland 		bytes_left -= bytes;
808b3b94faaSDavid Teigland 	}
809b3b94faaSDavid Teigland 
810b3b94faaSDavid Teigland 	if (bytes_left) {
811b3b94faaSDavid Teigland 		gfs2_consist_rgrpd(rgd);
812b3b94faaSDavid Teigland 		return -EIO;
813b3b94faaSDavid Teigland 	}
814b3b94faaSDavid Teigland 	bi = rgd->rd_bits + (length - 1);
815281b4952SAndreas Gruenbacher 	if ((bi->bi_start + bi->bi_bytes) * GFS2_NBBY != rgd->rd_data) {
8168dc88ac6SAndreas Gruenbacher 		gfs2_lm(sdp,
8178dc88ac6SAndreas Gruenbacher 			"ri_addr = %llu\n"
8188dc88ac6SAndreas Gruenbacher 			"ri_length = %u\n"
8198dc88ac6SAndreas Gruenbacher 			"ri_data0 = %llu\n"
8208dc88ac6SAndreas Gruenbacher 			"ri_data = %u\n"
8218dc88ac6SAndreas Gruenbacher 			"ri_bitbytes = %u\n"
8228dc88ac6SAndreas Gruenbacher 			"start=%u len=%u offset=%u\n",
8238dc88ac6SAndreas Gruenbacher 			(unsigned long long)rgd->rd_addr,
8248dc88ac6SAndreas Gruenbacher 			rgd->rd_length,
8258dc88ac6SAndreas Gruenbacher 			(unsigned long long)rgd->rd_data0,
8268dc88ac6SAndreas Gruenbacher 			rgd->rd_data,
8278dc88ac6SAndreas Gruenbacher 			rgd->rd_bitbytes,
828281b4952SAndreas Gruenbacher 			bi->bi_start, bi->bi_bytes, bi->bi_offset);
8298dc88ac6SAndreas Gruenbacher 		gfs2_consist_rgrpd(rgd);
830b3b94faaSDavid Teigland 		return -EIO;
831b3b94faaSDavid Teigland 	}
832b3b94faaSDavid Teigland 
833b3b94faaSDavid Teigland 	return 0;
834b3b94faaSDavid Teigland }
835b3b94faaSDavid Teigland 
836b3b94faaSDavid Teigland /**
8377ae8fa84SRobert Peterson  * gfs2_ri_total - Total up the file system space, according to the rindex.
838886b1416SBob Peterson  * @sdp: the filesystem
8397ae8fa84SRobert Peterson  *
8407ae8fa84SRobert Peterson  */
gfs2_ri_total(struct gfs2_sbd * sdp)8417ae8fa84SRobert Peterson u64 gfs2_ri_total(struct gfs2_sbd *sdp)
8427ae8fa84SRobert Peterson {
8437ae8fa84SRobert Peterson 	u64 total_data = 0;
8447ae8fa84SRobert Peterson 	struct inode *inode = sdp->sd_rindex;
8457ae8fa84SRobert Peterson 	struct gfs2_inode *ip = GFS2_I(inode);
8467ae8fa84SRobert Peterson 	char buf[sizeof(struct gfs2_rindex)];
8477ae8fa84SRobert Peterson 	int error, rgrps;
8487ae8fa84SRobert Peterson 
8497ae8fa84SRobert Peterson 	for (rgrps = 0;; rgrps++) {
8507ae8fa84SRobert Peterson 		loff_t pos = rgrps * sizeof(struct gfs2_rindex);
8517ae8fa84SRobert Peterson 
852bcd7278dSBob Peterson 		if (pos + sizeof(struct gfs2_rindex) > i_size_read(inode))
8537ae8fa84SRobert Peterson 			break;
8544306629eSAndrew Price 		error = gfs2_internal_read(ip, buf, &pos,
8557ae8fa84SRobert Peterson 					   sizeof(struct gfs2_rindex));
8567ae8fa84SRobert Peterson 		if (error != sizeof(struct gfs2_rindex))
8577ae8fa84SRobert Peterson 			break;
858bb8d8a6fSSteven Whitehouse 		total_data += be32_to_cpu(((struct gfs2_rindex *)buf)->ri_data);
8597ae8fa84SRobert Peterson 	}
8607ae8fa84SRobert Peterson 	return total_data;
8617ae8fa84SRobert Peterson }
8627ae8fa84SRobert Peterson 
rgd_insert(struct gfs2_rgrpd * rgd)8636aad1c3dSBob Peterson static int rgd_insert(struct gfs2_rgrpd *rgd)
8647c9ca621SBob Peterson {
8657c9ca621SBob Peterson 	struct gfs2_sbd *sdp = rgd->rd_sbd;
8667c9ca621SBob Peterson 	struct rb_node **newn = &sdp->sd_rindex_tree.rb_node, *parent = NULL;
8677c9ca621SBob Peterson 
8687c9ca621SBob Peterson 	/* Figure out where to put new node */
8697c9ca621SBob Peterson 	while (*newn) {
8707c9ca621SBob Peterson 		struct gfs2_rgrpd *cur = rb_entry(*newn, struct gfs2_rgrpd,
8717c9ca621SBob Peterson 						  rd_node);
8727c9ca621SBob Peterson 
8737c9ca621SBob Peterson 		parent = *newn;
8747c9ca621SBob Peterson 		if (rgd->rd_addr < cur->rd_addr)
8757c9ca621SBob Peterson 			newn = &((*newn)->rb_left);
8767c9ca621SBob Peterson 		else if (rgd->rd_addr > cur->rd_addr)
8777c9ca621SBob Peterson 			newn = &((*newn)->rb_right);
8787c9ca621SBob Peterson 		else
8796aad1c3dSBob Peterson 			return -EEXIST;
8807c9ca621SBob Peterson 	}
8817c9ca621SBob Peterson 
8827c9ca621SBob Peterson 	rb_link_node(&rgd->rd_node, parent, newn);
8837c9ca621SBob Peterson 	rb_insert_color(&rgd->rd_node, &sdp->sd_rindex_tree);
8846aad1c3dSBob Peterson 	sdp->sd_rgrps++;
8856aad1c3dSBob Peterson 	return 0;
8867c9ca621SBob Peterson }
8877c9ca621SBob Peterson 
8887ae8fa84SRobert Peterson /**
8896c53267fSRobert Peterson  * read_rindex_entry - Pull in a new resource index entry from the disk
8904306629eSAndrew Price  * @ip: Pointer to the rindex inode
891b3b94faaSDavid Teigland  *
8928339ee54SSteven Whitehouse  * Returns: 0 on success, > 0 on EOF, error code otherwise
893b3b94faaSDavid Teigland  */
894b3b94faaSDavid Teigland 
read_rindex_entry(struct gfs2_inode * ip)8954306629eSAndrew Price static int read_rindex_entry(struct gfs2_inode *ip)
896b3b94faaSDavid Teigland {
897feaa7bbaSSteven Whitehouse 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
898f42faf4fSSteven Whitehouse 	loff_t pos = sdp->sd_rgrps * sizeof(struct gfs2_rindex);
8998339ee54SSteven Whitehouse 	struct gfs2_rindex buf;
9006c53267fSRobert Peterson 	int error;
9016c53267fSRobert Peterson 	struct gfs2_rgrpd *rgd;
9027ae8fa84SRobert Peterson 
9038339ee54SSteven Whitehouse 	if (pos >= i_size_read(&ip->i_inode))
9048339ee54SSteven Whitehouse 		return 1;
9058339ee54SSteven Whitehouse 
9064306629eSAndrew Price 	error = gfs2_internal_read(ip, (char *)&buf, &pos,
907b3b94faaSDavid Teigland 				   sizeof(struct gfs2_rindex));
9088339ee54SSteven Whitehouse 
9098339ee54SSteven Whitehouse 	if (error != sizeof(struct gfs2_rindex))
9108339ee54SSteven Whitehouse 		return (error == 0) ? 1 : error;
911b3b94faaSDavid Teigland 
9126bdd9be6SBob Peterson 	rgd = kmem_cache_zalloc(gfs2_rgrpd_cachep, GFP_NOFS);
913b3b94faaSDavid Teigland 	error = -ENOMEM;
914b3b94faaSDavid Teigland 	if (!rgd)
9156c53267fSRobert Peterson 		return error;
916b3b94faaSDavid Teigland 
917b3b94faaSDavid Teigland 	rgd->rd_sbd = sdp;
9188339ee54SSteven Whitehouse 	rgd->rd_addr = be64_to_cpu(buf.ri_addr);
9198339ee54SSteven Whitehouse 	rgd->rd_length = be32_to_cpu(buf.ri_length);
9208339ee54SSteven Whitehouse 	rgd->rd_data0 = be64_to_cpu(buf.ri_data0);
9218339ee54SSteven Whitehouse 	rgd->rd_data = be32_to_cpu(buf.ri_data);
9228339ee54SSteven Whitehouse 	rgd->rd_bitbytes = be32_to_cpu(buf.ri_bitbytes);
9238e2e0047SBob Peterson 	spin_lock_init(&rgd->rd_rsspin);
9249e514605SAndreas Gruenbacher 	mutex_init(&rgd->rd_mutex);
9257c9ca621SBob Peterson 
926bb8d8a6fSSteven Whitehouse 	error = gfs2_glock_get(sdp, rgd->rd_addr,
927b3b94faaSDavid Teigland 			       &gfs2_rgrp_glops, CREATE, &rgd->rd_gl);
928b3b94faaSDavid Teigland 	if (error)
9298339ee54SSteven Whitehouse 		goto fail;
930b3b94faaSDavid Teigland 
931428f651cSBob Peterson 	error = compute_bitstructs(rgd);
932428f651cSBob Peterson 	if (error)
933428f651cSBob Peterson 		goto fail_glock;
934428f651cSBob Peterson 
9354e2f8849SDavid Teigland 	rgd->rd_rgl = (struct gfs2_rgrp_lvb *)rgd->rd_gl->gl_lksb.sb_lvbptr;
9364b3113a2SBob Peterson 	rgd->rd_flags &= ~GFS2_RDF_PREFERRED;
9377c9ca621SBob Peterson 	if (rgd->rd_data > sdp->sd_max_rg_data)
9387c9ca621SBob Peterson 		sdp->sd_max_rg_data = rgd->rd_data;
9398339ee54SSteven Whitehouse 	spin_lock(&sdp->sd_rindex_spin);
9406aad1c3dSBob Peterson 	error = rgd_insert(rgd);
9418339ee54SSteven Whitehouse 	spin_unlock(&sdp->sd_rindex_spin);
94236e4ad03SBob Peterson 	if (!error) {
9436f6597baSAndreas Gruenbacher 		glock_set_object(rgd->rd_gl, rgd);
9446aad1c3dSBob Peterson 		return 0;
94536e4ad03SBob Peterson 	}
9466aad1c3dSBob Peterson 
9476aad1c3dSBob Peterson 	error = 0; /* someone else read in the rgrp; free it and ignore it */
948428f651cSBob Peterson fail_glock:
949c1ac539eSBob Peterson 	gfs2_glock_put(rgd->rd_gl);
9508339ee54SSteven Whitehouse 
9518339ee54SSteven Whitehouse fail:
9528339ee54SSteven Whitehouse 	kfree(rgd->rd_bits);
95336e4ad03SBob Peterson 	rgd->rd_bits = NULL;
9548339ee54SSteven Whitehouse 	kmem_cache_free(gfs2_rgrpd_cachep, rgd);
9556c53267fSRobert Peterson 	return error;
9566c53267fSRobert Peterson }
9576c53267fSRobert Peterson 
9586c53267fSRobert Peterson /**
9590e27c18cSBob Peterson  * set_rgrp_preferences - Run all the rgrps, selecting some we prefer to use
9600e27c18cSBob Peterson  * @sdp: the GFS2 superblock
9610e27c18cSBob Peterson  *
9620e27c18cSBob Peterson  * The purpose of this function is to select a subset of the resource groups
9630e27c18cSBob Peterson  * and mark them as PREFERRED. We do it in such a way that each node prefers
9640e27c18cSBob Peterson  * to use a unique set of rgrps to minimize glock contention.
9650e27c18cSBob Peterson  */
set_rgrp_preferences(struct gfs2_sbd * sdp)9660e27c18cSBob Peterson static void set_rgrp_preferences(struct gfs2_sbd *sdp)
9670e27c18cSBob Peterson {
9680e27c18cSBob Peterson 	struct gfs2_rgrpd *rgd, *first;
9690e27c18cSBob Peterson 	int i;
9700e27c18cSBob Peterson 
9710e27c18cSBob Peterson 	/* Skip an initial number of rgrps, based on this node's journal ID.
9720e27c18cSBob Peterson 	   That should start each node out on its own set. */
9730e27c18cSBob Peterson 	rgd = gfs2_rgrpd_get_first(sdp);
9740e27c18cSBob Peterson 	for (i = 0; i < sdp->sd_lockstruct.ls_jid; i++)
9750e27c18cSBob Peterson 		rgd = gfs2_rgrpd_get_next(rgd);
9760e27c18cSBob Peterson 	first = rgd;
9770e27c18cSBob Peterson 
9780e27c18cSBob Peterson 	do {
9790e27c18cSBob Peterson 		rgd->rd_flags |= GFS2_RDF_PREFERRED;
9800e27c18cSBob Peterson 		for (i = 0; i < sdp->sd_journals; i++) {
9810e27c18cSBob Peterson 			rgd = gfs2_rgrpd_get_next(rgd);
982959b6717SAbhi Das 			if (!rgd || rgd == first)
9830e27c18cSBob Peterson 				break;
9840e27c18cSBob Peterson 		}
985959b6717SAbhi Das 	} while (rgd && rgd != first);
9860e27c18cSBob Peterson }
9870e27c18cSBob Peterson 
9880e27c18cSBob Peterson /**
9896c53267fSRobert Peterson  * gfs2_ri_update - Pull in a new resource index from the disk
9906c53267fSRobert Peterson  * @ip: pointer to the rindex inode
9916c53267fSRobert Peterson  *
9926c53267fSRobert Peterson  * Returns: 0 on successful update, error code otherwise
9936c53267fSRobert Peterson  */
9946c53267fSRobert Peterson 
gfs2_ri_update(struct gfs2_inode * ip)9958339ee54SSteven Whitehouse static int gfs2_ri_update(struct gfs2_inode *ip)
9966c53267fSRobert Peterson {
9976c53267fSRobert Peterson 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
9986c53267fSRobert Peterson 	int error;
9996c53267fSRobert Peterson 
10008339ee54SSteven Whitehouse 	do {
10014306629eSAndrew Price 		error = read_rindex_entry(ip);
10028339ee54SSteven Whitehouse 	} while (error == 0);
10038339ee54SSteven Whitehouse 
10048339ee54SSteven Whitehouse 	if (error < 0)
10056c53267fSRobert Peterson 		return error;
1006b3b94faaSDavid Teigland 
100777872151SBob Peterson 	if (RB_EMPTY_ROOT(&sdp->sd_rindex_tree)) {
100877872151SBob Peterson 		fs_err(sdp, "no resource groups found in the file system.\n");
100977872151SBob Peterson 		return -ENOENT;
101077872151SBob Peterson 	}
10110e27c18cSBob Peterson 	set_rgrp_preferences(sdp);
10120e27c18cSBob Peterson 
1013cf45b752SBob Peterson 	sdp->sd_rindex_uptodate = 1;
1014b3b94faaSDavid Teigland 	return 0;
10156c53267fSRobert Peterson }
1016b3b94faaSDavid Teigland 
10176c53267fSRobert Peterson /**
10188339ee54SSteven Whitehouse  * gfs2_rindex_update - Update the rindex if required
1019b3b94faaSDavid Teigland  * @sdp: The GFS2 superblock
1020b3b94faaSDavid Teigland  *
1021b3b94faaSDavid Teigland  * We grab a lock on the rindex inode to make sure that it doesn't
1022b3b94faaSDavid Teigland  * change whilst we are performing an operation. We keep this lock
1023b3b94faaSDavid Teigland  * for quite long periods of time compared to other locks. This
1024b3b94faaSDavid Teigland  * doesn't matter, since it is shared and it is very, very rarely
1025b3b94faaSDavid Teigland  * accessed in the exclusive mode (i.e. only when expanding the filesystem).
1026b3b94faaSDavid Teigland  *
1027b3b94faaSDavid Teigland  * This makes sure that we're using the latest copy of the resource index
1028b3b94faaSDavid Teigland  * special file, which might have been updated if someone expanded the
1029b3b94faaSDavid Teigland  * filesystem (via gfs2_grow utility), which adds new resource groups.
1030b3b94faaSDavid Teigland  *
10318339ee54SSteven Whitehouse  * Returns: 0 on succeess, error code otherwise
1032b3b94faaSDavid Teigland  */
1033b3b94faaSDavid Teigland 
gfs2_rindex_update(struct gfs2_sbd * sdp)10348339ee54SSteven Whitehouse int gfs2_rindex_update(struct gfs2_sbd *sdp)
1035b3b94faaSDavid Teigland {
1036feaa7bbaSSteven Whitehouse 	struct gfs2_inode *ip = GFS2_I(sdp->sd_rindex);
1037b3b94faaSDavid Teigland 	struct gfs2_glock *gl = ip->i_gl;
10388339ee54SSteven Whitehouse 	struct gfs2_holder ri_gh;
10398339ee54SSteven Whitehouse 	int error = 0;
1040a365fbf3SSteven Whitehouse 	int unlock_required = 0;
1041b3b94faaSDavid Teigland 
1042b3b94faaSDavid Teigland 	/* Read new copy from disk if we don't have the latest */
1043cf45b752SBob Peterson 	if (!sdp->sd_rindex_uptodate) {
1044a365fbf3SSteven Whitehouse 		if (!gfs2_glock_is_locked_by_me(gl)) {
10458339ee54SSteven Whitehouse 			error = gfs2_glock_nq_init(gl, LM_ST_SHARED, 0, &ri_gh);
1046b3b94faaSDavid Teigland 			if (error)
10476aad1c3dSBob Peterson 				return error;
1048a365fbf3SSteven Whitehouse 			unlock_required = 1;
1049a365fbf3SSteven Whitehouse 		}
10508339ee54SSteven Whitehouse 		if (!sdp->sd_rindex_uptodate)
10518339ee54SSteven Whitehouse 			error = gfs2_ri_update(ip);
1052a365fbf3SSteven Whitehouse 		if (unlock_required)
10538339ee54SSteven Whitehouse 			gfs2_glock_dq_uninit(&ri_gh);
1054b3b94faaSDavid Teigland 	}
1055b3b94faaSDavid Teigland 
1056b3b94faaSDavid Teigland 	return error;
1057b3b94faaSDavid Teigland }
1058b3b94faaSDavid Teigland 
gfs2_rgrp_in(struct gfs2_rgrpd * rgd,const void * buf)105942d52e38SBob Peterson static void gfs2_rgrp_in(struct gfs2_rgrpd *rgd, const void *buf)
1060bb8d8a6fSSteven Whitehouse {
1061bb8d8a6fSSteven Whitehouse 	const struct gfs2_rgrp *str = buf;
106242d52e38SBob Peterson 	u32 rg_flags;
1063bb8d8a6fSSteven Whitehouse 
106442d52e38SBob Peterson 	rg_flags = be32_to_cpu(str->rg_flags);
106509010978SSteven Whitehouse 	rg_flags &= ~GFS2_RDF_MASK;
10661ce97e56SSteven Whitehouse 	rgd->rd_flags &= GFS2_RDF_MASK;
10671ce97e56SSteven Whitehouse 	rgd->rd_flags |= rg_flags;
1068cfc8b549SSteven Whitehouse 	rgd->rd_free = be32_to_cpu(str->rg_free);
106973f74948SSteven Whitehouse 	rgd->rd_dinodes = be32_to_cpu(str->rg_dinodes);
1070d8b71f73SSteven Whitehouse 	rgd->rd_igeneration = be64_to_cpu(str->rg_igeneration);
1071166725d9SAndrew Price 	/* rd_data0, rd_data and rd_bitbytes already set from rindex */
1072bb8d8a6fSSteven Whitehouse }
1073bb8d8a6fSSteven Whitehouse 
gfs2_rgrp_ondisk2lvb(struct gfs2_rgrp_lvb * rgl,const void * buf)10743f30f929SBob Peterson static void gfs2_rgrp_ondisk2lvb(struct gfs2_rgrp_lvb *rgl, const void *buf)
10753f30f929SBob Peterson {
10763f30f929SBob Peterson 	const struct gfs2_rgrp *str = buf;
10773f30f929SBob Peterson 
10783f30f929SBob Peterson 	rgl->rl_magic = cpu_to_be32(GFS2_MAGIC);
10793f30f929SBob Peterson 	rgl->rl_flags = str->rg_flags;
10803f30f929SBob Peterson 	rgl->rl_free = str->rg_free;
10813f30f929SBob Peterson 	rgl->rl_dinodes = str->rg_dinodes;
10823f30f929SBob Peterson 	rgl->rl_igeneration = str->rg_igeneration;
10833f30f929SBob Peterson 	rgl->__pad = 0UL;
10843f30f929SBob Peterson }
10853f30f929SBob Peterson 
gfs2_rgrp_out(struct gfs2_rgrpd * rgd,void * buf)108642d52e38SBob Peterson static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf)
1087bb8d8a6fSSteven Whitehouse {
108865adc273SAndrew Price 	struct gfs2_rgrpd *next = gfs2_rgrpd_get_next(rgd);
1089bb8d8a6fSSteven Whitehouse 	struct gfs2_rgrp *str = buf;
1090850d2d91SAndrew Price 	u32 crc;
1091bb8d8a6fSSteven Whitehouse 
109209010978SSteven Whitehouse 	str->rg_flags = cpu_to_be32(rgd->rd_flags & ~GFS2_RDF_MASK);
1093cfc8b549SSteven Whitehouse 	str->rg_free = cpu_to_be32(rgd->rd_free);
109473f74948SSteven Whitehouse 	str->rg_dinodes = cpu_to_be32(rgd->rd_dinodes);
109565adc273SAndrew Price 	if (next == NULL)
109665adc273SAndrew Price 		str->rg_skip = 0;
109765adc273SAndrew Price 	else if (next->rd_addr > rgd->rd_addr)
109865adc273SAndrew Price 		str->rg_skip = cpu_to_be32(next->rd_addr - rgd->rd_addr);
1099d8b71f73SSteven Whitehouse 	str->rg_igeneration = cpu_to_be64(rgd->rd_igeneration);
1100166725d9SAndrew Price 	str->rg_data0 = cpu_to_be64(rgd->rd_data0);
1101166725d9SAndrew Price 	str->rg_data = cpu_to_be32(rgd->rd_data);
1102166725d9SAndrew Price 	str->rg_bitbytes = cpu_to_be32(rgd->rd_bitbytes);
1103850d2d91SAndrew Price 	str->rg_crc = 0;
1104850d2d91SAndrew Price 	crc = gfs2_disk_hash(buf, sizeof(struct gfs2_rgrp));
1105850d2d91SAndrew Price 	str->rg_crc = cpu_to_be32(crc);
1106166725d9SAndrew Price 
1107bb8d8a6fSSteven Whitehouse 	memset(&str->rg_reserved, 0, sizeof(str->rg_reserved));
11083f30f929SBob Peterson 	gfs2_rgrp_ondisk2lvb(rgd->rd_rgl, buf);
1109bb8d8a6fSSteven Whitehouse }
1110bb8d8a6fSSteven Whitehouse 
gfs2_rgrp_lvb_valid(struct gfs2_rgrpd * rgd)111190306c41SBenjamin Marzinski static int gfs2_rgrp_lvb_valid(struct gfs2_rgrpd *rgd)
111290306c41SBenjamin Marzinski {
111390306c41SBenjamin Marzinski 	struct gfs2_rgrp_lvb *rgl = rgd->rd_rgl;
111490306c41SBenjamin Marzinski 	struct gfs2_rgrp *str = (struct gfs2_rgrp *)rgd->rd_bits[0].bi_bh->b_data;
1115f29e62eeSBob Peterson 	struct gfs2_sbd *sdp = rgd->rd_sbd;
111672244b6bSBob Peterson 	int valid = 1;
111790306c41SBenjamin Marzinski 
111872244b6bSBob Peterson 	if (rgl->rl_flags != str->rg_flags) {
1119f29e62eeSBob Peterson 		fs_warn(sdp, "GFS2: rgd: %llu lvb flag mismatch %u/%u",
112072244b6bSBob Peterson 			(unsigned long long)rgd->rd_addr,
112172244b6bSBob Peterson 		       be32_to_cpu(rgl->rl_flags), be32_to_cpu(str->rg_flags));
112272244b6bSBob Peterson 		valid = 0;
112372244b6bSBob Peterson 	}
112472244b6bSBob Peterson 	if (rgl->rl_free != str->rg_free) {
1125f29e62eeSBob Peterson 		fs_warn(sdp, "GFS2: rgd: %llu lvb free mismatch %u/%u",
112672244b6bSBob Peterson 			(unsigned long long)rgd->rd_addr,
112772244b6bSBob Peterson 			be32_to_cpu(rgl->rl_free), be32_to_cpu(str->rg_free));
112872244b6bSBob Peterson 		valid = 0;
112972244b6bSBob Peterson 	}
113072244b6bSBob Peterson 	if (rgl->rl_dinodes != str->rg_dinodes) {
1131f29e62eeSBob Peterson 		fs_warn(sdp, "GFS2: rgd: %llu lvb dinode mismatch %u/%u",
113272244b6bSBob Peterson 			(unsigned long long)rgd->rd_addr,
113372244b6bSBob Peterson 			be32_to_cpu(rgl->rl_dinodes),
113472244b6bSBob Peterson 			be32_to_cpu(str->rg_dinodes));
113572244b6bSBob Peterson 		valid = 0;
113672244b6bSBob Peterson 	}
113772244b6bSBob Peterson 	if (rgl->rl_igeneration != str->rg_igeneration) {
1138f29e62eeSBob Peterson 		fs_warn(sdp, "GFS2: rgd: %llu lvb igen mismatch %llu/%llu",
1139f29e62eeSBob Peterson 			(unsigned long long)rgd->rd_addr,
114072244b6bSBob Peterson 			(unsigned long long)be64_to_cpu(rgl->rl_igeneration),
114172244b6bSBob Peterson 			(unsigned long long)be64_to_cpu(str->rg_igeneration));
114272244b6bSBob Peterson 		valid = 0;
114372244b6bSBob Peterson 	}
114472244b6bSBob Peterson 	return valid;
114590306c41SBenjamin Marzinski }
114690306c41SBenjamin Marzinski 
count_unlinked(struct gfs2_rgrpd * rgd)114790306c41SBenjamin Marzinski static u32 count_unlinked(struct gfs2_rgrpd *rgd)
114890306c41SBenjamin Marzinski {
114990306c41SBenjamin Marzinski 	struct gfs2_bitmap *bi;
115090306c41SBenjamin Marzinski 	const u32 length = rgd->rd_length;
115190306c41SBenjamin Marzinski 	const u8 *buffer = NULL;
115290306c41SBenjamin Marzinski 	u32 i, goal, count = 0;
115390306c41SBenjamin Marzinski 
115490306c41SBenjamin Marzinski 	for (i = 0, bi = rgd->rd_bits; i < length; i++, bi++) {
115590306c41SBenjamin Marzinski 		goal = 0;
115690306c41SBenjamin Marzinski 		buffer = bi->bi_bh->b_data + bi->bi_offset;
115790306c41SBenjamin Marzinski 		WARN_ON(!buffer_uptodate(bi->bi_bh));
1158281b4952SAndreas Gruenbacher 		while (goal < bi->bi_blocks) {
1159281b4952SAndreas Gruenbacher 			goal = gfs2_bitfit(buffer, bi->bi_bytes, goal,
116090306c41SBenjamin Marzinski 					   GFS2_BLKST_UNLINKED);
116190306c41SBenjamin Marzinski 			if (goal == BFITNOENT)
116290306c41SBenjamin Marzinski 				break;
116390306c41SBenjamin Marzinski 			count++;
116490306c41SBenjamin Marzinski 			goal++;
116590306c41SBenjamin Marzinski 		}
116690306c41SBenjamin Marzinski 	}
116790306c41SBenjamin Marzinski 
116890306c41SBenjamin Marzinski 	return count;
116990306c41SBenjamin Marzinski }
117090306c41SBenjamin Marzinski 
rgrp_set_bitmap_flags(struct gfs2_rgrpd * rgd)1171560b8ebaSAndreas Gruenbacher static void rgrp_set_bitmap_flags(struct gfs2_rgrpd *rgd)
1172560b8ebaSAndreas Gruenbacher {
1173560b8ebaSAndreas Gruenbacher 	struct gfs2_bitmap *bi;
1174560b8ebaSAndreas Gruenbacher 	int x;
1175560b8ebaSAndreas Gruenbacher 
1176560b8ebaSAndreas Gruenbacher 	if (rgd->rd_free) {
1177560b8ebaSAndreas Gruenbacher 		for (x = 0; x < rgd->rd_length; x++) {
1178560b8ebaSAndreas Gruenbacher 			bi = rgd->rd_bits + x;
1179560b8ebaSAndreas Gruenbacher 			clear_bit(GBF_FULL, &bi->bi_flags);
1180560b8ebaSAndreas Gruenbacher 		}
1181560b8ebaSAndreas Gruenbacher 	} else {
1182560b8ebaSAndreas Gruenbacher 		for (x = 0; x < rgd->rd_length; x++) {
1183560b8ebaSAndreas Gruenbacher 			bi = rgd->rd_bits + x;
1184560b8ebaSAndreas Gruenbacher 			set_bit(GBF_FULL, &bi->bi_flags);
1185560b8ebaSAndreas Gruenbacher 		}
1186560b8ebaSAndreas Gruenbacher 	}
1187560b8ebaSAndreas Gruenbacher }
118890306c41SBenjamin Marzinski 
1189b3b94faaSDavid Teigland /**
11904b3113a2SBob Peterson  * gfs2_rgrp_go_instantiate - Read in a RG's header and bitmaps
11914b3113a2SBob Peterson  * @gh: the glock holder representing the rgrpd to read in
1192b3b94faaSDavid Teigland  *
1193b3b94faaSDavid Teigland  * Read in all of a Resource Group's header and bitmap blocks.
119410283ea5SAndreas Gruenbacher  * Caller must eventually call gfs2_rgrp_brelse() to free the bitmaps.
1195b3b94faaSDavid Teigland  *
1196b3b94faaSDavid Teigland  * Returns: errno
1197b3b94faaSDavid Teigland  */
1198b3b94faaSDavid Teigland 
gfs2_rgrp_go_instantiate(struct gfs2_glock * gl)11995f38a4d3SAndreas Gruenbacher int gfs2_rgrp_go_instantiate(struct gfs2_glock *gl)
1200b3b94faaSDavid Teigland {
12014b3113a2SBob Peterson 	struct gfs2_rgrpd *rgd = gl->gl_object;
1202b3b94faaSDavid Teigland 	struct gfs2_sbd *sdp = rgd->rd_sbd;
1203bb8d8a6fSSteven Whitehouse 	unsigned int length = rgd->rd_length;
1204b3b94faaSDavid Teigland 	struct gfs2_bitmap *bi;
1205b3b94faaSDavid Teigland 	unsigned int x, y;
1206b3b94faaSDavid Teigland 	int error;
1207b3b94faaSDavid Teigland 
120890306c41SBenjamin Marzinski 	if (rgd->rd_bits[0].bi_bh != NULL)
120990306c41SBenjamin Marzinski 		return 0;
121090306c41SBenjamin Marzinski 
1211b3b94faaSDavid Teigland 	for (x = 0; x < length; x++) {
1212b3b94faaSDavid Teigland 		bi = rgd->rd_bits + x;
1213c8d57703SAndreas Gruenbacher 		error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, 0, &bi->bi_bh);
1214b3b94faaSDavid Teigland 		if (error)
1215b3b94faaSDavid Teigland 			goto fail;
1216b3b94faaSDavid Teigland 	}
1217b3b94faaSDavid Teigland 
1218b3b94faaSDavid Teigland 	for (y = length; y--;) {
1219b3b94faaSDavid Teigland 		bi = rgd->rd_bits + y;
12207276b3b0SSteven Whitehouse 		error = gfs2_meta_wait(sdp, bi->bi_bh);
1221b3b94faaSDavid Teigland 		if (error)
1222b3b94faaSDavid Teigland 			goto fail;
1223feaa7bbaSSteven Whitehouse 		if (gfs2_metatype_check(sdp, bi->bi_bh, y ? GFS2_METATYPE_RB :
1224b3b94faaSDavid Teigland 					      GFS2_METATYPE_RG)) {
1225b3b94faaSDavid Teigland 			error = -EIO;
1226b3b94faaSDavid Teigland 			goto fail;
1227b3b94faaSDavid Teigland 		}
1228b3b94faaSDavid Teigland 	}
1229b3b94faaSDavid Teigland 
123042d52e38SBob Peterson 	gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data);
1231560b8ebaSAndreas Gruenbacher 	rgrp_set_bitmap_flags(rgd);
12324b3113a2SBob Peterson 	rgd->rd_flags |= GFS2_RDF_CHECK;
1233cfc8b549SSteven Whitehouse 	rgd->rd_free_clone = rgd->rd_free;
1234c98c2ca5SBob Peterson 	GLOCK_BUG_ON(rgd->rd_gl, rgd->rd_reserved);
12355ea5050cSBob Peterson 	/* max out the rgrp allocation failure point */
12365ea5050cSBob Peterson 	rgd->rd_extfail_pt = rgd->rd_free;
1237951b4bd5SAl Viro 	if (cpu_to_be32(GFS2_MAGIC) != rgd->rd_rgl->rl_magic) {
123890306c41SBenjamin Marzinski 		rgd->rd_rgl->rl_unlinked = cpu_to_be32(count_unlinked(rgd));
123990306c41SBenjamin Marzinski 		gfs2_rgrp_ondisk2lvb(rgd->rd_rgl,
124090306c41SBenjamin Marzinski 				     rgd->rd_bits[0].bi_bh->b_data);
1241f2e70d8fSBob Peterson 	} else if (sdp->sd_args.ar_rgrplvb) {
124290306c41SBenjamin Marzinski 		if (!gfs2_rgrp_lvb_valid(rgd)){
124390306c41SBenjamin Marzinski 			gfs2_consist_rgrpd(rgd);
124490306c41SBenjamin Marzinski 			error = -EIO;
124590306c41SBenjamin Marzinski 			goto fail;
124690306c41SBenjamin Marzinski 		}
124790306c41SBenjamin Marzinski 		if (rgd->rd_rgl->rl_unlinked == 0)
124890306c41SBenjamin Marzinski 			rgd->rd_flags &= ~GFS2_RDF_CHECK;
124990306c41SBenjamin Marzinski 	}
1250b3b94faaSDavid Teigland 	return 0;
1251b3b94faaSDavid Teigland 
1252b3b94faaSDavid Teigland fail:
1253b3b94faaSDavid Teigland 	while (x--) {
1254b3b94faaSDavid Teigland 		bi = rgd->rd_bits + x;
1255b3b94faaSDavid Teigland 		brelse(bi->bi_bh);
1256b3b94faaSDavid Teigland 		bi->bi_bh = NULL;
1257b3b94faaSDavid Teigland 		gfs2_assert_warn(sdp, !bi->bi_clone);
1258b3b94faaSDavid Teigland 	}
1259b3b94faaSDavid Teigland 	return error;
1260b3b94faaSDavid Teigland }
1261b3b94faaSDavid Teigland 
update_rgrp_lvb(struct gfs2_rgrpd * rgd,struct gfs2_holder * gh)1262f2e70d8fSBob Peterson static int update_rgrp_lvb(struct gfs2_rgrpd *rgd, struct gfs2_holder *gh)
126390306c41SBenjamin Marzinski {
126490306c41SBenjamin Marzinski 	u32 rl_flags;
126590306c41SBenjamin Marzinski 
12664b3113a2SBob Peterson 	if (!test_bit(GLF_INSTANTIATE_NEEDED, &gh->gh_gl->gl_flags))
126790306c41SBenjamin Marzinski 		return 0;
126890306c41SBenjamin Marzinski 
1269951b4bd5SAl Viro 	if (cpu_to_be32(GFS2_MAGIC) != rgd->rd_rgl->rl_magic)
1270f2e70d8fSBob Peterson 		return gfs2_instantiate(gh);
127190306c41SBenjamin Marzinski 
127290306c41SBenjamin Marzinski 	rl_flags = be32_to_cpu(rgd->rd_rgl->rl_flags);
127390306c41SBenjamin Marzinski 	rl_flags &= ~GFS2_RDF_MASK;
127490306c41SBenjamin Marzinski 	rgd->rd_flags &= GFS2_RDF_MASK;
12754f36cb36SBob Peterson 	rgd->rd_flags |= (rl_flags | GFS2_RDF_CHECK);
127690306c41SBenjamin Marzinski 	if (rgd->rd_rgl->rl_unlinked == 0)
127790306c41SBenjamin Marzinski 		rgd->rd_flags &= ~GFS2_RDF_CHECK;
127890306c41SBenjamin Marzinski 	rgd->rd_free = be32_to_cpu(rgd->rd_rgl->rl_free);
1279560b8ebaSAndreas Gruenbacher 	rgrp_set_bitmap_flags(rgd);
128090306c41SBenjamin Marzinski 	rgd->rd_free_clone = rgd->rd_free;
1281c98c2ca5SBob Peterson 	GLOCK_BUG_ON(rgd->rd_gl, rgd->rd_reserved);
1282f38e998fSAndreas Gruenbacher 	/* max out the rgrp allocation failure point */
1283f38e998fSAndreas Gruenbacher 	rgd->rd_extfail_pt = rgd->rd_free;
128490306c41SBenjamin Marzinski 	rgd->rd_dinodes = be32_to_cpu(rgd->rd_rgl->rl_dinodes);
128590306c41SBenjamin Marzinski 	rgd->rd_igeneration = be64_to_cpu(rgd->rd_rgl->rl_igeneration);
128690306c41SBenjamin Marzinski 	return 0;
128790306c41SBenjamin Marzinski }
128890306c41SBenjamin Marzinski 
1289b3b94faaSDavid Teigland /**
129039b0f1e9SBob Peterson  * gfs2_rgrp_brelse - Release RG bitmaps read in with gfs2_rgrp_bh_get()
129139b0f1e9SBob Peterson  * @rgd: The resource group
1292b3b94faaSDavid Teigland  *
1293b3b94faaSDavid Teigland  */
1294b3b94faaSDavid Teigland 
gfs2_rgrp_brelse(struct gfs2_rgrpd * rgd)129539b0f1e9SBob Peterson void gfs2_rgrp_brelse(struct gfs2_rgrpd *rgd)
1296b3b94faaSDavid Teigland {
1297bb8d8a6fSSteven Whitehouse 	int x, length = rgd->rd_length;
1298b3b94faaSDavid Teigland 
1299b3b94faaSDavid Teigland 	for (x = 0; x < length; x++) {
1300b3b94faaSDavid Teigland 		struct gfs2_bitmap *bi = rgd->rd_bits + x;
130190306c41SBenjamin Marzinski 		if (bi->bi_bh) {
1302b3b94faaSDavid Teigland 			brelse(bi->bi_bh);
1303b3b94faaSDavid Teigland 			bi->bi_bh = NULL;
1304b3b94faaSDavid Teigland 		}
130590306c41SBenjamin Marzinski 	}
1306f2e70d8fSBob Peterson 	set_bit(GLF_INSTANTIATE_NEEDED, &rgd->rd_gl->gl_flags);
130739b0f1e9SBob Peterson }
130839b0f1e9SBob Peterson 
gfs2_rgrp_send_discards(struct gfs2_sbd * sdp,u64 offset,struct buffer_head * bh,const struct gfs2_bitmap * bi,unsigned minlen,u64 * ptrimmed)130966fc061bSSteven Whitehouse int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
13107c9ca621SBob Peterson 			     struct buffer_head *bh,
131166fc061bSSteven Whitehouse 			     const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed)
1312f15ab561SSteven Whitehouse {
1313f15ab561SSteven Whitehouse 	struct super_block *sb = sdp->sd_vfs;
1314f15ab561SSteven Whitehouse 	u64 blk;
131564d576baSSteven Whitehouse 	sector_t start = 0;
1316b2c87caeSBob Peterson 	sector_t nr_blks = 0;
1317f4a47561SAndrew Price 	int rv = -EIO;
1318f15ab561SSteven Whitehouse 	unsigned int x;
131966fc061bSSteven Whitehouse 	u32 trimmed = 0;
132066fc061bSSteven Whitehouse 	u8 diff;
1321f15ab561SSteven Whitehouse 
1322281b4952SAndreas Gruenbacher 	for (x = 0; x < bi->bi_bytes; x++) {
132366fc061bSSteven Whitehouse 		const u8 *clone = bi->bi_clone ? bi->bi_clone : bi->bi_bh->b_data;
132466fc061bSSteven Whitehouse 		clone += bi->bi_offset;
132566fc061bSSteven Whitehouse 		clone += x;
132666fc061bSSteven Whitehouse 		if (bh) {
13277c9ca621SBob Peterson 			const u8 *orig = bh->b_data + bi->bi_offset + x;
132866fc061bSSteven Whitehouse 			diff = ~(*orig | (*orig >> 1)) & (*clone | (*clone >> 1));
132966fc061bSSteven Whitehouse 		} else {
133066fc061bSSteven Whitehouse 			diff = ~(*clone | (*clone >> 1));
133166fc061bSSteven Whitehouse 		}
1332f15ab561SSteven Whitehouse 		diff &= 0x55;
1333f15ab561SSteven Whitehouse 		if (diff == 0)
1334f15ab561SSteven Whitehouse 			continue;
1335f15ab561SSteven Whitehouse 		blk = offset + ((bi->bi_start + x) * GFS2_NBBY);
1336f15ab561SSteven Whitehouse 		while(diff) {
1337f15ab561SSteven Whitehouse 			if (diff & 1) {
1338b2c87caeSBob Peterson 				if (nr_blks == 0)
1339f15ab561SSteven Whitehouse 					goto start_new_extent;
1340b2c87caeSBob Peterson 				if ((start + nr_blks) != blk) {
1341b2c87caeSBob Peterson 					if (nr_blks >= minlen) {
1342b2c87caeSBob Peterson 						rv = sb_issue_discard(sb,
1343b2c87caeSBob Peterson 							start, nr_blks,
134466fc061bSSteven Whitehouse 							GFP_NOFS, 0);
1345f15ab561SSteven Whitehouse 						if (rv)
1346f15ab561SSteven Whitehouse 							goto fail;
1347b2c87caeSBob Peterson 						trimmed += nr_blks;
134866fc061bSSteven Whitehouse 					}
1349b2c87caeSBob Peterson 					nr_blks = 0;
1350f15ab561SSteven Whitehouse start_new_extent:
1351f15ab561SSteven Whitehouse 					start = blk;
1352f15ab561SSteven Whitehouse 				}
1353b2c87caeSBob Peterson 				nr_blks++;
1354f15ab561SSteven Whitehouse 			}
1355f15ab561SSteven Whitehouse 			diff >>= 2;
1356b2c87caeSBob Peterson 			blk++;
1357f15ab561SSteven Whitehouse 		}
1358f15ab561SSteven Whitehouse 	}
1359b2c87caeSBob Peterson 	if (nr_blks >= minlen) {
1360b2c87caeSBob Peterson 		rv = sb_issue_discard(sb, start, nr_blks, GFP_NOFS, 0);
1361f15ab561SSteven Whitehouse 		if (rv)
1362f15ab561SSteven Whitehouse 			goto fail;
1363b2c87caeSBob Peterson 		trimmed += nr_blks;
1364f15ab561SSteven Whitehouse 	}
136566fc061bSSteven Whitehouse 	if (ptrimmed)
136666fc061bSSteven Whitehouse 		*ptrimmed = trimmed;
136766fc061bSSteven Whitehouse 	return 0;
136866fc061bSSteven Whitehouse 
1369f15ab561SSteven Whitehouse fail:
137066fc061bSSteven Whitehouse 	if (sdp->sd_args.ar_discard)
1371af38816eSAndreas Gruenbacher 		fs_warn(sdp, "error %d on discard request, turning discards off for this filesystem\n", rv);
1372f15ab561SSteven Whitehouse 	sdp->sd_args.ar_discard = 0;
1373f4a47561SAndrew Price 	return rv;
137466fc061bSSteven Whitehouse }
137566fc061bSSteven Whitehouse 
137666fc061bSSteven Whitehouse /**
137766fc061bSSteven Whitehouse  * gfs2_fitrim - Generate discard requests for unused bits of the filesystem
137866fc061bSSteven Whitehouse  * @filp: Any file on the filesystem
137966fc061bSSteven Whitehouse  * @argp: Pointer to the arguments (also used to pass result)
138066fc061bSSteven Whitehouse  *
138166fc061bSSteven Whitehouse  * Returns: 0 on success, otherwise error code
138266fc061bSSteven Whitehouse  */
138366fc061bSSteven Whitehouse 
gfs2_fitrim(struct file * filp,void __user * argp)138466fc061bSSteven Whitehouse int gfs2_fitrim(struct file *filp, void __user *argp)
138566fc061bSSteven Whitehouse {
1386496ad9aaSAl Viro 	struct inode *inode = file_inode(filp);
138766fc061bSSteven Whitehouse 	struct gfs2_sbd *sdp = GFS2_SB(inode);
13887b47ef52SChristoph Hellwig 	struct block_device *bdev = sdp->sd_vfs->s_bdev;
138966fc061bSSteven Whitehouse 	struct buffer_head *bh;
139066fc061bSSteven Whitehouse 	struct gfs2_rgrpd *rgd;
139166fc061bSSteven Whitehouse 	struct gfs2_rgrpd *rgd_end;
139266fc061bSSteven Whitehouse 	struct gfs2_holder gh;
139366fc061bSSteven Whitehouse 	struct fstrim_range r;
139466fc061bSSteven Whitehouse 	int ret = 0;
139566fc061bSSteven Whitehouse 	u64 amt;
139666fc061bSSteven Whitehouse 	u64 trimmed = 0;
1397076f0faaSLukas Czerner 	u64 start, end, minlen;
139866fc061bSSteven Whitehouse 	unsigned int x;
1399076f0faaSLukas Czerner 	unsigned bs_shift = sdp->sd_sb.sb_bsize_shift;
140066fc061bSSteven Whitehouse 
140166fc061bSSteven Whitehouse 	if (!capable(CAP_SYS_ADMIN))
140266fc061bSSteven Whitehouse 		return -EPERM;
140366fc061bSSteven Whitehouse 
1404c5c68724SBob Peterson 	if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))
1405c5c68724SBob Peterson 		return -EROFS;
1406c5c68724SBob Peterson 
14077b47ef52SChristoph Hellwig 	if (!bdev_max_discard_sectors(bdev))
140866fc061bSSteven Whitehouse 		return -EOPNOTSUPP;
140966fc061bSSteven Whitehouse 
14103a238adeSLukas Czerner 	if (copy_from_user(&r, argp, sizeof(r)))
141166fc061bSSteven Whitehouse 		return -EFAULT;
141266fc061bSSteven Whitehouse 
14135e2f7d61SBob Peterson 	ret = gfs2_rindex_update(sdp);
14145e2f7d61SBob Peterson 	if (ret)
14155e2f7d61SBob Peterson 		return ret;
14165e2f7d61SBob Peterson 
1417076f0faaSLukas Czerner 	start = r.start >> bs_shift;
1418076f0faaSLukas Czerner 	end = start + (r.len >> bs_shift);
141927ca8273SAndrew Price 	minlen = max_t(u64, r.minlen, sdp->sd_sb.sb_bsize);
14207b47ef52SChristoph Hellwig 	minlen = max_t(u64, minlen, bdev_discard_granularity(bdev)) >> bs_shift;
1421076f0faaSLukas Czerner 
14226a98c333SAbhijith Das 	if (end <= start || minlen > sdp->sd_max_rg_data)
1423076f0faaSLukas Czerner 		return -EINVAL;
142466fc061bSSteven Whitehouse 
14256a98c333SAbhijith Das 	rgd = gfs2_blk2rgrpd(sdp, start, 0);
14266a98c333SAbhijith Das 	rgd_end = gfs2_blk2rgrpd(sdp, end, 0);
14276a98c333SAbhijith Das 
14286a98c333SAbhijith Das 	if ((gfs2_rgrpd_get_first(sdp) == gfs2_rgrpd_get_next(rgd_end))
14296a98c333SAbhijith Das 	    && (start > rgd_end->rd_data0 + rgd_end->rd_data))
14306a98c333SAbhijith Das 		return -EINVAL; /* start is beyond the end of the fs */
14316a98c333SAbhijith Das 
143266fc061bSSteven Whitehouse 	while (1) {
143366fc061bSSteven Whitehouse 
14344fc7ec31SBob Peterson 		ret = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE,
14354fc7ec31SBob Peterson 					 LM_FLAG_NODE_SCOPE, &gh);
143666fc061bSSteven Whitehouse 		if (ret)
143766fc061bSSteven Whitehouse 			goto out;
143866fc061bSSteven Whitehouse 
143966fc061bSSteven Whitehouse 		if (!(rgd->rd_flags & GFS2_RGF_TRIMMED)) {
144066fc061bSSteven Whitehouse 			/* Trim each bitmap in the rgrp */
144166fc061bSSteven Whitehouse 			for (x = 0; x < rgd->rd_length; x++) {
144266fc061bSSteven Whitehouse 				struct gfs2_bitmap *bi = rgd->rd_bits + x;
14439e514605SAndreas Gruenbacher 				rgrp_lock_local(rgd);
1444076f0faaSLukas Czerner 				ret = gfs2_rgrp_send_discards(sdp,
1445076f0faaSLukas Czerner 						rgd->rd_data0, NULL, bi, minlen,
1446076f0faaSLukas Czerner 						&amt);
14479e514605SAndreas Gruenbacher 				rgrp_unlock_local(rgd);
144866fc061bSSteven Whitehouse 				if (ret) {
144966fc061bSSteven Whitehouse 					gfs2_glock_dq_uninit(&gh);
145066fc061bSSteven Whitehouse 					goto out;
145166fc061bSSteven Whitehouse 				}
145266fc061bSSteven Whitehouse 				trimmed += amt;
145366fc061bSSteven Whitehouse 			}
145466fc061bSSteven Whitehouse 
145566fc061bSSteven Whitehouse 			/* Mark rgrp as having been trimmed */
145666fc061bSSteven Whitehouse 			ret = gfs2_trans_begin(sdp, RES_RG_HDR, 0);
145766fc061bSSteven Whitehouse 			if (ret == 0) {
145866fc061bSSteven Whitehouse 				bh = rgd->rd_bits[0].bi_bh;
14599e514605SAndreas Gruenbacher 				rgrp_lock_local(rgd);
146066fc061bSSteven Whitehouse 				rgd->rd_flags |= GFS2_RGF_TRIMMED;
1461350a9b0aSSteven Whitehouse 				gfs2_trans_add_meta(rgd->rd_gl, bh);
146266fc061bSSteven Whitehouse 				gfs2_rgrp_out(rgd, bh->b_data);
14639e514605SAndreas Gruenbacher 				rgrp_unlock_local(rgd);
146466fc061bSSteven Whitehouse 				gfs2_trans_end(sdp);
146566fc061bSSteven Whitehouse 			}
146666fc061bSSteven Whitehouse 		}
146766fc061bSSteven Whitehouse 		gfs2_glock_dq_uninit(&gh);
146866fc061bSSteven Whitehouse 
146966fc061bSSteven Whitehouse 		if (rgd == rgd_end)
147066fc061bSSteven Whitehouse 			break;
147166fc061bSSteven Whitehouse 
147266fc061bSSteven Whitehouse 		rgd = gfs2_rgrpd_get_next(rgd);
147366fc061bSSteven Whitehouse 	}
147466fc061bSSteven Whitehouse 
147566fc061bSSteven Whitehouse out:
14766a98c333SAbhijith Das 	r.len = trimmed << bs_shift;
14773a238adeSLukas Czerner 	if (copy_to_user(argp, &r, sizeof(r)))
147866fc061bSSteven Whitehouse 		return -EFAULT;
147966fc061bSSteven Whitehouse 
148066fc061bSSteven Whitehouse 	return ret;
1481f15ab561SSteven Whitehouse }
1482f15ab561SSteven Whitehouse 
1483b3b94faaSDavid Teigland /**
14848e2e0047SBob Peterson  * rs_insert - insert a new multi-block reservation into the rgrp's rb_tree
14858e2e0047SBob Peterson  * @ip: the inode structure
14868e2e0047SBob Peterson  *
14878e2e0047SBob Peterson  */
rs_insert(struct gfs2_inode * ip)1488ff7f4cb4SSteven Whitehouse static void rs_insert(struct gfs2_inode *ip)
14898e2e0047SBob Peterson {
14908e2e0047SBob Peterson 	struct rb_node **newn, *parent = NULL;
14918e2e0047SBob Peterson 	int rc;
1492a097dc7eSBob Peterson 	struct gfs2_blkreserv *rs = &ip->i_res;
1493c65b76b8SAndreas Gruenbacher 	struct gfs2_rgrpd *rgd = rs->rs_rgd;
1494ff7f4cb4SSteven Whitehouse 
1495ff7f4cb4SSteven Whitehouse 	BUG_ON(gfs2_rs_active(rs));
14968e2e0047SBob Peterson 
14978e2e0047SBob Peterson 	spin_lock(&rgd->rd_rsspin);
14988e2e0047SBob Peterson 	newn = &rgd->rd_rstree.rb_node;
14998e2e0047SBob Peterson 	while (*newn) {
15008e2e0047SBob Peterson 		struct gfs2_blkreserv *cur =
15018e2e0047SBob Peterson 			rb_entry(*newn, struct gfs2_blkreserv, rs_node);
15028e2e0047SBob Peterson 
15038e2e0047SBob Peterson 		parent = *newn;
150407974d2aSAndreas Gruenbacher 		rc = rs_cmp(rs->rs_start, rs->rs_requested, cur);
15058e2e0047SBob Peterson 		if (rc > 0)
15068e2e0047SBob Peterson 			newn = &((*newn)->rb_right);
15078e2e0047SBob Peterson 		else if (rc < 0)
15088e2e0047SBob Peterson 			newn = &((*newn)->rb_left);
15098e2e0047SBob Peterson 		else {
15108e2e0047SBob Peterson 			spin_unlock(&rgd->rd_rsspin);
1511ff7f4cb4SSteven Whitehouse 			WARN_ON(1);
1512ff7f4cb4SSteven Whitehouse 			return;
15138e2e0047SBob Peterson 		}
15148e2e0047SBob Peterson 	}
15158e2e0047SBob Peterson 
15168e2e0047SBob Peterson 	rb_link_node(&rs->rs_node, parent, newn);
15178e2e0047SBob Peterson 	rb_insert_color(&rs->rs_node, &rgd->rd_rstree);
15188e2e0047SBob Peterson 
15198e2e0047SBob Peterson 	/* Do our rgrp accounting for the reservation */
152007974d2aSAndreas Gruenbacher 	rgd->rd_requested += rs->rs_requested; /* blocks requested */
15218e2e0047SBob Peterson 	spin_unlock(&rgd->rd_rsspin);
15229e733d39SSteven Whitehouse 	trace_gfs2_rs(rs, TRACE_RS_INSERT);
15238e2e0047SBob Peterson }
15248e2e0047SBob Peterson 
15258e2e0047SBob Peterson /**
1526c551f66cSLee Jones  * rgd_free - return the number of free blocks we can allocate
1527f6753df3SBob Peterson  * @rgd: the resource group
1528c551f66cSLee Jones  * @rs: The reservation to free
1529f6753df3SBob Peterson  *
1530f6753df3SBob Peterson  * This function returns the number of free blocks for an rgrp.
1531f6753df3SBob Peterson  * That's the clone-free blocks (blocks that are free, not including those
1532f6753df3SBob Peterson  * still being used for unlinked files that haven't been deleted.)
1533f6753df3SBob Peterson  *
1534f6753df3SBob Peterson  * It also subtracts any blocks reserved by someone else, but does not
1535f6753df3SBob Peterson  * include free blocks that are still part of our current reservation,
1536f6753df3SBob Peterson  * because obviously we can (and will) allocate them.
1537f6753df3SBob Peterson  */
rgd_free(struct gfs2_rgrpd * rgd,struct gfs2_blkreserv * rs)1538f6753df3SBob Peterson static inline u32 rgd_free(struct gfs2_rgrpd *rgd, struct gfs2_blkreserv *rs)
1539f6753df3SBob Peterson {
1540f6753df3SBob Peterson 	u32 tot_reserved, tot_free;
1541f6753df3SBob Peterson 
154207974d2aSAndreas Gruenbacher 	if (WARN_ON_ONCE(rgd->rd_requested < rs->rs_requested))
1543f6753df3SBob Peterson 		return 0;
154407974d2aSAndreas Gruenbacher 	tot_reserved = rgd->rd_requested - rs->rs_requested;
1545f6753df3SBob Peterson 
1546f6753df3SBob Peterson 	if (rgd->rd_free_clone < tot_reserved)
1547f6753df3SBob Peterson 		tot_reserved = 0;
1548f6753df3SBob Peterson 
1549f6753df3SBob Peterson 	tot_free = rgd->rd_free_clone - tot_reserved;
1550f6753df3SBob Peterson 
1551f6753df3SBob Peterson 	return tot_free;
1552f6753df3SBob Peterson }
1553f6753df3SBob Peterson 
1554f6753df3SBob Peterson /**
1555ff7f4cb4SSteven Whitehouse  * rg_mblk_search - find a group of multiple free blocks to form a reservation
15568e2e0047SBob Peterson  * @rgd: the resource group descriptor
15578e2e0047SBob Peterson  * @ip: pointer to the inode for which we're reserving blocks
15587b9cff46SSteven Whitehouse  * @ap: the allocation parameters
15598e2e0047SBob Peterson  *
15608e2e0047SBob Peterson  */
15618e2e0047SBob Peterson 
rg_mblk_search(struct gfs2_rgrpd * rgd,struct gfs2_inode * ip,const struct gfs2_alloc_parms * ap)1562ff7f4cb4SSteven Whitehouse static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip,
15637b9cff46SSteven Whitehouse 			   const struct gfs2_alloc_parms *ap)
15648e2e0047SBob Peterson {
1565ff7f4cb4SSteven Whitehouse 	struct gfs2_rbm rbm = { .rgd = rgd, };
1566ff7f4cb4SSteven Whitehouse 	u64 goal;
1567a097dc7eSBob Peterson 	struct gfs2_blkreserv *rs = &ip->i_res;
1568ff7f4cb4SSteven Whitehouse 	u32 extlen;
1569725d0e9dSAndreas Gruenbacher 	u32 free_blocks, blocks_available;
1570ff7f4cb4SSteven Whitehouse 	int ret;
1571af21ca8eSBob Peterson 	struct inode *inode = &ip->i_inode;
15728e2e0047SBob Peterson 
1573725d0e9dSAndreas Gruenbacher 	spin_lock(&rgd->rd_rsspin);
1574725d0e9dSAndreas Gruenbacher 	free_blocks = rgd_free(rgd, rs);
1575725d0e9dSAndreas Gruenbacher 	if (rgd->rd_free_clone < rgd->rd_requested)
1576725d0e9dSAndreas Gruenbacher 		free_blocks = 0;
1577725d0e9dSAndreas Gruenbacher 	blocks_available = rgd->rd_free_clone - rgd->rd_reserved;
1578725d0e9dSAndreas Gruenbacher 	if (rgd == rs->rs_rgd)
1579725d0e9dSAndreas Gruenbacher 		blocks_available += rs->rs_reserved;
1580725d0e9dSAndreas Gruenbacher 	spin_unlock(&rgd->rd_rsspin);
1581725d0e9dSAndreas Gruenbacher 
1582af21ca8eSBob Peterson 	if (S_ISDIR(inode->i_mode))
1583af21ca8eSBob Peterson 		extlen = 1;
1584af21ca8eSBob Peterson 	else {
158521f09c43SAndreas Gruenbacher 		extlen = max_t(u32, atomic_read(&ip->i_sizehint), ap->target);
1586ad899458SAndreas Gruenbacher 		extlen = clamp(extlen, (u32)RGRP_RSRV_MINBLKS, free_blocks);
1587af21ca8eSBob Peterson 	}
1588725d0e9dSAndreas Gruenbacher 	if (free_blocks < extlen || blocks_available < extlen)
1589c743ffd0SSteven Whitehouse 		return;
1590c743ffd0SSteven Whitehouse 
15918e2e0047SBob Peterson 	/* Find bitmap block that contains bits for goal block */
15928e2e0047SBob Peterson 	if (rgrp_contains_block(rgd, ip->i_goal))
1593ff7f4cb4SSteven Whitehouse 		goal = ip->i_goal;
15948e2e0047SBob Peterson 	else
1595ff7f4cb4SSteven Whitehouse 		goal = rgd->rd_last_alloc + rgd->rd_data0;
1596c743ffd0SSteven Whitehouse 
1597ff7f4cb4SSteven Whitehouse 	if (WARN_ON(gfs2_rbm_from_block(&rbm, goal)))
1598c743ffd0SSteven Whitehouse 		return;
1599ff7f4cb4SSteven Whitehouse 
16003d39fcd1SAndreas Gruenbacher 	ret = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, &extlen, &ip->i_res, true);
1601ff7f4cb4SSteven Whitehouse 	if (ret == 0) {
1602c65b76b8SAndreas Gruenbacher 		rs->rs_start = gfs2_rbm_to_block(&rbm);
160307974d2aSAndreas Gruenbacher 		rs->rs_requested = extlen;
1604ff7f4cb4SSteven Whitehouse 		rs_insert(ip);
160513d2eb01SBob Peterson 	} else {
160613d2eb01SBob Peterson 		if (goal == rgd->rd_last_alloc + rgd->rd_data0)
160713d2eb01SBob Peterson 			rgd->rd_last_alloc = 0;
16088e2e0047SBob Peterson 	}
1609b3e47ca0SBob Peterson }
1610b3e47ca0SBob Peterson 
1611b3b94faaSDavid Teigland /**
16125b924ae2SSteven Whitehouse  * gfs2_next_unreserved_block - Return next block that is not reserved
16135b924ae2SSteven Whitehouse  * @rgd: The resource group
16145b924ae2SSteven Whitehouse  * @block: The starting block
1615ff7f4cb4SSteven Whitehouse  * @length: The required length
16163d39fcd1SAndreas Gruenbacher  * @ignore_rs: Reservation to ignore
16175b924ae2SSteven Whitehouse  *
16185b924ae2SSteven Whitehouse  * If the block does not appear in any reservation, then return the
16195b924ae2SSteven Whitehouse  * block number unchanged. If it does appear in the reservation, then
16205b924ae2SSteven Whitehouse  * keep looking through the tree of reservations in order to find the
16215b924ae2SSteven Whitehouse  * first block number which is not reserved.
16225b924ae2SSteven Whitehouse  */
16235b924ae2SSteven Whitehouse 
gfs2_next_unreserved_block(struct gfs2_rgrpd * rgd,u64 block,u32 length,struct gfs2_blkreserv * ignore_rs)16245b924ae2SSteven Whitehouse static u64 gfs2_next_unreserved_block(struct gfs2_rgrpd *rgd, u64 block,
1625ff7f4cb4SSteven Whitehouse 				      u32 length,
16263d39fcd1SAndreas Gruenbacher 				      struct gfs2_blkreserv *ignore_rs)
16275b924ae2SSteven Whitehouse {
16285b924ae2SSteven Whitehouse 	struct gfs2_blkreserv *rs;
16295b924ae2SSteven Whitehouse 	struct rb_node *n;
16305b924ae2SSteven Whitehouse 	int rc;
16315b924ae2SSteven Whitehouse 
16325b924ae2SSteven Whitehouse 	spin_lock(&rgd->rd_rsspin);
1633ff7f4cb4SSteven Whitehouse 	n = rgd->rd_rstree.rb_node;
16345b924ae2SSteven Whitehouse 	while (n) {
16355b924ae2SSteven Whitehouse 		rs = rb_entry(n, struct gfs2_blkreserv, rs_node);
1636ff7f4cb4SSteven Whitehouse 		rc = rs_cmp(block, length, rs);
16375b924ae2SSteven Whitehouse 		if (rc < 0)
16385b924ae2SSteven Whitehouse 			n = n->rb_left;
16395b924ae2SSteven Whitehouse 		else if (rc > 0)
16405b924ae2SSteven Whitehouse 			n = n->rb_right;
16415b924ae2SSteven Whitehouse 		else
16425b924ae2SSteven Whitehouse 			break;
16435b924ae2SSteven Whitehouse 	}
16445b924ae2SSteven Whitehouse 
16455b924ae2SSteven Whitehouse 	if (n) {
16463d39fcd1SAndreas Gruenbacher 		while (rs_cmp(block, length, rs) == 0 && rs != ignore_rs) {
164707974d2aSAndreas Gruenbacher 			block = rs->rs_start + rs->rs_requested;
1648ff7f4cb4SSteven Whitehouse 			n = n->rb_right;
16495b924ae2SSteven Whitehouse 			if (n == NULL)
16505b924ae2SSteven Whitehouse 				break;
16515b924ae2SSteven Whitehouse 			rs = rb_entry(n, struct gfs2_blkreserv, rs_node);
16525b924ae2SSteven Whitehouse 		}
16535b924ae2SSteven Whitehouse 	}
16545b924ae2SSteven Whitehouse 
16555b924ae2SSteven Whitehouse 	spin_unlock(&rgd->rd_rsspin);
16565b924ae2SSteven Whitehouse 	return block;
16575b924ae2SSteven Whitehouse }
16585b924ae2SSteven Whitehouse 
16595b924ae2SSteven Whitehouse /**
16605b924ae2SSteven Whitehouse  * gfs2_reservation_check_and_update - Check for reservations during block alloc
16615b924ae2SSteven Whitehouse  * @rbm: The current position in the resource group
16623d39fcd1SAndreas Gruenbacher  * @rs: Our own reservation
1663ff7f4cb4SSteven Whitehouse  * @minext: The minimum extent length
16645ce13431SBob Peterson  * @maxext: A pointer to the maximum extent structure
16655b924ae2SSteven Whitehouse  *
16665b924ae2SSteven Whitehouse  * This checks the current position in the rgrp to see whether there is
16675b924ae2SSteven Whitehouse  * a reservation covering this block. If not then this function is a
16685b924ae2SSteven Whitehouse  * no-op. If there is, then the position is moved to the end of the
16695b924ae2SSteven Whitehouse  * contiguous reservation(s) so that we are pointing at the first
16705b924ae2SSteven Whitehouse  * non-reserved block.
16715b924ae2SSteven Whitehouse  *
16725b924ae2SSteven Whitehouse  * Returns: 0 if no reservation, 1 if @rbm has changed, otherwise an error
16735b924ae2SSteven Whitehouse  */
16745b924ae2SSteven Whitehouse 
gfs2_reservation_check_and_update(struct gfs2_rbm * rbm,struct gfs2_blkreserv * rs,u32 minext,struct gfs2_extent * maxext)16755b924ae2SSteven Whitehouse static int gfs2_reservation_check_and_update(struct gfs2_rbm *rbm,
16763d39fcd1SAndreas Gruenbacher 					     struct gfs2_blkreserv *rs,
16775ce13431SBob Peterson 					     u32 minext,
16785ce13431SBob Peterson 					     struct gfs2_extent *maxext)
16795b924ae2SSteven Whitehouse {
16805b924ae2SSteven Whitehouse 	u64 block = gfs2_rbm_to_block(rbm);
1681ff7f4cb4SSteven Whitehouse 	u32 extlen = 1;
16825b924ae2SSteven Whitehouse 	u64 nblock;
16835b924ae2SSteven Whitehouse 
1684ff7f4cb4SSteven Whitehouse 	/*
1685ff7f4cb4SSteven Whitehouse 	 * If we have a minimum extent length, then skip over any extent
1686ff7f4cb4SSteven Whitehouse 	 * which is less than the min extent length in size.
1687ff7f4cb4SSteven Whitehouse 	 */
1688f38e998fSAndreas Gruenbacher 	if (minext > 1) {
1689ff7f4cb4SSteven Whitehouse 		extlen = gfs2_free_extlen(rbm, minext);
16905ce13431SBob Peterson 		if (extlen <= maxext->len)
1691ff7f4cb4SSteven Whitehouse 			goto fail;
1692ff7f4cb4SSteven Whitehouse 	}
1693ff7f4cb4SSteven Whitehouse 
1694ff7f4cb4SSteven Whitehouse 	/*
1695ff7f4cb4SSteven Whitehouse 	 * Check the extent which has been found against the reservations
1696ff7f4cb4SSteven Whitehouse 	 * and skip if parts of it are already reserved
1697ff7f4cb4SSteven Whitehouse 	 */
16983d39fcd1SAndreas Gruenbacher 	nblock = gfs2_next_unreserved_block(rbm->rgd, block, extlen, rs);
16995ce13431SBob Peterson 	if (nblock == block) {
17005ce13431SBob Peterson 		if (!minext || extlen >= minext)
17015b924ae2SSteven Whitehouse 			return 0;
17025ce13431SBob Peterson 
17035ce13431SBob Peterson 		if (extlen > maxext->len) {
17045ce13431SBob Peterson 			maxext->len = extlen;
17055ce13431SBob Peterson 			maxext->rbm = *rbm;
17065ce13431SBob Peterson 		}
17070eacdd16SAndreas Gruenbacher 	} else {
17080eacdd16SAndreas Gruenbacher 		u64 len = nblock - block;
17090eacdd16SAndreas Gruenbacher 		if (len >= (u64)1 << 32)
17100eacdd16SAndreas Gruenbacher 			return -E2BIG;
17110eacdd16SAndreas Gruenbacher 		extlen = len;
17125ce13431SBob Peterson 	}
17130eacdd16SAndreas Gruenbacher fail:
17140eacdd16SAndreas Gruenbacher 	if (gfs2_rbm_add(rbm, extlen))
17150eacdd16SAndreas Gruenbacher 		return -E2BIG;
17165b924ae2SSteven Whitehouse 	return 1;
17175b924ae2SSteven Whitehouse }
17185b924ae2SSteven Whitehouse 
17195b924ae2SSteven Whitehouse /**
17205b924ae2SSteven Whitehouse  * gfs2_rbm_find - Look for blocks of a particular state
17215b924ae2SSteven Whitehouse  * @rbm: Value/result starting position and final position
17225b924ae2SSteven Whitehouse  * @state: The state which we want to find
1723f38e998fSAndreas Gruenbacher  * @minext: Pointer to the requested extent length
17245ce13431SBob Peterson  *          This is updated to be the actual reservation size.
17253d39fcd1SAndreas Gruenbacher  * @rs: Our own reservation (NULL to skip checking for reservations)
17265b924ae2SSteven Whitehouse  * @nowrap: Stop looking at the end of the rgrp, rather than wrapping
17275b924ae2SSteven Whitehouse  *          around until we've reached the starting point.
17285b924ae2SSteven Whitehouse  *
17295b924ae2SSteven Whitehouse  * Side effects:
17305b924ae2SSteven Whitehouse  * - If looking for free blocks, we set GBF_FULL on each bitmap which
17315b924ae2SSteven Whitehouse  *   has no free blocks in it.
17325ea5050cSBob Peterson  * - If looking for free blocks, we set rd_extfail_pt on each rgrp which
17335ea5050cSBob Peterson  *   has come up short on a free block search.
17345b924ae2SSteven Whitehouse  *
17355b924ae2SSteven Whitehouse  * Returns: 0 on success, -ENOSPC if there is no block of the requested state
17365b924ae2SSteven Whitehouse  */
17375b924ae2SSteven Whitehouse 
gfs2_rbm_find(struct gfs2_rbm * rbm,u8 state,u32 * minext,struct gfs2_blkreserv * rs,bool nowrap)17385ce13431SBob Peterson static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 *minext,
17393d39fcd1SAndreas Gruenbacher 			 struct gfs2_blkreserv *rs, bool nowrap)
17405b924ae2SSteven Whitehouse {
174171921ef8SAndreas Gruenbacher 	bool scan_from_start = rbm->bii == 0 && rbm->offset == 0;
17425b924ae2SSteven Whitehouse 	struct buffer_head *bh;
174371921ef8SAndreas Gruenbacher 	int last_bii;
17445b924ae2SSteven Whitehouse 	u32 offset;
17455b924ae2SSteven Whitehouse 	u8 *buffer;
174671921ef8SAndreas Gruenbacher 	bool wrapped = false;
17475b924ae2SSteven Whitehouse 	int ret;
1748e579ed4fSBob Peterson 	struct gfs2_bitmap *bi;
17495ce13431SBob Peterson 	struct gfs2_extent maxext = { .rbm.rgd = rbm->rgd, };
17505b924ae2SSteven Whitehouse 
175171921ef8SAndreas Gruenbacher 	/*
175271921ef8SAndreas Gruenbacher 	 * Determine the last bitmap to search.  If we're not starting at the
175371921ef8SAndreas Gruenbacher 	 * beginning of a bitmap, we need to search that bitmap twice to scan
175471921ef8SAndreas Gruenbacher 	 * the entire resource group.
17555b924ae2SSteven Whitehouse 	 */
175671921ef8SAndreas Gruenbacher 	last_bii = rbm->bii - (rbm->offset == 0);
17575b924ae2SSteven Whitehouse 
17585b924ae2SSteven Whitehouse 	while(1) {
1759e579ed4fSBob Peterson 		bi = rbm_bi(rbm);
17602fdc2fa2SAndreas Gruenbacher 		if (test_bit(GBF_FULL, &bi->bi_flags) &&
17615b924ae2SSteven Whitehouse 		    (state == GFS2_BLKST_FREE))
17625b924ae2SSteven Whitehouse 			goto next_bitmap;
17635b924ae2SSteven Whitehouse 
1764e579ed4fSBob Peterson 		bh = bi->bi_bh;
1765e579ed4fSBob Peterson 		buffer = bh->b_data + bi->bi_offset;
17665b924ae2SSteven Whitehouse 		WARN_ON(!buffer_uptodate(bh));
1767e579ed4fSBob Peterson 		if (state != GFS2_BLKST_UNLINKED && bi->bi_clone)
1768e579ed4fSBob Peterson 			buffer = bi->bi_clone + bi->bi_offset;
1769281b4952SAndreas Gruenbacher 		offset = gfs2_bitfit(buffer, bi->bi_bytes, rbm->offset, state);
177071921ef8SAndreas Gruenbacher 		if (offset == BFITNOENT) {
177171921ef8SAndreas Gruenbacher 			if (state == GFS2_BLKST_FREE && rbm->offset == 0)
177271921ef8SAndreas Gruenbacher 				set_bit(GBF_FULL, &bi->bi_flags);
177371921ef8SAndreas Gruenbacher 			goto next_bitmap;
177471921ef8SAndreas Gruenbacher 		}
17755b924ae2SSteven Whitehouse 		rbm->offset = offset;
1776bea906eeSAndreas Gruenbacher 		if (!rs || !minext)
17775b924ae2SSteven Whitehouse 			return 0;
17785b924ae2SSteven Whitehouse 
17793d39fcd1SAndreas Gruenbacher 		ret = gfs2_reservation_check_and_update(rbm, rs, *minext,
17805ce13431SBob Peterson 							&maxext);
17815b924ae2SSteven Whitehouse 		if (ret == 0)
17825b924ae2SSteven Whitehouse 			return 0;
178371921ef8SAndreas Gruenbacher 		if (ret > 0)
17848d8b752aSBob Peterson 			goto next_iter;
17855d50d532SSteven Whitehouse 		if (ret == -E2BIG) {
1786e579ed4fSBob Peterson 			rbm->bii = 0;
17875d50d532SSteven Whitehouse 			rbm->offset = 0;
17885d50d532SSteven Whitehouse 			goto res_covered_end_of_rgrp;
17895d50d532SSteven Whitehouse 		}
17905b924ae2SSteven Whitehouse 		return ret;
17915b924ae2SSteven Whitehouse 
17925b924ae2SSteven Whitehouse next_bitmap:	/* Find next bitmap in the rgrp */
17935b924ae2SSteven Whitehouse 		rbm->offset = 0;
1794e579ed4fSBob Peterson 		rbm->bii++;
1795e579ed4fSBob Peterson 		if (rbm->bii == rbm->rgd->rd_length)
1796e579ed4fSBob Peterson 			rbm->bii = 0;
17975d50d532SSteven Whitehouse res_covered_end_of_rgrp:
179871921ef8SAndreas Gruenbacher 		if (rbm->bii == 0) {
179971921ef8SAndreas Gruenbacher 			if (wrapped)
18005b924ae2SSteven Whitehouse 				break;
180171921ef8SAndreas Gruenbacher 			wrapped = true;
180271921ef8SAndreas Gruenbacher 			if (nowrap)
180371921ef8SAndreas Gruenbacher 				break;
180471921ef8SAndreas Gruenbacher 		}
18058d8b752aSBob Peterson next_iter:
180671921ef8SAndreas Gruenbacher 		/* Have we scanned the entire resource group? */
180771921ef8SAndreas Gruenbacher 		if (wrapped && rbm->bii > last_bii)
18085b924ae2SSteven Whitehouse 			break;
18095b924ae2SSteven Whitehouse 	}
18105b924ae2SSteven Whitehouse 
1811f38e998fSAndreas Gruenbacher 	if (state != GFS2_BLKST_FREE)
18125ce13431SBob Peterson 		return -ENOSPC;
18135ce13431SBob Peterson 
18145ea5050cSBob Peterson 	/* If the extent was too small, and it's smaller than the smallest
18155ea5050cSBob Peterson 	   to have failed before, remember for future reference that it's
18165ea5050cSBob Peterson 	   useless to search this rgrp again for this amount or more. */
181771921ef8SAndreas Gruenbacher 	if (wrapped && (scan_from_start || rbm->bii > last_bii) &&
181871921ef8SAndreas Gruenbacher 	    *minext < rbm->rgd->rd_extfail_pt)
1819f38e998fSAndreas Gruenbacher 		rbm->rgd->rd_extfail_pt = *minext - 1;
18205ea5050cSBob Peterson 
18215ce13431SBob Peterson 	/* If the maximum extent we found is big enough to fulfill the
18225ce13431SBob Peterson 	   minimum requirements, use it anyway. */
18235ce13431SBob Peterson 	if (maxext.len) {
18245ce13431SBob Peterson 		*rbm = maxext.rbm;
18255ce13431SBob Peterson 		*minext = maxext.len;
18265ce13431SBob Peterson 		return 0;
18275ce13431SBob Peterson 	}
18285ce13431SBob Peterson 
18295b924ae2SSteven Whitehouse 	return -ENOSPC;
18305b924ae2SSteven Whitehouse }
18315b924ae2SSteven Whitehouse 
18325b924ae2SSteven Whitehouse /**
1833c8cdf479SSteven Whitehouse  * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes
1834c8cdf479SSteven Whitehouse  * @rgd: The rgrp
1835886b1416SBob Peterson  * @last_unlinked: block address of the last dinode we unlinked
1836886b1416SBob Peterson  * @skip: block address we should explicitly not unlink
1837c8cdf479SSteven Whitehouse  *
18381a0eae88SBob Peterson  * Returns: 0 if no error
18391a0eae88SBob Peterson  *          The inode, if one has been found, in inode.
1840c8cdf479SSteven Whitehouse  */
1841c8cdf479SSteven Whitehouse 
try_rgrp_unlink(struct gfs2_rgrpd * rgd,u64 * last_unlinked,u64 skip)1842044b9414SSteven Whitehouse static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip)
1843c8cdf479SSteven Whitehouse {
18445b924ae2SSteven Whitehouse 	u64 block;
18455f3eae75SBob Peterson 	struct gfs2_sbd *sdp = rgd->rd_sbd;
1846044b9414SSteven Whitehouse 	struct gfs2_glock *gl;
1847044b9414SSteven Whitehouse 	struct gfs2_inode *ip;
1848044b9414SSteven Whitehouse 	int error;
1849044b9414SSteven Whitehouse 	int found = 0;
1850e579ed4fSBob Peterson 	struct gfs2_rbm rbm = { .rgd = rgd, .bii = 0, .offset = 0 };
1851c8cdf479SSteven Whitehouse 
18525b924ae2SSteven Whitehouse 	while (1) {
18535ce13431SBob Peterson 		error = gfs2_rbm_find(&rbm, GFS2_BLKST_UNLINKED, NULL, NULL,
18548381e602SBob Peterson 				      true);
18555b924ae2SSteven Whitehouse 		if (error == -ENOSPC)
18565b924ae2SSteven Whitehouse 			break;
18575b924ae2SSteven Whitehouse 		if (WARN_ON_ONCE(error))
185824c73873SBob Peterson 			break;
1859b3e47ca0SBob Peterson 
18605b924ae2SSteven Whitehouse 		block = gfs2_rbm_to_block(&rbm);
18615b924ae2SSteven Whitehouse 		if (gfs2_rbm_from_block(&rbm, block + 1))
18625b924ae2SSteven Whitehouse 			break;
18635b924ae2SSteven Whitehouse 		if (*last_unlinked != NO_BLOCK && block <= *last_unlinked)
1864c8cdf479SSteven Whitehouse 			continue;
18655b924ae2SSteven Whitehouse 		if (block == skip)
18661e19a195SSteven Whitehouse 			continue;
18675b924ae2SSteven Whitehouse 		*last_unlinked = block;
1868044b9414SSteven Whitehouse 
18695ea31bc0SBob Peterson 		error = gfs2_glock_get(sdp, block, &gfs2_iopen_glops, CREATE, &gl);
1870044b9414SSteven Whitehouse 		if (error)
1871044b9414SSteven Whitehouse 			continue;
1872044b9414SSteven Whitehouse 
1873044b9414SSteven Whitehouse 		/* If the inode is already in cache, we can ignore it here
1874044b9414SSteven Whitehouse 		 * because the existing inode disposal code will deal with
1875044b9414SSteven Whitehouse 		 * it when all refs have gone away. Accessing gl_object like
1876044b9414SSteven Whitehouse 		 * this is not safe in general. Here it is ok because we do
1877044b9414SSteven Whitehouse 		 * not dereference the pointer, and we only need an approx
1878044b9414SSteven Whitehouse 		 * answer to whether it is NULL or not.
1879044b9414SSteven Whitehouse 		 */
1880044b9414SSteven Whitehouse 		ip = gl->gl_object;
1881044b9414SSteven Whitehouse 
1882*e30cab28SAndreas Gruenbacher 		if (ip || !gfs2_queue_verify_delete(gl, false))
1883044b9414SSteven Whitehouse 			gfs2_glock_put(gl);
1884044b9414SSteven Whitehouse 		else
1885044b9414SSteven Whitehouse 			found++;
1886044b9414SSteven Whitehouse 
1887044b9414SSteven Whitehouse 		/* Limit reclaim to sensible number of tasks */
188844ad37d6SBob Peterson 		if (found > NR_CPUS)
1889044b9414SSteven Whitehouse 			return;
1890c8cdf479SSteven Whitehouse 	}
1891c8cdf479SSteven Whitehouse 
1892c8cdf479SSteven Whitehouse 	rgd->rd_flags &= ~GFS2_RDF_CHECK;
1893044b9414SSteven Whitehouse 	return;
1894c8cdf479SSteven Whitehouse }
1895c8cdf479SSteven Whitehouse 
1896bcd97c06SSteven Whitehouse /**
1897bcd97c06SSteven Whitehouse  * gfs2_rgrp_congested - Use stats to figure out whether an rgrp is congested
1898bcd97c06SSteven Whitehouse  * @rgd: The rgrp in question
1899bcd97c06SSteven Whitehouse  * @loops: An indication of how picky we can be (0=very, 1=less so)
1900bcd97c06SSteven Whitehouse  *
1901bcd97c06SSteven Whitehouse  * This function uses the recently added glock statistics in order to
1902bcd97c06SSteven Whitehouse  * figure out whether a parciular resource group is suffering from
1903bcd97c06SSteven Whitehouse  * contention from multiple nodes. This is done purely on the basis
1904bcd97c06SSteven Whitehouse  * of timings, since this is the only data we have to work with and
1905bcd97c06SSteven Whitehouse  * our aim here is to reject a resource group which is highly contended
1906bcd97c06SSteven Whitehouse  * but (very important) not to do this too often in order to ensure that
1907bcd97c06SSteven Whitehouse  * we do not land up introducing fragmentation by changing resource
1908bcd97c06SSteven Whitehouse  * groups when not actually required.
1909bcd97c06SSteven Whitehouse  *
1910bcd97c06SSteven Whitehouse  * The calculation is fairly simple, we want to know whether the SRTTB
1911bcd97c06SSteven Whitehouse  * (i.e. smoothed round trip time for blocking operations) to acquire
1912bcd97c06SSteven Whitehouse  * the lock for this rgrp's glock is significantly greater than the
1913bcd97c06SSteven Whitehouse  * time taken for resource groups on average. We introduce a margin in
1914bcd97c06SSteven Whitehouse  * the form of the variable @var which is computed as the sum of the two
1915bcd97c06SSteven Whitehouse  * respective variences, and multiplied by a factor depending on @loops
1916bcd97c06SSteven Whitehouse  * and whether we have a lot of data to base the decision on. This is
1917bcd97c06SSteven Whitehouse  * then tested against the square difference of the means in order to
1918bcd97c06SSteven Whitehouse  * decide whether the result is statistically significant or not.
1919bcd97c06SSteven Whitehouse  *
1920bcd97c06SSteven Whitehouse  * Returns: A boolean verdict on the congestion status
1921bcd97c06SSteven Whitehouse  */
1922bcd97c06SSteven Whitehouse 
gfs2_rgrp_congested(const struct gfs2_rgrpd * rgd,int loops)1923bcd97c06SSteven Whitehouse static bool gfs2_rgrp_congested(const struct gfs2_rgrpd *rgd, int loops)
1924bcd97c06SSteven Whitehouse {
1925bcd97c06SSteven Whitehouse 	const struct gfs2_glock *gl = rgd->rd_gl;
192615562c43SBob Peterson 	const struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
1927bcd97c06SSteven Whitehouse 	struct gfs2_lkstats *st;
19284d207133SBen Hutchings 	u64 r_dcount, l_dcount;
19294d207133SBen Hutchings 	u64 l_srttb, a_srttb = 0;
1930bcd97c06SSteven Whitehouse 	s64 srttb_diff;
19314d207133SBen Hutchings 	u64 sqr_diff;
19324d207133SBen Hutchings 	u64 var;
19330166b197SBob Peterson 	int cpu, nonzero = 0;
1934bcd97c06SSteven Whitehouse 
1935bcd97c06SSteven Whitehouse 	preempt_disable();
1936f4a3ae93SBob Peterson 	for_each_present_cpu(cpu) {
1937f4a3ae93SBob Peterson 		st = &per_cpu_ptr(sdp->sd_lkstats, cpu)->lkstats[LM_TYPE_RGRP];
19380166b197SBob Peterson 		if (st->stats[GFS2_LKS_SRTTB]) {
1939f4a3ae93SBob Peterson 			a_srttb += st->stats[GFS2_LKS_SRTTB];
19400166b197SBob Peterson 			nonzero++;
19410166b197SBob Peterson 		}
1942f4a3ae93SBob Peterson 	}
1943bcd97c06SSteven Whitehouse 	st = &this_cpu_ptr(sdp->sd_lkstats)->lkstats[LM_TYPE_RGRP];
19440166b197SBob Peterson 	if (nonzero)
19450166b197SBob Peterson 		do_div(a_srttb, nonzero);
1946bcd97c06SSteven Whitehouse 	r_dcount = st->stats[GFS2_LKS_DCOUNT];
1947bcd97c06SSteven Whitehouse 	var = st->stats[GFS2_LKS_SRTTVARB] +
1948bcd97c06SSteven Whitehouse 	      gl->gl_stats.stats[GFS2_LKS_SRTTVARB];
1949bcd97c06SSteven Whitehouse 	preempt_enable();
1950bcd97c06SSteven Whitehouse 
1951bcd97c06SSteven Whitehouse 	l_srttb = gl->gl_stats.stats[GFS2_LKS_SRTTB];
1952bcd97c06SSteven Whitehouse 	l_dcount = gl->gl_stats.stats[GFS2_LKS_DCOUNT];
1953bcd97c06SSteven Whitehouse 
1954f4a3ae93SBob Peterson 	if ((l_dcount < 1) || (r_dcount < 1) || (a_srttb == 0))
1955bcd97c06SSteven Whitehouse 		return false;
1956bcd97c06SSteven Whitehouse 
1957f4a3ae93SBob Peterson 	srttb_diff = a_srttb - l_srttb;
1958bcd97c06SSteven Whitehouse 	sqr_diff = srttb_diff * srttb_diff;
1959bcd97c06SSteven Whitehouse 
1960bcd97c06SSteven Whitehouse 	var *= 2;
1961bcd97c06SSteven Whitehouse 	if (l_dcount < 8 || r_dcount < 8)
1962bcd97c06SSteven Whitehouse 		var *= 2;
1963bcd97c06SSteven Whitehouse 	if (loops == 1)
1964bcd97c06SSteven Whitehouse 		var *= 2;
1965bcd97c06SSteven Whitehouse 
1966bcd97c06SSteven Whitehouse 	return ((srttb_diff < 0) && (sqr_diff > var));
1967bcd97c06SSteven Whitehouse }
1968bcd97c06SSteven Whitehouse 
1969bcd97c06SSteven Whitehouse /**
1970bcd97c06SSteven Whitehouse  * gfs2_rgrp_used_recently
1971bcd97c06SSteven Whitehouse  * @rs: The block reservation with the rgrp to test
1972bcd97c06SSteven Whitehouse  * @msecs: The time limit in milliseconds
1973bcd97c06SSteven Whitehouse  *
1974bcd97c06SSteven Whitehouse  * Returns: True if the rgrp glock has been used within the time limit
1975bcd97c06SSteven Whitehouse  */
gfs2_rgrp_used_recently(const struct gfs2_blkreserv * rs,u64 msecs)1976bcd97c06SSteven Whitehouse static bool gfs2_rgrp_used_recently(const struct gfs2_blkreserv *rs,
1977bcd97c06SSteven Whitehouse 				    u64 msecs)
1978bcd97c06SSteven Whitehouse {
1979bcd97c06SSteven Whitehouse 	u64 tdiff;
1980bcd97c06SSteven Whitehouse 
1981bcd97c06SSteven Whitehouse 	tdiff = ktime_to_ns(ktime_sub(ktime_get_real(),
1982c65b76b8SAndreas Gruenbacher                             rs->rs_rgd->rd_gl->gl_dstamp));
1983bcd97c06SSteven Whitehouse 
1984bcd97c06SSteven Whitehouse 	return tdiff > (msecs * 1000 * 1000);
1985bcd97c06SSteven Whitehouse }
1986bcd97c06SSteven Whitehouse 
gfs2_orlov_skip(const struct gfs2_inode * ip)19879dbe9610SSteven Whitehouse static u32 gfs2_orlov_skip(const struct gfs2_inode *ip)
19889dbe9610SSteven Whitehouse {
19899dbe9610SSteven Whitehouse 	const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
19909dbe9610SSteven Whitehouse 	u32 skip;
19919dbe9610SSteven Whitehouse 
19929dbe9610SSteven Whitehouse 	get_random_bytes(&skip, sizeof(skip));
19939dbe9610SSteven Whitehouse 	return skip % sdp->sd_rgrps;
19949dbe9610SSteven Whitehouse }
19959dbe9610SSteven Whitehouse 
gfs2_select_rgrp(struct gfs2_rgrpd ** pos,const struct gfs2_rgrpd * begin)1996c743ffd0SSteven Whitehouse static bool gfs2_select_rgrp(struct gfs2_rgrpd **pos, const struct gfs2_rgrpd *begin)
1997c743ffd0SSteven Whitehouse {
1998c743ffd0SSteven Whitehouse 	struct gfs2_rgrpd *rgd = *pos;
1999aa8920c9SSteven Whitehouse 	struct gfs2_sbd *sdp = rgd->rd_sbd;
2000c743ffd0SSteven Whitehouse 
2001c743ffd0SSteven Whitehouse 	rgd = gfs2_rgrpd_get_next(rgd);
2002c743ffd0SSteven Whitehouse 	if (rgd == NULL)
2003aa8920c9SSteven Whitehouse 		rgd = gfs2_rgrpd_get_first(sdp);
2004c743ffd0SSteven Whitehouse 	*pos = rgd;
2005c743ffd0SSteven Whitehouse 	if (rgd != begin) /* If we didn't wrap */
2006c743ffd0SSteven Whitehouse 		return true;
2007c743ffd0SSteven Whitehouse 	return false;
2008c743ffd0SSteven Whitehouse }
2009c743ffd0SSteven Whitehouse 
2010c8cdf479SSteven Whitehouse /**
20110e27c18cSBob Peterson  * fast_to_acquire - determine if a resource group will be fast to acquire
2012c551f66cSLee Jones  * @rgd: The rgrp
20130e27c18cSBob Peterson  *
20140e27c18cSBob Peterson  * If this is one of our preferred rgrps, it should be quicker to acquire,
20150e27c18cSBob Peterson  * because we tried to set ourselves up as dlm lock master.
20160e27c18cSBob Peterson  */
fast_to_acquire(struct gfs2_rgrpd * rgd)20170e27c18cSBob Peterson static inline int fast_to_acquire(struct gfs2_rgrpd *rgd)
20180e27c18cSBob Peterson {
20190e27c18cSBob Peterson 	struct gfs2_glock *gl = rgd->rd_gl;
20200e27c18cSBob Peterson 
20210e27c18cSBob Peterson 	if (gl->gl_state != LM_ST_UNLOCKED && list_empty(&gl->gl_holders) &&
20220e27c18cSBob Peterson 	    !test_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags) &&
20230e27c18cSBob Peterson 	    !test_bit(GLF_DEMOTE, &gl->gl_flags))
20240e27c18cSBob Peterson 		return 1;
20250e27c18cSBob Peterson 	if (rgd->rd_flags & GFS2_RDF_PREFERRED)
20260e27c18cSBob Peterson 		return 1;
20270e27c18cSBob Peterson 	return 0;
20280e27c18cSBob Peterson }
20290e27c18cSBob Peterson 
20300e27c18cSBob Peterson /**
2031666d1d8aSBob Peterson  * gfs2_inplace_reserve - Reserve space in the filesystem
2032b3b94faaSDavid Teigland  * @ip: the inode to reserve space for
20337b9cff46SSteven Whitehouse  * @ap: the allocation parameters
2034b3b94faaSDavid Teigland  *
203525435e5eSAbhi Das  * We try our best to find an rgrp that has at least ap->target blocks
203625435e5eSAbhi Das  * available. After a couple of passes (loops == 2), the prospects of finding
203725435e5eSAbhi Das  * such an rgrp diminish. At this stage, we return the first rgrp that has
2038725d0e9dSAndreas Gruenbacher  * at least ap->min_target blocks available.
203925435e5eSAbhi Das  *
204025435e5eSAbhi Das  * Returns: 0 on success,
204125435e5eSAbhi Das  *          -ENOMEM if a suitable rgrp can't be found
204225435e5eSAbhi Das  *          errno otherwise
2043b3b94faaSDavid Teigland  */
2044b3b94faaSDavid Teigland 
gfs2_inplace_reserve(struct gfs2_inode * ip,struct gfs2_alloc_parms * ap)204525435e5eSAbhi Das int gfs2_inplace_reserve(struct gfs2_inode *ip, struct gfs2_alloc_parms *ap)
2046b3b94faaSDavid Teigland {
2047feaa7bbaSSteven Whitehouse 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
20488e2e0047SBob Peterson 	struct gfs2_rgrpd *begin = NULL;
2049a097dc7eSBob Peterson 	struct gfs2_blkreserv *rs = &ip->i_res;
20504fc7ec31SBob Peterson 	int error = 0, flags = LM_FLAG_NODE_SCOPE;
20519e514605SAndreas Gruenbacher 	bool rg_locked;
2052666d1d8aSBob Peterson 	u64 last_unlinked = NO_BLOCK;
20534272006dSAndreas Gruenbacher 	u32 target = ap->target;
20547c9ca621SBob Peterson 	int loops = 0;
2055725d0e9dSAndreas Gruenbacher 	u32 free_blocks, blocks_available, skip = 0;
2056725d0e9dSAndreas Gruenbacher 
2057725d0e9dSAndreas Gruenbacher 	BUG_ON(rs->rs_reserved);
2058b3b94faaSDavid Teigland 
205990306c41SBenjamin Marzinski 	if (sdp->sd_args.ar_rgrplvb)
206090306c41SBenjamin Marzinski 		flags |= GL_SKIP;
20614272006dSAndreas Gruenbacher 	if (gfs2_assert_warn(sdp, target))
2062c743ffd0SSteven Whitehouse 		return -EINVAL;
20638e2e0047SBob Peterson 	if (gfs2_rs_active(rs)) {
2064c65b76b8SAndreas Gruenbacher 		begin = rs->rs_rgd;
2065c65b76b8SAndreas Gruenbacher 	} else if (rs->rs_rgd &&
2066c65b76b8SAndreas Gruenbacher 		   rgrp_contains_block(rs->rs_rgd, ip->i_goal)) {
2067c65b76b8SAndreas Gruenbacher 		begin = rs->rs_rgd;
20688e2e0047SBob Peterson 	} else {
206900a158beSAbhi Das 		check_and_update_goal(ip);
2070c65b76b8SAndreas Gruenbacher 		rs->rs_rgd = begin = gfs2_blk2rgrpd(sdp, ip->i_goal, 1);
20718e2e0047SBob Peterson 	}
20727b9cff46SSteven Whitehouse 	if (S_ISDIR(ip->i_inode.i_mode) && (ap->aflags & GFS2_AF_ORLOV))
20739dbe9610SSteven Whitehouse 		skip = gfs2_orlov_skip(ip);
2074c65b76b8SAndreas Gruenbacher 	if (rs->rs_rgd == NULL)
20757c9ca621SBob Peterson 		return -EBADSLT;
20767c9ca621SBob Peterson 
20777c9ca621SBob Peterson 	while (loops < 3) {
2078725d0e9dSAndreas Gruenbacher 		struct gfs2_rgrpd *rgd;
2079725d0e9dSAndreas Gruenbacher 
20809e514605SAndreas Gruenbacher 		rg_locked = gfs2_glock_is_locked_by_me(rs->rs_rgd->rd_gl);
20819e514605SAndreas Gruenbacher 		if (rg_locked) {
20829e514605SAndreas Gruenbacher 			rgrp_lock_local(rs->rs_rgd);
20839e514605SAndreas Gruenbacher 		} else {
20849dbe9610SSteven Whitehouse 			if (skip && skip--)
20859dbe9610SSteven Whitehouse 				goto next_rgrp;
20860e27c18cSBob Peterson 			if (!gfs2_rs_active(rs)) {
20870e27c18cSBob Peterson 				if (loops == 0 &&
2088c65b76b8SAndreas Gruenbacher 				    !fast_to_acquire(rs->rs_rgd))
20890e27c18cSBob Peterson 					goto next_rgrp;
20900e27c18cSBob Peterson 				if ((loops < 2) &&
2091bcd97c06SSteven Whitehouse 				    gfs2_rgrp_used_recently(rs, 1000) &&
2092c65b76b8SAndreas Gruenbacher 				    gfs2_rgrp_congested(rs->rs_rgd, loops))
2093bcd97c06SSteven Whitehouse 					goto next_rgrp;
20940e27c18cSBob Peterson 			}
2095c65b76b8SAndreas Gruenbacher 			error = gfs2_glock_nq_init(rs->rs_rgd->rd_gl,
20968e2e0047SBob Peterson 						   LM_ST_EXCLUSIVE, flags,
209721f09c43SAndreas Gruenbacher 						   &ip->i_rgd_gh);
2098c743ffd0SSteven Whitehouse 			if (unlikely(error))
2099c743ffd0SSteven Whitehouse 				return error;
21009e514605SAndreas Gruenbacher 			rgrp_lock_local(rs->rs_rgd);
2101bcd97c06SSteven Whitehouse 			if (!gfs2_rs_active(rs) && (loops < 2) &&
2102c65b76b8SAndreas Gruenbacher 			    gfs2_rgrp_congested(rs->rs_rgd, loops))
2103bcd97c06SSteven Whitehouse 				goto skip_rgrp;
2104c743ffd0SSteven Whitehouse 			if (sdp->sd_args.ar_rgrplvb) {
2105f2e70d8fSBob Peterson 				error = update_rgrp_lvb(rs->rs_rgd,
2106f2e70d8fSBob Peterson 							&ip->i_rgd_gh);
2107c743ffd0SSteven Whitehouse 				if (unlikely(error)) {
21089e514605SAndreas Gruenbacher 					rgrp_unlock_local(rs->rs_rgd);
210921f09c43SAndreas Gruenbacher 					gfs2_glock_dq_uninit(&ip->i_rgd_gh);
211090306c41SBenjamin Marzinski 					return error;
211190306c41SBenjamin Marzinski 				}
211290306c41SBenjamin Marzinski 			}
2113292c8c14SAbhijith Das 		}
2114c743ffd0SSteven Whitehouse 
2115243fea4dSAndreas Gruenbacher 		/* Skip unusable resource groups */
2116c65b76b8SAndreas Gruenbacher 		if ((rs->rs_rgd->rd_flags & (GFS2_RGF_NOALLOC |
21175ea5050cSBob Peterson 						 GFS2_RDF_ERROR)) ||
21184272006dSAndreas Gruenbacher 		    (loops == 0 && target > rs->rs_rgd->rd_extfail_pt))
2119c743ffd0SSteven Whitehouse 			goto skip_rgrp;
2120c743ffd0SSteven Whitehouse 
2121f2e70d8fSBob Peterson 		if (sdp->sd_args.ar_rgrplvb) {
2122f2e70d8fSBob Peterson 			error = gfs2_instantiate(&ip->i_rgd_gh);
2123f2e70d8fSBob Peterson 			if (error)
2124f2e70d8fSBob Peterson 				goto skip_rgrp;
2125f2e70d8fSBob Peterson 		}
2126c743ffd0SSteven Whitehouse 
2127c743ffd0SSteven Whitehouse 		/* Get a reservation if we don't already have one */
2128c743ffd0SSteven Whitehouse 		if (!gfs2_rs_active(rs))
2129c65b76b8SAndreas Gruenbacher 			rg_mblk_search(rs->rs_rgd, ip, ap);
2130c743ffd0SSteven Whitehouse 
2131c743ffd0SSteven Whitehouse 		/* Skip rgrps when we can't get a reservation on first pass */
2132c743ffd0SSteven Whitehouse 		if (!gfs2_rs_active(rs) && (loops < 1))
2133c743ffd0SSteven Whitehouse 			goto check_rgrp;
2134c743ffd0SSteven Whitehouse 
2135c743ffd0SSteven Whitehouse 		/* If rgrp has enough free space, use it */
2136725d0e9dSAndreas Gruenbacher 		rgd = rs->rs_rgd;
2137725d0e9dSAndreas Gruenbacher 		spin_lock(&rgd->rd_rsspin);
2138725d0e9dSAndreas Gruenbacher 		free_blocks = rgd_free(rgd, rs);
2139725d0e9dSAndreas Gruenbacher 		blocks_available = rgd->rd_free_clone - rgd->rd_reserved;
2140725d0e9dSAndreas Gruenbacher 		if (free_blocks < target || blocks_available < target) {
2141725d0e9dSAndreas Gruenbacher 			spin_unlock(&rgd->rd_rsspin);
2142725d0e9dSAndreas Gruenbacher 			goto check_rgrp;
214354335b1fSSteven Whitehouse 		}
2144725d0e9dSAndreas Gruenbacher 		rs->rs_reserved = ap->target;
2145725d0e9dSAndreas Gruenbacher 		if (rs->rs_reserved > blocks_available)
2146725d0e9dSAndreas Gruenbacher 			rs->rs_reserved = blocks_available;
2147725d0e9dSAndreas Gruenbacher 		rgd->rd_reserved += rs->rs_reserved;
2148725d0e9dSAndreas Gruenbacher 		spin_unlock(&rgd->rd_rsspin);
21499e514605SAndreas Gruenbacher 		rgrp_unlock_local(rs->rs_rgd);
2150725d0e9dSAndreas Gruenbacher 		return 0;
2151c743ffd0SSteven Whitehouse check_rgrp:
2152c743ffd0SSteven Whitehouse 		/* Check for unlinked inodes which can be reclaimed */
2153c65b76b8SAndreas Gruenbacher 		if (rs->rs_rgd->rd_flags & GFS2_RDF_CHECK)
2154c65b76b8SAndreas Gruenbacher 			try_rgrp_unlink(rs->rs_rgd, &last_unlinked,
2155666d1d8aSBob Peterson 					ip->i_no_addr);
2156c743ffd0SSteven Whitehouse skip_rgrp:
21579e514605SAndreas Gruenbacher 		rgrp_unlock_local(rs->rs_rgd);
21589e514605SAndreas Gruenbacher 
21591330edbeSBob Peterson 		/* Drop reservation, if we couldn't use reserved rgrp */
21601330edbeSBob Peterson 		if (gfs2_rs_active(rs))
21611330edbeSBob Peterson 			gfs2_rs_deltree(rs);
21621330edbeSBob Peterson 
2163c743ffd0SSteven Whitehouse 		/* Unlock rgrp if required */
2164292c8c14SAbhijith Das 		if (!rg_locked)
216521f09c43SAndreas Gruenbacher 			gfs2_glock_dq_uninit(&ip->i_rgd_gh);
2166c743ffd0SSteven Whitehouse next_rgrp:
2167c743ffd0SSteven Whitehouse 		/* Find the next rgrp, and continue looking */
2168c65b76b8SAndreas Gruenbacher 		if (gfs2_select_rgrp(&rs->rs_rgd, begin))
2169c743ffd0SSteven Whitehouse 			continue;
21709dbe9610SSteven Whitehouse 		if (skip)
21719dbe9610SSteven Whitehouse 			continue;
2172666d1d8aSBob Peterson 
2173c743ffd0SSteven Whitehouse 		/* If we've scanned all the rgrps, but found no free blocks
2174c743ffd0SSteven Whitehouse 		 * then this checks for some less likely conditions before
2175c743ffd0SSteven Whitehouse 		 * trying again.
2176c743ffd0SSteven Whitehouse 		 */
2177172e045aSBenjamin Marzinski 		loops++;
217854335b1fSSteven Whitehouse 		/* Check that fs hasn't grown if writing to rindex */
2179c743ffd0SSteven Whitehouse 		if (ip == GFS2_I(sdp->sd_rindex) && !sdp->sd_rindex_uptodate) {
21800489b3f5SBenjamin Marzinski 			error = gfs2_ri_update(ip);
2181044b9414SSteven Whitehouse 			if (error)
2182cc0581bdSBob Peterson 				return error;
2183b3b94faaSDavid Teigland 		}
2184c743ffd0SSteven Whitehouse 		/* Flushing the log may release space */
21854272006dSAndreas Gruenbacher 		if (loops == 2) {
21864272006dSAndreas Gruenbacher 			if (ap->min_target)
21874272006dSAndreas Gruenbacher 				target = ap->min_target;
2188805c0907SBob Peterson 			gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
2189805c0907SBob Peterson 				       GFS2_LFC_INPLACE_RESERVE);
2190c743ffd0SSteven Whitehouse 		}
21914272006dSAndreas Gruenbacher 	}
2192c743ffd0SSteven Whitehouse 
2193c743ffd0SSteven Whitehouse 	return -ENOSPC;
2194c743ffd0SSteven Whitehouse }
2195b3b94faaSDavid Teigland 
2196b3b94faaSDavid Teigland /**
2197b3b94faaSDavid Teigland  * gfs2_inplace_release - release an inplace reservation
2198b3b94faaSDavid Teigland  * @ip: the inode the reservation was taken out on
2199b3b94faaSDavid Teigland  *
2200b3b94faaSDavid Teigland  * Release a reservation made by gfs2_inplace_reserve().
2201b3b94faaSDavid Teigland  */
2202b3b94faaSDavid Teigland 
gfs2_inplace_release(struct gfs2_inode * ip)2203b3b94faaSDavid Teigland void gfs2_inplace_release(struct gfs2_inode *ip)
2204b3b94faaSDavid Teigland {
2205725d0e9dSAndreas Gruenbacher 	struct gfs2_blkreserv *rs = &ip->i_res;
2206725d0e9dSAndreas Gruenbacher 
2207725d0e9dSAndreas Gruenbacher 	if (rs->rs_reserved) {
2208725d0e9dSAndreas Gruenbacher 		struct gfs2_rgrpd *rgd = rs->rs_rgd;
2209725d0e9dSAndreas Gruenbacher 
2210725d0e9dSAndreas Gruenbacher 		spin_lock(&rgd->rd_rsspin);
2211c98c2ca5SBob Peterson 		GLOCK_BUG_ON(rgd->rd_gl, rgd->rd_reserved < rs->rs_reserved);
2212725d0e9dSAndreas Gruenbacher 		rgd->rd_reserved -= rs->rs_reserved;
2213725d0e9dSAndreas Gruenbacher 		spin_unlock(&rgd->rd_rsspin);
2214725d0e9dSAndreas Gruenbacher 		rs->rs_reserved = 0;
2215725d0e9dSAndreas Gruenbacher 	}
221621f09c43SAndreas Gruenbacher 	if (gfs2_holder_initialized(&ip->i_rgd_gh))
221721f09c43SAndreas Gruenbacher 		gfs2_glock_dq_uninit(&ip->i_rgd_gh);
2218b3b94faaSDavid Teigland }
2219b3b94faaSDavid Teigland 
2220b3b94faaSDavid Teigland /**
2221b3e47ca0SBob Peterson  * gfs2_alloc_extent - allocate an extent from a given bitmap
22224a993fb1SSteven Whitehouse  * @rbm: the resource group information
2223b3e47ca0SBob Peterson  * @dinode: TRUE if the first block we allocate is for a dinode
2224c04a2ef3SSteven Whitehouse  * @n: The extent length (value/result)
2225b3e47ca0SBob Peterson  *
2226c04a2ef3SSteven Whitehouse  * Add the bitmap buffer to the transaction.
2227b3e47ca0SBob Peterson  * Set the found bits to @new_state to change block's allocation state.
2228b3e47ca0SBob Peterson  */
gfs2_alloc_extent(const struct gfs2_rbm * rbm,bool dinode,unsigned int * n)2229c04a2ef3SSteven Whitehouse static void gfs2_alloc_extent(const struct gfs2_rbm *rbm, bool dinode,
22304a993fb1SSteven Whitehouse 			     unsigned int *n)
2231b3e47ca0SBob Peterson {
2232c04a2ef3SSteven Whitehouse 	struct gfs2_rbm pos = { .rgd = rbm->rgd, };
2233b3e47ca0SBob Peterson 	const unsigned int elen = *n;
2234c04a2ef3SSteven Whitehouse 	u64 block;
2235c04a2ef3SSteven Whitehouse 	int ret;
223660a0b8f9SSteven Whitehouse 
2237c04a2ef3SSteven Whitehouse 	*n = 1;
2238c04a2ef3SSteven Whitehouse 	block = gfs2_rbm_to_block(rbm);
2239e579ed4fSBob Peterson 	gfs2_trans_add_meta(rbm->rgd->rd_gl, rbm_bi(rbm)->bi_bh);
22403e6339ddSSteven Whitehouse 	gfs2_setbit(rbm, true, dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED);
2241c04a2ef3SSteven Whitehouse 	block++;
2242b45e41d7SSteven Whitehouse 	while (*n < elen) {
2243c04a2ef3SSteven Whitehouse 		ret = gfs2_rbm_from_block(&pos, block);
2244dffe12a8SBob Peterson 		if (ret || gfs2_testbit(&pos, true) != GFS2_BLKST_FREE)
2245b45e41d7SSteven Whitehouse 			break;
2246e579ed4fSBob Peterson 		gfs2_trans_add_meta(pos.rgd->rd_gl, rbm_bi(&pos)->bi_bh);
22473e6339ddSSteven Whitehouse 		gfs2_setbit(&pos, true, GFS2_BLKST_USED);
22489b8c81d1SSteven Whitehouse 		(*n)++;
2249c04a2ef3SSteven Whitehouse 		block++;
2250b45e41d7SSteven Whitehouse 	}
2251b3b94faaSDavid Teigland }
2252b3b94faaSDavid Teigland 
2253b3b94faaSDavid Teigland /**
2254b3b94faaSDavid Teigland  * rgblk_free - Change alloc state of given block(s)
2255b3b94faaSDavid Teigland  * @sdp: the filesystem
22560ddeded4SAndreas Gruenbacher  * @rgd: the resource group the blocks are in
2257b3b94faaSDavid Teigland  * @bstart: the start of a run of blocks to free
2258b3b94faaSDavid Teigland  * @blen: the length of the block run (all must lie within ONE RG!)
2259b3b94faaSDavid Teigland  * @new_state: GFS2_BLKST_XXX the after-allocation block state
2260b3b94faaSDavid Teigland  */
2261b3b94faaSDavid Teigland 
rgblk_free(struct gfs2_sbd * sdp,struct gfs2_rgrpd * rgd,u64 bstart,u32 blen,unsigned char new_state)22620ddeded4SAndreas Gruenbacher static void rgblk_free(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd,
22630ddeded4SAndreas Gruenbacher 		       u64 bstart, u32 blen, unsigned char new_state)
2264b3b94faaSDavid Teigland {
22653b1d0b9dSSteven Whitehouse 	struct gfs2_rbm rbm;
2266d24e0569SBob Peterson 	struct gfs2_bitmap *bi, *bi_prev = NULL;
2267b3b94faaSDavid Teigland 
22680ddeded4SAndreas Gruenbacher 	rbm.rgd = rgd;
2269f654683dSAndreas Gruenbacher 	if (WARN_ON_ONCE(gfs2_rbm_from_block(&rbm, bstart)))
22700ddeded4SAndreas Gruenbacher 		return;
2271d24e0569SBob Peterson 	while (blen--) {
2272e579ed4fSBob Peterson 		bi = rbm_bi(&rbm);
2273d24e0569SBob Peterson 		if (bi != bi_prev) {
2274e579ed4fSBob Peterson 			if (!bi->bi_clone) {
2275e579ed4fSBob Peterson 				bi->bi_clone = kmalloc(bi->bi_bh->b_size,
2276dd894be8SSteven Whitehouse 						      GFP_NOFS | __GFP_NOFAIL);
2277e579ed4fSBob Peterson 				memcpy(bi->bi_clone + bi->bi_offset,
2278d24e0569SBob Peterson 				       bi->bi_bh->b_data + bi->bi_offset,
2279281b4952SAndreas Gruenbacher 				       bi->bi_bytes);
2280b3b94faaSDavid Teigland 			}
2281e579ed4fSBob Peterson 			gfs2_trans_add_meta(rbm.rgd->rd_gl, bi->bi_bh);
2282d24e0569SBob Peterson 			bi_prev = bi;
2283d24e0569SBob Peterson 		}
22843e6339ddSSteven Whitehouse 		gfs2_setbit(&rbm, false, new_state);
22850eacdd16SAndreas Gruenbacher 		gfs2_rbm_add(&rbm, 1);
2286b3b94faaSDavid Teigland 	}
2287b3b94faaSDavid Teigland }
2288b3b94faaSDavid Teigland 
2289b3b94faaSDavid Teigland /**
229009010978SSteven Whitehouse  * gfs2_rgrp_dump - print out an rgrp
229109010978SSteven Whitehouse  * @seq: The iterator
22920e539ca1SAndrew Price  * @rgd: The rgrp in question
22933792ce97SBob Peterson  * @fs_id_buf: pointer to file system id (if requested)
2294b3b94faaSDavid Teigland  *
2295b3b94faaSDavid Teigland  */
2296b3b94faaSDavid Teigland 
gfs2_rgrp_dump(struct seq_file * seq,struct gfs2_rgrpd * rgd,const char * fs_id_buf)22970e539ca1SAndrew Price void gfs2_rgrp_dump(struct seq_file *seq, struct gfs2_rgrpd *rgd,
22983792ce97SBob Peterson 		    const char *fs_id_buf)
229909010978SSteven Whitehouse {
23008e2e0047SBob Peterson 	struct gfs2_blkreserv *trs;
23018e2e0047SBob Peterson 	const struct rb_node *n;
23028e2e0047SBob Peterson 
23039e514605SAndreas Gruenbacher 	spin_lock(&rgd->rd_rsspin);
2304725d0e9dSAndreas Gruenbacher 	gfs2_print_dbg(seq, "%s R: n:%llu f:%02x b:%u/%u i:%u q:%u r:%u e:%u\n",
23053792ce97SBob Peterson 		       fs_id_buf,
230609010978SSteven Whitehouse 		       (unsigned long long)rgd->rd_addr, rgd->rd_flags,
23078e2e0047SBob Peterson 		       rgd->rd_free, rgd->rd_free_clone, rgd->rd_dinodes,
2308725d0e9dSAndreas Gruenbacher 		       rgd->rd_requested, rgd->rd_reserved, rgd->rd_extfail_pt);
2309067a7c48SOsama Muhammad 	if (rgd->rd_sbd->sd_args.ar_rgrplvb && rgd->rd_rgl) {
231072244b6bSBob Peterson 		struct gfs2_rgrp_lvb *rgl = rgd->rd_rgl;
231172244b6bSBob Peterson 
23123792ce97SBob Peterson 		gfs2_print_dbg(seq, "%s  L: f:%02x b:%u i:%u\n", fs_id_buf,
231372244b6bSBob Peterson 			       be32_to_cpu(rgl->rl_flags),
231472244b6bSBob Peterson 			       be32_to_cpu(rgl->rl_free),
231572244b6bSBob Peterson 			       be32_to_cpu(rgl->rl_dinodes));
231672244b6bSBob Peterson 	}
23178e2e0047SBob Peterson 	for (n = rb_first(&rgd->rd_rstree); n; n = rb_next(&trs->rs_node)) {
23188e2e0047SBob Peterson 		trs = rb_entry(n, struct gfs2_blkreserv, rs_node);
23193792ce97SBob Peterson 		dump_rs(seq, trs, fs_id_buf);
23208e2e0047SBob Peterson 	}
23218e2e0047SBob Peterson 	spin_unlock(&rgd->rd_rsspin);
232209010978SSteven Whitehouse }
232309010978SSteven Whitehouse 
gfs2_rgrp_error(struct gfs2_rgrpd * rgd)23246050b9c7SSteven Whitehouse static void gfs2_rgrp_error(struct gfs2_rgrpd *rgd)
23256050b9c7SSteven Whitehouse {
23266050b9c7SSteven Whitehouse 	struct gfs2_sbd *sdp = rgd->rd_sbd;
232798fb0574SBob Peterson 	char fs_id_buf[sizeof(sdp->sd_fsname) + 7];
23283792ce97SBob Peterson 
23296050b9c7SSteven Whitehouse 	fs_warn(sdp, "rgrp %llu has an error, marking it readonly until umount\n",
23306050b9c7SSteven Whitehouse 		(unsigned long long)rgd->rd_addr);
23316050b9c7SSteven Whitehouse 	fs_warn(sdp, "umount on all nodes and run fsck.gfs2 to fix the error\n");
23323792ce97SBob Peterson 	sprintf(fs_id_buf, "fsid=%s: ", sdp->sd_fsname);
23330e539ca1SAndrew Price 	gfs2_rgrp_dump(NULL, rgd, fs_id_buf);
23346050b9c7SSteven Whitehouse 	rgd->rd_flags |= GFS2_RDF_ERROR;
23356050b9c7SSteven Whitehouse }
23366050b9c7SSteven Whitehouse 
233709010978SSteven Whitehouse /**
23385b924ae2SSteven Whitehouse  * gfs2_adjust_reservation - Adjust (or remove) a reservation after allocation
23395b924ae2SSteven Whitehouse  * @ip: The inode we have just allocated blocks for
23405b924ae2SSteven Whitehouse  * @rbm: The start of the allocated blocks
23415b924ae2SSteven Whitehouse  * @len: The extent length
23428e2e0047SBob Peterson  *
23435b924ae2SSteven Whitehouse  * Adjusts a reservation after an allocation has taken place. If the
23445b924ae2SSteven Whitehouse  * reservation does not match the allocation, or if it is now empty
23455b924ae2SSteven Whitehouse  * then it is removed.
23468e2e0047SBob Peterson  */
23475b924ae2SSteven Whitehouse 
gfs2_adjust_reservation(struct gfs2_inode * ip,const struct gfs2_rbm * rbm,unsigned len)23485b924ae2SSteven Whitehouse static void gfs2_adjust_reservation(struct gfs2_inode *ip,
23495b924ae2SSteven Whitehouse 				    const struct gfs2_rbm *rbm, unsigned len)
23508e2e0047SBob Peterson {
2351a097dc7eSBob Peterson 	struct gfs2_blkreserv *rs = &ip->i_res;
23525b924ae2SSteven Whitehouse 	struct gfs2_rgrpd *rgd = rbm->rgd;
23538e2e0047SBob Peterson 
2354725d0e9dSAndreas Gruenbacher 	BUG_ON(rs->rs_reserved < len);
2355725d0e9dSAndreas Gruenbacher 	rs->rs_reserved -= len;
23565b924ae2SSteven Whitehouse 	if (gfs2_rs_active(rs)) {
2357c65b76b8SAndreas Gruenbacher 		u64 start = gfs2_rbm_to_block(rbm);
2358c65b76b8SAndreas Gruenbacher 
2359c65b76b8SAndreas Gruenbacher 		if (rs->rs_start == start) {
2360c65b76b8SAndreas Gruenbacher 			unsigned int rlen;
2361c65b76b8SAndreas Gruenbacher 
2362c65b76b8SAndreas Gruenbacher 			rs->rs_start += len;
236307974d2aSAndreas Gruenbacher 			rlen = min(rs->rs_requested, len);
236407974d2aSAndreas Gruenbacher 			rs->rs_requested -= rlen;
236507974d2aSAndreas Gruenbacher 			rgd->rd_requested -= rlen;
23669e733d39SSteven Whitehouse 			trace_gfs2_rs(rs, TRACE_RS_CLAIM);
2367c65b76b8SAndreas Gruenbacher 			if (rs->rs_start < rgd->rd_data0 + rgd->rd_data &&
236807974d2aSAndreas Gruenbacher 			    rs->rs_requested)
2369725d0e9dSAndreas Gruenbacher 				return;
23701a855033SBob Peterson 			/* We used up our block reservation, so we should
23711a855033SBob Peterson 			   reserve more blocks next time. */
237221f09c43SAndreas Gruenbacher 			atomic_add(RGRP_RSRV_ADDBLKS, &ip->i_sizehint);
23735b924ae2SSteven Whitehouse 		}
237420095218SBob Peterson 		__rs_deltree(rs);
23755b924ae2SSteven Whitehouse 	}
23768e2e0047SBob Peterson }
23778e2e0047SBob Peterson 
23788e2e0047SBob Peterson /**
23799e07f2cbSSteven Whitehouse  * gfs2_set_alloc_start - Set starting point for block allocation
23809e07f2cbSSteven Whitehouse  * @rbm: The rbm which will be set to the required location
23819e07f2cbSSteven Whitehouse  * @ip: The gfs2 inode
23829e07f2cbSSteven Whitehouse  * @dinode: Flag to say if allocation includes a new inode
23839e07f2cbSSteven Whitehouse  *
23849e07f2cbSSteven Whitehouse  * This sets the starting point from the reservation if one is active
23859e07f2cbSSteven Whitehouse  * otherwise it falls back to guessing a start point based on the
23869e07f2cbSSteven Whitehouse  * inode's goal block or the last allocation point in the rgrp.
23879e07f2cbSSteven Whitehouse  */
23889e07f2cbSSteven Whitehouse 
gfs2_set_alloc_start(struct gfs2_rbm * rbm,const struct gfs2_inode * ip,bool dinode)23899e07f2cbSSteven Whitehouse static void gfs2_set_alloc_start(struct gfs2_rbm *rbm,
23909e07f2cbSSteven Whitehouse 				 const struct gfs2_inode *ip, bool dinode)
23919e07f2cbSSteven Whitehouse {
23929e07f2cbSSteven Whitehouse 	u64 goal;
23939e07f2cbSSteven Whitehouse 
2394a097dc7eSBob Peterson 	if (gfs2_rs_active(&ip->i_res)) {
2395c65b76b8SAndreas Gruenbacher 		goal = ip->i_res.rs_start;
2396c65b76b8SAndreas Gruenbacher 	} else {
23979e07f2cbSSteven Whitehouse 		if (!dinode && rgrp_contains_block(rbm->rgd, ip->i_goal))
23989e07f2cbSSteven Whitehouse 			goal = ip->i_goal;
23999e07f2cbSSteven Whitehouse 		else
24009e07f2cbSSteven Whitehouse 			goal = rbm->rgd->rd_last_alloc + rbm->rgd->rd_data0;
2401c65b76b8SAndreas Gruenbacher 	}
2402f654683dSAndreas Gruenbacher 	if (WARN_ON_ONCE(gfs2_rbm_from_block(rbm, goal))) {
2403f654683dSAndreas Gruenbacher 		rbm->bii = 0;
2404f654683dSAndreas Gruenbacher 		rbm->offset = 0;
2405f654683dSAndreas Gruenbacher 	}
24069e07f2cbSSteven Whitehouse }
24079e07f2cbSSteven Whitehouse 
24089e07f2cbSSteven Whitehouse /**
24096e87ed0fSBob Peterson  * gfs2_alloc_blocks - Allocate one or more blocks of data and/or a dinode
241009010978SSteven Whitehouse  * @ip: the inode to allocate the block for
241109010978SSteven Whitehouse  * @bn: Used to return the starting block number
24128e2e0047SBob Peterson  * @nblocks: requested number of blocks/extent length (value/result)
24136e87ed0fSBob Peterson  * @dinode: 1 if we're allocating a dinode block, else 0
241409010978SSteven Whitehouse  *
241509010978SSteven Whitehouse  * Returns: 0 or error
241609010978SSteven Whitehouse  */
241709010978SSteven Whitehouse 
gfs2_alloc_blocks(struct gfs2_inode * ip,u64 * bn,unsigned int * nblocks,bool dinode)24186a8099edSSteven Whitehouse int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
2419d92445b2SAndreas Gruenbacher 		      bool dinode)
2420b3b94faaSDavid Teigland {
2421feaa7bbaSSteven Whitehouse 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
2422d9ba7615SSteven Whitehouse 	struct buffer_head *dibh;
2423c65b76b8SAndreas Gruenbacher 	struct gfs2_rbm rbm = { .rgd = ip->i_res.rs_rgd, };
24243c5d785aSBob Peterson 	u64 block; /* block, within the file system scope */
2425f38e998fSAndreas Gruenbacher 	u32 minext = 1;
2426b2598965SAndreas Gruenbacher 	int error = -ENOSPC;
2427b3b94faaSDavid Teigland 
2428725d0e9dSAndreas Gruenbacher 	BUG_ON(ip->i_res.rs_reserved < *nblocks);
2429725d0e9dSAndreas Gruenbacher 
24309e514605SAndreas Gruenbacher 	rgrp_lock_local(rbm.rgd);
2431b2598965SAndreas Gruenbacher 	if (gfs2_rs_active(&ip->i_res)) {
24329e07f2cbSSteven Whitehouse 		gfs2_set_alloc_start(&rbm, ip, dinode);
24333d39fcd1SAndreas Gruenbacher 		error = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, &minext, &ip->i_res, false);
2434b2598965SAndreas Gruenbacher 	}
2435137834a6SSteven Whitehouse 	if (error == -ENOSPC) {
24369e07f2cbSSteven Whitehouse 		gfs2_set_alloc_start(&rbm, ip, dinode);
2437f38e998fSAndreas Gruenbacher 		error = gfs2_rbm_find(&rbm, GFS2_BLKST_FREE, &minext, NULL, false);
2438137834a6SSteven Whitehouse 	}
2439137834a6SSteven Whitehouse 
244062e252eeSSteven Whitehouse 	/* Since all blocks are reserved in advance, this shouldn't happen */
24415b924ae2SSteven Whitehouse 	if (error) {
24425ea5050cSBob Peterson 		fs_warn(sdp, "inum=%llu error=%d, nblocks=%u, full=%d fail_pt=%d\n",
24439e733d39SSteven Whitehouse 			(unsigned long long)ip->i_no_addr, error, *nblocks,
24445ea5050cSBob Peterson 			test_bit(GBF_FULL, &rbm.rgd->rd_bits->bi_flags),
24455ea5050cSBob Peterson 			rbm.rgd->rd_extfail_pt);
244609010978SSteven Whitehouse 		goto rgrp_error;
24478e2e0047SBob Peterson 	}
2448b3b94faaSDavid Teigland 
2449c04a2ef3SSteven Whitehouse 	gfs2_alloc_extent(&rbm, dinode, nblocks);
2450c04a2ef3SSteven Whitehouse 	block = gfs2_rbm_to_block(&rbm);
2451c743ffd0SSteven Whitehouse 	rbm.rgd->rd_last_alloc = block - rbm.rgd->rd_data0;
24523c5d785aSBob Peterson 	if (!dinode) {
24533ed08befSAndreas Gruenbacher 		ip->i_goal = block + *nblocks - 1;
2454d9ba7615SSteven Whitehouse 		error = gfs2_meta_inode_buffer(ip, &dibh);
2455d9ba7615SSteven Whitehouse 		if (error == 0) {
24563c5d785aSBob Peterson 			struct gfs2_dinode *di =
24573c5d785aSBob Peterson 				(struct gfs2_dinode *)dibh->b_data;
2458350a9b0aSSteven Whitehouse 			gfs2_trans_add_meta(ip->i_gl, dibh);
24593c5d785aSBob Peterson 			di->di_goal_meta = di->di_goal_data =
24603c5d785aSBob Peterson 				cpu_to_be64(ip->i_goal);
2461d9ba7615SSteven Whitehouse 			brelse(dibh);
2462d9ba7615SSteven Whitehouse 		}
24633c5d785aSBob Peterson 	}
2464725d0e9dSAndreas Gruenbacher 	spin_lock(&rbm.rgd->rd_rsspin);
2465725d0e9dSAndreas Gruenbacher 	gfs2_adjust_reservation(ip, &rbm, *nblocks);
2466725d0e9dSAndreas Gruenbacher 	if (rbm.rgd->rd_free < *nblocks || rbm.rgd->rd_reserved < *nblocks) {
2467e54c78a2SBob Peterson 		fs_warn(sdp, "nblocks=%u\n", *nblocks);
2468725d0e9dSAndreas Gruenbacher 		spin_unlock(&rbm.rgd->rd_rsspin);
246909010978SSteven Whitehouse 		goto rgrp_error;
24708e2e0047SBob Peterson 	}
2471c98c2ca5SBob Peterson 	GLOCK_BUG_ON(rbm.rgd->rd_gl, rbm.rgd->rd_reserved < *nblocks);
2472c98c2ca5SBob Peterson 	GLOCK_BUG_ON(rbm.rgd->rd_gl, rbm.rgd->rd_free_clone < *nblocks);
2473c98c2ca5SBob Peterson 	GLOCK_BUG_ON(rbm.rgd->rd_gl, rbm.rgd->rd_free < *nblocks);
2474725d0e9dSAndreas Gruenbacher 	rbm.rgd->rd_reserved -= *nblocks;
2475725d0e9dSAndreas Gruenbacher 	rbm.rgd->rd_free_clone -= *nblocks;
24764a993fb1SSteven Whitehouse 	rbm.rgd->rd_free -= *nblocks;
2477725d0e9dSAndreas Gruenbacher 	spin_unlock(&rbm.rgd->rd_rsspin);
24783c5d785aSBob Peterson 	if (dinode) {
2479d92445b2SAndreas Gruenbacher 		u64 generation;
2480d92445b2SAndreas Gruenbacher 
24814a993fb1SSteven Whitehouse 		rbm.rgd->rd_dinodes++;
2482d92445b2SAndreas Gruenbacher 		generation = rbm.rgd->rd_igeneration++;
2483d92445b2SAndreas Gruenbacher 		if (generation == 0)
2484d92445b2SAndreas Gruenbacher 			generation = rbm.rgd->rd_igeneration++;
2485d92445b2SAndreas Gruenbacher 		ip->i_generation = generation;
24863c5d785aSBob Peterson 	}
2487b3b94faaSDavid Teigland 
2488350a9b0aSSteven Whitehouse 	gfs2_trans_add_meta(rbm.rgd->rd_gl, rbm.rgd->rd_bits[0].bi_bh);
24894a993fb1SSteven Whitehouse 	gfs2_rgrp_out(rbm.rgd, rbm.rgd->rd_bits[0].bi_bh->b_data);
24909e514605SAndreas Gruenbacher 	rgrp_unlock_local(rbm.rgd);
2491b3b94faaSDavid Teigland 
24926a8099edSSteven Whitehouse 	gfs2_statfs_change(sdp, 0, -(s64)*nblocks, dinode ? 1 : 0);
24933c5d785aSBob Peterson 	if (dinode)
2494fbb27873SAndreas Gruenbacher 		gfs2_trans_remove_revoke(sdp, block, *nblocks);
24956a8099edSSteven Whitehouse 
2496fd4b4e04SSteven Whitehouse 	gfs2_quota_change(ip, *nblocks, ip->i_inode.i_uid, ip->i_inode.i_gid);
2497b3b94faaSDavid Teigland 
24984a993fb1SSteven Whitehouse 	trace_gfs2_block_alloc(ip, rbm.rgd, block, *nblocks,
24996e87ed0fSBob Peterson 			       dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED);
25006050b9c7SSteven Whitehouse 	*bn = block;
25016050b9c7SSteven Whitehouse 	return 0;
25026050b9c7SSteven Whitehouse 
25036050b9c7SSteven Whitehouse rgrp_error:
25049e514605SAndreas Gruenbacher 	rgrp_unlock_local(rbm.rgd);
25054a993fb1SSteven Whitehouse 	gfs2_rgrp_error(rbm.rgd);
25066050b9c7SSteven Whitehouse 	return -EIO;
2507b3b94faaSDavid Teigland }
2508b3b94faaSDavid Teigland 
2509b3b94faaSDavid Teigland /**
251046fcb2edSEric Sandeen  * __gfs2_free_blocks - free a contiguous run of block(s)
2511b3b94faaSDavid Teigland  * @ip: the inode these blocks are being freed from
25120ddeded4SAndreas Gruenbacher  * @rgd: the resource group the blocks are in
2513b3b94faaSDavid Teigland  * @bstart: first block of a run of contiguous blocks
2514b3b94faaSDavid Teigland  * @blen: the length of the block run
251546fcb2edSEric Sandeen  * @meta: 1 if the blocks represent metadata
2516b3b94faaSDavid Teigland  *
2517b3b94faaSDavid Teigland  */
2518b3b94faaSDavid Teigland 
__gfs2_free_blocks(struct gfs2_inode * ip,struct gfs2_rgrpd * rgd,u64 bstart,u32 blen,int meta)25190ddeded4SAndreas Gruenbacher void __gfs2_free_blocks(struct gfs2_inode *ip, struct gfs2_rgrpd *rgd,
25200ddeded4SAndreas Gruenbacher 			u64 bstart, u32 blen, int meta)
2521b3b94faaSDavid Teigland {
2522feaa7bbaSSteven Whitehouse 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
2523b3b94faaSDavid Teigland 
25249e514605SAndreas Gruenbacher 	rgrp_lock_local(rgd);
25250ddeded4SAndreas Gruenbacher 	rgblk_free(sdp, rgd, bstart, blen, GFS2_BLKST_FREE);
252641db1ab9SBob Peterson 	trace_gfs2_block_alloc(ip, rgd, bstart, blen, GFS2_BLKST_FREE);
2527cfc8b549SSteven Whitehouse 	rgd->rd_free += blen;
252866fc061bSSteven Whitehouse 	rgd->rd_flags &= ~GFS2_RGF_TRIMMED;
2529350a9b0aSSteven Whitehouse 	gfs2_trans_add_meta(rgd->rd_gl, rgd->rd_bits[0].bi_bh);
253042d52e38SBob Peterson 	gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data);
25319e514605SAndreas Gruenbacher 	rgrp_unlock_local(rgd);
2532b3b94faaSDavid Teigland 
25336d3117b4SSteven Whitehouse 	/* Directories keep their data in the metadata address space */
253468942870SBob Peterson 	if (meta || ip->i_depth || gfs2_is_jdata(ip))
253568942870SBob Peterson 		gfs2_journal_wipe(ip, bstart, blen);
25364c16c36aSBob Peterson }
25374c16c36aSBob Peterson 
25384c16c36aSBob Peterson /**
25394c16c36aSBob Peterson  * gfs2_free_meta - free a contiguous run of data block(s)
25404c16c36aSBob Peterson  * @ip: the inode these blocks are being freed from
25410ddeded4SAndreas Gruenbacher  * @rgd: the resource group the blocks are in
25424c16c36aSBob Peterson  * @bstart: first block of a run of contiguous blocks
25434c16c36aSBob Peterson  * @blen: the length of the block run
25444c16c36aSBob Peterson  *
25454c16c36aSBob Peterson  */
25464c16c36aSBob Peterson 
gfs2_free_meta(struct gfs2_inode * ip,struct gfs2_rgrpd * rgd,u64 bstart,u32 blen)25470ddeded4SAndreas Gruenbacher void gfs2_free_meta(struct gfs2_inode *ip, struct gfs2_rgrpd *rgd,
25480ddeded4SAndreas Gruenbacher 		    u64 bstart, u32 blen)
2549b3b94faaSDavid Teigland {
2550feaa7bbaSSteven Whitehouse 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
2551b3b94faaSDavid Teigland 
25520ddeded4SAndreas Gruenbacher 	__gfs2_free_blocks(ip, rgd, bstart, blen, 1);
2553b3b94faaSDavid Teigland 	gfs2_statfs_change(sdp, 0, +blen, 0);
25542933f925SSteven Whitehouse 	gfs2_quota_change(ip, -(s64)blen, ip->i_inode.i_uid, ip->i_inode.i_gid);
2555b3b94faaSDavid Teigland }
2556b3b94faaSDavid Teigland 
gfs2_unlink_di(struct inode * inode)2557feaa7bbaSSteven Whitehouse void gfs2_unlink_di(struct inode *inode)
2558feaa7bbaSSteven Whitehouse {
2559feaa7bbaSSteven Whitehouse 	struct gfs2_inode *ip = GFS2_I(inode);
2560feaa7bbaSSteven Whitehouse 	struct gfs2_sbd *sdp = GFS2_SB(inode);
2561feaa7bbaSSteven Whitehouse 	struct gfs2_rgrpd *rgd;
2562dbb7cae2SSteven Whitehouse 	u64 blkno = ip->i_no_addr;
2563feaa7bbaSSteven Whitehouse 
25640ddeded4SAndreas Gruenbacher 	rgd = gfs2_blk2rgrpd(sdp, blkno, true);
2565feaa7bbaSSteven Whitehouse 	if (!rgd)
2566feaa7bbaSSteven Whitehouse 		return;
25679e514605SAndreas Gruenbacher 	rgrp_lock_local(rgd);
25680ddeded4SAndreas Gruenbacher 	rgblk_free(sdp, rgd, blkno, 1, GFS2_BLKST_UNLINKED);
256941db1ab9SBob Peterson 	trace_gfs2_block_alloc(ip, rgd, blkno, 1, GFS2_BLKST_UNLINKED);
2570350a9b0aSSteven Whitehouse 	gfs2_trans_add_meta(rgd->rd_gl, rgd->rd_bits[0].bi_bh);
257142d52e38SBob Peterson 	gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data);
2572f5580d0fSBob Peterson 	be32_add_cpu(&rgd->rd_rgl->rl_unlinked, 1);
25739e514605SAndreas Gruenbacher 	rgrp_unlock_local(rgd);
2574feaa7bbaSSteven Whitehouse }
2575feaa7bbaSSteven Whitehouse 
gfs2_free_di(struct gfs2_rgrpd * rgd,struct gfs2_inode * ip)2576a18c78c5SBob Peterson void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip)
2577b3b94faaSDavid Teigland {
2578b3b94faaSDavid Teigland 	struct gfs2_sbd *sdp = rgd->rd_sbd;
2579b3b94faaSDavid Teigland 
25809e514605SAndreas Gruenbacher 	rgrp_lock_local(rgd);
25810ddeded4SAndreas Gruenbacher 	rgblk_free(sdp, rgd, ip->i_no_addr, 1, GFS2_BLKST_FREE);
258273f74948SSteven Whitehouse 	if (!rgd->rd_dinodes)
2583b3b94faaSDavid Teigland 		gfs2_consist_rgrpd(rgd);
258473f74948SSteven Whitehouse 	rgd->rd_dinodes--;
2585cfc8b549SSteven Whitehouse 	rgd->rd_free++;
2586b3b94faaSDavid Teigland 
2587350a9b0aSSteven Whitehouse 	gfs2_trans_add_meta(rgd->rd_gl, rgd->rd_bits[0].bi_bh);
258842d52e38SBob Peterson 	gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data);
2589f5580d0fSBob Peterson 	be32_add_cpu(&rgd->rd_rgl->rl_unlinked, -1);
259017a59346SBob Peterson 	rgrp_unlock_local(rgd);
2591b3b94faaSDavid Teigland 
2592b3b94faaSDavid Teigland 	gfs2_statfs_change(sdp, 0, +1, -1);
259341db1ab9SBob Peterson 	trace_gfs2_block_alloc(ip, rgd, ip->i_no_addr, 1, GFS2_BLKST_FREE);
25942933f925SSteven Whitehouse 	gfs2_quota_change(ip, -1, ip->i_inode.i_uid, ip->i_inode.i_gid);
259568942870SBob Peterson 	gfs2_journal_wipe(ip, ip->i_no_addr, 1);
2596b3b94faaSDavid Teigland }
2597b3b94faaSDavid Teigland 
2598b3b94faaSDavid Teigland /**
2599acf7e244SSteven Whitehouse  * gfs2_check_blk_type - Check the type of a block
2600acf7e244SSteven Whitehouse  * @sdp: The superblock
2601acf7e244SSteven Whitehouse  * @no_addr: The block number to check
2602acf7e244SSteven Whitehouse  * @type: The block type we are looking for
2603acf7e244SSteven Whitehouse  *
26049e514605SAndreas Gruenbacher  * The inode glock of @no_addr must be held.  The @type to check for is either
26059e514605SAndreas Gruenbacher  * GFS2_BLKST_DINODE or GFS2_BLKST_UNLINKED; checking for type GFS2_BLKST_FREE
26069e514605SAndreas Gruenbacher  * or GFS2_BLKST_USED would make no sense.
26079e514605SAndreas Gruenbacher  *
2608acf7e244SSteven Whitehouse  * Returns: 0 if the block type matches the expected type
2609acf7e244SSteven Whitehouse  *          -ESTALE if it doesn't match
2610acf7e244SSteven Whitehouse  *          or -ve errno if something went wrong while checking
2611acf7e244SSteven Whitehouse  */
2612acf7e244SSteven Whitehouse 
gfs2_check_blk_type(struct gfs2_sbd * sdp,u64 no_addr,unsigned int type)2613acf7e244SSteven Whitehouse int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr, unsigned int type)
2614acf7e244SSteven Whitehouse {
2615acf7e244SSteven Whitehouse 	struct gfs2_rgrpd *rgd;
26168339ee54SSteven Whitehouse 	struct gfs2_holder rgd_gh;
2617dffe12a8SBob Peterson 	struct gfs2_rbm rbm;
261858884c4dSBob Peterson 	int error = -EINVAL;
2619acf7e244SSteven Whitehouse 
262066fc061bSSteven Whitehouse 	rgd = gfs2_blk2rgrpd(sdp, no_addr, 1);
2621acf7e244SSteven Whitehouse 	if (!rgd)
26228339ee54SSteven Whitehouse 		goto fail;
2623acf7e244SSteven Whitehouse 
2624acf7e244SSteven Whitehouse 	error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_SHARED, 0, &rgd_gh);
2625acf7e244SSteven Whitehouse 	if (error)
26268339ee54SSteven Whitehouse 		goto fail;
2627acf7e244SSteven Whitehouse 
2628dffe12a8SBob Peterson 	rbm.rgd = rgd;
2629dffe12a8SBob Peterson 	error = gfs2_rbm_from_block(&rbm, no_addr);
2630bc923818SZhang Qilong 	if (!WARN_ON_ONCE(error)) {
26319e514605SAndreas Gruenbacher 		/*
26329e514605SAndreas Gruenbacher 		 * No need to take the local resource group lock here; the
26339e514605SAndreas Gruenbacher 		 * inode glock of @no_addr provides the necessary
26349e514605SAndreas Gruenbacher 		 * synchronization in case the block is an inode.  (In case
26359e514605SAndreas Gruenbacher 		 * the block is not an inode, the block type will not match
26369e514605SAndreas Gruenbacher 		 * the @type we are looking for.)
26379e514605SAndreas Gruenbacher 		 */
2638dffe12a8SBob Peterson 		if (gfs2_testbit(&rbm, false) != type)
2639acf7e244SSteven Whitehouse 			error = -ESTALE;
2640bc923818SZhang Qilong 	}
2641acf7e244SSteven Whitehouse 
2642acf7e244SSteven Whitehouse 	gfs2_glock_dq_uninit(&rgd_gh);
2643bc923818SZhang Qilong 
2644acf7e244SSteven Whitehouse fail:
2645acf7e244SSteven Whitehouse 	return error;
2646acf7e244SSteven Whitehouse }
2647acf7e244SSteven Whitehouse 
2648acf7e244SSteven Whitehouse /**
2649b3b94faaSDavid Teigland  * gfs2_rlist_add - add a RG to a list of RGs
265070b0c365SSteven Whitehouse  * @ip: the inode
2651b3b94faaSDavid Teigland  * @rlist: the list of resource groups
2652b3b94faaSDavid Teigland  * @block: the block
2653b3b94faaSDavid Teigland  *
2654b3b94faaSDavid Teigland  * Figure out what RG a block belongs to and add that RG to the list
2655b3b94faaSDavid Teigland  *
2656b3b94faaSDavid Teigland  * FIXME: Don't use NOFAIL
2657b3b94faaSDavid Teigland  *
2658b3b94faaSDavid Teigland  */
2659b3b94faaSDavid Teigland 
gfs2_rlist_add(struct gfs2_inode * ip,struct gfs2_rgrp_list * rlist,u64 block)266070b0c365SSteven Whitehouse void gfs2_rlist_add(struct gfs2_inode *ip, struct gfs2_rgrp_list *rlist,
2661cd915493SSteven Whitehouse 		    u64 block)
2662b3b94faaSDavid Teigland {
266370b0c365SSteven Whitehouse 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
2664b3b94faaSDavid Teigland 	struct gfs2_rgrpd *rgd;
2665b3b94faaSDavid Teigland 	struct gfs2_rgrpd **tmp;
2666b3b94faaSDavid Teigland 	unsigned int new_space;
2667b3b94faaSDavid Teigland 	unsigned int x;
2668b3b94faaSDavid Teigland 
2669b3b94faaSDavid Teigland 	if (gfs2_assert_warn(sdp, !rlist->rl_ghs))
2670b3b94faaSDavid Teigland 		return;
2671b3b94faaSDavid Teigland 
267203f8c41cSAndreas Gruenbacher 	/*
267303f8c41cSAndreas Gruenbacher 	 * The resource group last accessed is kept in the last position.
267403f8c41cSAndreas Gruenbacher 	 */
267503f8c41cSAndreas Gruenbacher 
267603f8c41cSAndreas Gruenbacher 	if (rlist->rl_rgrps) {
267703f8c41cSAndreas Gruenbacher 		rgd = rlist->rl_rgd[rlist->rl_rgrps - 1];
267803f8c41cSAndreas Gruenbacher 		if (rgrp_contains_block(rgd, block))
267903f8c41cSAndreas Gruenbacher 			return;
268066fc061bSSteven Whitehouse 		rgd = gfs2_blk2rgrpd(sdp, block, 1);
268103f8c41cSAndreas Gruenbacher 	} else {
2682c65b76b8SAndreas Gruenbacher 		rgd = ip->i_res.rs_rgd;
268303f8c41cSAndreas Gruenbacher 		if (!rgd || !rgrp_contains_block(rgd, block))
268403f8c41cSAndreas Gruenbacher 			rgd = gfs2_blk2rgrpd(sdp, block, 1);
268503f8c41cSAndreas Gruenbacher 	}
268603f8c41cSAndreas Gruenbacher 
2687b3b94faaSDavid Teigland 	if (!rgd) {
268803f8c41cSAndreas Gruenbacher 		fs_err(sdp, "rlist_add: no rgrp for block %llu\n",
268903f8c41cSAndreas Gruenbacher 		       (unsigned long long)block);
2690b3b94faaSDavid Teigland 		return;
2691b3b94faaSDavid Teigland 	}
2692b3b94faaSDavid Teigland 
269303f8c41cSAndreas Gruenbacher 	for (x = 0; x < rlist->rl_rgrps; x++) {
269403f8c41cSAndreas Gruenbacher 		if (rlist->rl_rgd[x] == rgd) {
269503f8c41cSAndreas Gruenbacher 			swap(rlist->rl_rgd[x],
269603f8c41cSAndreas Gruenbacher 			     rlist->rl_rgd[rlist->rl_rgrps - 1]);
2697b3b94faaSDavid Teigland 			return;
269803f8c41cSAndreas Gruenbacher 		}
269903f8c41cSAndreas Gruenbacher 	}
2700b3b94faaSDavid Teigland 
2701b3b94faaSDavid Teigland 	if (rlist->rl_rgrps == rlist->rl_space) {
2702b3b94faaSDavid Teigland 		new_space = rlist->rl_space + 10;
2703b3b94faaSDavid Teigland 
2704b3b94faaSDavid Teigland 		tmp = kcalloc(new_space, sizeof(struct gfs2_rgrpd *),
2705dd894be8SSteven Whitehouse 			      GFP_NOFS | __GFP_NOFAIL);
2706b3b94faaSDavid Teigland 
2707b3b94faaSDavid Teigland 		if (rlist->rl_rgd) {
2708b3b94faaSDavid Teigland 			memcpy(tmp, rlist->rl_rgd,
2709b3b94faaSDavid Teigland 			       rlist->rl_space * sizeof(struct gfs2_rgrpd *));
2710b3b94faaSDavid Teigland 			kfree(rlist->rl_rgd);
2711b3b94faaSDavid Teigland 		}
2712b3b94faaSDavid Teigland 
2713b3b94faaSDavid Teigland 		rlist->rl_space = new_space;
2714b3b94faaSDavid Teigland 		rlist->rl_rgd = tmp;
2715b3b94faaSDavid Teigland 	}
2716b3b94faaSDavid Teigland 
2717b3b94faaSDavid Teigland 	rlist->rl_rgd[rlist->rl_rgrps++] = rgd;
2718b3b94faaSDavid Teigland }
2719b3b94faaSDavid Teigland 
2720b3b94faaSDavid Teigland /**
2721b3b94faaSDavid Teigland  * gfs2_rlist_alloc - all RGs have been added to the rlist, now allocate
2722b3b94faaSDavid Teigland  *      and initialize an array of glock holders for them
2723b3b94faaSDavid Teigland  * @rlist: the list of resource groups
272444dab005SAndreas Gruenbacher  * @state: the state we're requesting
272544dab005SAndreas Gruenbacher  * @flags: the modifier flags
2726b3b94faaSDavid Teigland  *
2727b3b94faaSDavid Teigland  * FIXME: Don't use NOFAIL
2728b3b94faaSDavid Teigland  *
2729b3b94faaSDavid Teigland  */
2730b3b94faaSDavid Teigland 
gfs2_rlist_alloc(struct gfs2_rgrp_list * rlist,unsigned int state,u16 flags)273144dab005SAndreas Gruenbacher void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist,
273244dab005SAndreas Gruenbacher 		      unsigned int state, u16 flags)
2733b3b94faaSDavid Teigland {
2734b3b94faaSDavid Teigland 	unsigned int x;
2735b3b94faaSDavid Teigland 
27366da2ec56SKees Cook 	rlist->rl_ghs = kmalloc_array(rlist->rl_rgrps,
27376da2ec56SKees Cook 				      sizeof(struct gfs2_holder),
2738dd894be8SSteven Whitehouse 				      GFP_NOFS | __GFP_NOFAIL);
2739b3b94faaSDavid Teigland 	for (x = 0; x < rlist->rl_rgrps; x++)
274044dab005SAndreas Gruenbacher 		gfs2_holder_init(rlist->rl_rgd[x]->rd_gl, state, flags,
274144dab005SAndreas Gruenbacher 				 &rlist->rl_ghs[x]);
2742b3b94faaSDavid Teigland }
2743b3b94faaSDavid Teigland 
2744b3b94faaSDavid Teigland /**
2745b3b94faaSDavid Teigland  * gfs2_rlist_free - free a resource group list
274627ff6a0fSFabian Frederick  * @rlist: the list of resource groups
2747b3b94faaSDavid Teigland  *
2748b3b94faaSDavid Teigland  */
2749b3b94faaSDavid Teigland 
gfs2_rlist_free(struct gfs2_rgrp_list * rlist)2750b3b94faaSDavid Teigland void gfs2_rlist_free(struct gfs2_rgrp_list *rlist)
2751b3b94faaSDavid Teigland {
2752b3b94faaSDavid Teigland 	unsigned int x;
2753b3b94faaSDavid Teigland 
2754b3b94faaSDavid Teigland 	kfree(rlist->rl_rgd);
2755b3b94faaSDavid Teigland 
2756b3b94faaSDavid Teigland 	if (rlist->rl_ghs) {
2757b3b94faaSDavid Teigland 		for (x = 0; x < rlist->rl_rgrps; x++)
2758b3b94faaSDavid Teigland 			gfs2_holder_uninit(&rlist->rl_ghs[x]);
2759b3b94faaSDavid Teigland 		kfree(rlist->rl_ghs);
27608e2e0047SBob Peterson 		rlist->rl_ghs = NULL;
2761b3b94faaSDavid Teigland 	}
2762b3b94faaSDavid Teigland }
2763b3b94faaSDavid Teigland 
rgrp_lock_local(struct gfs2_rgrpd * rgd)27649e514605SAndreas Gruenbacher void rgrp_lock_local(struct gfs2_rgrpd *rgd)
27659e514605SAndreas Gruenbacher {
27669e514605SAndreas Gruenbacher 	mutex_lock(&rgd->rd_mutex);
27679e514605SAndreas Gruenbacher }
27689e514605SAndreas Gruenbacher 
rgrp_unlock_local(struct gfs2_rgrpd * rgd)27699e514605SAndreas Gruenbacher void rgrp_unlock_local(struct gfs2_rgrpd *rgd)
27709e514605SAndreas Gruenbacher {
27719e514605SAndreas Gruenbacher 	mutex_unlock(&rgd->rd_mutex);
27729e514605SAndreas Gruenbacher }
2773