|
|
1.1.1.2 root 1: /*
2: * linux/fs/bitmap.c
3: *
4: * (C) 1991 Linus Torvalds
5: */
6:
1.1 root 7: /* bitmap.c contains the code that handles the inode and block bitmaps */
8: #include <string.h>
9:
10: #include <linux/sched.h>
11: #include <linux/kernel.h>
12:
13: #define clear_block(addr) \
14: __asm__("cld\n\t" \
15: "rep\n\t" \
16: "stosl" \
17: ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
18:
19: #define set_bit(nr,addr) ({\
20: register int res __asm__("ax"); \
1.1.1.3 ! root 21: __asm__ __volatile__("btsl %2,%3\n\tsetb %%al": \
! 22: "=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \
1.1 root 23: res;})
24:
25: #define clear_bit(nr,addr) ({\
26: register int res __asm__("ax"); \
1.1.1.3 ! root 27: __asm__ __volatile__("btrl %2,%3\n\tsetnb %%al": \
! 28: "=a" (res):"0" (0),"r" (nr),"m" (*(addr))); \
1.1 root 29: res;})
30:
31: #define find_first_zero(addr) ({ \
32: int __res; \
33: __asm__("cld\n" \
34: "1:\tlodsl\n\t" \
35: "notl %%eax\n\t" \
36: "bsfl %%eax,%%edx\n\t" \
37: "je 2f\n\t" \
38: "addl %%edx,%%ecx\n\t" \
39: "jmp 3f\n" \
40: "2:\taddl $32,%%ecx\n\t" \
41: "cmpl $8192,%%ecx\n\t" \
42: "jl 1b\n" \
43: "3:" \
44: :"=c" (__res):"c" (0),"S" (addr):"ax","dx","si"); \
45: __res;})
46:
47: void free_block(int dev, int block)
48: {
49: struct super_block * sb;
50: struct buffer_head * bh;
51:
52: if (!(sb = get_super(dev)))
53: panic("trying to free block on nonexistent device");
54: if (block < sb->s_firstdatazone || block >= sb->s_nzones)
55: panic("trying to free block not in datazone");
56: bh = get_hash_table(dev,block);
57: if (bh) {
58: if (bh->b_count != 1) {
59: printk("trying to free block (%04x:%d), count=%d\n",
60: dev,block,bh->b_count);
61: return;
62: }
63: bh->b_dirt=0;
64: bh->b_uptodate=0;
65: brelse(bh);
66: }
67: block -= sb->s_firstdatazone - 1 ;
68: if (clear_bit(block&8191,sb->s_zmap[block/8192]->b_data)) {
69: printk("block (%04x:%d) ",dev,block+sb->s_firstdatazone-1);
70: panic("free_block: bit already cleared");
71: }
72: sb->s_zmap[block/8192]->b_dirt = 1;
73: }
74:
75: int new_block(int dev)
76: {
77: struct buffer_head * bh;
78: struct super_block * sb;
79: int i,j;
80:
81: if (!(sb = get_super(dev)))
82: panic("trying to get new block from nonexistant device");
83: j = 8192;
84: for (i=0 ; i<8 ; i++)
85: if (bh=sb->s_zmap[i])
86: if ((j=find_first_zero(bh->b_data))<8192)
87: break;
88: if (i>=8 || !bh || j>=8192)
89: return 0;
90: if (set_bit(j,bh->b_data))
91: panic("new_block: bit already set");
92: bh->b_dirt = 1;
93: j += i*8192 + sb->s_firstdatazone-1;
94: if (j >= sb->s_nzones)
95: return 0;
96: if (!(bh=getblk(dev,j)))
97: panic("new_block: cannot get block");
98: if (bh->b_count != 1)
99: panic("new block: count is != 1");
100: clear_block(bh->b_data);
101: bh->b_uptodate = 1;
102: bh->b_dirt = 1;
103: brelse(bh);
104: return j;
105: }
106:
107: void free_inode(struct m_inode * inode)
108: {
109: struct super_block * sb;
110: struct buffer_head * bh;
111:
112: if (!inode)
113: return;
114: if (!inode->i_dev) {
115: memset(inode,0,sizeof(*inode));
116: return;
117: }
118: if (inode->i_count>1) {
119: printk("trying to free inode with count=%d\n",inode->i_count);
120: panic("free_inode");
121: }
122: if (inode->i_nlinks)
123: panic("trying to free inode with links");
124: if (!(sb = get_super(inode->i_dev)))
125: panic("trying to free inode on nonexistent device");
126: if (inode->i_num < 1 || inode->i_num > sb->s_ninodes)
127: panic("trying to free inode 0 or nonexistant inode");
128: if (!(bh=sb->s_imap[inode->i_num>>13]))
129: panic("nonexistent imap in superblock");
130: if (clear_bit(inode->i_num&8191,bh->b_data))
1.1.1.3 ! root 131: printk("free_inode: bit already cleared.\n\r");
1.1 root 132: bh->b_dirt = 1;
133: memset(inode,0,sizeof(*inode));
134: }
135:
136: struct m_inode * new_inode(int dev)
137: {
138: struct m_inode * inode;
139: struct super_block * sb;
140: struct buffer_head * bh;
141: int i,j;
142:
143: if (!(inode=get_empty_inode()))
144: return NULL;
145: if (!(sb = get_super(dev)))
146: panic("new_inode with unknown device");
147: j = 8192;
148: for (i=0 ; i<8 ; i++)
149: if (bh=sb->s_imap[i])
150: if ((j=find_first_zero(bh->b_data))<8192)
151: break;
152: if (!bh || j >= 8192 || j+i*8192 > sb->s_ninodes) {
153: iput(inode);
154: return NULL;
155: }
156: if (set_bit(j,bh->b_data))
157: panic("new_inode: bit already set");
158: bh->b_dirt = 1;
159: inode->i_count=1;
160: inode->i_nlinks=1;
161: inode->i_dev=dev;
1.1.1.3 ! root 162: inode->i_uid=current->euid;
! 163: inode->i_gid=current->egid;
1.1 root 164: inode->i_dirt=1;
165: inode->i_num = j + i*8192;
166: inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
167: return inode;
168: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.