root/fs/ext2/inode.c

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

DEFINITIONS

This source file includes following definitions.
  1. ext2_put_inode
  2. ext2_put_super
  3. convert_pre_02b_fs
  4. ext2_read_super
  5. ext2_write_super
  6. ext2_statfs
  7. block_bmap
  8. ext2_bmap
  9. inode_getblk
  10. block_getblk
  11. ext2_getblk
  12. ext2_bread
  13. ext2_read_inode
  14. ext2_write_inode

   1 /*
   2  *  linux/fs/ext2/inode.c
   3  *
   4  *  Copyright (C) 1992, 1993  Remy Card (card@masi.ibp.fr)
   5  *
   6  *  from
   7  *
   8  *  linux/fs/minix/inode.c
   9  *
  10  *  Copyright (C) 1991, 1992  Linus Torvalds
  11  *
  12  *  Goal-directed block allocation by Stephen Tweedie (sct@dcs.ed.ac.uk), 1993
  13  */
  14 
  15 #include <linux/sched.h>
  16 #include <linux/ext2_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 
  26 void ext2_put_inode (struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  27 {
  28         if (inode->i_nlink)
  29                 return;
  30         inode->i_size = 0;
  31         if (inode->i_blocks)
  32                 ext2_truncate (inode);
  33         ext2_free_inode (inode);
  34 }
  35 
  36 void ext2_put_super (struct super_block * sb)
     /* [previous][next][first][last][top][bottom][index][help] */
  37 {
  38         struct ext2_super_block * es;
  39         int i;
  40 
  41         lock_super (sb);
  42         es = (struct ext2_super_block *) sb->u.ext2_sb.s_sbh->b_data;
  43         es->s_valid = sb->u.ext2_sb.s_was_mounted_valid;
  44         sb->u.ext2_sb.s_sbh->b_dirt = 1;
  45 #ifndef DONT_USE_DCACHE
  46         ext2_dcache_invalidate (sb->s_dev);
  47 #endif
  48         sb->s_dev = 0;
  49         for (i = 0; i < EXT2_MAX_GROUP_DESC; i++)
  50                 if (sb->u.ext2_sb.s_group_desc[i])
  51                         brelse (sb->u.ext2_sb.s_group_desc[i]);
  52         for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
  53                 if (sb->u.ext2_sb.s_inode_bitmap[i])
  54                         brelse (sb->u.ext2_sb.s_inode_bitmap[i]);
  55         for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
  56                 if (sb->u.ext2_sb.s_block_bitmap[i])
  57                         brelse (sb->u.ext2_sb.s_block_bitmap[i]);
  58         unlock_super (sb);
  59         return;
  60 }
  61 
  62 static struct super_operations ext2_sops = { 
  63         ext2_read_inode,
  64         NULL,
  65         ext2_write_inode,
  66         ext2_put_inode,
  67         ext2_put_super,
  68         ext2_write_super,
  69         ext2_statfs
  70 };
  71 
  72 static int convert_pre_02b_fs (struct super_block * sb,
     /* [previous][next][first][last][top][bottom][index][help] */
  73                                struct buffer_head * bh)
  74 {
  75         struct ext2_super_block * es;
  76         struct ext2_old_group_desc old_group_desc [BLOCK_SIZE / sizeof (struct ext2_old_group_desc)];
  77         struct ext2_group_desc * gdp;
  78         struct buffer_head * bh2;
  79         int groups_count;
  80         int i;
  81 
  82         es = (struct ext2_super_block *) bh->b_data;
  83         bh2 = bread (sb->s_dev, 2, BLOCK_SIZE);
  84         if (!bh2) {
  85                 printk ("Cannot read descriptor blocks while converting !\n");
  86                 return 0;
  87         }
  88         memcpy (old_group_desc, bh2->b_data, BLOCK_SIZE);
  89         groups_count = (sb->u.ext2_sb.s_blocks_count - 
  90                         sb->u.ext2_sb.s_first_data_block +
  91                         (EXT2_BLOCK_SIZE(sb) * 8) - 1) /
  92                                 (EXT2_BLOCK_SIZE(sb) * 8);
  93         memset (bh2->b_data, 0, BLOCK_SIZE);
  94         gdp = (struct ext2_group_desc *) bh2->b_data;
  95         for (i = 0; i < groups_count; i++) {
  96                 gdp[i].bg_block_bitmap = old_group_desc[i].bg_block_bitmap;
  97                 gdp[i].bg_inode_bitmap = old_group_desc[i].bg_inode_bitmap;
  98                 gdp[i].bg_inode_table = old_group_desc[i].bg_inode_table;
  99                 gdp[i].bg_free_blocks_count = old_group_desc[i].bg_free_blocks_count;
 100                 gdp[i].bg_free_inodes_count = old_group_desc[i].bg_free_inodes_count;
 101         }
 102         bh2->b_dirt = 1;
 103         brelse (bh2);
 104         es->s_magic = EXT2_SUPER_MAGIC;
 105         bh->b_dirt = 1;
 106         sb->s_magic = EXT2_SUPER_MAGIC;
 107         return 1;
 108 }
 109 
 110 struct super_block * ext2_read_super (struct super_block * s, void * data,
     /* [previous][next][first][last][top][bottom][index][help] */
 111                                       int silent)
 112 {
 113         struct buffer_head * bh;
 114         struct ext2_super_block * es;
 115         int dev = s->s_dev;
 116         int bh_count;
 117         int i, j;
 118         int fs_converted = 0;
 119 
 120         lock_super (s);
 121         if (!(bh = bread (dev, 1, BLOCK_SIZE))) {
 122                 s->s_dev = 0;
 123                 unlock_super (s);
 124                 printk ("EXT2-fs: unable to read superblock\n");
 125                 return NULL;
 126         }
 127         es = (struct ext2_super_block *) bh->b_data;
 128         s->s_magic = es->s_magic;
 129         s->s_blocksize = EXT2_MIN_BLOCK_SIZE << es->s_log_block_size;
 130         s->u.ext2_sb.s_inodes_count = es->s_inodes_count;
 131         s->u.ext2_sb.s_blocks_count = es->s_blocks_count;
 132         s->u.ext2_sb.s_r_blocks_count = es->s_r_blocks_count;
 133         s->u.ext2_sb.s_first_data_block = es->s_first_data_block;
 134         s->u.ext2_sb.s_log_block_size = es->s_log_block_size;
 135         s->u.ext2_sb.s_log_frag_size = es->s_log_frag_size;
 136         s->u.ext2_sb.s_frag_size = EXT2_MIN_FRAG_SIZE <<
 137                                      es->s_log_frag_size;
 138         if (s->u.ext2_sb.s_frag_size)
 139                 s->u.ext2_sb.s_frags_per_block = s->s_blocksize /
 140                                            s->u.ext2_sb.s_frag_size;
 141         else
 142                 s->s_magic = 0;
 143         s->u.ext2_sb.s_blocks_per_group = es->s_blocks_per_group;
 144         s->u.ext2_sb.s_frags_per_group = es->s_frags_per_group;
 145         s->u.ext2_sb.s_inodes_per_group = es->s_inodes_per_group;
 146         s->u.ext2_sb.s_inodes_per_block = s->s_blocksize /
 147                                             sizeof (struct ext2_inode);
 148         s->u.ext2_sb.s_desc_per_block = s->s_blocksize /
 149                                           sizeof (struct ext2_group_desc);
 150         s->u.ext2_sb.s_sbh = bh;
 151         s->u.ext2_sb.s_was_mounted_valid = es->s_valid;
 152         s->u.ext2_sb.s_rename_lock = 0;
 153         s->u.ext2_sb.s_rename_wait = NULL;
 154         if (s->s_magic == EXT2_OLD_SUPER_MAGIC) {
 155                 if (es->s_blocks_count > 262144) {
 156                          /* fs > 256 MB can't be converted */ 
 157                         s->s_dev = 0;
 158                         unlock_super (s);
 159                         brelse (bh);
 160                         printk ("EXT2-fs: trying to mount a pre-0.2b file"
 161                                 "system which cannot be converted\n");
 162                         return NULL;
 163                 }
 164                 printk ("EXT2-fs: mounting a pre 0.2b file system, "
 165                         "will try to convert the structure\n");
 166                 if (s->s_flags & MS_RDONLY == 0) {
 167                         s->s_dev = 0;
 168                         unlock_super (s);
 169                         brelse (bh);
 170                         printk ("EXT2-fs: cannot convert a read-only fs\n");
 171                         return NULL;
 172                 }
 173                 if (!convert_pre_02b_fs (s, bh)) {
 174                         s->s_dev = 0;
 175                         unlock_super (s);
 176                         brelse (bh);
 177                         printk ("EXT2-fs: conversion failed !!!\n");
 178                         return NULL;
 179                 }
 180                 printk ("EXT2-fs: conversion succeeded !!!\n");
 181                 fs_converted = 1;
 182         }
 183         if (s->s_magic != EXT2_SUPER_MAGIC) {
 184                 s->s_dev = 0;
 185                 unlock_super (s);
 186                 brelse (bh);
 187                 if (!silent)
 188                         printk("VFS: Can't find an ext2fs filesystem on dev 0x%04x.\n",
 189                                    dev);
 190                 return NULL;
 191         }
 192         if (s->s_blocksize != s->u.ext2_sb.s_frag_size) {
 193                 s->s_dev = 0;
 194                 unlock_super (s);
 195                 brelse (bh);
 196                 printk ("EXT2-fs: fragsize != blocksize (not supported yet)\n");
 197                 return NULL;
 198         }
 199         if (!es->s_valid)
 200                 printk ("EXT2-fs warning: mounting unchecked file system, "
 201                         "running e2fsck is recommended\n");
 202         s->u.ext2_sb.s_groups_count = (s->u.ext2_sb.s_blocks_count -
 203                                        s->u.ext2_sb.s_first_data_block +
 204                                        (EXT2_BLOCK_SIZE(s) * 8) - 1) /
 205                                        (EXT2_BLOCK_SIZE(s) * 8);
 206         for (i = 0; i < EXT2_MAX_GROUP_DESC; i++)
 207                 s->u.ext2_sb.s_group_desc[i] = NULL;
 208         bh_count = (s->u.ext2_sb.s_groups_count +
 209                    EXT2_DESC_PER_BLOCK(s) - 1) /
 210                    EXT2_DESC_PER_BLOCK(s);
 211         for (i = 0; i < bh_count; i++) {
 212                 s->u.ext2_sb.s_group_desc[i] = bread (dev, i + 2, s->s_blocksize);
 213                 if (!s->u.ext2_sb.s_group_desc[i]) {
 214                         s->s_dev = 0;
 215                         unlock_super (s);
 216                         for (j = 0; j < i; j++)
 217                                 brelse (s->u.ext2_sb.s_group_desc[i]);
 218                         brelse (bh);
 219                         printk ("ext2_read_super: unable to read group descriptors\n");
 220                         return NULL;
 221                 }
 222         }
 223         for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) {
 224                 s->u.ext2_sb.s_inode_bitmap_number[i] = 0;
 225                 s->u.ext2_sb.s_inode_bitmap[i] = NULL;
 226                 s->u.ext2_sb.s_block_bitmap_number[i] = 0;
 227                 s->u.ext2_sb.s_block_bitmap[i] = NULL;
 228         }
 229         s->u.ext2_sb.s_loaded_inode_bitmaps = 0;
 230         s->u.ext2_sb.s_loaded_block_bitmaps = 0;
 231         unlock_super (s);
 232         /* set up enough so that it can read an inode */
 233         s->s_dev = dev;
 234         s->s_op = &ext2_sops;
 235         if (!(s->s_mounted = iget(s, EXT2_ROOT_INO))) {
 236                 s->s_dev = 0;
 237                 for (i = 0; i < EXT2_MAX_GROUP_DESC; i++)
 238                         if (s->u.ext2_sb.s_group_desc[i])
 239                                 brelse (s->u.ext2_sb.s_group_desc[i]);
 240                 brelse (bh);
 241                 printk ("EXT2-fs: get root inode failed\n");
 242                 return NULL;
 243         }
 244         if ((s->s_flags & MS_RDONLY) == 0) {
 245                 es->s_valid = 0;
 246                 es->s_mtime = CURRENT_TIME;
 247                 bh->b_dirt = 1;
 248                 s->s_dirt = 1;
 249         }
 250         if (fs_converted) {
 251                 for (i = 0; i < bh_count; i++)
 252                         s->u.ext2_sb.s_group_desc[i]->b_dirt = 1;
 253                 s->s_dirt = 1;
 254         }
 255         printk ("[EXT II FS %s, bs=%d, fs=%d, gc=%d, bpg=%d, ipg=%d]\n",
 256                 EXT2FS_VERSION, s->s_blocksize, s->u.ext2_sb.s_frag_size,
 257                 s->u.ext2_sb.s_groups_count,
 258                 EXT2_BLOCKS_PER_GROUP(s), EXT2_INODES_PER_GROUP(s));
 259         return s;
 260 }
 261 
 262 /*
 263  * In the second extended file system, it is not necessary to
 264  * write the super block since we use a mapping of the
 265  * disk super block in a buffer.
 266  *
 267  * However, this function is still used to set the fs valid
 268  * flags to 0.  We need to set this flag to 0 since the fs
 269  * may have been checked while mounted and e2fsck may have
 270  * set s_valid to 1 after some corrections.
 271  *
 272  * Note that this function also writes backups of the super block and
 273  * of the group descriptors in each group.
 274  */
 275 void ext2_write_super (struct super_block * sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 276 {
 277         struct ext2_super_block * es;
 278         struct buffer_head * bh;
 279         unsigned long block;
 280         unsigned long bh_count;
 281         int i, j;
 282 
 283         if ((sb->s_flags & MS_RDONLY) == 0) {
 284                 es = (struct ext2_super_block *) sb->u.ext2_sb.s_sbh->b_data;
 285 #ifdef EXT2FS_DEBUG
 286                 printk ("ext2_write_super: setting valid to 0\n");
 287 #endif
 288                 es->s_valid = 0;
 289                 es->s_wtime = CURRENT_TIME;
 290                 sb->u.ext2_sb.s_sbh->b_dirt = 1;
 291                 bh_count = (sb->u.ext2_sb.s_groups_count +
 292                             EXT2_DESC_PER_BLOCK(sb) - 1) /
 293                             EXT2_DESC_PER_BLOCK(sb);
 294                 for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) {
 295                         block = sb->u.ext2_sb.s_first_data_block +
 296                                 i * sb->u.ext2_sb.s_blocks_per_group;
 297                         if (!(bh = bread (sb->s_dev, block, BLOCK_SIZE)))
 298                                 printk ("ext2_write_super: Unable to read backup super block for group %d\n", i);
 299                         else {
 300 #ifdef EXT2FS_DEBUG
 301                                 printk ("ext2_write_super: writing super block backup in group %d at block %d\n", i, block);
 302 #endif  
 303                                 memcpy (bh->b_data, es, BLOCK_SIZE);
 304                                 bh ->b_dirt = 1;
 305                                 brelse (bh);
 306                         }
 307                         for (j = 0; j < bh_count; j++) {
 308                                 block ++;
 309 #ifdef EXT2FS_DEBUG
 310                                 printk ("ext2_write_super: writing descriptors (block %d) backup in group %d at block %d\n", j, i, block);
 311 #endif  
 312                                 if (!(bh = bread (sb->s_dev, block, sb->s_blocksize)))
 313                                         printk ("ext2_write_super: Unable to read backup descriptor for group %d\n", i);
 314                                 else {
 315                                         memcpy (bh->b_data, sb->u.ext2_sb.s_group_desc[j]->b_data, sb->s_blocksize);
 316                                         bh ->b_dirt = 1;
 317                                         brelse (bh);
 318                                 }
 319                         }
 320                 }
 321         }
 322         sb->s_dirt = 0;
 323 }
 324 
 325 void ext2_statfs (struct super_block * sb, struct statfs * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 326 {
 327         long tmp;
 328 
 329         put_fs_long (EXT2_SUPER_MAGIC, &buf->f_type);
 330         put_fs_long (sb->s_blocksize, &buf->f_bsize);
 331         put_fs_long (sb->u.ext2_sb.s_blocks_count << sb->u.ext2_sb.s_log_block_size,
 332                 &buf->f_blocks);
 333         tmp = ext2_count_free_blocks (sb);
 334         put_fs_long (tmp, &buf->f_bfree);
 335         if (tmp >= sb->u.ext2_sb.s_r_blocks_count)
 336                 put_fs_long (tmp - sb->u.ext2_sb.s_r_blocks_count,
 337                              &buf->f_bavail);
 338         else
 339                 put_fs_long (0, &buf->f_bavail);
 340         put_fs_long (sb->u.ext2_sb.s_inodes_count, &buf->f_files);
 341         put_fs_long (ext2_count_free_inodes(sb), &buf->f_ffree);
 342         put_fs_long (EXT2_NAME_LEN, &buf->f_namelen);
 343         /* Don't know what value to put in buf->f_fsid */
 344 }
 345 
 346 #define inode_bmap(inode, nr) ((inode)->u.ext2_i.i_data[(nr)])
 347 
 348 static int block_bmap (struct buffer_head * bh, int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 349 {
 350         int tmp;
 351 
 352         if (!bh)
 353                 return 0;
 354         tmp = ((unsigned long *) bh->b_data)[nr];
 355         brelse (bh);
 356         return tmp;
 357 }
 358 
 359 int ext2_bmap (struct inode * inode, int block)
     /* [previous][next][first][last][top][bottom][index][help] */
 360 {
 361         int i;
 362         int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
 363 
 364         if (block < 0) {
 365                 printk("ext2_bmap: block < 0");
 366                 return 0;
 367         }
 368         if (block >= EXT2_NDIR_BLOCKS + addr_per_block +
 369                      addr_per_block * addr_per_block +
 370                      addr_per_block * addr_per_block * addr_per_block) {
 371                 printk ("ext2_bmap: block > big");
 372                 return 0;
 373         }
 374         if (block < EXT2_NDIR_BLOCKS)
 375                 return inode_bmap (inode, block);
 376         block -= EXT2_NDIR_BLOCKS;
 377         if (block < addr_per_block) {
 378                 i = inode_bmap (inode, EXT2_IND_BLOCK);
 379                 if (!i)
 380                         return 0;
 381                 return block_bmap (bread (inode->i_dev, i,
 382                                           inode->i_sb->s_blocksize), block);
 383         }
 384         block -= addr_per_block;
 385         if (block < addr_per_block * addr_per_block) {
 386                 i = inode_bmap (inode, EXT2_DIND_BLOCK);
 387                 if (!i)
 388                         return 0;
 389                 i = block_bmap (bread (inode->i_dev, i,
 390                                        inode->i_sb->s_blocksize),
 391                                 block / addr_per_block);
 392                 if (!i)
 393                         return 0;
 394                 return block_bmap (bread (inode->i_dev, i,
 395                                           inode->i_sb->s_blocksize),
 396                                    block & (addr_per_block - 1));
 397         }
 398         block -= addr_per_block * addr_per_block;
 399         i = inode_bmap (inode, EXT2_TIND_BLOCK);
 400         if (!i)
 401                 return 0;
 402         i = block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
 403                         block / (addr_per_block * addr_per_block));
 404         if (!i)
 405                 return 0;
 406         i = block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
 407                         (block / addr_per_block) & (addr_per_block - 1));
 408         if (!i)
 409                 return 0;
 410         return block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
 411                            block & (addr_per_block - 1));
 412 }
 413 
 414 static struct buffer_head * inode_getblk (struct inode * inode, int nr,
     /* [previous][next][first][last][top][bottom][index][help] */
 415                                           int create, int new_block)
 416 {
 417         int tmp, goal = 0;
 418         unsigned long * p;
 419         struct buffer_head * result;
 420         int blocks = inode->i_sb->s_blocksize / 512;
 421 
 422         p = inode->u.ext2_i.i_data + nr;
 423 repeat:
 424         tmp = *p;
 425         if (tmp) {
 426                 result = getblk (inode->i_dev, tmp, inode->i_sb->s_blocksize);
 427                 if (tmp == *p)
 428                         return result;
 429                 brelse (result);
 430                 goto repeat;
 431         }
 432         if (!create || new_block >= 
 433             (current->rlim[RLIMIT_FSIZE].rlim_cur >>
 434              EXT2_BLOCK_SIZE_BITS(inode->i_sb)))
 435                 return NULL;
 436         if (inode->u.ext2_i.i_next_alloc_block == new_block)
 437                 goal = inode->u.ext2_i.i_next_alloc_goal;
 438 #ifdef EXT2FS_DEBUG
 439         printk ("ext2 inode_getblk: hint = %d,", goal);
 440 #endif
 441         if (!goal) {
 442                 for (tmp = nr-1; tmp>=0; tmp--) {
 443                         if (inode->u.ext2_i.i_data[tmp]) {
 444                                 goal = inode->u.ext2_i.i_data[tmp];
 445                                 break;
 446                         }
 447                 }
 448                 if (!goal)
 449                         goal = (inode->u.ext2_i.i_block_group * 
 450                                 EXT2_BLOCKS_PER_GROUP(inode->i_sb))
 451                                 + inode->i_sb->u.ext2_sb.s_first_data_block;
 452         }
 453 
 454 #ifdef EXT2FS_DEBUG
 455         printk (" goal = %d.\n", goal);
 456 #endif
 457         tmp = ext2_new_block (inode->i_sb, goal);
 458         if (!tmp)
 459                 return NULL;
 460         result = getblk (inode->i_dev, tmp, inode->i_sb->s_blocksize);
 461         if (*p) {
 462                 ext2_free_block (inode->i_sb, tmp);
 463                 brelse (result);
 464                 goto repeat;
 465         }
 466         *p = tmp;
 467         inode->u.ext2_i.i_next_alloc_block = new_block;
 468         inode->u.ext2_i.i_next_alloc_goal = tmp;
 469         inode->i_ctime = CURRENT_TIME;
 470         inode->i_blocks += blocks;
 471         inode->i_dirt = 1;
 472         return result;
 473 }
 474 
 475 static struct buffer_head * block_getblk (struct inode * inode,
     /* [previous][next][first][last][top][bottom][index][help] */
 476                                           struct buffer_head * bh, int nr,
 477                                           int create, int blocksize, int new_block)
 478 {
 479         int tmp, goal;
 480         unsigned long * p;
 481         struct buffer_head * result;
 482         int blocks = inode->i_sb->s_blocksize / 512;
 483 
 484         if (!bh)
 485                 return NULL;
 486         if (!bh->b_uptodate) {
 487                 ll_rw_block (READ, 1, &bh);
 488                 wait_on_buffer (bh);
 489                 if (!bh->b_uptodate) {
 490                         brelse (bh);
 491                         return NULL;
 492                 }
 493         }
 494         p = nr + (unsigned long *) bh->b_data;
 495 repeat:
 496         tmp = *p;
 497         if (tmp) {
 498                 result = getblk (bh->b_dev, tmp, blocksize);
 499                 if (tmp == *p) {
 500                         brelse (bh);
 501                         return result;
 502                 }
 503                 brelse (result);
 504                 goto repeat;
 505         }
 506         if (!create || new_block >= 
 507             (current->rlim[RLIMIT_FSIZE].rlim_cur >> 
 508              EXT2_BLOCK_SIZE_BITS(inode->i_sb))) {
 509                 brelse (bh);
 510                 return NULL;
 511         }
 512         if (inode->u.ext2_i.i_next_alloc_block == new_block)
 513                 goal = inode->u.ext2_i.i_next_alloc_goal;
 514         if (!goal) {
 515                 for (tmp = nr-1; tmp>=0; tmp--) {
 516                         if (bh->b_data[tmp]) {
 517                                 goal = bh->b_data[tmp];
 518                                 break;
 519                         }
 520                 }
 521                 if (!goal)
 522                         goal = bh->b_blocknr+1;
 523         }
 524         tmp = ext2_new_block (inode->i_sb, goal);
 525         if (!tmp) {
 526 #ifdef EXT2FS_DEBUG
 527                 printk ("inode_getblk: ext2_new_block returned 0\n");
 528 #endif
 529                 brelse (bh);
 530                 return NULL;
 531         }
 532         result = getblk (bh->b_dev, tmp, blocksize);
 533         if (*p) {
 534                 ext2_free_block (inode->i_sb, tmp);
 535                 brelse (result);
 536                 goto repeat;
 537         }
 538         *p = tmp;
 539         bh->b_dirt = 1;
 540         inode->i_ctime = CURRENT_TIME;
 541         inode->i_blocks += blocks;
 542         inode->i_dirt = 1;
 543         inode->u.ext2_i.i_next_alloc_block = new_block;
 544         inode->u.ext2_i.i_next_alloc_goal = tmp;
 545         brelse (bh);
 546         return result;
 547 }
 548 
 549 struct buffer_head * ext2_getblk (struct inode * inode, int block,
     /* [previous][next][first][last][top][bottom][index][help] */
 550                                   int create)
 551 {
 552         struct buffer_head * bh;
 553         int b;
 554         unsigned long addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
 555 
 556         if (block < 0) {
 557                 printk ("ext2_getblk: block < 0\n");
 558                 return NULL;
 559         }
 560         if (block > EXT2_NDIR_BLOCKS + addr_per_block  +
 561                     addr_per_block * addr_per_block +
 562                     addr_per_block * addr_per_block * addr_per_block) {
 563                 printk ("ext2_getblk: block > big\n");
 564                 return NULL;
 565         }
 566         /* If this is a sequential block allocation, set the next_alloc_block
 567            to this block now so that all the indblock and data block allocations
 568            use the same goal zone */
 569 #ifdef EXT2FS_DEBUG
 570         printk ("ext2_getblk: block %d, next %d, goal %d.\n", block, 
 571                 inode->u.ext2_i.i_next_alloc_block,
 572                 inode->u.ext2_i.i_next_alloc_goal);
 573 #endif
 574         if (block == inode->u.ext2_i.i_next_alloc_block + 1) {
 575                 inode->u.ext2_i.i_next_alloc_block++;
 576                 inode->u.ext2_i.i_next_alloc_goal++;
 577         }
 578 
 579         b = block;
 580         if (block < EXT2_NDIR_BLOCKS)
 581                 return inode_getblk (inode, block, create, b);
 582         block -= EXT2_NDIR_BLOCKS;
 583         if (block < addr_per_block) {
 584                 bh = inode_getblk (inode, EXT2_IND_BLOCK, create, b);
 585                 return block_getblk (inode, bh, block, create,
 586                                      inode->i_sb->s_blocksize, b);
 587         }
 588         block -= addr_per_block;
 589         if (block < addr_per_block * addr_per_block) {
 590                 bh = inode_getblk (inode, EXT2_DIND_BLOCK, create,b );
 591                 bh = block_getblk (inode, bh, block / addr_per_block, create,
 592                                    inode->i_sb->s_blocksize, b);
 593                 return block_getblk (inode, bh, block & (addr_per_block - 1),
 594                                      create, inode->i_sb->s_blocksize, b);
 595         }
 596         block -= addr_per_block * addr_per_block;
 597         bh = inode_getblk (inode, EXT2_TIND_BLOCK, create, b);
 598         bh = block_getblk (inode, bh, block / (addr_per_block * addr_per_block),
 599                            create, inode->i_sb->s_blocksize, b);
 600         bh = block_getblk (inode, bh, (block / addr_per_block) & (addr_per_block - 1),
 601                            create, inode->i_sb->s_blocksize, b);
 602         return block_getblk (inode, bh, block & (addr_per_block - 1), create,
 603                              inode->i_sb->s_blocksize, b);
 604 }
 605 
 606 struct buffer_head * ext2_bread (struct inode * inode, int block, int create)
     /* [previous][next][first][last][top][bottom][index][help] */
 607 {
 608         struct buffer_head * bh;
 609 
 610         bh = ext2_getblk (inode, block, create);
 611         if (!bh || bh->b_uptodate)
 612                 return bh;
 613         ll_rw_block (READ, 1, &bh);
 614         wait_on_buffer (bh);
 615         if (bh->b_uptodate)
 616                 return bh;
 617         brelse (bh);
 618         return NULL;
 619 }
 620 
 621 void ext2_read_inode (struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 622 {
 623         struct buffer_head * bh;
 624         struct ext2_inode * raw_inode;
 625         unsigned long block_group;
 626         unsigned long group_desc;
 627         unsigned long desc;
 628         unsigned long block;
 629         struct ext2_group_desc * gdp;
 630 
 631         if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino < EXT2_FIRST_INO) ||
 632             inode->i_ino > inode->i_sb->u.ext2_sb.s_inodes_count) {
 633                 printk ("ext2_read_inode: bad inode number of dev %0x04: %d\n",
 634                         inode->i_dev, inode->i_ino);
 635                 return;
 636         }
 637         block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);
 638         if (block_group >= inode->i_sb->u.ext2_sb.s_groups_count)
 639                 panic ("ext2_read_inode: group >= groups count");
 640         group_desc = block_group / EXT2_DESC_PER_BLOCK(inode->i_sb);
 641         desc = block_group % EXT2_DESC_PER_BLOCK(inode->i_sb);
 642         bh = inode->i_sb->u.ext2_sb.s_group_desc[group_desc];
 643         if (!bh)
 644                 panic ("ext2_read_inode: Descriptor not loaded");
 645         gdp = (struct ext2_group_desc *) bh->b_data;
 646         block = gdp[desc].bg_inode_table +
 647                 (((inode->i_ino - 1) % EXT2_INODES_PER_GROUP(inode->i_sb))
 648                  / EXT2_INODES_PER_BLOCK(inode->i_sb));
 649         if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize)))
 650                 panic ("ext2_read_inode: unable to read i-node block");
 651         raw_inode = ((struct ext2_inode *) bh->b_data) +
 652                 (inode->i_ino - 1) % EXT2_INODES_PER_BLOCK(inode->i_sb);
 653         inode->i_mode = raw_inode->i_mode;
 654         inode->i_uid = raw_inode->i_uid;
 655         inode->i_gid = raw_inode->i_gid;
 656         inode->i_nlink = raw_inode->i_links_count;
 657         inode->i_size = raw_inode->i_size;
 658         inode->i_atime = raw_inode->i_atime;
 659         inode->i_ctime = raw_inode->i_ctime;
 660         inode->i_mtime = raw_inode->i_mtime;
 661         if (!S_ISFIFO(inode->i_mode))
 662                 inode->u.ext2_i.i_dtime = raw_inode->i_dtime;
 663         inode->i_blksize = inode->i_sb->s_blocksize;
 664         inode->i_blocks = raw_inode->i_blocks;
 665         if (!S_ISFIFO(inode->i_mode)) {
 666                 inode->u.ext2_i.i_flags = raw_inode->i_flags;
 667                 inode->u.ext2_i.i_faddr = raw_inode->i_faddr;
 668                 inode->u.ext2_i.i_frag = raw_inode->i_frag;
 669                 inode->u.ext2_i.i_fsize = raw_inode->i_fsize;
 670                 inode->u.ext2_i.i_file_acl = raw_inode->i_file_acl;
 671                 inode->u.ext2_i.i_dir_acl = raw_inode->i_dir_acl;
 672                 inode->u.ext2_i.i_version = raw_inode->i_version;
 673                 inode->u.ext2_i.i_block_group = block_group;
 674                 inode->u.ext2_i.i_next_alloc_block = 0;
 675                 inode->u.ext2_i.i_next_alloc_goal = 0;
 676                 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 677                         inode->i_rdev = raw_inode->i_block[0];
 678                 else for (block = 0; block < EXT2_N_BLOCKS; block++)
 679                         inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];
 680         }
 681         brelse (bh);
 682         inode->i_op = NULL;
 683         if (S_ISREG(inode->i_mode))
 684                 inode->i_op = &ext2_file_inode_operations;
 685         else if (S_ISDIR(inode->i_mode))
 686                 inode->i_op = &ext2_dir_inode_operations;
 687         else if (S_ISLNK(inode->i_mode))
 688                 inode->i_op = &ext2_symlink_inode_operations;
 689         else if (S_ISCHR(inode->i_mode))
 690                 inode->i_op = &chrdev_inode_operations;
 691         else if (S_ISBLK(inode->i_mode))
 692                 inode->i_op = &blkdev_inode_operations;
 693         else if (S_ISFIFO(inode->i_mode))
 694                 init_fifo(inode);
 695 }
 696 
 697 void ext2_write_inode (struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 698 {
 699         struct buffer_head * bh;
 700         struct ext2_inode * raw_inode;
 701         unsigned long block_group;
 702         unsigned long group_desc;
 703         unsigned long desc;
 704         unsigned long block;
 705         struct ext2_group_desc * gdp;
 706 
 707         if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino < EXT2_FIRST_INO) ||
 708             inode->i_ino > inode->i_sb->u.ext2_sb.s_inodes_count) {
 709                 printk ("ext2_write_inode: bad inode number of dev %0x04: %d\n",
 710                         inode->i_dev, inode->i_ino);
 711                 return;
 712         }
 713         block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);
 714         if (block_group >= inode->i_sb->u.ext2_sb.s_groups_count)
 715                 panic ("ext2_write_inode: group >= groups count");
 716         group_desc = block_group / EXT2_DESC_PER_BLOCK(inode->i_sb);
 717         desc = block_group % EXT2_DESC_PER_BLOCK(inode->i_sb);
 718         bh = inode->i_sb->u.ext2_sb.s_group_desc[group_desc];
 719         if (!bh)
 720                 panic ("ext2_write_inode: Descriptor not loaded");
 721         gdp = (struct ext2_group_desc *) bh->b_data;
 722         block = gdp[desc].bg_inode_table +
 723                 (((inode->i_ino - 1) % EXT2_INODES_PER_GROUP(inode->i_sb))
 724                  / EXT2_INODES_PER_BLOCK(inode->i_sb));
 725         if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize)))
 726                 panic ("ext2_write_inode: unable to read i-node block");
 727         raw_inode = ((struct ext2_inode *)bh->b_data) +
 728                 (inode->i_ino - 1) % EXT2_INODES_PER_BLOCK(inode->i_sb);
 729         raw_inode->i_mode = inode->i_mode;
 730         raw_inode->i_uid = inode->i_uid;
 731         raw_inode->i_gid = inode->i_gid;
 732         raw_inode->i_links_count = inode->i_nlink;
 733         raw_inode->i_size = inode->i_size;
 734         raw_inode->i_atime = inode->i_atime;
 735         raw_inode->i_ctime = inode->i_ctime;
 736         raw_inode->i_mtime = inode->i_mtime;
 737         raw_inode->i_blocks = inode->i_blocks;
 738         if (!S_ISFIFO(inode->i_mode)) {
 739                 raw_inode->i_dtime = inode->u.ext2_i.i_dtime;
 740                 raw_inode->i_flags = inode->u.ext2_i.i_flags;
 741                 raw_inode->i_faddr = inode->u.ext2_i.i_faddr;
 742                 raw_inode->i_frag = inode->u.ext2_i.i_frag;
 743                 raw_inode->i_fsize = inode->u.ext2_i.i_fsize;
 744                 raw_inode->i_file_acl = inode->u.ext2_i.i_file_acl;
 745                 raw_inode->i_dir_acl = inode->u.ext2_i.i_dir_acl;
 746                 raw_inode->i_version = inode->u.ext2_i.i_version;
 747                 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 748                         raw_inode->i_block[0] = inode->i_rdev;
 749                 else for (block = 0; block < EXT2_N_BLOCKS; block++)
 750                         raw_inode->i_block[block] = inode->u.ext2_i.i_data[block];
 751         }
 752         bh->b_dirt = 1;
 753         inode->i_dirt = 0;
 754         brelse (bh);
 755 }

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