1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * linux/fs/affs/bitmap.c
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * (c) 1996 Hans-Joachim Widmaier
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * bitmap.c contains the code that handles all bitmap related stuff -
8*4882a593Smuzhiyun * block allocation, deallocation, calculation of free space.
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <linux/slab.h>
12*4882a593Smuzhiyun #include "affs.h"
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun u32
affs_count_free_blocks(struct super_block * sb)15*4882a593Smuzhiyun affs_count_free_blocks(struct super_block *sb)
16*4882a593Smuzhiyun {
17*4882a593Smuzhiyun struct affs_bm_info *bm;
18*4882a593Smuzhiyun u32 free;
19*4882a593Smuzhiyun int i;
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun pr_debug("%s()\n", __func__);
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun if (sb_rdonly(sb))
24*4882a593Smuzhiyun return 0;
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun mutex_lock(&AFFS_SB(sb)->s_bmlock);
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun bm = AFFS_SB(sb)->s_bitmap;
29*4882a593Smuzhiyun free = 0;
30*4882a593Smuzhiyun for (i = AFFS_SB(sb)->s_bmap_count; i > 0; bm++, i--)
31*4882a593Smuzhiyun free += bm->bm_free;
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun mutex_unlock(&AFFS_SB(sb)->s_bmlock);
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun return free;
36*4882a593Smuzhiyun }
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun void
affs_free_block(struct super_block * sb,u32 block)39*4882a593Smuzhiyun affs_free_block(struct super_block *sb, u32 block)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun struct affs_sb_info *sbi = AFFS_SB(sb);
42*4882a593Smuzhiyun struct affs_bm_info *bm;
43*4882a593Smuzhiyun struct buffer_head *bh;
44*4882a593Smuzhiyun u32 blk, bmap, bit, mask, tmp;
45*4882a593Smuzhiyun __be32 *data;
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun pr_debug("%s(%u)\n", __func__, block);
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun if (block > sbi->s_partition_size)
50*4882a593Smuzhiyun goto err_range;
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun blk = block - sbi->s_reserved;
53*4882a593Smuzhiyun bmap = blk / sbi->s_bmap_bits;
54*4882a593Smuzhiyun bit = blk % sbi->s_bmap_bits;
55*4882a593Smuzhiyun bm = &sbi->s_bitmap[bmap];
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun mutex_lock(&sbi->s_bmlock);
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun bh = sbi->s_bmap_bh;
60*4882a593Smuzhiyun if (sbi->s_last_bmap != bmap) {
61*4882a593Smuzhiyun affs_brelse(bh);
62*4882a593Smuzhiyun bh = affs_bread(sb, bm->bm_key);
63*4882a593Smuzhiyun if (!bh)
64*4882a593Smuzhiyun goto err_bh_read;
65*4882a593Smuzhiyun sbi->s_bmap_bh = bh;
66*4882a593Smuzhiyun sbi->s_last_bmap = bmap;
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun mask = 1 << (bit & 31);
70*4882a593Smuzhiyun data = (__be32 *)bh->b_data + bit / 32 + 1;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun /* mark block free */
73*4882a593Smuzhiyun tmp = be32_to_cpu(*data);
74*4882a593Smuzhiyun if (tmp & mask)
75*4882a593Smuzhiyun goto err_free;
76*4882a593Smuzhiyun *data = cpu_to_be32(tmp | mask);
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun /* fix checksum */
79*4882a593Smuzhiyun tmp = be32_to_cpu(*(__be32 *)bh->b_data);
80*4882a593Smuzhiyun *(__be32 *)bh->b_data = cpu_to_be32(tmp - mask);
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun mark_buffer_dirty(bh);
83*4882a593Smuzhiyun affs_mark_sb_dirty(sb);
84*4882a593Smuzhiyun bm->bm_free++;
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun mutex_unlock(&sbi->s_bmlock);
87*4882a593Smuzhiyun return;
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun err_free:
90*4882a593Smuzhiyun affs_warning(sb,"affs_free_block","Trying to free block %u which is already free", block);
91*4882a593Smuzhiyun mutex_unlock(&sbi->s_bmlock);
92*4882a593Smuzhiyun return;
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun err_bh_read:
95*4882a593Smuzhiyun affs_error(sb,"affs_free_block","Cannot read bitmap block %u", bm->bm_key);
96*4882a593Smuzhiyun sbi->s_bmap_bh = NULL;
97*4882a593Smuzhiyun sbi->s_last_bmap = ~0;
98*4882a593Smuzhiyun mutex_unlock(&sbi->s_bmlock);
99*4882a593Smuzhiyun return;
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun err_range:
102*4882a593Smuzhiyun affs_error(sb, "affs_free_block","Block %u outside partition", block);
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun /*
106*4882a593Smuzhiyun * Allocate a block in the given allocation zone.
107*4882a593Smuzhiyun * Since we have to byte-swap the bitmap on little-endian
108*4882a593Smuzhiyun * machines, this is rather expensive. Therefore we will
109*4882a593Smuzhiyun * preallocate up to 16 blocks from the same word, if
110*4882a593Smuzhiyun * possible. We are not doing preallocations in the
111*4882a593Smuzhiyun * header zone, though.
112*4882a593Smuzhiyun */
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun u32
affs_alloc_block(struct inode * inode,u32 goal)115*4882a593Smuzhiyun affs_alloc_block(struct inode *inode, u32 goal)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun struct super_block *sb;
118*4882a593Smuzhiyun struct affs_sb_info *sbi;
119*4882a593Smuzhiyun struct affs_bm_info *bm;
120*4882a593Smuzhiyun struct buffer_head *bh;
121*4882a593Smuzhiyun __be32 *data, *enddata;
122*4882a593Smuzhiyun u32 blk, bmap, bit, mask, mask2, tmp;
123*4882a593Smuzhiyun int i;
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun sb = inode->i_sb;
126*4882a593Smuzhiyun sbi = AFFS_SB(sb);
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun pr_debug("balloc(inode=%lu,goal=%u): ", inode->i_ino, goal);
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun if (AFFS_I(inode)->i_pa_cnt) {
131*4882a593Smuzhiyun pr_debug("%d\n", AFFS_I(inode)->i_lastalloc+1);
132*4882a593Smuzhiyun AFFS_I(inode)->i_pa_cnt--;
133*4882a593Smuzhiyun return ++AFFS_I(inode)->i_lastalloc;
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun if (!goal || goal > sbi->s_partition_size) {
137*4882a593Smuzhiyun if (goal)
138*4882a593Smuzhiyun affs_warning(sb, "affs_balloc", "invalid goal %d", goal);
139*4882a593Smuzhiyun //if (!AFFS_I(inode)->i_last_block)
140*4882a593Smuzhiyun // affs_warning(sb, "affs_balloc", "no last alloc block");
141*4882a593Smuzhiyun goal = sbi->s_reserved;
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun blk = goal - sbi->s_reserved;
145*4882a593Smuzhiyun bmap = blk / sbi->s_bmap_bits;
146*4882a593Smuzhiyun bm = &sbi->s_bitmap[bmap];
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun mutex_lock(&sbi->s_bmlock);
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun if (bm->bm_free)
151*4882a593Smuzhiyun goto find_bmap_bit;
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun find_bmap:
154*4882a593Smuzhiyun /* search for the next bmap buffer with free bits */
155*4882a593Smuzhiyun i = sbi->s_bmap_count;
156*4882a593Smuzhiyun do {
157*4882a593Smuzhiyun if (--i < 0)
158*4882a593Smuzhiyun goto err_full;
159*4882a593Smuzhiyun bmap++;
160*4882a593Smuzhiyun bm++;
161*4882a593Smuzhiyun if (bmap < sbi->s_bmap_count)
162*4882a593Smuzhiyun continue;
163*4882a593Smuzhiyun /* restart search at zero */
164*4882a593Smuzhiyun bmap = 0;
165*4882a593Smuzhiyun bm = sbi->s_bitmap;
166*4882a593Smuzhiyun } while (!bm->bm_free);
167*4882a593Smuzhiyun blk = bmap * sbi->s_bmap_bits;
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun find_bmap_bit:
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun bh = sbi->s_bmap_bh;
172*4882a593Smuzhiyun if (sbi->s_last_bmap != bmap) {
173*4882a593Smuzhiyun affs_brelse(bh);
174*4882a593Smuzhiyun bh = affs_bread(sb, bm->bm_key);
175*4882a593Smuzhiyun if (!bh)
176*4882a593Smuzhiyun goto err_bh_read;
177*4882a593Smuzhiyun sbi->s_bmap_bh = bh;
178*4882a593Smuzhiyun sbi->s_last_bmap = bmap;
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun /* find an unused block in this bitmap block */
182*4882a593Smuzhiyun bit = blk % sbi->s_bmap_bits;
183*4882a593Smuzhiyun data = (__be32 *)bh->b_data + bit / 32 + 1;
184*4882a593Smuzhiyun enddata = (__be32 *)((u8 *)bh->b_data + sb->s_blocksize);
185*4882a593Smuzhiyun mask = ~0UL << (bit & 31);
186*4882a593Smuzhiyun blk &= ~31UL;
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun tmp = be32_to_cpu(*data);
189*4882a593Smuzhiyun if (tmp & mask)
190*4882a593Smuzhiyun goto find_bit;
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun /* scan the rest of the buffer */
193*4882a593Smuzhiyun do {
194*4882a593Smuzhiyun blk += 32;
195*4882a593Smuzhiyun if (++data >= enddata)
196*4882a593Smuzhiyun /* didn't find something, can only happen
197*4882a593Smuzhiyun * if scan didn't start at 0, try next bmap
198*4882a593Smuzhiyun */
199*4882a593Smuzhiyun goto find_bmap;
200*4882a593Smuzhiyun } while (!*data);
201*4882a593Smuzhiyun tmp = be32_to_cpu(*data);
202*4882a593Smuzhiyun mask = ~0;
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun find_bit:
205*4882a593Smuzhiyun /* finally look for a free bit in the word */
206*4882a593Smuzhiyun bit = ffs(tmp & mask) - 1;
207*4882a593Smuzhiyun blk += bit + sbi->s_reserved;
208*4882a593Smuzhiyun mask2 = mask = 1 << (bit & 31);
209*4882a593Smuzhiyun AFFS_I(inode)->i_lastalloc = blk;
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun /* prealloc as much as possible within this word */
212*4882a593Smuzhiyun while ((mask2 <<= 1)) {
213*4882a593Smuzhiyun if (!(tmp & mask2))
214*4882a593Smuzhiyun break;
215*4882a593Smuzhiyun AFFS_I(inode)->i_pa_cnt++;
216*4882a593Smuzhiyun mask |= mask2;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun bm->bm_free -= AFFS_I(inode)->i_pa_cnt + 1;
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun *data = cpu_to_be32(tmp & ~mask);
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun /* fix checksum */
223*4882a593Smuzhiyun tmp = be32_to_cpu(*(__be32 *)bh->b_data);
224*4882a593Smuzhiyun *(__be32 *)bh->b_data = cpu_to_be32(tmp + mask);
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun mark_buffer_dirty(bh);
227*4882a593Smuzhiyun affs_mark_sb_dirty(sb);
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun mutex_unlock(&sbi->s_bmlock);
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun pr_debug("%d\n", blk);
232*4882a593Smuzhiyun return blk;
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun err_bh_read:
235*4882a593Smuzhiyun affs_error(sb,"affs_read_block","Cannot read bitmap block %u", bm->bm_key);
236*4882a593Smuzhiyun sbi->s_bmap_bh = NULL;
237*4882a593Smuzhiyun sbi->s_last_bmap = ~0;
238*4882a593Smuzhiyun err_full:
239*4882a593Smuzhiyun mutex_unlock(&sbi->s_bmlock);
240*4882a593Smuzhiyun pr_debug("failed\n");
241*4882a593Smuzhiyun return 0;
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun
affs_init_bitmap(struct super_block * sb,int * flags)244*4882a593Smuzhiyun int affs_init_bitmap(struct super_block *sb, int *flags)
245*4882a593Smuzhiyun {
246*4882a593Smuzhiyun struct affs_bm_info *bm;
247*4882a593Smuzhiyun struct buffer_head *bmap_bh = NULL, *bh = NULL;
248*4882a593Smuzhiyun __be32 *bmap_blk;
249*4882a593Smuzhiyun u32 size, blk, end, offset, mask;
250*4882a593Smuzhiyun int i, res = 0;
251*4882a593Smuzhiyun struct affs_sb_info *sbi = AFFS_SB(sb);
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun if (*flags & SB_RDONLY)
254*4882a593Smuzhiyun return 0;
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun if (!AFFS_ROOT_TAIL(sb, sbi->s_root_bh)->bm_flag) {
257*4882a593Smuzhiyun pr_notice("Bitmap invalid - mounting %s read only\n", sb->s_id);
258*4882a593Smuzhiyun *flags |= SB_RDONLY;
259*4882a593Smuzhiyun return 0;
260*4882a593Smuzhiyun }
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun sbi->s_last_bmap = ~0;
263*4882a593Smuzhiyun sbi->s_bmap_bh = NULL;
264*4882a593Smuzhiyun sbi->s_bmap_bits = sb->s_blocksize * 8 - 32;
265*4882a593Smuzhiyun sbi->s_bmap_count = (sbi->s_partition_size - sbi->s_reserved +
266*4882a593Smuzhiyun sbi->s_bmap_bits - 1) / sbi->s_bmap_bits;
267*4882a593Smuzhiyun size = sbi->s_bmap_count * sizeof(*bm);
268*4882a593Smuzhiyun bm = sbi->s_bitmap = kzalloc(size, GFP_KERNEL);
269*4882a593Smuzhiyun if (!sbi->s_bitmap) {
270*4882a593Smuzhiyun pr_err("Bitmap allocation failed\n");
271*4882a593Smuzhiyun return -ENOMEM;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun bmap_blk = (__be32 *)sbi->s_root_bh->b_data;
275*4882a593Smuzhiyun blk = sb->s_blocksize / 4 - 49;
276*4882a593Smuzhiyun end = blk + 25;
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun for (i = sbi->s_bmap_count; i > 0; bm++, i--) {
279*4882a593Smuzhiyun affs_brelse(bh);
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun bm->bm_key = be32_to_cpu(bmap_blk[blk]);
282*4882a593Smuzhiyun bh = affs_bread(sb, bm->bm_key);
283*4882a593Smuzhiyun if (!bh) {
284*4882a593Smuzhiyun pr_err("Cannot read bitmap\n");
285*4882a593Smuzhiyun res = -EIO;
286*4882a593Smuzhiyun goto out;
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun if (affs_checksum_block(sb, bh)) {
289*4882a593Smuzhiyun pr_warn("Bitmap %u invalid - mounting %s read only.\n",
290*4882a593Smuzhiyun bm->bm_key, sb->s_id);
291*4882a593Smuzhiyun *flags |= SB_RDONLY;
292*4882a593Smuzhiyun goto out;
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun pr_debug("read bitmap block %d: %d\n", blk, bm->bm_key);
295*4882a593Smuzhiyun bm->bm_free = memweight(bh->b_data + 4, sb->s_blocksize - 4);
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun /* Don't try read the extension if this is the last block,
298*4882a593Smuzhiyun * but we also need the right bm pointer below
299*4882a593Smuzhiyun */
300*4882a593Smuzhiyun if (++blk < end || i == 1)
301*4882a593Smuzhiyun continue;
302*4882a593Smuzhiyun if (bmap_bh)
303*4882a593Smuzhiyun affs_brelse(bmap_bh);
304*4882a593Smuzhiyun bmap_bh = affs_bread(sb, be32_to_cpu(bmap_blk[blk]));
305*4882a593Smuzhiyun if (!bmap_bh) {
306*4882a593Smuzhiyun pr_err("Cannot read bitmap extension\n");
307*4882a593Smuzhiyun res = -EIO;
308*4882a593Smuzhiyun goto out;
309*4882a593Smuzhiyun }
310*4882a593Smuzhiyun bmap_blk = (__be32 *)bmap_bh->b_data;
311*4882a593Smuzhiyun blk = 0;
312*4882a593Smuzhiyun end = sb->s_blocksize / 4 - 1;
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun offset = (sbi->s_partition_size - sbi->s_reserved) % sbi->s_bmap_bits;
316*4882a593Smuzhiyun mask = ~(0xFFFFFFFFU << (offset & 31));
317*4882a593Smuzhiyun pr_debug("last word: %d %d %d\n", offset, offset / 32 + 1, mask);
318*4882a593Smuzhiyun offset = offset / 32 + 1;
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun if (mask) {
321*4882a593Smuzhiyun u32 old, new;
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun /* Mark unused bits in the last word as allocated */
324*4882a593Smuzhiyun old = be32_to_cpu(((__be32 *)bh->b_data)[offset]);
325*4882a593Smuzhiyun new = old & mask;
326*4882a593Smuzhiyun //if (old != new) {
327*4882a593Smuzhiyun ((__be32 *)bh->b_data)[offset] = cpu_to_be32(new);
328*4882a593Smuzhiyun /* fix checksum */
329*4882a593Smuzhiyun //new -= old;
330*4882a593Smuzhiyun //old = be32_to_cpu(*(__be32 *)bh->b_data);
331*4882a593Smuzhiyun //*(__be32 *)bh->b_data = cpu_to_be32(old - new);
332*4882a593Smuzhiyun //mark_buffer_dirty(bh);
333*4882a593Smuzhiyun //}
334*4882a593Smuzhiyun /* correct offset for the bitmap count below */
335*4882a593Smuzhiyun //offset++;
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun while (++offset < sb->s_blocksize / 4)
338*4882a593Smuzhiyun ((__be32 *)bh->b_data)[offset] = 0;
339*4882a593Smuzhiyun ((__be32 *)bh->b_data)[0] = 0;
340*4882a593Smuzhiyun ((__be32 *)bh->b_data)[0] = cpu_to_be32(-affs_checksum_block(sb, bh));
341*4882a593Smuzhiyun mark_buffer_dirty(bh);
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun /* recalculate bitmap count for last block */
344*4882a593Smuzhiyun bm--;
345*4882a593Smuzhiyun bm->bm_free = memweight(bh->b_data + 4, sb->s_blocksize - 4);
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun out:
348*4882a593Smuzhiyun affs_brelse(bh);
349*4882a593Smuzhiyun affs_brelse(bmap_bh);
350*4882a593Smuzhiyun return res;
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun
affs_free_bitmap(struct super_block * sb)353*4882a593Smuzhiyun void affs_free_bitmap(struct super_block *sb)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun struct affs_sb_info *sbi = AFFS_SB(sb);
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun if (!sbi->s_bitmap)
358*4882a593Smuzhiyun return;
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun affs_brelse(sbi->s_bmap_bh);
361*4882a593Smuzhiyun sbi->s_bmap_bh = NULL;
362*4882a593Smuzhiyun sbi->s_last_bmap = ~0;
363*4882a593Smuzhiyun kfree(sbi->s_bitmap);
364*4882a593Smuzhiyun sbi->s_bitmap = NULL;
365*4882a593Smuzhiyun }
366