home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / fs / ext / inode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-01  |  10.4 KB  |  445 lines

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