|
|
1.1 root 1: /* 1.1.1.2 ! root 2: * linux/fs/super.c ! 3: * ! 4: * (C) 1991 Linus Torvalds ! 5: */ ! 6: ! 7: /* 1.1 root 8: * super.c contains code to handle the super-block tables. 9: */ 10: #include <linux/config.h> 11: #include <linux/sched.h> 12: #include <linux/kernel.h> 1.1.1.2 ! root 13: #include <asm/system.h> ! 14: ! 15: #include <errno.h> ! 16: #include <sys/stat.h> ! 17: ! 18: int sync_dev(int dev); ! 19: void wait_for_keypress(void); 1.1 root 20: 21: /* set_bit uses setb, as gas doesn't recognize setc */ 22: #define set_bit(bitnr,addr) ({ \ 23: register int __res __asm__("ax"); \ 24: __asm__("bt %2,%3;setb %%al":"=a" (__res):"a" (0),"r" (bitnr),"m" (*(addr))); \ 25: __res; }) 26: 27: struct super_block super_block[NR_SUPER]; 1.1.1.2 ! root 28: /* this is initialized in init/main.c */ ! 29: int ROOT_DEV = 0; 1.1 root 30: 1.1.1.2 ! root 31: static void lock_super(struct super_block * sb) 1.1 root 32: { 1.1.1.2 ! root 33: cli(); ! 34: while (sb->s_lock) ! 35: sleep_on(&(sb->s_wait)); ! 36: sb->s_lock = 1; ! 37: sti(); ! 38: } ! 39: ! 40: static void free_super(struct super_block * sb) ! 41: { ! 42: cli(); ! 43: sb->s_lock = 0; ! 44: wake_up(&(sb->s_wait)); ! 45: sti(); ! 46: } ! 47: ! 48: static void wait_on_super(struct super_block * sb) ! 49: { ! 50: cli(); ! 51: while (sb->s_lock) ! 52: sleep_on(&(sb->s_wait)); ! 53: sti(); ! 54: } ! 55: ! 56: struct super_block * get_super(int dev) ! 57: { ! 58: struct super_block * s; ! 59: ! 60: if (!dev) ! 61: return NULL; ! 62: s = 0+super_block; ! 63: while (s < NR_SUPER+super_block) ! 64: if (s->s_dev == dev) { ! 65: wait_on_super(s); ! 66: if (s->s_dev == dev) ! 67: return s; ! 68: s = 0+super_block; ! 69: } else ! 70: s++; ! 71: return NULL; ! 72: } ! 73: ! 74: void put_super(int dev) ! 75: { ! 76: struct super_block * sb; ! 77: int i; ! 78: ! 79: if (dev == ROOT_DEV) { ! 80: printk("root diskette changed: prepare for armageddon\n\r"); ! 81: return; ! 82: } ! 83: if (!(sb = get_super(dev))) ! 84: return; ! 85: if (sb->s_imount) { ! 86: printk("Mounted disk changed - tssk, tssk\n\r"); ! 87: return; ! 88: } ! 89: lock_super(sb); ! 90: sb->s_dev = 0; ! 91: for(i=0;i<I_MAP_SLOTS;i++) ! 92: brelse(sb->s_imap[i]); ! 93: for(i=0;i<Z_MAP_SLOTS;i++) ! 94: brelse(sb->s_zmap[i]); ! 95: free_super(sb); ! 96: return; ! 97: } ! 98: ! 99: static struct super_block * read_super(int dev) ! 100: { ! 101: struct super_block * s; 1.1 root 102: struct buffer_head * bh; 103: int i,block; 104: 1.1.1.2 ! root 105: if (!dev) 1.1 root 106: return NULL; 1.1.1.2 ! root 107: check_disk_change(dev); ! 108: if (s = get_super(dev)) ! 109: return s; ! 110: for (s = 0+super_block ;; s++) { ! 111: if (s >= NR_SUPER+super_block) ! 112: return NULL; ! 113: if (!s->s_dev) ! 114: break; ! 115: } ! 116: s->s_dev = dev; ! 117: s->s_isup = NULL; ! 118: s->s_imount = NULL; ! 119: s->s_time = 0; ! 120: s->s_rd_only = 0; ! 121: s->s_dirt = 0; ! 122: lock_super(s); ! 123: if (!(bh = bread(dev,1))) { ! 124: s->s_dev=0; ! 125: free_super(s); 1.1 root 126: return NULL; 1.1.1.2 ! root 127: } ! 128: *((struct d_super_block *) s) = ! 129: *((struct d_super_block *) bh->b_data); 1.1 root 130: brelse(bh); 1.1.1.2 ! root 131: if (s->s_magic != SUPER_MAGIC) { ! 132: s->s_dev = 0; ! 133: free_super(s); 1.1 root 134: return NULL; 135: } 136: for (i=0;i<I_MAP_SLOTS;i++) 1.1.1.2 ! root 137: s->s_imap[i] = NULL; 1.1 root 138: for (i=0;i<Z_MAP_SLOTS;i++) 1.1.1.2 ! root 139: s->s_zmap[i] = NULL; 1.1 root 140: block=2; 1.1.1.2 ! root 141: for (i=0 ; i < s->s_imap_blocks ; i++) ! 142: if (s->s_imap[i]=bread(dev,block)) 1.1 root 143: block++; 144: else 145: break; 1.1.1.2 ! root 146: for (i=0 ; i < s->s_zmap_blocks ; i++) ! 147: if (s->s_zmap[i]=bread(dev,block)) 1.1 root 148: block++; 149: else 150: break; 1.1.1.2 ! root 151: if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) { 1.1 root 152: for(i=0;i<I_MAP_SLOTS;i++) 1.1.1.2 ! root 153: brelse(s->s_imap[i]); 1.1 root 154: for(i=0;i<Z_MAP_SLOTS;i++) 1.1.1.2 ! root 155: brelse(s->s_zmap[i]); ! 156: s->s_dev=0; ! 157: free_super(s); 1.1 root 158: return NULL; 159: } 1.1.1.2 ! root 160: s->s_imap[0]->b_data[0] |= 1; ! 161: s->s_zmap[0]->b_data[0] |= 1; ! 162: free_super(s); ! 163: return s; ! 164: } ! 165: ! 166: int sys_umount(char * dev_name) ! 167: { ! 168: struct m_inode * inode; ! 169: struct super_block * sb; ! 170: int dev; ! 171: ! 172: if (!(inode=namei(dev_name))) ! 173: return -ENOENT; ! 174: dev = inode->i_zone[0]; ! 175: if (!S_ISBLK(inode->i_mode)) { ! 176: iput(inode); ! 177: return -ENOTBLK; ! 178: } ! 179: iput(inode); ! 180: if (dev==ROOT_DEV) ! 181: return -EBUSY; ! 182: if (!(sb=get_super(dev)) || !(sb->s_imount)) ! 183: return -ENOENT; ! 184: if (!sb->s_imount->i_mount) ! 185: printk("Mounted inode has i_mount=0\n"); ! 186: for(inode=inode_table+0 ; inode<inode_table+NR_INODE ; inode++) ! 187: if (inode->i_dev==dev && inode->i_count) ! 188: return -EBUSY; ! 189: sb->s_imount->i_mount=0; ! 190: iput(sb->s_imount); ! 191: sb->s_imount = NULL; ! 192: iput(sb->s_isup); ! 193: sb->s_isup = NULL; ! 194: put_super(dev); ! 195: sync_dev(dev); ! 196: return 0; ! 197: } ! 198: ! 199: int sys_mount(char * dev_name, char * dir_name, int rw_flag) ! 200: { ! 201: struct m_inode * dev_i, * dir_i; ! 202: struct super_block * sb; ! 203: int dev; ! 204: ! 205: if (!(dev_i=namei(dev_name))) ! 206: return -ENOENT; ! 207: dev = dev_i->i_zone[0]; ! 208: if (!S_ISBLK(dev_i->i_mode)) { ! 209: iput(dev_i); ! 210: return -EPERM; ! 211: } ! 212: iput(dev_i); ! 213: if (!(dir_i=namei(dir_name))) ! 214: return -ENOENT; ! 215: if (dir_i->i_count != 1 || dir_i->i_num == ROOT_INO) { ! 216: iput(dir_i); ! 217: return -EBUSY; ! 218: } ! 219: if (!S_ISDIR(dir_i->i_mode)) { ! 220: iput(dir_i); ! 221: return -EPERM; ! 222: } ! 223: if (!(sb=read_super(dev))) { ! 224: iput(dir_i); ! 225: return -EBUSY; ! 226: } ! 227: if (sb->s_imount) { ! 228: iput(dir_i); ! 229: return -EBUSY; ! 230: } ! 231: if (dir_i->i_mount) { ! 232: iput(dir_i); ! 233: return -EPERM; ! 234: } ! 235: sb->s_imount=dir_i; ! 236: dir_i->i_mount=1; ! 237: dir_i->i_dirt=1; /* NOTE! we don't iput(dir_i) */ ! 238: return 0; /* we do that in umount */ 1.1 root 239: } 240: 241: void mount_root(void) 242: { 243: int i,free; 244: struct super_block * p; 245: struct m_inode * mi; 246: 247: if (32 != sizeof (struct d_inode)) 248: panic("bad i-node size"); 249: for(i=0;i<NR_FILE;i++) 250: file_table[i].f_count=0; 1.1.1.2 ! root 251: if (MAJOR(ROOT_DEV) == 2) { ! 252: printk("Insert root floppy and press ENTER"); ! 253: wait_for_keypress(); ! 254: } ! 255: for(p = &super_block[0] ; p < &super_block[NR_SUPER] ; p++) { 1.1 root 256: p->s_dev = 0; 1.1.1.2 ! root 257: p->s_lock = 0; ! 258: p->s_wait = NULL; ! 259: } ! 260: if (!(p=read_super(ROOT_DEV))) 1.1 root 261: panic("Unable to mount root"); 1.1.1.2 ! root 262: if (!(mi=iget(ROOT_DEV,ROOT_INO))) 1.1 root 263: panic("Unable to read root i-node"); 264: mi->i_count += 3 ; /* NOTE! it is logically used 4 times, not 1 */ 265: p->s_isup = p->s_imount = mi; 266: current->pwd = mi; 267: current->root = mi; 268: free=0; 269: i=p->s_nzones; 270: while (-- i >= 0) 271: if (!set_bit(i&8191,p->s_zmap[i>>13]->b_data)) 272: free++; 273: printk("%d/%d free blocks\n\r",free,p->s_nzones); 274: free=0; 275: i=p->s_ninodes+1; 276: while (-- i >= 0) 277: if (!set_bit(i&8191,p->s_imap[i>>13]->b_data)) 278: free++; 279: printk("%d/%d free inodes\n\r",free,p->s_ninodes); 280: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.