home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / fs / minix / inode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-10  |  13.1 KB  |  550 lines

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