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

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