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

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