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

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