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_commit_super
  3. minix_write_super
  4. minix_put_super
  5. minix_remount
  6. minix_read_super
  7. minix_statfs
  8. block_bmap
  9. minix_bmap
  10. inode_getblk
  11. block_getblk
  12. minix_getblk
  13. minix_bread
  14. minix_read_inode
  15. minix_update_inode
  16. minix_write_inode
  17. minix_sync_inode
  18. init_module
  19. cleanup_module

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

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