root/fs/minix/inode.c

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

DEFINITIONS

This source file includes following definitions.
  1. wait_on_buffer
  2. minix_put_inode
  3. minix_put_super
  4. minix_read_super
  5. minix_statfs
  6. block_bmap
  7. minix_bmap
  8. inode_getblk
  9. block_getblk
  10. minix_getblk
  11. minix_bread
  12. minix_read_inode
  13. minix_write_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 
  14 #include <asm/system.h>
  15 #include <asm/segment.h>
  16 
  17 int sync_dev(int dev);
  18 
  19 static inline void wait_on_buffer(struct buffer_head * bh)
     /* [previous][next][first][last][top][bottom][index][help] */
  20 {
  21         cli();
  22         while (bh->b_lock)
  23                 sleep_on(&bh->b_wait);
  24         sti();
  25 }
  26 
  27 void minix_put_inode(struct inode *inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  28 {
  29         inode->i_size = 0;
  30         minix_truncate(inode);
  31         minix_free_inode(inode);
  32 }
  33 
  34 void minix_put_super(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
  35 {
  36         int i;
  37 
  38         lock_super(sb);
  39         sb->s_dev = 0;
  40         for(i = 0 ; i < MINIX_I_MAP_SLOTS ; i++)
  41                 brelse(sb->u.minix_sb.s_imap[i]);
  42         for(i = 0 ; i < MINIX_Z_MAP_SLOTS ; i++)
  43                 brelse(sb->u.minix_sb.s_zmap[i]);
  44         free_super(sb);
  45         return;
  46 }
  47 
  48 static struct super_operations minix_sops = { 
  49         minix_read_inode,
  50         minix_write_inode,
  51         minix_put_inode,
  52         minix_put_super,
  53         NULL,
  54         minix_statfs
  55 };
  56 
  57 struct super_block *minix_read_super(struct super_block *s,void *data)
     /* [previous][next][first][last][top][bottom][index][help] */
  58 {
  59         struct buffer_head *bh;
  60         struct minix_super_block *ms;
  61         int i,dev=s->s_dev,block;
  62 
  63         lock_super(s);
  64         if (!(bh = bread(dev,1,BLOCK_SIZE))) {
  65                 s->s_dev=0;
  66                 free_super(s);
  67                 printk("bread failed\n");
  68                 return NULL;
  69         }
  70         ms = (struct minix_super_block *) bh->b_data;
  71         s->s_blocksize = 1024;
  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->s_dev = 0;
  83                 free_super(s);
  84                 printk("magic match failed\n");
  85                 return NULL;
  86         }
  87         for (i=0;i < MINIX_I_MAP_SLOTS;i++)
  88                 s->u.minix_sb.s_imap[i] = NULL;
  89         for (i=0;i < MINIX_Z_MAP_SLOTS;i++)
  90                 s->u.minix_sb.s_zmap[i] = NULL;
  91         block=2;
  92         for (i=0 ; i < s->u.minix_sb.s_imap_blocks ; i++)
  93                 if (s->u.minix_sb.s_imap[i]=bread(dev,block,BLOCK_SIZE))
  94                         block++;
  95                 else
  96                         break;
  97         for (i=0 ; i < s->u.minix_sb.s_zmap_blocks ; i++)
  98                 if (s->u.minix_sb.s_zmap[i]=bread(dev,block,BLOCK_SIZE))
  99                         block++;
 100                 else
 101                         break;
 102         if (block != 2+s->u.minix_sb.s_imap_blocks+s->u.minix_sb.s_zmap_blocks) {
 103                 for(i=0;i<MINIX_I_MAP_SLOTS;i++)
 104                         brelse(s->u.minix_sb.s_imap[i]);
 105                 for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
 106                         brelse(s->u.minix_sb.s_zmap[i]);
 107                 s->s_dev=0;
 108                 free_super(s);
 109                 printk("block failed\n");
 110                 return NULL;
 111         }
 112         s->u.minix_sb.s_imap[0]->b_data[0] |= 1;
 113         s->u.minix_sb.s_zmap[0]->b_data[0] |= 1;
 114         free_super(s);
 115         /* set up enough so that it can read an inode */
 116         s->s_dev = dev;
 117         s->s_op = &minix_sops;
 118         if (!(s->s_mounted = iget(dev,MINIX_ROOT_INO))) {
 119                 s->s_dev=0;
 120                 printk("get root inode failed\n");
 121                 return NULL;
 122         }
 123         return s;
 124 }
 125 
 126 void minix_statfs (struct super_block *sb, struct statfs *buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 127 {
 128         long tmp;
 129 
 130         put_fs_long(MINIX_SUPER_MAGIC, &buf->f_type);
 131         put_fs_long(1024, &buf->f_bsize);
 132         put_fs_long(sb->u.minix_sb.s_nzones << sb->u.minix_sb.s_log_zone_size, &buf->f_blocks);
 133         tmp = minix_count_free_blocks(sb);
 134         put_fs_long(tmp, &buf->f_bfree);
 135         put_fs_long(tmp, &buf->f_bavail);
 136         put_fs_long(sb->u.minix_sb.s_ninodes, &buf->f_files);
 137         put_fs_long(minix_count_free_inodes(sb), &buf->f_ffree);
 138         /* Don't know what value to put in buf->f_fsid */
 139 }
 140 
 141 #define inode_bmap(inode,nr) ((inode)->u.minix_i.i_data[(nr)])
 142 
 143 static int block_bmap(struct buffer_head * bh, int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 144 {
 145         int tmp;
 146 
 147         if (!bh)
 148                 return 0;
 149         tmp = ((unsigned short *) bh->b_data)[nr];
 150         brelse(bh);
 151         return tmp;
 152 }
 153 
 154 int minix_bmap(struct inode * inode,int block)
     /* [previous][next][first][last][top][bottom][index][help] */
 155 {
 156         int i;
 157 
 158         if (block<0) {
 159                 printk("minix_bmap: block<0");
 160                 return 0;
 161         }
 162         if (block >= 7+512+512*512) {
 163                 printk("minix_bmap: block>big");
 164                 return 0;
 165         }
 166         if (block < 7)
 167                 return inode_bmap(inode,block);
 168         block -= 7;
 169         if (block < 512) {
 170                 i = inode_bmap(inode,7);
 171                 if (!i)
 172                         return 0;
 173                 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
 174         }
 175         block -= 512;
 176         i = inode_bmap(inode,8);
 177         if (!i)
 178                 return 0;
 179         i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>9);
 180         if (!i)
 181                 return 0;
 182         return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 511);
 183 }
 184 
 185 static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
     /* [previous][next][first][last][top][bottom][index][help] */
 186 {
 187         int tmp;
 188         unsigned short *p;
 189         struct buffer_head * result;
 190 
 191         p = inode->u.minix_i.i_data + nr;
 192 repeat:
 193         tmp = *p;
 194         if (tmp) {
 195                 result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
 196                 if (tmp == *p)
 197                         return result;
 198                 brelse(result);
 199                 goto repeat;
 200         }
 201         if (!create)
 202                 return NULL;
 203         tmp = minix_new_block(inode->i_dev);
 204         if (!tmp)
 205                 return NULL;
 206         result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
 207         if (*p) {
 208                 minix_free_block(inode->i_dev,tmp);
 209                 brelse(result);
 210                 goto repeat;
 211         }
 212         *p = tmp;
 213         inode->i_ctime = CURRENT_TIME;
 214         inode->i_dirt = 1;
 215         return result;
 216 }
 217 
 218 static struct buffer_head * block_getblk(struct buffer_head * bh, int nr, int create)
     /* [previous][next][first][last][top][bottom][index][help] */
 219 {
 220         int tmp;
 221         unsigned short *p;
 222         struct buffer_head * result;
 223 
 224         if (!bh)
 225                 return NULL;
 226         if (!bh->b_uptodate) {
 227                 ll_rw_block(READ,bh);
 228                 wait_on_buffer(bh);
 229                 if (!bh->b_uptodate) {
 230                         brelse(bh);
 231                         return NULL;
 232                 }
 233         }
 234         p = nr + (unsigned short *) bh->b_data;
 235 repeat:
 236         tmp = *p;
 237         if (tmp) {
 238                 result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
 239                 if (tmp == *p) {
 240                         brelse(bh);
 241                         return result;
 242                 }
 243                 brelse(result);
 244                 goto repeat;
 245         }
 246         if (!create) {
 247                 brelse(bh);
 248                 return NULL;
 249         }
 250         tmp = minix_new_block(bh->b_dev);
 251         if (!tmp) {
 252                 brelse(bh);
 253                 return NULL;
 254         }
 255         result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
 256         if (*p) {
 257                 minix_free_block(bh->b_dev,tmp);
 258                 brelse(result);
 259                 goto repeat;
 260         }
 261         *p = tmp;
 262         bh->b_dirt = 1;
 263         brelse(bh);
 264         return result;
 265 }
 266 
 267 struct buffer_head * minix_getblk(struct inode * inode, int block, int create)
     /* [previous][next][first][last][top][bottom][index][help] */
 268 {
 269         struct buffer_head * bh;
 270 
 271         if (block<0) {
 272                 printk("minix_getblk: block<0");
 273                 return NULL;
 274         }
 275         if (block >= 7+512+512*512) {
 276                 printk("minix_getblk: block>big");
 277                 return NULL;
 278         }
 279         if (block < 7)
 280                 return inode_getblk(inode,block,create);
 281         block -= 7;
 282         if (block < 512) {
 283                 bh = inode_getblk(inode,7,create);
 284                 return block_getblk(bh,block,create);
 285         }
 286         block -= 512;
 287         bh = inode_getblk(inode,8,create);
 288         bh = block_getblk(bh,block>>9,create);
 289         return block_getblk(bh,block & 511,create);
 290 }
 291 
 292 struct buffer_head * minix_bread(struct inode * inode, int block, int create)
     /* [previous][next][first][last][top][bottom][index][help] */
 293 {
 294         struct buffer_head * bh;
 295 
 296         bh = minix_getblk(inode,block,create);
 297         if (!bh || bh->b_uptodate)
 298                 return bh;
 299         ll_rw_block(READ,bh);
 300         wait_on_buffer(bh);
 301         if (bh->b_uptodate)
 302                 return bh;
 303         brelse(bh);
 304         return NULL;
 305 }
 306 
 307 void minix_read_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 308 {
 309         struct buffer_head * bh;
 310         struct minix_inode * raw_inode;
 311         int block;
 312 
 313         block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
 314                 (inode->i_ino-1)/MINIX_INODES_PER_BLOCK;
 315         if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE)))
 316                 panic("unable to read i-node block");
 317         raw_inode = ((struct minix_inode *) bh->b_data) +
 318                 (inode->i_ino-1)%MINIX_INODES_PER_BLOCK;
 319         inode->i_mode = raw_inode->i_mode;
 320         inode->i_uid = raw_inode->i_uid;
 321         inode->i_gid = raw_inode->i_gid;
 322         inode->i_nlink = raw_inode->i_nlinks;
 323         inode->i_size = raw_inode->i_size;
 324         inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
 325         inode->i_blocks = inode->i_blksize = 0;
 326         if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 327                 inode->i_rdev = raw_inode->i_zone[0];
 328         else for (block = 0; block < 9; block++)
 329                 inode->u.minix_i.i_data[block] = raw_inode->i_zone[block];
 330         brelse(bh);
 331         inode->i_op = NULL;
 332         if (S_ISREG(inode->i_mode))
 333                 inode->i_op = &minix_file_inode_operations;
 334         else if (S_ISDIR(inode->i_mode))
 335                 inode->i_op = &minix_dir_inode_operations;
 336         else if (S_ISLNK(inode->i_mode))
 337                 inode->i_op = &minix_symlink_inode_operations;
 338         else if (S_ISCHR(inode->i_mode))
 339                 inode->i_op = &minix_chrdev_inode_operations;
 340         else if (S_ISBLK(inode->i_mode))
 341                 inode->i_op = &minix_blkdev_inode_operations;
 342         else if (S_ISFIFO(inode->i_mode)) {
 343                 inode->i_op = &minix_fifo_inode_operations;
 344                 inode->i_pipe = 1;
 345                 PIPE_BASE(*inode) = NULL;
 346                 PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
 347                 PIPE_READ_WAIT(*inode) = PIPE_WRITE_WAIT(*inode) = NULL;
 348                 PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
 349         }
 350 }
 351 
 352 void minix_write_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 353 {
 354         struct buffer_head * bh;
 355         struct minix_inode * raw_inode;
 356         int block;
 357 
 358         block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
 359                 (inode->i_ino-1)/MINIX_INODES_PER_BLOCK;
 360         if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
 361                 panic("unable to read i-node block");
 362         raw_inode = ((struct minix_inode *)bh->b_data) +
 363                 (inode->i_ino-1)%MINIX_INODES_PER_BLOCK;
 364         raw_inode->i_mode = inode->i_mode;
 365         raw_inode->i_uid = inode->i_uid;
 366         raw_inode->i_gid = inode->i_gid;
 367         raw_inode->i_nlinks = inode->i_nlink;
 368         raw_inode->i_size = inode->i_size;
 369         raw_inode->i_time = inode->i_mtime;
 370         if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 371                 raw_inode->i_zone[0] = inode->i_rdev;
 372         else for (block = 0; block < 9; block++)
 373                 raw_inode->i_zone[block] = inode->u.minix_i.i_data[block];
 374         bh->b_dirt=1;
 375         inode->i_dirt=0;
 376         brelse(bh);
 377 }

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