root/fs/minix/inode.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. minix_put_inode
  2. minix_put_super
  3. minix_read_super
  4. minix_statfs
  5. block_bmap
  6. minix_bmap
  7. inode_getblk
  8. block_getblk
  9. minix_getblk
  10. minix_bread
  11. minix_read_inode
  12. minix_update_inode
  13. minix_write_inode
  14. minix_sync_inode

   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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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 void minix_put_super(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
  29 {
  30         int i;
  31 
  32         lock_super(sb);
  33         sb->s_dev = 0;
  34         for(i = 0 ; i < MINIX_I_MAP_SLOTS ; i++)
  35                 brelse(sb->u.minix_sb.s_imap[i]);
  36         for(i = 0 ; i < MINIX_Z_MAP_SLOTS ; i++)
  37                 brelse(sb->u.minix_sb.s_zmap[i]);
  38         unlock_super(sb);
  39         return;
  40 }
  41 
  42 static struct super_operations minix_sops = { 
  43         minix_read_inode,
  44         NULL,
  45         minix_write_inode,
  46         minix_put_inode,
  47         minix_put_super,
  48         NULL,
  49         minix_statfs,
  50         NULL
  51 };
  52 
  53 struct super_block *minix_read_super(struct super_block *s,void *data, 
     /* [previous][next][first][last][top][bottom][index][help] */
  54                                      int silent)
  55 {
  56         struct buffer_head *bh;
  57         struct minix_super_block *ms;
  58         int i,dev=s->s_dev,block;
  59 
  60         if (32 != sizeof (struct minix_inode))
  61                 panic("bad i-node size");
  62         lock_super(s);
  63         if (!(bh = bread(dev,1,BLOCK_SIZE))) {
  64                 s->s_dev=0;
  65                 unlock_super(s);
  66                 printk("MINIX-fs: unable to read superblock\n");
  67                 return NULL;
  68         }
  69         ms = (struct minix_super_block *) bh->b_data;
  70         s->s_blocksize = 1024;
  71         s->s_blocksize_bits = 10;
  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;
  79         s->s_magic = ms->s_magic;
  80         brelse(bh);
  81         if (s->s_magic == MINIX_SUPER_MAGIC) {
  82                 s->u.minix_sb.s_dirsize = 16;
  83                 s->u.minix_sb.s_namelen = 14;
  84         } else if (s->s_magic == MINIX_SUPER_MAGIC2) {
  85                 s->u.minix_sb.s_dirsize = 32;
  86                 s->u.minix_sb.s_namelen = 30;
  87         } else {
  88                 s->s_dev = 0;
  89                 unlock_super(s);
  90                 if (!silent)
  91                         printk("VFS: Can't find a minix filesystem on dev 0x%04x.\n",
  92                                    dev);
  93                 return NULL;
  94         }
  95         for (i=0;i < MINIX_I_MAP_SLOTS;i++)
  96                 s->u.minix_sb.s_imap[i] = NULL;
  97         for (i=0;i < MINIX_Z_MAP_SLOTS;i++)
  98                 s->u.minix_sb.s_zmap[i] = NULL;
  99         block=2;
 100         for (i=0 ; i < s->u.minix_sb.s_imap_blocks ; i++)
 101                 if ((s->u.minix_sb.s_imap[i]=bread(dev,block,BLOCK_SIZE)) != NULL)
 102                         block++;
 103                 else
 104                         break;
 105         for (i=0 ; i < s->u.minix_sb.s_zmap_blocks ; i++)
 106                 if ((s->u.minix_sb.s_zmap[i]=bread(dev,block,BLOCK_SIZE)) != NULL)
 107                         block++;
 108                 else
 109                         break;
 110         if (block != 2+s->u.minix_sb.s_imap_blocks+s->u.minix_sb.s_zmap_blocks) {
 111                 for(i=0;i<MINIX_I_MAP_SLOTS;i++)
 112                         brelse(s->u.minix_sb.s_imap[i]);
 113                 for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
 114                         brelse(s->u.minix_sb.s_zmap[i]);
 115                 s->s_dev=0;
 116                 unlock_super(s);
 117                 printk("MINIX-fs: bad superblock or unable to read bitmaps\n");
 118                 return NULL;
 119         }
 120         set_bit(0,s->u.minix_sb.s_imap[0]->b_data);
 121         set_bit(0,s->u.minix_sb.s_zmap[0]->b_data);
 122         /* set up enough so that it can read an inode */
 123         s->s_dev = dev;
 124         s->s_op = &minix_sops;
 125         s->s_mounted = iget(s,MINIX_ROOT_INO);
 126         unlock_super(s);
 127         if (!s->s_mounted) {
 128                 s->s_dev = 0;
 129                 printk("MINIX-fs: get root inode failed\n");
 130                 return NULL;
 131         }
 132         return s;
 133 }
 134 
 135 void minix_statfs(struct super_block *sb, struct statfs *buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 136 {
 137         long tmp;
 138 
 139         put_fs_long(MINIX_SUPER_MAGIC, &buf->f_type);
 140         put_fs_long(1024, &buf->f_bsize);
 141         tmp = sb->u.minix_sb.s_nzones - sb->u.minix_sb.s_firstdatazone;
 142         tmp <<= sb->u.minix_sb.s_log_zone_size;
 143         put_fs_long(tmp, &buf->f_blocks);
 144         tmp = minix_count_free_blocks(sb);
 145         put_fs_long(tmp, &buf->f_bfree);
 146         put_fs_long(tmp, &buf->f_bavail);
 147         put_fs_long(sb->u.minix_sb.s_ninodes, &buf->f_files);
 148         put_fs_long(minix_count_free_inodes(sb), &buf->f_ffree);
 149         put_fs_long(sb->u.minix_sb.s_namelen, &buf->f_namelen);
 150         /* Don't know what value to put in buf->f_fsid */
 151 }
 152 
 153 #define inode_bmap(inode,nr) ((inode)->u.minix_i.i_data[(nr)])
 154 
 155 static int block_bmap(struct buffer_head * bh, int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 156 {
 157         int tmp;
 158 
 159         if (!bh)
 160                 return 0;
 161         tmp = ((unsigned short *) bh->b_data)[nr];
 162         brelse(bh);
 163         return tmp;
 164 }
 165 
 166 int minix_bmap(struct inode * inode,int block)
     /* [previous][next][first][last][top][bottom][index][help] */
 167 {
 168         int i;
 169 
 170         if (block<0) {
 171                 printk("minix_bmap: block<0");
 172                 return 0;
 173         }
 174         if (block >= 7+512+512*512) {
 175                 printk("minix_bmap: block>big");
 176                 return 0;
 177         }
 178         if (block < 7)
 179                 return inode_bmap(inode,block);
 180         block -= 7;
 181         if (block < 512) {
 182                 i = inode_bmap(inode,7);
 183                 if (!i)
 184                         return 0;
 185                 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
 186         }
 187         block -= 512;
 188         i = inode_bmap(inode,8);
 189         if (!i)
 190                 return 0;
 191         i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>9);
 192         if (!i)
 193                 return 0;
 194         return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 511);
 195 }
 196 
 197 static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
     /* [previous][next][first][last][top][bottom][index][help] */
 198 {
 199         int tmp;
 200         unsigned short *p;
 201         struct buffer_head * result;
 202 
 203         p = inode->u.minix_i.i_data + nr;
 204 repeat:
 205         tmp = *p;
 206         if (tmp) {
 207                 result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
 208                 if (tmp == *p)
 209                         return result;
 210                 brelse(result);
 211                 goto repeat;
 212         }
 213         if (!create)
 214                 return NULL;
 215         tmp = minix_new_block(inode->i_sb);
 216         if (!tmp)
 217                 return NULL;
 218         result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
 219         if (*p) {
 220                 minix_free_block(inode->i_sb,tmp);
 221                 brelse(result);
 222                 goto repeat;
 223         }
 224         *p = tmp;
 225         inode->i_ctime = CURRENT_TIME;
 226         inode->i_dirt = 1;
 227         return result;
 228 }
 229 
 230 static struct buffer_head * block_getblk(struct inode * inode, 
     /* [previous][next][first][last][top][bottom][index][help] */
 231         struct buffer_head * bh, int nr, int create)
 232 {
 233         int tmp;
 234         unsigned short *p;
 235         struct buffer_head * result;
 236 
 237         if (!bh)
 238                 return NULL;
 239         if (!bh->b_uptodate) {
 240                 ll_rw_block(READ, 1, &bh);
 241                 wait_on_buffer(bh);
 242                 if (!bh->b_uptodate) {
 243                         brelse(bh);
 244                         return NULL;
 245                 }
 246         }
 247         p = nr + (unsigned short *) bh->b_data;
 248 repeat:
 249         tmp = *p;
 250         if (tmp) {
 251                 result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
 252                 if (tmp == *p) {
 253                         brelse(bh);
 254                         return result;
 255                 }
 256                 brelse(result);
 257                 goto repeat;
 258         }
 259         if (!create) {
 260                 brelse(bh);
 261                 return NULL;
 262         }
 263         tmp = minix_new_block(inode->i_sb);
 264         if (!tmp) {
 265                 brelse(bh);
 266                 return NULL;
 267         }
 268         result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
 269         if (*p) {
 270                 minix_free_block(inode->i_sb,tmp);
 271                 brelse(result);
 272                 goto repeat;
 273         }
 274         *p = tmp;
 275         bh->b_dirt = 1;
 276         brelse(bh);
 277         return result;
 278 }
 279 
 280 struct buffer_head * minix_getblk(struct inode * inode, int block, int create)
     /* [previous][next][first][last][top][bottom][index][help] */
 281 {
 282         struct buffer_head * bh;
 283 
 284         if (block<0) {
 285                 printk("minix_getblk: block<0");
 286                 return NULL;
 287         }
 288         if (block >= 7+512+512*512) {
 289                 printk("minix_getblk: block>big");
 290                 return NULL;
 291         }
 292         if (block < 7)
 293                 return inode_getblk(inode,block,create);
 294         block -= 7;
 295         if (block < 512) {
 296                 bh = inode_getblk(inode,7,create);
 297                 return block_getblk(inode, bh, block, create);
 298         }
 299         block -= 512;
 300         bh = inode_getblk(inode,8,create);
 301         bh = block_getblk(inode, bh, block>>9, create);
 302         return block_getblk(inode, bh, block & 511, create);
 303 }
 304 
 305 struct buffer_head * minix_bread(struct inode * inode, int block, int create)
     /* [previous][next][first][last][top][bottom][index][help] */
 306 {
 307         struct buffer_head * bh;
 308 
 309         bh = minix_getblk(inode,block,create);
 310         if (!bh || bh->b_uptodate)
 311                 return bh;
 312         ll_rw_block(READ, 1, &bh);
 313         wait_on_buffer(bh);
 314         if (bh->b_uptodate)
 315                 return bh;
 316         brelse(bh);
 317         return NULL;
 318 }
 319 
 320 void minix_read_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 321 {
 322         struct buffer_head * bh;
 323         struct minix_inode * raw_inode;
 324         int block, ino;
 325 
 326         ino = inode->i_ino;
 327         inode->i_op = NULL;
 328         inode->i_mode = 0;
 329         if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
 330                 printk("Bad inode number on dev 0x%04x: %d is out of range\n",
 331                         inode->i_dev, ino);
 332                 return;
 333         }
 334         block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks +
 335                     inode->i_sb->u.minix_sb.s_zmap_blocks +
 336                     (ino-1)/MINIX_INODES_PER_BLOCK;
 337         if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE))) {
 338                 printk("Major problem: unable to read inode from dev 0x%04x\n",
 339                         inode->i_dev);
 340                 return;
 341         }
 342         raw_inode = ((struct minix_inode *) bh->b_data) +
 343                     (ino-1)%MINIX_INODES_PER_BLOCK;
 344         inode->i_mode = raw_inode->i_mode;
 345         inode->i_uid = raw_inode->i_uid;
 346         inode->i_gid = raw_inode->i_gid;
 347         inode->i_nlink = raw_inode->i_nlinks;
 348         inode->i_size = raw_inode->i_size;
 349         inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
 350         inode->i_blocks = inode->i_blksize = 0;
 351         if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 352                 inode->i_rdev = raw_inode->i_zone[0];
 353         else for (block = 0; block < 9; block++)
 354                 inode->u.minix_i.i_data[block] = raw_inode->i_zone[block];
 355         brelse(bh);
 356         if (S_ISREG(inode->i_mode))
 357                 inode->i_op = &minix_file_inode_operations;
 358         else if (S_ISDIR(inode->i_mode))
 359                 inode->i_op = &minix_dir_inode_operations;
 360         else if (S_ISLNK(inode->i_mode))
 361                 inode->i_op = &minix_symlink_inode_operations;
 362         else if (S_ISCHR(inode->i_mode))
 363                 inode->i_op = &chrdev_inode_operations;
 364         else if (S_ISBLK(inode->i_mode))
 365                 inode->i_op = &blkdev_inode_operations;
 366         else if (S_ISFIFO(inode->i_mode))
 367                 init_fifo(inode);
 368 }
 369 
 370 static struct buffer_head * minix_update_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 371 {
 372         struct buffer_head * bh;
 373         struct minix_inode * raw_inode;
 374         int ino, block;
 375 
 376         ino = inode->i_ino;
 377         if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
 378                 printk("Bad inode number on dev 0x%04x: %d is out of range\n",
 379                         inode->i_dev, ino);
 380                 inode->i_dirt = 0;
 381                 return 0;
 382         }
 383         block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
 384                 (ino-1)/MINIX_INODES_PER_BLOCK;
 385         if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) {
 386                 printk("unable to read i-node block\n");
 387                 inode->i_dirt = 0;
 388                 return 0;
 389         }
 390         raw_inode = ((struct minix_inode *)bh->b_data) +
 391                 (ino-1)%MINIX_INODES_PER_BLOCK;
 392         raw_inode->i_mode = inode->i_mode;
 393         raw_inode->i_uid = inode->i_uid;
 394         raw_inode->i_gid = inode->i_gid;
 395         raw_inode->i_nlinks = inode->i_nlink;
 396         raw_inode->i_size = inode->i_size;
 397         raw_inode->i_time = inode->i_mtime;
 398         if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 399                 raw_inode->i_zone[0] = inode->i_rdev;
 400         else for (block = 0; block < 9; block++)
 401                 raw_inode->i_zone[block] = inode->u.minix_i.i_data[block];
 402         inode->i_dirt=0;
 403         bh->b_dirt=1;
 404         return bh;
 405 }
 406 
 407 void minix_write_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 408 {
 409         struct buffer_head *bh;
 410         bh = minix_update_inode(inode);
 411         brelse(bh);
 412 }
 413 
 414 int minix_sync_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 415 {
 416         int err = 0;
 417         struct buffer_head *bh;
 418 
 419         bh = minix_update_inode(inode);
 420         if (bh && bh->b_dirt)
 421         {
 422                 ll_rw_block(WRITE, 1, &bh);
 423                 wait_on_buffer(bh);
 424                 if (bh->b_req && !bh->b_uptodate)
 425                 {
 426                         printk ("IO error syncing minix inode [%04x:%08x]\n",
 427                                 inode->i_dev, inode->i_ino);
 428                         err = -1;
 429                 }
 430         }
 431         else if (!bh)
 432                 err = -1;
 433         brelse (bh);
 434         return err;
 435 }

/* [previous][next][first][last][top][bottom][index][help] */