|
|
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:
1.1.1.4 ! root 47: int free_block(int dev, int block)
1.1 root 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) {
1.1.1.4 ! root 58: if (bh->b_count > 1) {
! 59: brelse(bh);
! 60: return 0;
1.1 root 61: }
62: bh->b_dirt=0;
63: bh->b_uptodate=0;
1.1.1.4 ! root 64: if (bh->b_count)
! 65: brelse(bh);
1.1 root 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);
1.1.1.4 ! root 70: printk("free_block: bit already cleared\n");
1.1 root 71: }
72: sb->s_zmap[block/8192]->b_dirt = 1;
1.1.1.4 ! root 73: return 1;
1.1 root 74: }
75:
76: int new_block(int dev)
77: {
78: struct buffer_head * bh;
79: struct super_block * sb;
80: int i,j;
81:
82: if (!(sb = get_super(dev)))
83: panic("trying to get new block from nonexistant device");
84: j = 8192;
85: for (i=0 ; i<8 ; i++)
86: if (bh=sb->s_zmap[i])
87: if ((j=find_first_zero(bh->b_data))<8192)
88: break;
89: if (i>=8 || !bh || j>=8192)
90: return 0;
91: if (set_bit(j,bh->b_data))
92: panic("new_block: bit already set");
93: bh->b_dirt = 1;
94: j += i*8192 + sb->s_firstdatazone-1;
95: if (j >= sb->s_nzones)
96: return 0;
97: if (!(bh=getblk(dev,j)))
98: panic("new_block: cannot get block");
99: if (bh->b_count != 1)
100: panic("new block: count is != 1");
101: clear_block(bh->b_data);
102: bh->b_uptodate = 1;
103: bh->b_dirt = 1;
104: brelse(bh);
105: return j;
106: }
107:
108: void free_inode(struct m_inode * inode)
109: {
110: struct super_block * sb;
111: struct buffer_head * bh;
112:
113: if (!inode)
114: return;
115: if (!inode->i_dev) {
116: memset(inode,0,sizeof(*inode));
117: return;
118: }
119: if (inode->i_count>1) {
120: printk("trying to free inode with count=%d\n",inode->i_count);
121: panic("free_inode");
122: }
123: if (inode->i_nlinks)
124: panic("trying to free inode with links");
125: if (!(sb = get_super(inode->i_dev)))
126: panic("trying to free inode on nonexistent device");
127: if (inode->i_num < 1 || inode->i_num > sb->s_ninodes)
128: panic("trying to free inode 0 or nonexistant inode");
129: if (!(bh=sb->s_imap[inode->i_num>>13]))
130: panic("nonexistent imap in superblock");
131: if (clear_bit(inode->i_num&8191,bh->b_data))
1.1.1.3 root 132: printk("free_inode: bit already cleared.\n\r");
1.1 root 133: bh->b_dirt = 1;
134: memset(inode,0,sizeof(*inode));
135: }
136:
137: struct m_inode * new_inode(int dev)
138: {
139: struct m_inode * inode;
140: struct super_block * sb;
141: struct buffer_head * bh;
142: int i,j;
143:
144: if (!(inode=get_empty_inode()))
145: return NULL;
146: if (!(sb = get_super(dev)))
147: panic("new_inode with unknown device");
148: j = 8192;
149: for (i=0 ; i<8 ; i++)
150: if (bh=sb->s_imap[i])
151: if ((j=find_first_zero(bh->b_data))<8192)
152: break;
153: if (!bh || j >= 8192 || j+i*8192 > sb->s_ninodes) {
154: iput(inode);
155: return NULL;
156: }
157: if (set_bit(j,bh->b_data))
158: panic("new_inode: bit already set");
159: bh->b_dirt = 1;
160: inode->i_count=1;
161: inode->i_nlinks=1;
162: inode->i_dev=dev;
1.1.1.3 root 163: inode->i_uid=current->euid;
164: inode->i_gid=current->egid;
1.1 root 165: inode->i_dirt=1;
166: inode->i_num = j + i*8192;
167: inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
168: return inode;
169: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.