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