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. block_bmap
  3. ext2_discard_prealloc
  4. ext2_alloc_block
  5. ext2_bmap
  6. inode_getblk
  7. block_getblk
  8. block_getcluster
  9. ext2_getblk
  10. ext2_getcluster
  11. ext2_bread
  12. ext2_read_inode
  13. ext2_update_inode
  14. ext2_write_inode
  15. ext2_sync_inode

   1 /*
   2  *  linux/fs/ext2/inode.c
   3  *
   4  *  Copyright (C) 1992, 1993, 1994  Remy Card (card@masi.ibp.fr)
   5  *                                  Laboratoire MASI - Institut Blaise Pascal
   6  *                                  Universite Pierre et Marie Curie (Paris VI)
   7  *
   8  *  from
   9  *
  10  *  linux/fs/minix/inode.c
  11  *
  12  *  Copyright (C) 1991, 1992  Linus Torvalds
  13  *
  14  *  Goal-directed block allocation by Stephen Tweedie (sct@dcs.ed.ac.uk), 1993
  15  */
  16 
  17 #include <asm/segment.h>
  18 #include <asm/system.h>
  19 
  20 #include <linux/errno.h>
  21 #include <linux/fs.h>
  22 #include <linux/ext2_fs.h>
  23 #include <linux/sched.h>
  24 #include <linux/stat.h>
  25 #include <linux/string.h>
  26 #include <linux/locks.h>
  27 
  28 void ext2_put_inode (struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  29 {
  30         ext2_discard_prealloc (inode);
  31         if (inode->i_nlink || inode->i_ino == EXT2_ACL_IDX_INO ||
  32             inode->i_ino == EXT2_ACL_DATA_INO)
  33                 return;
  34         inode->i_size = 0;
  35         if (inode->i_blocks)
  36                 ext2_truncate (inode);
  37         ext2_free_inode (inode);
  38 }
  39 
  40 #define inode_bmap(inode, nr) ((inode)->u.ext2_i.i_data[(nr)])
  41 
  42 static int block_bmap (struct buffer_head * bh, int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
  43 {
  44         int tmp;
  45 
  46         if (!bh)
  47                 return 0;
  48         tmp = ((unsigned long *) bh->b_data)[nr];
  49         brelse (bh);
  50         return tmp;
  51 }
  52 
  53 /* 
  54  * ext2_discard_prealloc and ext2_alloc_block are atomic wrt. the
  55  * superblock in the same manner as are ext2_free_blocks and
  56  * ext2_new_block.  We just wait on the super rather than locking it
  57  * here, since ext2_new_block will do the necessary locking and we
  58  * can't block until then.
  59  */
  60 void ext2_discard_prealloc (struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  61 {
  62 #ifdef EXT2_PREALLOCATE
  63         if (inode->u.ext2_i.i_prealloc_count) {
  64                 int i = inode->u.ext2_i.i_prealloc_count;
  65                 inode->u.ext2_i.i_prealloc_count = 0;
  66                 ext2_free_blocks (inode->i_sb,
  67                                   inode->u.ext2_i.i_prealloc_block,
  68                                   i);
  69         }
  70 #endif
  71 }
  72 
  73 static int ext2_alloc_block (struct inode * inode, unsigned long goal)
     /* [previous][next][first][last][top][bottom][index][help] */
  74 {
  75 #ifdef EXT2FS_DEBUG
  76         static unsigned long alloc_hits = 0, alloc_attempts = 0;
  77 #endif
  78         unsigned long result;
  79         struct buffer_head * bh;
  80 
  81         wait_on_super (inode->i_sb);
  82 
  83 #ifdef EXT2_PREALLOCATE
  84         if (inode->u.ext2_i.i_prealloc_count &&
  85             (goal == inode->u.ext2_i.i_prealloc_block ||
  86              goal + 1 == inode->u.ext2_i.i_prealloc_block))
  87         {               
  88                 result = inode->u.ext2_i.i_prealloc_block++;
  89                 inode->u.ext2_i.i_prealloc_count--;
  90                 ext2_debug ("preallocation hit (%lu/%lu).\n",
  91                             ++alloc_hits, ++alloc_attempts);
  92 
  93                 /* It doesn't matter if we block in getblk() since
  94                    we have already atomically allocated the block, and
  95                    are only clearing it now. */
  96                 if (!(bh = getblk (inode->i_sb->s_dev, result,
  97                                    inode->i_sb->s_blocksize))) {
  98                         ext2_error (inode->i_sb, "ext2_alloc_block",
  99                                     "cannot get block %lu", result);
 100                         return 0;
 101                 }
 102                 memset(bh->b_data, 0, inode->i_sb->s_blocksize);
 103                 bh->b_uptodate = 1;
 104                 mark_buffer_dirty(bh, 1);
 105                 brelse (bh);
 106         } else {
 107                 ext2_discard_prealloc (inode);
 108                 ext2_debug ("preallocation miss (%lu/%lu).\n",
 109                             alloc_hits, ++alloc_attempts);
 110                 if (S_ISREG(inode->i_mode))
 111                         result = ext2_new_block
 112                                 (inode->i_sb, goal,
 113                                  &inode->u.ext2_i.i_prealloc_count,
 114                                  &inode->u.ext2_i.i_prealloc_block);
 115                 else
 116                         result = ext2_new_block (inode->i_sb, goal, 0, 0);
 117         }
 118 #else
 119         result = ext2_new_block (inode->i_sb, goal, 0, 0);
 120 #endif
 121 
 122         return result;
 123 }
 124 
 125 
 126 int ext2_bmap (struct inode * inode, int block)
     /* [previous][next][first][last][top][bottom][index][help] */
 127 {
 128         int i;
 129         int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
 130 
 131         if (block < 0) {
 132                 ext2_warning (inode->i_sb, "ext2_bmap", "block < 0");
 133                 return 0;
 134         }
 135         if (block >= EXT2_NDIR_BLOCKS + addr_per_block +
 136                      addr_per_block * addr_per_block +
 137                      addr_per_block * addr_per_block * addr_per_block) {
 138                 ext2_warning (inode->i_sb, "ext2_bmap", "block > big");
 139                 return 0;
 140         }
 141         if (block < EXT2_NDIR_BLOCKS)
 142                 return inode_bmap (inode, block);
 143         block -= EXT2_NDIR_BLOCKS;
 144         if (block < addr_per_block) {
 145                 i = inode_bmap (inode, EXT2_IND_BLOCK);
 146                 if (!i)
 147                         return 0;
 148                 return block_bmap (bread (inode->i_dev, i,
 149                                           inode->i_sb->s_blocksize), block);
 150         }
 151         block -= addr_per_block;
 152         if (block < addr_per_block * addr_per_block) {
 153                 i = inode_bmap (inode, EXT2_DIND_BLOCK);
 154                 if (!i)
 155                         return 0;
 156                 i = block_bmap (bread (inode->i_dev, i,
 157                                        inode->i_sb->s_blocksize),
 158                                 block / addr_per_block);
 159                 if (!i)
 160                         return 0;
 161                 return block_bmap (bread (inode->i_dev, i,
 162                                           inode->i_sb->s_blocksize),
 163                                    block & (addr_per_block - 1));
 164         }
 165         block -= addr_per_block * addr_per_block;
 166         i = inode_bmap (inode, EXT2_TIND_BLOCK);
 167         if (!i)
 168                 return 0;
 169         i = block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
 170                         block / (addr_per_block * addr_per_block));
 171         if (!i)
 172                 return 0;
 173         i = block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
 174                         (block / addr_per_block) & (addr_per_block - 1));
 175         if (!i)
 176                 return 0;
 177         return block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
 178                            block & (addr_per_block - 1));
 179 }
 180 
 181 static struct buffer_head * inode_getblk (struct inode * inode, int nr,
     /* [previous][next][first][last][top][bottom][index][help] */
 182                                           int create, int new_block, int * err)
 183 {
 184         int tmp, goal = 0;
 185         unsigned long * p;
 186         struct buffer_head * result;
 187         int blocks = inode->i_sb->s_blocksize / 512;
 188 
 189         p = inode->u.ext2_i.i_data + nr;
 190 repeat:
 191         tmp = *p;
 192         if (tmp) {
 193                 result = getblk (inode->i_dev, tmp, inode->i_sb->s_blocksize);
 194                 if (tmp == *p)
 195                         return result;
 196                 brelse (result);
 197                 goto repeat;
 198         }
 199         if (!create || new_block >= 
 200             (current->rlim[RLIMIT_FSIZE].rlim_cur >>
 201              EXT2_BLOCK_SIZE_BITS(inode->i_sb))) {
 202                 *err = -EFBIG;
 203                 return NULL;
 204         }
 205         if (inode->u.ext2_i.i_next_alloc_block == new_block)
 206                 goal = inode->u.ext2_i.i_next_alloc_goal;
 207 
 208         ext2_debug ("hint = %d,", goal);
 209 
 210         if (!goal) {
 211                 for (tmp = nr - 1; tmp >= 0; tmp--) {
 212                         if (inode->u.ext2_i.i_data[tmp]) {
 213                                 goal = inode->u.ext2_i.i_data[tmp];
 214                                 break;
 215                         }
 216                 }
 217                 if (!goal)
 218                         goal = (inode->u.ext2_i.i_block_group * 
 219                                 EXT2_BLOCKS_PER_GROUP(inode->i_sb)) +
 220                                inode->i_sb->u.ext2_sb.s_es->s_first_data_block;
 221         }
 222 
 223         ext2_debug ("goal = %d.\n", goal);
 224 
 225         tmp = ext2_alloc_block (inode, goal);
 226         if (!tmp)
 227                 return NULL;
 228         result = getblk (inode->i_dev, tmp, inode->i_sb->s_blocksize);
 229         if (*p) {
 230                 ext2_free_blocks (inode->i_sb, tmp, 1);
 231                 brelse (result);
 232                 goto repeat;
 233         }
 234         *p = tmp;
 235         inode->u.ext2_i.i_next_alloc_block = new_block;
 236         inode->u.ext2_i.i_next_alloc_goal = tmp;
 237         inode->i_ctime = CURRENT_TIME;
 238         inode->i_blocks += blocks;
 239         if (IS_SYNC(inode) || inode->u.ext2_i.i_osync)
 240                 ext2_sync_inode (inode);
 241         else
 242                 inode->i_dirt = 1;
 243         return result;
 244 }
 245 
 246 static struct buffer_head * block_getblk (struct inode * inode,
     /* [previous][next][first][last][top][bottom][index][help] */
 247                                           struct buffer_head * bh, int nr,
 248                                           int create, int blocksize, 
 249                                           int new_block, int * err)
 250 {
 251         int tmp, goal = 0;
 252         unsigned long * p;
 253         struct buffer_head * result;
 254         int blocks = inode->i_sb->s_blocksize / 512;
 255 
 256         if (!bh)
 257                 return NULL;
 258         if (!bh->b_uptodate) {
 259                 ll_rw_block (READ, 1, &bh);
 260                 wait_on_buffer (bh);
 261                 if (!bh->b_uptodate) {
 262                         brelse (bh);
 263                         return NULL;
 264                 }
 265         }
 266         p = (unsigned long *) bh->b_data + nr;
 267 repeat:
 268         tmp = *p;
 269         if (tmp) {
 270                 result = getblk (bh->b_dev, tmp, blocksize);
 271                 if (tmp == *p) {
 272                         brelse (bh);
 273                         return result;
 274                 }
 275                 brelse (result);
 276                 goto repeat;
 277         }
 278         if (!create || new_block >= 
 279             (current->rlim[RLIMIT_FSIZE].rlim_cur >> 
 280              EXT2_BLOCK_SIZE_BITS(inode->i_sb))) {
 281                 brelse (bh);
 282                 *err = -EFBIG;
 283                 return NULL;
 284         }
 285         if (inode->u.ext2_i.i_next_alloc_block == new_block)
 286                 goal = inode->u.ext2_i.i_next_alloc_goal;
 287         if (!goal) {
 288                 for (tmp = nr - 1; tmp >= 0; tmp--) {
 289                         if (((unsigned long *) bh->b_data)[tmp]) {
 290                                 goal = ((unsigned long *)bh->b_data)[tmp];
 291                                 break;
 292                         }
 293                 }
 294                 if (!goal)
 295                         goal = bh->b_blocknr;
 296         }
 297         tmp = ext2_alloc_block (inode, goal);
 298         if (!tmp) {
 299                 brelse (bh);
 300                 return NULL;
 301         }
 302         result = getblk (bh->b_dev, tmp, blocksize);
 303         if (*p) {
 304                 ext2_free_blocks (inode->i_sb, tmp, 1);
 305                 brelse (result);
 306                 goto repeat;
 307         }
 308         *p = tmp;
 309         mark_buffer_dirty(bh, 1);
 310         if (IS_SYNC(inode) || inode->u.ext2_i.i_osync) {
 311                 ll_rw_block (WRITE, 1, &bh);
 312                 wait_on_buffer (bh);
 313         }
 314         inode->i_ctime = CURRENT_TIME;
 315         inode->i_blocks += blocks;
 316         inode->i_dirt = 1;
 317         inode->u.ext2_i.i_next_alloc_block = new_block;
 318         inode->u.ext2_i.i_next_alloc_goal = tmp;
 319         brelse (bh);
 320         return result;
 321 }
 322 
 323 static int block_getcluster (struct inode * inode, struct buffer_head * bh,
     /* [previous][next][first][last][top][bottom][index][help] */
 324                                           int nr,
 325                                           int blocksize)
 326 {
 327         unsigned long * p;
 328         int firstblock = 0;
 329         int result = 0;
 330         int i;
 331 
 332         /* Check to see if clustering possible here. */
 333 
 334         if(!bh) return 0;
 335 
 336         if(nr % (PAGE_SIZE / inode->i_sb->s_blocksize) != 0) goto out;
 337         if(nr + 3 > EXT2_ADDR_PER_BLOCK(inode->i_sb)) goto out;
 338 
 339         for(i=0; i< (PAGE_SIZE / inode->i_sb->s_blocksize); i++) {
 340           p = (unsigned long *) bh->b_data + nr + i;
 341           
 342           /* All blocks in cluster must already be allocated */
 343           if(*p == 0) goto out;
 344           
 345           /* See if aligned correctly */
 346           if(i==0) firstblock = *p;
 347           else if(*p != firstblock + i) goto out;
 348         };
 349         
 350         p = (unsigned long *) bh->b_data + nr;
 351         result = generate_cluster(bh->b_dev, (int *) p, blocksize);
 352 
 353       out:
 354         brelse(bh);
 355         return result;
 356 }
 357 
 358 struct buffer_head * ext2_getblk (struct inode * inode, long block,
     /* [previous][next][first][last][top][bottom][index][help] */
 359                                   int create, int * err)
 360 {
 361         struct buffer_head * bh;
 362         unsigned long b;
 363         unsigned long addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
 364 
 365         *err = -EIO;
 366         if (block < 0) {
 367                 ext2_warning (inode->i_sb, "ext2_getblk", "block < 0");
 368                 return NULL;
 369         }
 370         if (block > EXT2_NDIR_BLOCKS + addr_per_block  +
 371                     addr_per_block * addr_per_block +
 372                     addr_per_block * addr_per_block * addr_per_block) {
 373                 ext2_warning (inode->i_sb, "ext2_getblk", "block > big");
 374                 return NULL;
 375         }
 376         /*
 377          * If this is a sequential block allocation, set the next_alloc_block
 378          * to this block now so that all the indblock and data block
 379          * allocations use the same goal zone
 380          */
 381 
 382         ext2_debug ("block %lu, next %lu, goal %lu.\n", block, 
 383                     inode->u.ext2_i.i_next_alloc_block,
 384                     inode->u.ext2_i.i_next_alloc_goal);
 385 
 386         if (block == inode->u.ext2_i.i_next_alloc_block + 1) {
 387                 inode->u.ext2_i.i_next_alloc_block++;
 388                 inode->u.ext2_i.i_next_alloc_goal++;
 389         }
 390 
 391         *err = -ENOSPC;
 392         b = block;
 393         if (block < EXT2_NDIR_BLOCKS)
 394                 return inode_getblk (inode, block, create, b, err);
 395         block -= EXT2_NDIR_BLOCKS;
 396         if (block < addr_per_block) {
 397                 bh = inode_getblk (inode, EXT2_IND_BLOCK, create, b, err);
 398                 return block_getblk (inode, bh, block, create,
 399                                      inode->i_sb->s_blocksize, b, err);
 400         }
 401         block -= addr_per_block;
 402         if (block < addr_per_block * addr_per_block) {
 403                 bh = inode_getblk (inode, EXT2_DIND_BLOCK, create, b, err);
 404                 bh = block_getblk (inode, bh, block / addr_per_block, create,
 405                                    inode->i_sb->s_blocksize, b, err);
 406                 return block_getblk (inode, bh, block & (addr_per_block - 1),
 407                                      create, inode->i_sb->s_blocksize, b, err);
 408         }
 409         block -= addr_per_block * addr_per_block;
 410         bh = inode_getblk (inode, EXT2_TIND_BLOCK, create, b, err);
 411         bh = block_getblk (inode, bh, block/(addr_per_block * addr_per_block),
 412                            create, inode->i_sb->s_blocksize, b, err);
 413         bh = block_getblk (inode, bh, (block/addr_per_block) & (addr_per_block - 1),
 414                            create, inode->i_sb->s_blocksize, b, err);
 415         return block_getblk (inode, bh, block & (addr_per_block - 1), create,
 416                              inode->i_sb->s_blocksize, b, err);
 417 }
 418 
 419 int ext2_getcluster (struct inode * inode, long block)
     /* [previous][next][first][last][top][bottom][index][help] */
 420 {
 421         struct buffer_head * bh;
 422         int err, create;
 423         unsigned long b;
 424         unsigned long addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
 425 
 426         create = 0;
 427         err = -EIO;
 428         if (block < 0) {
 429                 ext2_warning (inode->i_sb, "ext2_getblk", "block < 0");
 430                 return 0;
 431         }
 432         if (block > EXT2_NDIR_BLOCKS + addr_per_block  +
 433                     addr_per_block * addr_per_block +
 434                     addr_per_block * addr_per_block * addr_per_block) {
 435                 ext2_warning (inode->i_sb, "ext2_getblk", "block > big");
 436                 return 0;
 437         }
 438 
 439         err = -ENOSPC;
 440         b = block;
 441         if (block < EXT2_NDIR_BLOCKS) return 0;
 442 
 443         block -= EXT2_NDIR_BLOCKS;
 444 
 445         if (block < addr_per_block) {
 446                 bh = inode_getblk (inode, EXT2_IND_BLOCK, create, b, &err);
 447                 return block_getcluster (inode, bh, block, 
 448                                          inode->i_sb->s_blocksize);
 449         }
 450         block -= addr_per_block;
 451         if (block < addr_per_block * addr_per_block) {
 452                 bh = inode_getblk (inode, EXT2_DIND_BLOCK, create, b, &err);
 453                 bh = block_getblk (inode, bh, block / addr_per_block, create,
 454                                    inode->i_sb->s_blocksize, b, &err);
 455                 return block_getcluster (inode, bh, block & (addr_per_block - 1),
 456                                      inode->i_sb->s_blocksize);
 457         }
 458         block -= addr_per_block * addr_per_block;
 459         bh = inode_getblk (inode, EXT2_TIND_BLOCK, create, b, &err);
 460         bh = block_getblk (inode, bh, block/(addr_per_block * addr_per_block),
 461                            create, inode->i_sb->s_blocksize, b, &err);
 462         bh = block_getblk (inode, bh, (block/addr_per_block) & (addr_per_block - 1),
 463                            create, inode->i_sb->s_blocksize, b, &err);
 464         return block_getcluster (inode, bh, block & (addr_per_block - 1),
 465                                  inode->i_sb->s_blocksize);
 466 }
 467 
 468 struct buffer_head * ext2_bread (struct inode * inode, int block, 
     /* [previous][next][first][last][top][bottom][index][help] */
 469                                  int create, int *err)
 470 {
 471         struct buffer_head * bh;
 472 
 473         bh = ext2_getblk (inode, block, create, err);
 474         if (!bh || bh->b_uptodate)
 475                 return bh;
 476         ll_rw_block (READ, 1, &bh);
 477         wait_on_buffer (bh);
 478         if (bh->b_uptodate)
 479                 return bh;
 480         brelse (bh);
 481         *err = -EIO;
 482         return NULL;
 483 }
 484 
 485 void ext2_read_inode (struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 486 {
 487         struct buffer_head * bh;
 488         struct ext2_inode * raw_inode;
 489         unsigned long block_group;
 490         unsigned long group_desc;
 491         unsigned long desc;
 492         unsigned long block;
 493         struct ext2_group_desc * gdp;
 494 
 495         if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino != EXT2_ACL_IDX_INO &&
 496              inode->i_ino != EXT2_ACL_DATA_INO && inode->i_ino < EXT2_FIRST_INO) ||
 497             inode->i_ino > inode->i_sb->u.ext2_sb.s_es->s_inodes_count) {
 498                 ext2_error (inode->i_sb, "ext2_read_inode",
 499                             "bad inode number: %lu", inode->i_ino);
 500                 return;
 501         }
 502         block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);
 503         if (block_group >= inode->i_sb->u.ext2_sb.s_groups_count)
 504                 ext2_panic (inode->i_sb, "ext2_read_inode",
 505                             "group >= groups count");
 506         group_desc = block_group / EXT2_DESC_PER_BLOCK(inode->i_sb);
 507         desc = block_group % EXT2_DESC_PER_BLOCK(inode->i_sb);
 508         bh = inode->i_sb->u.ext2_sb.s_group_desc[group_desc];
 509         if (!bh)
 510                 ext2_panic (inode->i_sb, "ext2_read_inode",
 511                             "Descriptor not loaded");
 512         gdp = (struct ext2_group_desc *) bh->b_data;
 513         block = gdp[desc].bg_inode_table +
 514                 (((inode->i_ino - 1) % EXT2_INODES_PER_GROUP(inode->i_sb))
 515                  / EXT2_INODES_PER_BLOCK(inode->i_sb));
 516         if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize)))
 517                 ext2_panic (inode->i_sb, "ext2_read_inode",
 518                             "unable to read i-node block\n"
 519                             "inode=%lu, block=%lu", inode->i_ino, block);
 520         raw_inode = ((struct ext2_inode *) bh->b_data) +
 521                 (inode->i_ino - 1) % EXT2_INODES_PER_BLOCK(inode->i_sb);
 522         inode->i_mode = raw_inode->i_mode;
 523         inode->i_uid = raw_inode->i_uid;
 524         inode->i_gid = raw_inode->i_gid;
 525         inode->i_nlink = raw_inode->i_links_count;
 526         inode->i_size = raw_inode->i_size;
 527         inode->i_atime = raw_inode->i_atime;
 528         inode->i_ctime = raw_inode->i_ctime;
 529         inode->i_mtime = raw_inode->i_mtime;
 530         inode->u.ext2_i.i_dtime = raw_inode->i_dtime;
 531         inode->i_blksize = inode->i_sb->s_blocksize;
 532         inode->i_blocks = raw_inode->i_blocks;
 533         inode->i_version = ++event;
 534         inode->u.ext2_i.i_flags = raw_inode->i_flags;
 535         inode->u.ext2_i.i_faddr = raw_inode->i_faddr;
 536         inode->u.ext2_i.i_frag_no = raw_inode->i_frag;
 537         inode->u.ext2_i.i_frag_size = raw_inode->i_fsize;
 538         inode->u.ext2_i.i_osync = 0;
 539         inode->u.ext2_i.i_file_acl = raw_inode->i_file_acl;
 540         inode->u.ext2_i.i_dir_acl = raw_inode->i_dir_acl;
 541         inode->u.ext2_i.i_version = raw_inode->i_version;
 542         inode->u.ext2_i.i_block_group = block_group;
 543         inode->u.ext2_i.i_next_alloc_block = 0;
 544         inode->u.ext2_i.i_next_alloc_goal = 0;
 545         if (inode->u.ext2_i.i_prealloc_count)
 546                 ext2_error (inode->i_sb, "ext2_read_inode",
 547                             "New inode has non-zero prealloc count!");
 548         if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 549                 inode->i_rdev = raw_inode->i_block[0];
 550         else for (block = 0; block < EXT2_N_BLOCKS; block++)
 551                 inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];
 552         brelse (bh);
 553         inode->i_op = NULL;
 554         if (inode->i_ino == EXT2_ACL_IDX_INO ||
 555             inode->i_ino == EXT2_ACL_DATA_INO)
 556                 /* Nothing to do */ ;
 557         else if (S_ISREG(inode->i_mode))
 558                 inode->i_op = &ext2_file_inode_operations;
 559         else if (S_ISDIR(inode->i_mode))
 560                 inode->i_op = &ext2_dir_inode_operations;
 561         else if (S_ISLNK(inode->i_mode))
 562                 inode->i_op = &ext2_symlink_inode_operations;
 563         else if (S_ISCHR(inode->i_mode))
 564                 inode->i_op = &chrdev_inode_operations;
 565         else if (S_ISBLK(inode->i_mode))
 566                 inode->i_op = &blkdev_inode_operations;
 567         else if (S_ISFIFO(inode->i_mode))
 568                 init_fifo(inode);
 569         if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL)
 570                 inode->i_flags |= MS_SYNC;
 571         if (inode->u.ext2_i.i_flags & EXT2_APPEND_FL)
 572                 inode->i_flags |= S_APPEND;
 573         if (inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL)
 574                 inode->i_flags |= S_IMMUTABLE;
 575 }
 576 
 577 static struct buffer_head * ext2_update_inode (struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 578 {
 579         struct buffer_head * bh;
 580         struct ext2_inode * raw_inode;
 581         unsigned long block_group;
 582         unsigned long group_desc;
 583         unsigned long desc;
 584         unsigned long block;
 585         struct ext2_group_desc * gdp;
 586 
 587         if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino < EXT2_FIRST_INO) ||
 588             inode->i_ino > inode->i_sb->u.ext2_sb.s_es->s_inodes_count) {
 589                 ext2_error (inode->i_sb, "ext2_write_inode",
 590                             "bad inode number: %lu", inode->i_ino);
 591                 return 0;
 592         }
 593         block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);
 594         if (block_group >= inode->i_sb->u.ext2_sb.s_groups_count)
 595                 ext2_panic (inode->i_sb, "ext2_write_inode",
 596                             "group >= groups count");
 597         group_desc = block_group / EXT2_DESC_PER_BLOCK(inode->i_sb);
 598         desc = block_group % EXT2_DESC_PER_BLOCK(inode->i_sb);
 599         bh = inode->i_sb->u.ext2_sb.s_group_desc[group_desc];
 600         if (!bh)
 601                 ext2_panic (inode->i_sb, "ext2_write_inode",
 602                             "Descriptor not loaded");
 603         gdp = (struct ext2_group_desc *) bh->b_data;
 604         block = gdp[desc].bg_inode_table +
 605                 (((inode->i_ino - 1) % EXT2_INODES_PER_GROUP(inode->i_sb))
 606                  / EXT2_INODES_PER_BLOCK(inode->i_sb));
 607         if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize)))
 608                 ext2_panic (inode->i_sb, "ext2_write_inode",
 609                             "unable to read i-node block\n"
 610                             "inode=%lu, block=%lu", inode->i_ino, block);
 611         raw_inode = ((struct ext2_inode *)bh->b_data) +
 612                 (inode->i_ino - 1) % EXT2_INODES_PER_BLOCK(inode->i_sb);
 613         raw_inode->i_mode = inode->i_mode;
 614         raw_inode->i_uid = inode->i_uid;
 615         raw_inode->i_gid = inode->i_gid;
 616         raw_inode->i_links_count = inode->i_nlink;
 617         raw_inode->i_size = inode->i_size;
 618         raw_inode->i_atime = inode->i_atime;
 619         raw_inode->i_ctime = inode->i_ctime;
 620         raw_inode->i_mtime = inode->i_mtime;
 621         raw_inode->i_blocks = inode->i_blocks;
 622         raw_inode->i_dtime = inode->u.ext2_i.i_dtime;
 623         raw_inode->i_flags = inode->u.ext2_i.i_flags;
 624         raw_inode->i_faddr = inode->u.ext2_i.i_faddr;
 625         raw_inode->i_frag = inode->u.ext2_i.i_frag_no;
 626         raw_inode->i_fsize = inode->u.ext2_i.i_frag_size;
 627         raw_inode->i_file_acl = inode->u.ext2_i.i_file_acl;
 628         raw_inode->i_dir_acl = inode->u.ext2_i.i_dir_acl;
 629         raw_inode->i_version = inode->u.ext2_i.i_version;
 630         if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 631                 raw_inode->i_block[0] = inode->i_rdev;
 632         else for (block = 0; block < EXT2_N_BLOCKS; block++)
 633                 raw_inode->i_block[block] = inode->u.ext2_i.i_data[block];
 634         mark_buffer_dirty(bh, 1);
 635         inode->i_dirt = 0;
 636         return bh;
 637 }
 638 
 639 void ext2_write_inode (struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 640 {
 641         struct buffer_head * bh;
 642         bh = ext2_update_inode (inode);
 643         brelse (bh);
 644 }
 645 
 646 int ext2_sync_inode (struct inode *inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 647 {
 648         int err = 0;
 649         struct buffer_head *bh;
 650 
 651         bh = ext2_update_inode (inode);
 652         if (bh && bh->b_dirt)
 653         {
 654                 ll_rw_block (WRITE, 1, &bh);
 655                 wait_on_buffer (bh);
 656                 if (bh->b_req && !bh->b_uptodate)
 657                 {
 658                         printk ("IO error syncing ext2 inode [%04x:%08lx]\n",
 659                                 inode->i_dev, inode->i_ino);
 660                         err = -1;
 661                 }
 662         }
 663         else if (!bh)
 664                 err = -1;
 665         brelse (bh);
 666         return err;
 667 }

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