|
|
1.1 root 1: /*
2: * linux/fs/minix/inode.c
3: *
1.1.1.6 root 4: * Copyright (C) 1991, 1992 Linus Torvalds
1.1 root 5: */
6:
7: #include <linux/sched.h>
8: #include <linux/minix_fs.h>
9: #include <linux/kernel.h>
10: #include <linux/mm.h>
1.1.1.6 root 11: #include <linux/string.h>
12: #include <linux/stat.h>
13:
1.1 root 14: #include <asm/system.h>
1.1.1.4 root 15: #include <asm/segment.h>
1.1 root 16:
1.1.1.2 root 17: int sync_dev(int dev);
18:
1.1.1.7 ! root 19: static inline void wait_on_buffer(struct buffer_head * bh)
! 20: {
! 21: cli();
! 22: while (bh->b_lock)
! 23: sleep_on(&bh->b_wait);
! 24: sti();
! 25: }
! 26:
1.1.1.3 root 27: void minix_put_inode(struct inode *inode)
28: {
29: inode->i_size = 0;
30: minix_truncate(inode);
31: minix_free_inode(inode);
32: }
33:
1.1.1.2 root 34: void minix_put_super(struct super_block *sb)
35: {
36: int i;
37:
38: lock_super(sb);
39: sb->s_dev = 0;
40: for(i = 0 ; i < MINIX_I_MAP_SLOTS ; i++)
1.1.1.6 root 41: brelse(sb->u.minix_sb.s_imap[i]);
1.1.1.2 root 42: for(i = 0 ; i < MINIX_Z_MAP_SLOTS ; i++)
1.1.1.6 root 43: brelse(sb->u.minix_sb.s_zmap[i]);
1.1.1.2 root 44: free_super(sb);
45: return;
46: }
47:
48: static struct super_operations minix_sops = {
49: minix_read_inode,
1.1.1.3 root 50: minix_write_inode,
51: minix_put_inode,
1.1.1.4 root 52: minix_put_super,
1.1.1.5 root 53: NULL,
1.1.1.4 root 54: minix_statfs
1.1.1.2 root 55: };
56:
57: struct super_block *minix_read_super(struct super_block *s,void *data)
58: {
59: struct buffer_head *bh;
1.1.1.4 root 60: struct minix_super_block *ms;
1.1.1.2 root 61: int i,dev=s->s_dev,block;
62:
63: lock_super(s);
1.1.1.6 root 64: if (!(bh = bread(dev,1,BLOCK_SIZE))) {
1.1.1.2 root 65: s->s_dev=0;
66: free_super(s);
67: printk("bread failed\n");
68: return NULL;
69: }
1.1.1.4 root 70: ms = (struct minix_super_block *) bh->b_data;
1.1.1.6 root 71: s->s_blocksize = 1024;
72: s->u.minix_sb.s_ninodes = ms->s_ninodes;
73: s->u.minix_sb.s_nzones = ms->s_nzones;
74: s->u.minix_sb.s_imap_blocks = ms->s_imap_blocks;
75: s->u.minix_sb.s_zmap_blocks = ms->s_zmap_blocks;
76: s->u.minix_sb.s_firstdatazone = ms->s_firstdatazone;
77: s->u.minix_sb.s_log_zone_size = ms->s_log_zone_size;
78: s->u.minix_sb.s_max_size = ms->s_max_size;
1.1.1.4 root 79: s->s_magic = ms->s_magic;
1.1.1.2 root 80: brelse(bh);
81: if (s->s_magic != MINIX_SUPER_MAGIC) {
82: s->s_dev = 0;
83: free_super(s);
84: printk("magic match failed\n");
85: return NULL;
86: }
87: for (i=0;i < MINIX_I_MAP_SLOTS;i++)
1.1.1.6 root 88: s->u.minix_sb.s_imap[i] = NULL;
1.1.1.2 root 89: for (i=0;i < MINIX_Z_MAP_SLOTS;i++)
1.1.1.6 root 90: s->u.minix_sb.s_zmap[i] = NULL;
1.1.1.2 root 91: block=2;
1.1.1.6 root 92: for (i=0 ; i < s->u.minix_sb.s_imap_blocks ; i++)
93: if (s->u.minix_sb.s_imap[i]=bread(dev,block,BLOCK_SIZE))
1.1.1.2 root 94: block++;
95: else
96: break;
1.1.1.6 root 97: for (i=0 ; i < s->u.minix_sb.s_zmap_blocks ; i++)
98: if (s->u.minix_sb.s_zmap[i]=bread(dev,block,BLOCK_SIZE))
1.1.1.2 root 99: block++;
100: else
101: break;
1.1.1.6 root 102: if (block != 2+s->u.minix_sb.s_imap_blocks+s->u.minix_sb.s_zmap_blocks) {
1.1.1.2 root 103: for(i=0;i<MINIX_I_MAP_SLOTS;i++)
1.1.1.6 root 104: brelse(s->u.minix_sb.s_imap[i]);
1.1.1.2 root 105: for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
1.1.1.6 root 106: brelse(s->u.minix_sb.s_zmap[i]);
1.1.1.2 root 107: s->s_dev=0;
108: free_super(s);
109: printk("block failed\n");
110: return NULL;
111: }
1.1.1.6 root 112: s->u.minix_sb.s_imap[0]->b_data[0] |= 1;
113: s->u.minix_sb.s_zmap[0]->b_data[0] |= 1;
1.1.1.2 root 114: free_super(s);
115: /* set up enough so that it can read an inode */
116: s->s_dev = dev;
117: s->s_op = &minix_sops;
118: if (!(s->s_mounted = iget(dev,MINIX_ROOT_INO))) {
119: s->s_dev=0;
120: printk("get root inode failed\n");
121: return NULL;
122: }
123: return s;
124: }
125:
1.1.1.4 root 126: void minix_statfs (struct super_block *sb, struct statfs *buf)
127: {
128: long tmp;
129:
130: put_fs_long(MINIX_SUPER_MAGIC, &buf->f_type);
131: put_fs_long(1024, &buf->f_bsize);
1.1.1.6 root 132: put_fs_long(sb->u.minix_sb.s_nzones << sb->u.minix_sb.s_log_zone_size, &buf->f_blocks);
1.1.1.4 root 133: tmp = minix_count_free_blocks(sb);
134: put_fs_long(tmp, &buf->f_bfree);
135: put_fs_long(tmp, &buf->f_bavail);
1.1.1.6 root 136: put_fs_long(sb->u.minix_sb.s_ninodes, &buf->f_files);
1.1.1.4 root 137: put_fs_long(minix_count_free_inodes(sb), &buf->f_ffree);
138: /* Don't know what value to put in buf->f_fsid */
139: }
140:
1.1.1.7 ! root 141: #define inode_bmap(inode,nr) ((inode)->u.minix_i.i_data[(nr)])
! 142:
! 143: static int block_bmap(struct buffer_head * bh, int nr)
! 144: {
! 145: int tmp;
! 146:
! 147: if (!bh)
! 148: return 0;
! 149: tmp = ((unsigned short *) bh->b_data)[nr];
! 150: brelse(bh);
! 151: return tmp;
! 152: }
! 153:
! 154: int minix_bmap(struct inode * inode,int block)
1.1 root 155: {
156: int i;
157:
1.1.1.2 root 158: if (block<0) {
1.1.1.7 ! root 159: printk("minix_bmap: block<0");
1.1.1.2 root 160: return 0;
161: }
162: if (block >= 7+512+512*512) {
1.1.1.7 ! root 163: printk("minix_bmap: block>big");
1.1.1.2 root 164: return 0;
165: }
1.1.1.7 ! root 166: if (block < 7)
! 167: return inode_bmap(inode,block);
1.1 root 168: block -= 7;
1.1.1.7 ! root 169: if (block < 512) {
! 170: i = inode_bmap(inode,7);
! 171: if (!i)
1.1 root 172: return 0;
1.1.1.7 ! root 173: return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
1.1 root 174: }
175: block -= 512;
1.1.1.7 ! root 176: i = inode_bmap(inode,8);
1.1 root 177: if (!i)
178: return 0;
1.1.1.7 ! root 179: i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>9);
! 180: if (!i)
1.1 root 181: return 0;
1.1.1.7 ! root 182: return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 511);
! 183: }
! 184:
! 185: static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
! 186: {
! 187: int tmp;
! 188: unsigned short *p;
! 189: struct buffer_head * result;
! 190:
! 191: p = inode->u.minix_i.i_data + nr;
! 192: repeat:
! 193: tmp = *p;
! 194: if (tmp) {
! 195: result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
! 196: if (tmp == *p)
! 197: return result;
! 198: brelse(result);
! 199: goto repeat;
! 200: }
! 201: if (!create)
! 202: return NULL;
! 203: tmp = minix_new_block(inode->i_dev);
! 204: if (!tmp)
! 205: return NULL;
! 206: result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
! 207: if (*p) {
! 208: minix_free_block(inode->i_dev,tmp);
! 209: brelse(result);
! 210: goto repeat;
! 211: }
! 212: *p = tmp;
! 213: inode->i_ctime = CURRENT_TIME;
! 214: inode->i_dirt = 1;
! 215: return result;
! 216: }
! 217:
! 218: static struct buffer_head * block_getblk(struct buffer_head * bh, int nr, int create)
! 219: {
! 220: int tmp;
! 221: unsigned short *p;
! 222: struct buffer_head * result;
! 223:
! 224: if (!bh)
! 225: return NULL;
! 226: if (!bh->b_uptodate) {
! 227: ll_rw_block(READ,bh);
! 228: wait_on_buffer(bh);
! 229: if (!bh->b_uptodate) {
! 230: brelse(bh);
! 231: return NULL;
1.1 root 232: }
1.1.1.7 ! root 233: }
! 234: p = nr + (unsigned short *) bh->b_data;
! 235: repeat:
! 236: tmp = *p;
! 237: if (tmp) {
! 238: result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
! 239: if (tmp == *p) {
! 240: brelse(bh);
! 241: return result;
! 242: }
! 243: brelse(result);
! 244: goto repeat;
! 245: }
! 246: if (!create) {
! 247: brelse(bh);
! 248: return NULL;
! 249: }
! 250: tmp = minix_new_block(bh->b_dev);
! 251: if (!tmp) {
! 252: brelse(bh);
! 253: return NULL;
! 254: }
! 255: result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
! 256: if (*p) {
! 257: minix_free_block(bh->b_dev,tmp);
! 258: brelse(result);
! 259: goto repeat;
! 260: }
! 261: *p = tmp;
! 262: bh->b_dirt = 1;
1.1 root 263: brelse(bh);
1.1.1.7 ! root 264: return result;
1.1 root 265: }
266:
1.1.1.7 ! root 267: struct buffer_head * minix_getblk(struct inode * inode, int block, int create)
1.1 root 268: {
1.1.1.7 ! root 269: struct buffer_head * bh;
! 270:
! 271: if (block<0) {
! 272: printk("minix_getblk: block<0");
! 273: return NULL;
! 274: }
! 275: if (block >= 7+512+512*512) {
! 276: printk("minix_getblk: block>big");
! 277: return NULL;
! 278: }
! 279: if (block < 7)
! 280: return inode_getblk(inode,block,create);
! 281: block -= 7;
! 282: if (block < 512) {
! 283: bh = inode_getblk(inode,7,create);
! 284: return block_getblk(bh,block,create);
! 285: }
! 286: block -= 512;
! 287: bh = inode_getblk(inode,8,create);
! 288: bh = block_getblk(bh,block>>9,create);
! 289: return block_getblk(bh,block & 511,create);
1.1 root 290: }
291:
1.1.1.7 ! root 292: struct buffer_head * minix_bread(struct inode * inode, int block, int create)
1.1 root 293: {
1.1.1.7 ! root 294: struct buffer_head * bh;
! 295:
! 296: bh = minix_getblk(inode,block,create);
! 297: if (!bh || bh->b_uptodate)
! 298: return bh;
! 299: ll_rw_block(READ,bh);
! 300: wait_on_buffer(bh);
! 301: if (bh->b_uptodate)
! 302: return bh;
! 303: brelse(bh);
! 304: return NULL;
1.1 root 305: }
306:
307: void minix_read_inode(struct inode * inode)
308: {
309: struct buffer_head * bh;
310: struct minix_inode * raw_inode;
311: int block;
312:
1.1.1.6 root 313: block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
1.1 root 314: (inode->i_ino-1)/MINIX_INODES_PER_BLOCK;
1.1.1.6 root 315: if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE)))
1.1 root 316: panic("unable to read i-node block");
317: raw_inode = ((struct minix_inode *) bh->b_data) +
318: (inode->i_ino-1)%MINIX_INODES_PER_BLOCK;
319: inode->i_mode = raw_inode->i_mode;
320: inode->i_uid = raw_inode->i_uid;
321: inode->i_gid = raw_inode->i_gid;
322: inode->i_nlink = raw_inode->i_nlinks;
323: inode->i_size = raw_inode->i_size;
324: inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
1.1.1.7 ! root 325: inode->i_blocks = inode->i_blksize = 0;
1.1 root 326: if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
327: inode->i_rdev = raw_inode->i_zone[0];
328: else for (block = 0; block < 9; block++)
1.1.1.7 ! root 329: inode->u.minix_i.i_data[block] = raw_inode->i_zone[block];
1.1 root 330: brelse(bh);
1.1.1.3 root 331: inode->i_op = NULL;
332: if (S_ISREG(inode->i_mode))
333: inode->i_op = &minix_file_inode_operations;
334: else if (S_ISDIR(inode->i_mode))
335: inode->i_op = &minix_dir_inode_operations;
336: else if (S_ISLNK(inode->i_mode))
337: inode->i_op = &minix_symlink_inode_operations;
338: else if (S_ISCHR(inode->i_mode))
339: inode->i_op = &minix_chrdev_inode_operations;
340: else if (S_ISBLK(inode->i_mode))
341: inode->i_op = &minix_blkdev_inode_operations;
1.1.1.5 root 342: else if (S_ISFIFO(inode->i_mode)) {
343: inode->i_op = &minix_fifo_inode_operations;
344: inode->i_pipe = 1;
1.1.1.7 ! root 345: PIPE_BASE(*inode) = NULL;
1.1.1.5 root 346: PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
1.1.1.7 ! root 347: PIPE_READ_WAIT(*inode) = PIPE_WRITE_WAIT(*inode) = NULL;
1.1.1.5 root 348: PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
349: }
1.1 root 350: }
351:
352: void minix_write_inode(struct inode * inode)
353: {
354: struct buffer_head * bh;
355: struct minix_inode * raw_inode;
356: int block;
357:
1.1.1.6 root 358: block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
1.1 root 359: (inode->i_ino-1)/MINIX_INODES_PER_BLOCK;
1.1.1.6 root 360: if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
1.1 root 361: panic("unable to read i-node block");
362: raw_inode = ((struct minix_inode *)bh->b_data) +
363: (inode->i_ino-1)%MINIX_INODES_PER_BLOCK;
364: raw_inode->i_mode = inode->i_mode;
365: raw_inode->i_uid = inode->i_uid;
366: raw_inode->i_gid = inode->i_gid;
367: raw_inode->i_nlinks = inode->i_nlink;
368: raw_inode->i_size = inode->i_size;
369: raw_inode->i_time = inode->i_mtime;
370: if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
371: raw_inode->i_zone[0] = inode->i_rdev;
372: else for (block = 0; block < 9; block++)
1.1.1.7 ! root 373: raw_inode->i_zone[block] = inode->u.minix_i.i_data[block];
1.1 root 374: bh->b_dirt=1;
375: inode->i_dirt=0;
376: brelse(bh);
377: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.