|
|
1.1 root 1: /*
2: * linux/fs/ext/inode.c
3: *
1.1.1.2 ! root 4: * Copyright (C) 1992 Remy Card ([email protected])
1.1 root 5: *
6: * from
7: *
8: * linux/fs/minix/inode.c
9: *
1.1.1.2 ! root 10: * Copyright (C) 1991, 1992 Linus Torvalds
1.1 root 11: */
12:
13: #include <linux/sched.h>
14: #include <linux/ext_fs.h>
15: #include <linux/kernel.h>
16: #include <linux/mm.h>
1.1.1.2 ! root 17: #include <linux/string.h>
! 18: #include <linux/stat.h>
! 19:
1.1 root 20: #include <asm/system.h>
21: #include <asm/segment.h>
22:
23: int sync_dev(int dev);
24:
25: void ext_put_inode(struct inode *inode)
26: {
27: inode->i_size = 0;
28: ext_truncate(inode);
29: ext_free_inode(inode);
30: }
31:
32: void ext_put_super(struct super_block *sb)
33: {
34: #ifdef EXTFS_BITMAP
35: int i;
36: #endif
37:
38: lock_super(sb);
39: sb->s_dev = 0;
40: #ifdef EXTFS_BITMAP
41: for(i = 0 ; i < EXT_I_MAP_SLOTS ; i++)
1.1.1.2 ! root 42: brelse(sb->u.ext_sb.s_imap[i]);
1.1 root 43: for(i = 0 ; i < EXT_Z_MAP_SLOTS ; i++)
1.1.1.2 ! root 44: brelse(sb->u.ext_sb.s_zmap[i]);
1.1 root 45: #endif
46: #ifdef EXTFS_FREELIST
1.1.1.2 ! root 47: if (sb->u.ext_sb.s_imap[1])
! 48: brelse (sb->u.ext_sb.s_imap[1]);
! 49: if (sb->u.ext_sb.s_zmap[1])
! 50: brelse (sb->u.ext_sb.s_zmap[1]);
1.1 root 51: #endif
52: free_super(sb);
53: return;
54: }
55:
56: static struct super_operations ext_sops = {
57: ext_read_inode,
58: ext_write_inode,
59: ext_put_inode,
60: ext_put_super,
61: ext_write_super,
62: ext_statfs
63: };
64:
65: struct super_block *ext_read_super(struct super_block *s,void *data)
66: {
67: struct buffer_head *bh;
68: struct ext_super_block *es;
1.1.1.2 ! root 69: int dev = s->s_dev,block;
1.1 root 70: #ifdef EXTFS_BITMAP
71: int i;
72: #endif
73:
74: lock_super(s);
1.1.1.2 ! root 75: if (!(bh = bread(dev, 1, BLOCK_SIZE))) {
1.1 root 76: s->s_dev=0;
77: free_super(s);
78: printk("bread failed\n");
79: return NULL;
80: }
81: /* *((struct ext_super_block *) s) =
82: *((struct ext_super_block *) bh->b_data); */
83: es = (struct ext_super_block *) bh->b_data;
1.1.1.2 ! root 84: s->s_blocksize = 1024;
! 85: s->u.ext_sb.s_ninodes = es->s_ninodes;
! 86: s->u.ext_sb.s_nzones = es->s_nzones;
1.1 root 87: #ifdef EXTFS_BITMAP
1.1.1.2 ! root 88: s->u.ext_sb.s_imap_blocks = es->s_imap_blocks;
! 89: s->u.ext_sb.s_zmap_blocks = es->s_zmap_blocks;
1.1 root 90: #endif
1.1.1.2 ! root 91: s->u.ext_sb.s_firstdatazone = es->s_firstdatazone;
! 92: s->u.ext_sb.s_log_zone_size = es->s_log_zone_size;
! 93: s->u.ext_sb.s_max_size = es->s_max_size;
1.1 root 94: s->s_magic = es->s_magic;
95: #ifdef EXTFS_FREELIST
1.1.1.2 ! root 96: s->u.ext_sb.s_zmap[0] = (struct buffer_head *) es->s_firstfreeblock;
! 97: s->u.ext_sb.s_zmap[2] = (struct buffer_head *) es->s_freeblockscount;
! 98: s->u.ext_sb.s_imap[0] = (struct buffer_head *) es->s_firstfreeinode;
! 99: s->u.ext_sb.s_imap[2] = (struct buffer_head *) es->s_freeinodescount;
1.1 root 100: #endif
101: brelse(bh);
102: if (s->s_magic != EXT_SUPER_MAGIC) {
103: s->s_dev = 0;
104: free_super(s);
105: printk("magic match failed\n");
106: return NULL;
107: }
108: #ifdef EXTFS_BITMAP
109: for (i=0;i < EXT_I_MAP_SLOTS;i++)
1.1.1.2 ! root 110: s->u.ext_sb.s_imap[i] = NULL;
1.1 root 111: for (i=0;i < EXT_Z_MAP_SLOTS;i++)
1.1.1.2 ! root 112: s->u.ext_sb.s_zmap[i] = NULL;
1.1 root 113: block=2;
1.1.1.2 ! root 114: for (i=0 ; i < s->u.ext_sb.s_imap_blocks ; i++)
! 115: if (s->u.ext_sb.s_imap[i]=bread(dev, block, BLOCK_SIZE))
1.1 root 116: block++;
117: else
118: break;
1.1.1.2 ! root 119: for (i=0 ; i < s->u.ext_sb.s_zmap_blocks ; i++)
! 120: if (s->u.ext_sb.s_zmap[i]=bread(dev, block, BLOCK_SIZE))
1.1 root 121: block++;
122: else
123: break;
1.1.1.2 ! root 124: if (block != 2+s->u.ext_sb.s_imap_blocks+s->u.ext_sb.s_zmap_blocks) {
1.1 root 125: for(i=0;i<EXT_I_MAP_SLOTS;i++)
1.1.1.2 ! root 126: brelse(s->u.ext_sb.s_imap[i]);
1.1 root 127: for(i=0;i<EXT_Z_MAP_SLOTS;i++)
1.1.1.2 ! root 128: brelse(s->u.ext_sb.s_zmap[i]);
1.1 root 129: s->s_dev=0;
130: free_super(s);
131: printk("block failed\n");
132: return NULL;
133: }
1.1.1.2 ! root 134: s->u.ext_sb.s_imap[0]->b_data[0] |= 1;
! 135: s->u.ext_sb.s_zmap[0]->b_data[0] |= 1;
1.1 root 136: #endif
137: #ifdef EXTFS_FREELIST
1.1.1.2 ! root 138: if (!s->u.ext_sb.s_zmap[0])
! 139: s->u.ext_sb.s_zmap[1] = NULL;
1.1 root 140: else
1.1.1.2 ! root 141: if (!(s->u.ext_sb.s_zmap[1] = bread(dev, (unsigned long) s->u.ext_sb.s_zmap[0], BLOCK_SIZE))) {
1.1 root 142: printk ("ext_read_super: unable to read first free block\n");
143: s->s_dev = 0;
144: free_super(s);
145: return NULL;
146: }
1.1.1.2 ! root 147: if (!s->u.ext_sb.s_imap[0])
! 148: s->u.ext_sb.s_imap[1] = NULL;
1.1 root 149: else {
1.1.1.2 ! root 150: block = 2 + (((unsigned long) s->u.ext_sb.s_imap[0]) - 1) / EXT_INODES_PER_BLOCK;
! 151: if (!(s->u.ext_sb.s_imap[1] = bread(dev, block, BLOCK_SIZE))) {
1.1 root 152: printk ("ext_read_super: unable to read first free inode block\n");
1.1.1.2 ! root 153: brelse(s->u.ext_sb.s_zmap[1]);
1.1 root 154: s->s_dev = 0;
155: free_super (s);
156: return NULL;
157: }
158: }
159: #endif
160:
161: free_super(s);
162: /* set up enough so that it can read an inode */
163: s->s_dev = dev;
164: s->s_op = &ext_sops;
165: if (!(s->s_mounted = iget(dev,EXT_ROOT_INO))) {
166: s->s_dev=0;
167: printk("get root inode failed\n");
168: return NULL;
169: }
170: return s;
171: }
172:
173: void ext_write_super (struct super_block *sb)
174: {
175: #ifdef EXTFS_FREELIST
176: struct buffer_head * bh;
177: struct ext_super_block * es;
178:
179: #ifdef EXTFS_DEBUG
180: printk ("ext_write_super called\n");
181: #endif
1.1.1.2 ! root 182: if (!(bh = bread(sb->s_dev, 1, BLOCK_SIZE))) {
1.1 root 183: printk ("ext_write_super: bread failed\n");
184: return;
185: }
186: es = (struct ext_super_block *) bh->b_data;
1.1.1.2 ! root 187: es->s_firstfreeblock = (unsigned long) sb->u.ext_sb.s_zmap[0];
! 188: es->s_freeblockscount = (unsigned long) sb->u.ext_sb.s_zmap[2];
! 189: es->s_firstfreeinode = (unsigned long) sb->u.ext_sb.s_imap[0];
! 190: es->s_freeinodescount = (unsigned long) sb->u.ext_sb.s_imap[2];
1.1 root 191: bh->b_dirt = 1;
192: brelse (bh);
193: sb->s_dirt = 0;
194: #endif
195: }
196:
197: void ext_statfs (struct super_block *sb, struct statfs *buf)
198: {
199: long tmp;
200:
201: put_fs_long(EXT_SUPER_MAGIC, &buf->f_type);
202: put_fs_long(1024, &buf->f_bsize);
1.1.1.2 ! root 203: put_fs_long(sb->u.ext_sb.s_nzones << sb->u.ext_sb.s_log_zone_size, &buf->f_blocks);
1.1 root 204: tmp = ext_count_free_blocks(sb);
205: put_fs_long(tmp, &buf->f_bfree);
206: put_fs_long(tmp, &buf->f_bavail);
1.1.1.2 ! root 207: put_fs_long(sb->u.ext_sb.s_ninodes, &buf->f_files);
1.1 root 208: put_fs_long(ext_count_free_inodes(sb), &buf->f_ffree);
209: /* Don't know what value to put in buf->f_fsid */
210: }
211:
212: static int _ext_bmap(struct inode * inode,int block,int create)
213: {
214: struct buffer_head * bh;
215: int i;
216:
217: if (block<0) {
218: printk("_ext_bmap: block<0");
219: return 0;
220: }
221: if (block >= 9+256+256*256+256*256*256) {
222: printk("_ext_bmap: block>big");
223: return 0;
224: }
225: if (block<9) {
226: if (create && !inode->i_data[block])
227: if (inode->i_data[block]=ext_new_block(inode->i_dev)) {
228: inode->i_ctime=CURRENT_TIME;
229: inode->i_dirt=1;
230: }
231: return inode->i_data[block];
232: }
233: block -= 9;
234: if (block<256) {
235: if (create && !inode->i_data[9])
236: if (inode->i_data[9]=ext_new_block(inode->i_dev)) {
237: inode->i_dirt=1;
238: inode->i_ctime=CURRENT_TIME;
239: }
240: if (!inode->i_data[9])
241: return 0;
1.1.1.2 ! root 242: if (!(bh = bread(inode->i_dev, inode->i_data[9], BLOCK_SIZE)))
1.1 root 243: return 0;
244: i = ((unsigned long *) (bh->b_data))[block];
245: if (create && !i)
246: if (i=ext_new_block(inode->i_dev)) {
247: ((unsigned long *) (bh->b_data))[block]=i;
248: bh->b_dirt=1;
249: }
250: brelse(bh);
251: return i;
252: }
253: block -= 256;
254: if (block<256*256) {
255: if (create && !inode->i_data[10])
256: if (inode->i_data[10]=ext_new_block(inode->i_dev)) {
257: inode->i_dirt=1;
258: inode->i_ctime=CURRENT_TIME;
259: }
260: if (!inode->i_data[10])
261: return 0;
1.1.1.2 ! root 262: if (!(bh=bread(inode->i_dev, inode->i_data[10], BLOCK_SIZE)))
1.1 root 263: return 0;
264: i = ((unsigned long *)bh->b_data)[block>>8];
265: if (create && !i)
266: if (i=ext_new_block(inode->i_dev)) {
267: ((unsigned long *) (bh->b_data))[block>>8]=i;
268: bh->b_dirt=1;
269: }
270: brelse(bh);
271: if (!i)
272: return 0;
1.1.1.2 ! root 273: if (!(bh=bread(inode->i_dev, i, BLOCK_SIZE)))
1.1 root 274: return 0;
275: i = ((unsigned long *)bh->b_data)[block&255];
276: if (create && !i)
277: if (i=ext_new_block(inode->i_dev)) {
278: ((unsigned long *) (bh->b_data))[block&255]=i;
279: bh->b_dirt=1;
280: }
281: brelse(bh);
282: return i;
283: }
1.1.1.2 ! root 284: if (create && !inode->i_data[11])
! 285: if (inode->i_data[11] = ext_new_block(inode->i_dev)) {
! 286: inode->i_dirt = 1;
! 287: inode->i_ctime = CURRENT_TIME;
! 288: }
! 289: if (!inode->i_data[11])
! 290: return 0;
! 291: if (!(bh = bread(inode->i_dev, inode->i_data[11], BLOCK_SIZE)))
! 292: return 0;
! 293: i = ((unsigned long *) bh->b_data)[block >> 16];
! 294: if (create && !i)
! 295: if (i = ext_new_block(inode->i_dev)) {
! 296: ((unsigned long *) bh->b_data)[block >> 16] = i;
! 297: bh->b_dirt = 1;
! 298: }
! 299: brelse (bh);
! 300: if (!i)
! 301: return 0;
! 302: if (!(bh = bread(inode->i_dev, i, BLOCK_SIZE)))
! 303: return 0;
! 304: i = ((unsigned long *) bh->b_data)[(block >> 8) & 255];
! 305: if (create && !i)
! 306: if (i = ext_new_block(inode->i_dev)) {
! 307: ((unsigned long *) bh->b_data)[(block >> 8) & 255] = i;
! 308: bh->b_dirt = 1;
! 309: }
! 310: brelse (bh);
! 311: if (!i)
! 312: return 0;
! 313: if (!(bh = bread(inode->i_dev, i, BLOCK_SIZE)))
! 314: return 0;
! 315: i = ((unsigned long *) bh->b_data)[block & 255];
! 316: if (create && !i)
! 317: if (i = ext_new_block(inode->i_dev)) {
! 318: ((unsigned long *) bh->b_data)[block & 255] = i;
! 319: bh->b_dirt = 1;
! 320: }
! 321: brelse (bh);
! 322: return i;
! 323:
1.1 root 324: printk("ext_bmap: triple indirection not yet implemented\n");
325: return 0;
326: }
327:
328: int ext_bmap(struct inode * inode,int block)
329: {
330: return _ext_bmap(inode,block,0);
331: }
332:
333: int ext_create_block(struct inode * inode, int block)
334: {
335: return _ext_bmap(inode,block,1);
336: }
337:
338: void ext_read_inode(struct inode * inode)
339: {
340: struct buffer_head * bh;
341: struct ext_inode * raw_inode;
342: int block;
343:
344: #ifdef EXTFS_BITMAP
1.1.1.2 ! root 345: block = 2 + inode->i_sb->u.ext_sb.s_imap_blocks + inode->i_sb->u.ext_sb.s_zmap_blocks +
1.1 root 346: (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
347: #endif
348: #ifdef EXTFS_FREELIST
349: block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
350: #endif
1.1.1.2 ! root 351: if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
1.1 root 352: panic("unable to read i-node block");
353: raw_inode = ((struct ext_inode *) bh->b_data) +
354: (inode->i_ino-1)%EXT_INODES_PER_BLOCK;
355: inode->i_mode = raw_inode->i_mode;
356: inode->i_uid = raw_inode->i_uid;
357: inode->i_gid = raw_inode->i_gid;
358: inode->i_nlink = raw_inode->i_nlinks;
359: inode->i_size = raw_inode->i_size;
360: inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
361: if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
362: inode->i_rdev = raw_inode->i_zone[0];
363: else for (block = 0; block < 12; block++)
364: inode->i_data[block] = raw_inode->i_zone[block];
365: brelse(bh);
366: inode->i_op = NULL;
367: if (S_ISREG(inode->i_mode))
368: inode->i_op = &ext_file_inode_operations;
369: else if (S_ISDIR(inode->i_mode))
370: inode->i_op = &ext_dir_inode_operations;
371: else if (S_ISLNK(inode->i_mode))
372: inode->i_op = &ext_symlink_inode_operations;
373: else if (S_ISCHR(inode->i_mode))
374: inode->i_op = &ext_chrdev_inode_operations;
375: else if (S_ISBLK(inode->i_mode))
376: inode->i_op = &ext_blkdev_inode_operations;
377: else if (S_ISFIFO(inode->i_mode)) {
378: inode->i_op = &ext_fifo_inode_operations;
379: inode->i_size = 0;
380: inode->i_pipe = 1;
381: PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
382: PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
383: }
384: }
385:
386: void ext_write_inode(struct inode * inode)
387: {
388: struct buffer_head * bh;
389: struct ext_inode * raw_inode;
390: int block;
391:
392: #ifdef EXTFS_BITMAP
1.1.1.2 ! root 393: block = 2 + inode->i_sb->u.ext_sb.s_imap_blocks + inode->i_sb->u.ext_sb.s_zmap_blocks +
1.1 root 394: (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
395: #endif
396: #ifdef EXTFS_FREELIST
397: block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
398: #endif
1.1.1.2 ! root 399: if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
1.1 root 400: panic("unable to read i-node block");
401: raw_inode = ((struct ext_inode *)bh->b_data) +
402: (inode->i_ino-1)%EXT_INODES_PER_BLOCK;
403: raw_inode->i_mode = inode->i_mode;
404: raw_inode->i_uid = inode->i_uid;
405: raw_inode->i_gid = inode->i_gid;
406: raw_inode->i_nlinks = inode->i_nlink;
407: raw_inode->i_size = inode->i_size;
408: raw_inode->i_time = inode->i_mtime;
409: if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
410: raw_inode->i_zone[0] = inode->i_rdev;
411: else for (block = 0; block < 12; block++)
412: raw_inode->i_zone[block] = inode->i_data[block];
413: bh->b_dirt=1;
414: inode->i_dirt=0;
415: brelse(bh);
416: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.