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

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