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 / minix / inode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-03  |  12.4 KB  |  513 lines

  1. /*
  2.  *  linux/fs/minix/inode.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  */
  6.  
  7. #include <linux/sched.h>
  8. #include <linux/minix_fs.h>
  9. #include <linux/kernel.h>
  10. #include <linux/mm.h>
  11. #include <linux/string.h>
  12. #include <linux/stat.h>
  13. #include <linux/locks.h>
  14.  
  15. #include <asm/system.h>
  16. #include <asm/segment.h>
  17. #include <asm/bitops.h>
  18.  
  19. void minix_put_inode(struct inode *inode)
  20. {
  21.     if (inode->i_nlink)
  22.         return;
  23.     inode->i_size = 0;
  24.     minix_truncate(inode);
  25.     minix_free_inode(inode);
  26. }
  27.  
  28. static void minix_commit_super (struct super_block * sb,
  29.                    struct minix_super_block * ms)
  30. {
  31.     sb->u.minix_sb.s_sbh->b_dirt = 1;
  32.     sb->s_dirt = 0;
  33. }
  34.  
  35. void minix_write_super (struct super_block * sb)
  36. {
  37.     struct minix_super_block * ms;
  38.  
  39.     if (!(sb->s_flags & MS_RDONLY)) {
  40.         ms = sb->u.minix_sb.s_ms;
  41.  
  42.         if (ms->s_state & MINIX_VALID_FS)
  43.             ms->s_state &= ~MINIX_VALID_FS;
  44.         minix_commit_super (sb, ms);
  45.     }
  46.     sb->s_dirt = 0;
  47. }
  48.  
  49.  
  50. void minix_put_super(struct super_block *sb)
  51. {
  52.     int i;
  53.  
  54.     lock_super(sb);
  55.     if (!(sb->s_flags & MS_RDONLY)) {
  56.         sb->u.minix_sb.s_ms->s_state = sb->u.minix_sb.s_mount_state;
  57.         sb->u.minix_sb.s_sbh->b_dirt = 1;
  58.     }
  59.     sb->s_dev = 0;
  60.     for(i = 0 ; i < MINIX_I_MAP_SLOTS ; i++)
  61.         brelse(sb->u.minix_sb.s_imap[i]);
  62.     for(i = 0 ; i < MINIX_Z_MAP_SLOTS ; i++)
  63.         brelse(sb->u.minix_sb.s_zmap[i]);
  64.     brelse (sb->u.minix_sb.s_sbh);
  65.     unlock_super(sb);
  66.     return;
  67. }
  68.  
  69. static struct super_operations minix_sops = { 
  70.     minix_read_inode,
  71.     NULL,
  72.     minix_write_inode,
  73.     minix_put_inode,
  74.     minix_put_super,
  75.     minix_write_super,
  76.     minix_statfs,
  77.     minix_remount
  78. };
  79.  
  80. int minix_remount (struct super_block * sb, int * flags, char * data)
  81. {
  82.     struct minix_super_block * ms;
  83.  
  84.     ms = sb->u.minix_sb.s_ms;
  85.     if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
  86.         return 0;
  87.     if (*flags & MS_RDONLY) {
  88.         if (ms->s_state & MINIX_VALID_FS ||
  89.             !(sb->u.minix_sb.s_mount_state & MINIX_VALID_FS))
  90.             return 0;
  91.         /* Mounting a rw partition read-only. */
  92.         ms->s_state = sb->u.minix_sb.s_mount_state;
  93.         sb->u.minix_sb.s_sbh->b_dirt = 1;
  94.         sb->s_dirt = 1;
  95.         minix_commit_super (sb, ms);
  96.     }
  97.     else {
  98.           /* Mount a partition which is read-only, read-write. */
  99.         sb->u.minix_sb.s_mount_state = ms->s_state;
  100.         ms->s_state &= ~MINIX_VALID_FS;
  101.         sb->u.minix_sb.s_sbh->b_dirt = 1;
  102.         sb->s_dirt = 1;
  103.  
  104.         if (!(sb->u.minix_sb.s_mount_state & MINIX_VALID_FS))
  105.             printk ("MINIX-fs warning: remounting unchecked fs, "
  106.                 "running fsck is recommended.\n");
  107.         else if ((sb->u.minix_sb.s_mount_state & MINIX_ERROR_FS))
  108.             printk ("MINIX-fs warning: remounting fs with errors, "
  109.                 "running fsck is recommended.\n");
  110.     }
  111.     return 0;
  112. }
  113.  
  114.  
  115. struct super_block *minix_read_super(struct super_block *s,void *data, 
  116.                      int silent)
  117. {
  118.     struct buffer_head *bh;
  119.     struct minix_super_block *ms;
  120.     int i,dev=s->s_dev,block;
  121.  
  122.     if (32 != sizeof (struct minix_inode))
  123.         panic("bad i-node size");
  124.     lock_super(s);
  125.     if (!(bh = bread(dev,1,BLOCK_SIZE))) {
  126.         s->s_dev=0;
  127.         unlock_super(s);
  128.         printk("MINIX-fs: unable to read superblock\n");
  129.         return NULL;
  130.     }
  131.     ms = (struct minix_super_block *) bh->b_data;
  132.     s->u.minix_sb.s_ms = ms;
  133.     s->u.minix_sb.s_sbh = bh;
  134.     s->u.minix_sb.s_mount_state = ms->s_state;
  135.     s->s_blocksize = 1024;
  136.     s->s_blocksize_bits = 10;
  137.     s->u.minix_sb.s_ninodes = ms->s_ninodes;
  138.     s->u.minix_sb.s_nzones = ms->s_nzones;
  139.     s->u.minix_sb.s_imap_blocks = ms->s_imap_blocks;
  140.     s->u.minix_sb.s_zmap_blocks = ms->s_zmap_blocks;
  141.     s->u.minix_sb.s_firstdatazone = ms->s_firstdatazone;
  142.     s->u.minix_sb.s_log_zone_size = ms->s_log_zone_size;
  143.     s->u.minix_sb.s_max_size = ms->s_max_size;
  144.     s->s_magic = ms->s_magic;
  145.     if (s->s_magic == MINIX_SUPER_MAGIC) {
  146.         s->u.minix_sb.s_dirsize = 16;
  147.         s->u.minix_sb.s_namelen = 14;
  148.     } else if (s->s_magic == MINIX_SUPER_MAGIC2) {
  149.         s->u.minix_sb.s_dirsize = 32;
  150.         s->u.minix_sb.s_namelen = 30;
  151.     } else {
  152.         s->s_dev = 0;
  153.         unlock_super(s);
  154.         brelse(bh);
  155.         if (!silent)
  156.             printk("VFS: Can't find a minix filesystem on dev 0x%04x.\n", dev);
  157.         return NULL;
  158.     }
  159.     for (i=0;i < MINIX_I_MAP_SLOTS;i++)
  160.         s->u.minix_sb.s_imap[i] = NULL;
  161.     for (i=0;i < MINIX_Z_MAP_SLOTS;i++)
  162.         s->u.minix_sb.s_zmap[i] = NULL;
  163.     block=2;
  164.     for (i=0 ; i < s->u.minix_sb.s_imap_blocks ; i++)
  165.         if ((s->u.minix_sb.s_imap[i]=bread(dev,block,BLOCK_SIZE)) != NULL)
  166.             block++;
  167.         else
  168.             break;
  169.     for (i=0 ; i < s->u.minix_sb.s_zmap_blocks ; i++)
  170.         if ((s->u.minix_sb.s_zmap[i]=bread(dev,block,BLOCK_SIZE)) != NULL)
  171.             block++;
  172.         else
  173.             break;
  174.     if (block != 2+s->u.minix_sb.s_imap_blocks+s->u.minix_sb.s_zmap_blocks) {
  175.         for(i=0;i<MINIX_I_MAP_SLOTS;i++)
  176.             brelse(s->u.minix_sb.s_imap[i]);
  177.         for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
  178.             brelse(s->u.minix_sb.s_zmap[i]);
  179.         s->s_dev=0;
  180.         unlock_super(s);
  181.         brelse(bh);
  182.         printk("MINIX-fs: bad superblock or unable to read bitmaps\n");
  183.         return NULL;
  184.     }
  185.     set_bit(0,s->u.minix_sb.s_imap[0]->b_data);
  186.     set_bit(0,s->u.minix_sb.s_zmap[0]->b_data);
  187.     unlock_super(s);
  188.     /* set up enough so that it can read an inode */
  189.     s->s_dev = dev;
  190.     s->s_op = &minix_sops;
  191.     s->s_mounted = iget(s,MINIX_ROOT_INO);
  192.     if (!s->s_mounted) {
  193.         s->s_dev = 0;
  194.         brelse(bh);
  195.         printk("MINIX-fs: get root inode failed\n");
  196.         return NULL;
  197.     }
  198.     if (!(s->s_flags & MS_RDONLY)) {
  199.         ms->s_state &= ~MINIX_VALID_FS;
  200.         bh->b_dirt = 1;
  201.         s->s_dirt = 1;
  202.     }
  203.     if (!(s->u.minix_sb.s_mount_state & MINIX_VALID_FS))
  204.         printk ("MINIX-fs: mounting unchecked file system, "
  205.             "running fsck is recommended.\n");
  206.      else if (s->u.minix_sb.s_mount_state & MINIX_ERROR_FS)
  207.         printk ("MINIX-fs: mounting file system with errors, "
  208.             "running fsck is recommended.\n");
  209.     return s;
  210. }
  211.  
  212. void minix_statfs(struct super_block *sb, struct statfs *buf)
  213. {
  214.     long tmp;
  215.  
  216.     put_fs_long(MINIX_SUPER_MAGIC, &buf->f_type);
  217.     put_fs_long(1024, &buf->f_bsize);
  218.     tmp = sb->u.minix_sb.s_nzones - sb->u.minix_sb.s_firstdatazone;
  219.     tmp <<= sb->u.minix_sb.s_log_zone_size;
  220.     put_fs_long(tmp, &buf->f_blocks);
  221.     tmp = minix_count_free_blocks(sb);
  222.     put_fs_long(tmp, &buf->f_bfree);
  223.     put_fs_long(tmp, &buf->f_bavail);
  224.     put_fs_long(sb->u.minix_sb.s_ninodes, &buf->f_files);
  225.     put_fs_long(minix_count_free_inodes(sb), &buf->f_ffree);
  226.     put_fs_long(sb->u.minix_sb.s_namelen, &buf->f_namelen);
  227.     /* Don't know what value to put in buf->f_fsid */
  228. }
  229.  
  230. #define inode_bmap(inode,nr) ((inode)->u.minix_i.i_data[(nr)])
  231.  
  232. static int block_bmap(struct buffer_head * bh, int nr)
  233. {
  234.     int tmp;
  235.  
  236.     if (!bh)
  237.         return 0;
  238.     tmp = ((unsigned short *) bh->b_data)[nr];
  239.     brelse(bh);
  240.     return tmp;
  241. }
  242.  
  243. int minix_bmap(struct inode * inode,int block)
  244. {
  245.     int i;
  246.  
  247.     if (block<0) {
  248.         printk("minix_bmap: block<0");
  249.         return 0;
  250.     }
  251.     if (block >= 7+512+512*512) {
  252.         printk("minix_bmap: block>big");
  253.         return 0;
  254.     }
  255.     if (block < 7)
  256.         return inode_bmap(inode,block);
  257.     block -= 7;
  258.     if (block < 512) {
  259.         i = inode_bmap(inode,7);
  260.         if (!i)
  261.             return 0;
  262.         return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
  263.     }
  264.     block -= 512;
  265.     i = inode_bmap(inode,8);
  266.     if (!i)
  267.         return 0;
  268.     i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>9);
  269.     if (!i)
  270.         return 0;
  271.     return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 511);
  272. }
  273.  
  274. static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
  275. {
  276.     int tmp;
  277.     unsigned short *p;
  278.     struct buffer_head * result;
  279.  
  280.     p = inode->u.minix_i.i_data + nr;
  281. repeat:
  282.     tmp = *p;
  283.     if (tmp) {
  284.         result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
  285.         if (tmp == *p)
  286.             return result;
  287.         brelse(result);
  288.         goto repeat;
  289.     }
  290.     if (!create)
  291.         return NULL;
  292.     tmp = minix_new_block(inode->i_sb);
  293.     if (!tmp)
  294.         return NULL;
  295.     result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
  296.     if (*p) {
  297.         minix_free_block(inode->i_sb,tmp);
  298.         brelse(result);
  299.         goto repeat;
  300.     }
  301.     *p = tmp;
  302.     inode->i_ctime = CURRENT_TIME;
  303.     inode->i_dirt = 1;
  304.     return result;
  305. }
  306.  
  307. static struct buffer_head * block_getblk(struct inode * inode, 
  308.     struct buffer_head * bh, int nr, int create)
  309. {
  310.     int tmp;
  311.     unsigned short *p;
  312.     struct buffer_head * result;
  313.  
  314.     if (!bh)
  315.         return NULL;
  316.     if (!bh->b_uptodate) {
  317.         ll_rw_block(READ, 1, &bh);
  318.         wait_on_buffer(bh);
  319.         if (!bh->b_uptodate) {
  320.             brelse(bh);
  321.             return NULL;
  322.         }
  323.     }
  324.     p = nr + (unsigned short *) bh->b_data;
  325. repeat:
  326.     tmp = *p;
  327.     if (tmp) {
  328.         result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
  329.         if (tmp == *p) {
  330.             brelse(bh);
  331.             return result;
  332.         }
  333.         brelse(result);
  334.         goto repeat;
  335.     }
  336.     if (!create) {
  337.         brelse(bh);
  338.         return NULL;
  339.     }
  340.     tmp = minix_new_block(inode->i_sb);
  341.     if (!tmp) {
  342.         brelse(bh);
  343.         return NULL;
  344.     }
  345.     result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
  346.     if (*p) {
  347.         minix_free_block(inode->i_sb,tmp);
  348.         brelse(result);
  349.         goto repeat;
  350.     }
  351.     *p = tmp;
  352.     bh->b_dirt = 1;
  353.     brelse(bh);
  354.     return result;
  355. }
  356.  
  357. struct buffer_head * minix_getblk(struct inode * inode, int block, int create)
  358. {
  359.     struct buffer_head * bh;
  360.  
  361.     if (block<0) {
  362.         printk("minix_getblk: block<0");
  363.         return NULL;
  364.     }
  365.     if (block >= 7+512+512*512) {
  366.         printk("minix_getblk: block>big");
  367.         return NULL;
  368.     }
  369.     if (block < 7)
  370.         return inode_getblk(inode,block,create);
  371.     block -= 7;
  372.     if (block < 512) {
  373.         bh = inode_getblk(inode,7,create);
  374.         return block_getblk(inode, bh, block, create);
  375.     }
  376.     block -= 512;
  377.     bh = inode_getblk(inode,8,create);
  378.     bh = block_getblk(inode, bh, block>>9, create);
  379.     return block_getblk(inode, bh, block & 511, create);
  380. }
  381.  
  382. struct buffer_head * minix_bread(struct inode * inode, int block, int create)
  383. {
  384.     struct buffer_head * bh;
  385.  
  386.     bh = minix_getblk(inode,block,create);
  387.     if (!bh || bh->b_uptodate)
  388.         return bh;
  389.     ll_rw_block(READ, 1, &bh);
  390.     wait_on_buffer(bh);
  391.     if (bh->b_uptodate)
  392.         return bh;
  393.     brelse(bh);
  394.     return NULL;
  395. }
  396.  
  397. void minix_read_inode(struct inode * inode)
  398. {
  399.     struct buffer_head * bh;
  400.     struct minix_inode * raw_inode;
  401.     int block, ino;
  402.  
  403.     ino = inode->i_ino;
  404.     inode->i_op = NULL;
  405.     inode->i_mode = 0;
  406.     if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
  407.         printk("Bad inode number on dev 0x%04x: %d is out of range\n",
  408.             inode->i_dev, ino);
  409.         return;
  410.     }
  411.     block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks +
  412.             inode->i_sb->u.minix_sb.s_zmap_blocks +
  413.             (ino-1)/MINIX_INODES_PER_BLOCK;
  414.     if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE))) {
  415.         printk("Major problem: unable to read inode from dev 0x%04x\n",
  416.             inode->i_dev);
  417.         return;
  418.     }
  419.     raw_inode = ((struct minix_inode *) bh->b_data) +
  420.             (ino-1)%MINIX_INODES_PER_BLOCK;
  421.     inode->i_mode = raw_inode->i_mode;
  422.     inode->i_uid = raw_inode->i_uid;
  423.     inode->i_gid = raw_inode->i_gid;
  424.     inode->i_nlink = raw_inode->i_nlinks;
  425.     inode->i_size = raw_inode->i_size;
  426.     inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
  427.     inode->i_blocks = inode->i_blksize = 0;
  428.     if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
  429.         inode->i_rdev = raw_inode->i_zone[0];
  430.     else for (block = 0; block < 9; block++)
  431.         inode->u.minix_i.i_data[block] = raw_inode->i_zone[block];
  432.     brelse(bh);
  433.     if (S_ISREG(inode->i_mode))
  434.         inode->i_op = &minix_file_inode_operations;
  435.     else if (S_ISDIR(inode->i_mode))
  436.         inode->i_op = &minix_dir_inode_operations;
  437.     else if (S_ISLNK(inode->i_mode))
  438.         inode->i_op = &minix_symlink_inode_operations;
  439.     else if (S_ISCHR(inode->i_mode))
  440.         inode->i_op = &chrdev_inode_operations;
  441.     else if (S_ISBLK(inode->i_mode))
  442.         inode->i_op = &blkdev_inode_operations;
  443.     else if (S_ISFIFO(inode->i_mode))
  444.         init_fifo(inode);
  445. }
  446.  
  447. static struct buffer_head * minix_update_inode(struct inode * inode)
  448. {
  449.     struct buffer_head * bh;
  450.     struct minix_inode * raw_inode;
  451.     int ino, block;
  452.  
  453.     ino = inode->i_ino;
  454.     if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
  455.         printk("Bad inode number on dev 0x%04x: %d is out of range\n",
  456.             inode->i_dev, ino);
  457.         inode->i_dirt = 0;
  458.         return 0;
  459.     }
  460.     block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
  461.         (ino-1)/MINIX_INODES_PER_BLOCK;
  462.     if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) {
  463.         printk("unable to read i-node block\n");
  464.         inode->i_dirt = 0;
  465.         return 0;
  466.     }
  467.     raw_inode = ((struct minix_inode *)bh->b_data) +
  468.         (ino-1)%MINIX_INODES_PER_BLOCK;
  469.     raw_inode->i_mode = inode->i_mode;
  470.     raw_inode->i_uid = inode->i_uid;
  471.     raw_inode->i_gid = inode->i_gid;
  472.     raw_inode->i_nlinks = inode->i_nlink;
  473.     raw_inode->i_size = inode->i_size;
  474.     raw_inode->i_time = inode->i_mtime;
  475.     if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
  476.         raw_inode->i_zone[0] = inode->i_rdev;
  477.     else for (block = 0; block < 9; block++)
  478.         raw_inode->i_zone[block] = inode->u.minix_i.i_data[block];
  479.     inode->i_dirt=0;
  480.     bh->b_dirt=1;
  481.     return bh;
  482. }
  483.  
  484. void minix_write_inode(struct inode * inode)
  485. {
  486.     struct buffer_head *bh;
  487.     bh = minix_update_inode(inode);
  488.     brelse(bh);
  489. }
  490.  
  491. int minix_sync_inode(struct inode * inode)
  492. {
  493.     int err = 0;
  494.     struct buffer_head *bh;
  495.  
  496.     bh = minix_update_inode(inode);
  497.     if (bh && bh->b_dirt)
  498.     {
  499.         ll_rw_block(WRITE, 1, &bh);
  500.         wait_on_buffer(bh);
  501.         if (bh->b_req && !bh->b_uptodate)
  502.         {
  503.             printk ("IO error syncing minix inode [%04x:%08lx]\n",
  504.                 inode->i_dev, inode->i_ino);
  505.             err = -1;
  506.         }
  507.     }
  508.     else if (!bh)
  509.         err = -1;
  510.     brelse (bh);
  511.     return err;
  512. }
  513.