11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  linux/fs/minix/bitmap.c
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Copyright (C) 1991, 1992  Linus Torvalds
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Modified for 680x0 by Hamish Macdonald
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Fixed for 680x0 by Andreas Schwab
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* bitmap.c contains the code that handles the inode and block bitmaps */
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "minix.h"
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/buffer_head.h>
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/bitops.h>
17e8edc6e03a5c8562dc70a6d969f732bdb355a7e7Alexey Dobriyan#include <linux/sched.h>
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19cc46759a8c0ac4c6f13aa4b0f470305c05f600e1Al Virostatic DEFINE_SPINLOCK(bitmap_lock);
20cc46759a8c0ac4c6f13aa4b0f470305c05f600e1Al Viro
21f1fd306a91f875e65af0e04855b23adda6831ac9Al Viro/*
22f1fd306a91f875e65af0e04855b23adda6831ac9Al Viro * bitmap consists of blocks filled with 16bit words
23f1fd306a91f875e65af0e04855b23adda6831ac9Al Viro * bit set == busy, bit clear == free
24f1fd306a91f875e65af0e04855b23adda6831ac9Al Viro * endianness is a mess, but for counting zero bits it really doesn't matter...
25f1fd306a91f875e65af0e04855b23adda6831ac9Al Viro */
26f1fd306a91f875e65af0e04855b23adda6831ac9Al Virostatic __u32 count_free(struct buffer_head *map[], unsigned blocksize, __u32 numbits)
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
28f1fd306a91f875e65af0e04855b23adda6831ac9Al Viro	__u32 sum = 0;
29f1fd306a91f875e65af0e04855b23adda6831ac9Al Viro	unsigned blocks = DIV_ROUND_UP(numbits, blocksize * 8);
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
31f1fd306a91f875e65af0e04855b23adda6831ac9Al Viro	while (blocks--) {
32f1fd306a91f875e65af0e04855b23adda6831ac9Al Viro		unsigned words = blocksize / 2;
33f1fd306a91f875e65af0e04855b23adda6831ac9Al Viro		__u16 *p = (__u16 *)(*map++)->b_data;
34f1fd306a91f875e65af0e04855b23adda6831ac9Al Viro		while (words--)
35f1fd306a91f875e65af0e04855b23adda6831ac9Al Viro			sum += 16 - hweight16(*p++);
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
38f1fd306a91f875e65af0e04855b23adda6831ac9Al Viro	return sum;
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
41939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwervoid minix_free_block(struct inode *inode, unsigned long block)
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
43939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	struct super_block *sb = inode->i_sb;
44939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	struct minix_sb_info *sbi = minix_sb(sb);
45939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	struct buffer_head *bh;
46939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	int k = sb->s_blocksize_bits + 3;
47939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	unsigned long bit, zone;
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (block < sbi->s_firstdatazone || block >= sbi->s_nzones) {
5011b8448751ba114416c63899638a8e473ebd21e7Denis Vlasenko		printk("Trying to free block not in datazone\n");
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	zone = block - sbi->s_firstdatazone + 1;
54939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	bit = zone & ((1<<k) - 1);
55939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	zone >>= k;
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (zone >= sbi->s_zmap_blocks) {
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("minix_free_block: nonexistent bitmap buffer\n");
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bh = sbi->s_zmap[zone];
61cc46759a8c0ac4c6f13aa4b0f470305c05f600e1Al Viro	spin_lock(&bitmap_lock);
62939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	if (!minix_test_and_clear_bit(bit, bh->b_data))
63939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer		printk("minix_free_block (%s:%lu): bit already cleared\n",
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       sb->s_id, block);
65cc46759a8c0ac4c6f13aa4b0f470305c05f600e1Al Viro	spin_unlock(&bitmap_lock);
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mark_buffer_dirty(bh);
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return;
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint minix_new_block(struct inode * inode)
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct minix_sb_info *sbi = minix_sb(inode->i_sb);
73939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	int bits_per_zone = 8 * inode->i_sb->s_blocksize;
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < sbi->s_zmap_blocks; i++) {
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct buffer_head *bh = sbi->s_zmap[i];
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int j;
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
80cc46759a8c0ac4c6f13aa4b0f470305c05f600e1Al Viro		spin_lock(&bitmap_lock);
81939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer		j = minix_find_first_zero_bit(bh->b_data, bits_per_zone);
82939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer		if (j < bits_per_zone) {
83939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer			minix_set_bit(j, bh->b_data);
84cc46759a8c0ac4c6f13aa4b0f470305c05f600e1Al Viro			spin_unlock(&bitmap_lock);
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mark_buffer_dirty(bh);
86939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer			j += i * bits_per_zone + sbi->s_firstdatazone-1;
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (j < sbi->s_firstdatazone || j >= sbi->s_nzones)
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return j;
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
91cc46759a8c0ac4c6f13aa4b0f470305c05f600e1Al Viro		spin_unlock(&bitmap_lock);
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
96016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyerunsigned long minix_count_free_blocks(struct super_block *sb)
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
98016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer	struct minix_sb_info *sbi = minix_sb(sb);
996d6747f85314687f72012ae85cde401db531e130Qi Yong	u32 bits = sbi->s_nzones - sbi->s_firstdatazone + 1;
100016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer
101016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer	return (count_free(sbi->s_zmap, sb->s_blocksize, bits)
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		<< sbi->s_log_zone_size);
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct minix_inode *
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsminix_V1_raw_inode(struct super_block *sb, ino_t ino, struct buffer_head **bh)
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int block;
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct minix_sb_info *sbi = minix_sb(sb);
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct minix_inode *p;
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ino || ino > sbi->s_ninodes) {
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("Bad inode number on dev %s: %ld is out of range\n",
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       sb->s_id, (long)ino);
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ino--;
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	block = 2 + sbi->s_imap_blocks + sbi->s_zmap_blocks +
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 ino / MINIX_INODES_PER_BLOCK;
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*bh = sb_bread(sb, block);
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!*bh) {
12211b8448751ba114416c63899638a8e473ebd21e7Denis Vlasenko		printk("Unable to read inode block\n");
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	p = (void *)(*bh)->b_data;
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return p + ino % MINIX_INODES_PER_BLOCK;
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct minix2_inode *
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsminix_V2_raw_inode(struct super_block *sb, ino_t ino, struct buffer_head **bh)
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int block;
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct minix_sb_info *sbi = minix_sb(sb);
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct minix2_inode *p;
135939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	int minix2_inodes_per_block = sb->s_blocksize / sizeof(struct minix2_inode);
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*bh = NULL;
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ino || ino > sbi->s_ninodes) {
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("Bad inode number on dev %s: %ld is out of range\n",
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       sb->s_id, (long)ino);
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ino--;
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	block = 2 + sbi->s_imap_blocks + sbi->s_zmap_blocks +
145939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer		 ino / minix2_inodes_per_block;
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*bh = sb_bread(sb, block);
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!*bh) {
14811b8448751ba114416c63899638a8e473ebd21e7Denis Vlasenko		printk("Unable to read inode block\n");
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	p = (void *)(*bh)->b_data;
152939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	return p + ino % minix2_inodes_per_block;
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Clear the link count and mode of a deleted inode on disk. */
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void minix_clear_inode(struct inode *inode)
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct buffer_head *bh = NULL;
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (INODE_VERSION(inode) == MINIX_V1) {
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct minix_inode *raw_inode;
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		raw_inode = minix_V1_raw_inode(inode->i_sb, inode->i_ino, &bh);
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (raw_inode) {
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			raw_inode->i_nlinks = 0;
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			raw_inode->i_mode = 0;
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct minix2_inode *raw_inode;
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		raw_inode = minix_V2_raw_inode(inode->i_sb, inode->i_ino, &bh);
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (raw_inode) {
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			raw_inode->i_nlinks = 0;
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			raw_inode->i_mode = 0;
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (bh) {
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mark_buffer_dirty(bh);
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		brelse (bh);
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid minix_free_inode(struct inode * inode)
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
184939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	struct super_block *sb = inode->i_sb;
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct minix_sb_info *sbi = minix_sb(inode->i_sb);
186939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	struct buffer_head *bh;
187939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	int k = sb->s_blocksize_bits + 3;
188939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	unsigned long ino, bit;
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ino = inode->i_ino;
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ino < 1 || ino > sbi->s_ninodes) {
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("minix_free_inode: inode 0 or nonexistent inode\n");
1935ccb4a78d8c0e27985afec32cc4894d48e7b876eAl Viro		return;
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
195939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	bit = ino & ((1<<k) - 1);
196939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	ino >>= k;
197939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	if (ino >= sbi->s_imap_blocks) {
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("minix_free_inode: nonexistent imap in superblock\n");
1995ccb4a78d8c0e27985afec32cc4894d48e7b876eAl Viro		return;
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	minix_clear_inode(inode);	/* clear on-disk copy */
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
204939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	bh = sbi->s_imap[ino];
205cc46759a8c0ac4c6f13aa4b0f470305c05f600e1Al Viro	spin_lock(&bitmap_lock);
206939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	if (!minix_test_and_clear_bit(bit, bh->b_data))
207939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer		printk("minix_free_inode: bit %lu already cleared\n", bit);
208cc46759a8c0ac4c6f13aa4b0f470305c05f600e1Al Viro	spin_unlock(&bitmap_lock);
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mark_buffer_dirty(bh);
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2124f45ba3d101fd882ed122059e6797786c81e2c17Al Virostruct inode *minix_new_inode(const struct inode *dir, umode_t mode, int *error)
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct super_block *sb = dir->i_sb;
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct minix_sb_info *sbi = minix_sb(sb);
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct inode *inode = new_inode(sb);
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct buffer_head * bh;
218939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	int bits_per_zone = 8 * sb->s_blocksize;
219939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	unsigned long j;
220939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	int i;
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!inode) {
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*error = -ENOMEM;
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
226939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	j = bits_per_zone;
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bh = NULL;
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*error = -ENOSPC;
229cc46759a8c0ac4c6f13aa4b0f470305c05f600e1Al Viro	spin_lock(&bitmap_lock);
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < sbi->s_imap_blocks; i++) {
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		bh = sbi->s_imap[i];
232939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer		j = minix_find_first_zero_bit(bh->b_data, bits_per_zone);
233939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer		if (j < bits_per_zone)
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
236939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	if (!bh || j >= bits_per_zone) {
237cc46759a8c0ac4c6f13aa4b0f470305c05f600e1Al Viro		spin_unlock(&bitmap_lock);
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		iput(inode);
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
241939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	if (minix_test_and_set_bit(j, bh->b_data)) {	/* shouldn't happen */
242cc46759a8c0ac4c6f13aa4b0f470305c05f600e1Al Viro		spin_unlock(&bitmap_lock);
243939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer		printk("minix_new_inode: bit already set\n");
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		iput(inode);
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
247cc46759a8c0ac4c6f13aa4b0f470305c05f600e1Al Viro	spin_unlock(&bitmap_lock);
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mark_buffer_dirty(bh);
249939b00df0306bc4b5cd25c3c3c78e89b91e72fc8Andries Brouwer	j += i * bits_per_zone;
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!j || j > sbi->s_ninodes) {
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		iput(inode);
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return NULL;
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2549eed1fb721c6c512795f8847bccc413f3a1143bbDmitry Monakhov	inode_init_owner(inode, dir, mode);
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	inode->i_ino = j;
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
257ba52de123d454b57369f291348266d86f4b35070Theodore Ts'o	inode->i_blocks = 0;
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(&minix_i(inode)->u, 0, sizeof(minix_i(inode)->u));
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	insert_inode_hash(inode);
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mark_inode_dirty(inode);
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*error = 0;
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return inode;
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
266016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyerunsigned long minix_count_free_inodes(struct super_block *sb)
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
268016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer	struct minix_sb_info *sbi = minix_sb(sb);
269016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer	u32 bits = sbi->s_ninodes + 1;
270016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer
271016e8d44bc06dd3322f26712bdd3f3a6973592d0Josh Boyer	return count_free(sbi->s_imap, sb->s_blocksize, bits);
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
273