aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/rgrp.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-05-18 13:52:39 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-05-18 13:52:39 -0400
commit88c8ab1fcb53feadb8ebdcb4cda7e6137c6416bd (patch)
tree263f0e4e38724be2313ab73c7b6b8ff9f9f10da7 /fs/gfs2/rgrp.c
parent64c14ea73b58e2c3759682d67eeb00d088355f08 (diff)
[GFS2] Merge bits.[ch] into rgrp.c
Since they are small and will be inlined by the complier, it makes sense to merge the contents of bits.[ch] into rgrp.c Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r--fs/gfs2/rgrp.c162
1 files changed, 161 insertions, 1 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 15c326ce13d1..5a32d6932978 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -19,7 +19,6 @@
19#include "gfs2.h" 19#include "gfs2.h"
20#include "lm_interface.h" 20#include "lm_interface.h"
21#include "incore.h" 21#include "incore.h"
22#include "bits.h"
23#include "glock.h" 22#include "glock.h"
24#include "glops.h" 23#include "glops.h"
25#include "lops.h" 24#include "lops.h"
@@ -31,6 +30,167 @@
31#include "ops_file.h" 30#include "ops_file.h"
32#include "util.h" 31#include "util.h"
33 32
33#define BFITNOENT 0xFFFFFFFF
34
35/*
36 * These routines are used by the resource group routines (rgrp.c)
37 * to keep track of block allocation. Each block is represented by two
38 * bits. One bit indicates whether or not the block is used. (1=used,
39 * 0=free) The other bit indicates whether or not the block contains a
40 * dinode or not. (1=dinode, 0=not-dinode) So, each byte represents
41 * GFS2_NBBY (i.e. 4) blocks.
42 */
43
44static const char valid_change[16] = {
45 /* current */
46 /* n */ 0, 1, 0, 1,
47 /* e */ 1, 0, 0, 0,
48 /* w */ 0, 0, 0, 0,
49 1, 0, 0, 0
50};
51
52/**
53 * gfs2_setbit - Set a bit in the bitmaps
54 * @buffer: the buffer that holds the bitmaps
55 * @buflen: the length (in bytes) of the buffer
56 * @block: the block to set
57 * @new_state: the new state of the block
58 *
59 */
60
61void gfs2_setbit(struct gfs2_rgrpd *rgd, unsigned char *buffer,
62 unsigned int buflen, uint32_t block, unsigned char new_state)
63{
64 unsigned char *byte, *end, cur_state;
65 unsigned int bit;
66
67 byte = buffer + (block / GFS2_NBBY);
68 bit = (block % GFS2_NBBY) * GFS2_BIT_SIZE;
69 end = buffer + buflen;
70
71 gfs2_assert(rgd->rd_sbd, byte < end);
72
73 cur_state = (*byte >> bit) & GFS2_BIT_MASK;
74
75 if (valid_change[new_state * 4 + cur_state]) {
76 *byte ^= cur_state << bit;
77 *byte |= new_state << bit;
78 } else
79 gfs2_consist_rgrpd(rgd);
80}
81
82/**
83 * gfs2_testbit - test a bit in the bitmaps
84 * @buffer: the buffer that holds the bitmaps
85 * @buflen: the length (in bytes) of the buffer
86 * @block: the block to read
87 *
88 */
89
90unsigned char gfs2_testbit(struct gfs2_rgrpd *rgd, unsigned char *buffer,
91 unsigned int buflen, uint32_t block)
92{
93 unsigned char *byte, *end, cur_state;
94 unsigned int bit;
95
96 byte = buffer + (block / GFS2_NBBY);
97 bit = (block % GFS2_NBBY) * GFS2_BIT_SIZE;
98 end = buffer + buflen;
99
100 gfs2_assert(rgd->rd_sbd, byte < end);
101
102 cur_state = (*byte >> bit) & GFS2_BIT_MASK;
103
104 return cur_state;
105}
106
107/**
108 * gfs2_bitfit - Search an rgrp's bitmap buffer to find a bit-pair representing
109 * a block in a given allocation state.
110 * @buffer: the buffer that holds the bitmaps
111 * @buflen: the length (in bytes) of the buffer
112 * @goal: start search at this block's bit-pair (within @buffer)
113 * @old_state: GFS2_BLKST_XXX the state of the block we're looking for;
114 * bit 0 = alloc(1)/free(0), bit 1 = meta(1)/data(0)
115 *
116 * Scope of @goal and returned block number is only within this bitmap buffer,
117 * not entire rgrp or filesystem. @buffer will be offset from the actual
118 * beginning of a bitmap block buffer, skipping any header structures.
119 *
120 * Return: the block number (bitmap buffer scope) that was found
121 */
122
123uint32_t gfs2_bitfit(struct gfs2_rgrpd *rgd, unsigned char *buffer,
124 unsigned int buflen, uint32_t goal,
125 unsigned char old_state)
126{
127 unsigned char *byte, *end, alloc;
128 uint32_t blk = goal;
129 unsigned int bit;
130
131 byte = buffer + (goal / GFS2_NBBY);
132 bit = (goal % GFS2_NBBY) * GFS2_BIT_SIZE;
133 end = buffer + buflen;
134 alloc = (old_state & 1) ? 0 : 0x55;
135
136 while (byte < end) {
137 if ((*byte & 0x55) == alloc) {
138 blk += (8 - bit) >> 1;
139
140 bit = 0;
141 byte++;
142
143 continue;
144 }
145
146 if (((*byte >> bit) & GFS2_BIT_MASK) == old_state)
147 return blk;
148
149 bit += GFS2_BIT_SIZE;
150 if (bit >= 8) {
151 bit = 0;
152 byte++;
153 }
154
155 blk++;
156 }
157
158 return BFITNOENT;
159}
160
161/**
162 * gfs2_bitcount - count the number of bits in a certain state
163 * @buffer: the buffer that holds the bitmaps
164 * @buflen: the length (in bytes) of the buffer
165 * @state: the state of the block we're looking for
166 *
167 * Returns: The number of bits
168 */
169
170uint32_t gfs2_bitcount(struct gfs2_rgrpd *rgd, unsigned char *buffer,
171 unsigned int buflen, unsigned char state)
172{
173 unsigned char *byte = buffer;
174 unsigned char *end = buffer + buflen;
175 unsigned char state1 = state << 2;
176 unsigned char state2 = state << 4;
177 unsigned char state3 = state << 6;
178 uint32_t count = 0;
179
180 for (; byte < end; byte++) {
181 if (((*byte) & 0x03) == state)
182 count++;
183 if (((*byte) & 0x0C) == state1)
184 count++;
185 if (((*byte) & 0x30) == state2)
186 count++;
187 if (((*byte) & 0xC0) == state3)
188 count++;
189 }
190
191 return count;
192}
193
34/** 194/**
35 * gfs2_rgrp_verify - Verify that a resource group is consistent 195 * gfs2_rgrp_verify - Verify that a resource group is consistent
36 * @sdp: the filesystem 196 * @sdp: the filesystem