The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/jfs/jfs_imap.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  *   Copyright (c) International Business Machines Corp., 2000-2002
    3  *
    4  *   This program is free software;  you can redistribute it and/or modify
    5  *   it under the terms of the GNU General Public License as published by
    6  *   the Free Software Foundation; either version 2 of the License, or 
    7  *   (at your option) any later version.
    8  * 
    9  *   This program is distributed in the hope that it will be useful,
   10  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
   11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
   12  *   the GNU General Public License for more details.
   13  *
   14  *   You should have received a copy of the GNU General Public License
   15  *   along with this program;  if not, write to the Free Software 
   16  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
   17  */
   18 
   19 /*
   20  *      jfs_imap.c: inode allocation map manager
   21  *
   22  * Serialization:
   23  *   Each AG has a simple lock which is used to control the serialization of
   24  *      the AG level lists.  This lock should be taken first whenever an AG
   25  *      level list will be modified or accessed.
   26  *
   27  *   Each IAG is locked by obtaining the buffer for the IAG page.
   28  *
   29  *   There is also a inode lock for the inode map inode.  A read lock needs to
   30  *      be taken whenever an IAG is read from the map or the global level
   31  *      information is read.  A write lock needs to be taken whenever the global
   32  *      level information is modified or an atomic operation needs to be used.
   33  *
   34  *      If more than one IAG is read at one time, the read lock may not
   35  *      be given up until all of the IAG's are read.  Otherwise, a deadlock
   36  *      may occur when trying to obtain the read lock while another thread
   37  *      holding the read lock is waiting on the IAG already being held.
   38  *
   39  *   The control page of the inode map is read into memory by diMount().
   40  *      Thereafter it should only be modified in memory and then it will be
   41  *      written out when the filesystem is unmounted by diUnmount().
   42  */
   43 
   44 #include <linux/fs.h>
   45 #include <linux/locks.h>
   46 #include "jfs_incore.h"
   47 #include "jfs_filsys.h"
   48 #include "jfs_dinode.h"
   49 #include "jfs_dmap.h"
   50 #include "jfs_imap.h"
   51 #include "jfs_metapage.h"
   52 #include "jfs_superblock.h"
   53 #include "jfs_debug.h"
   54 
   55 /*
   56  * imap locks
   57  */
   58 /* iag free list lock */
   59 #define IAGFREE_LOCK_INIT(imap)         init_MUTEX(&imap->im_freelock)
   60 #define IAGFREE_LOCK(imap)              down(&imap->im_freelock)
   61 #define IAGFREE_UNLOCK(imap)            up(&imap->im_freelock)
   62 
   63 /* per ag iag list locks */
   64 #define AG_LOCK_INIT(imap,index)        init_MUTEX(&(imap->im_aglock[index]))
   65 #define AG_LOCK(imap,agno)              down(&imap->im_aglock[agno])
   66 #define AG_UNLOCK(imap,agno)            up(&imap->im_aglock[agno])
   67 
   68 /*
   69  * external references
   70  */
   71 extern struct address_space_operations jfs_aops;
   72 
   73 /*
   74  * forward references
   75  */
   76 static int diAllocAG(struct inomap *, int, boolean_t, struct inode *);
   77 static int diAllocAny(struct inomap *, int, boolean_t, struct inode *);
   78 static int diAllocBit(struct inomap *, struct iag *, int);
   79 static int diAllocExt(struct inomap *, int, struct inode *);
   80 static int diAllocIno(struct inomap *, int, struct inode *);
   81 static int diFindFree(u32, int);
   82 static int diNewExt(struct inomap *, struct iag *, int);
   83 static int diNewIAG(struct inomap *, int *, int, struct metapage **);
   84 static void duplicateIXtree(struct super_block *, s64, int, s64 *);
   85 
   86 static int diIAGRead(struct inomap * imap, int, struct metapage **);
   87 static int copy_from_dinode(struct dinode *, struct inode *);
   88 static void copy_to_dinode(struct dinode *, struct inode *);
   89 
   90 /*
   91  *      debug code for double-checking inode map
   92  */
   93 /* #define      _JFS_DEBUG_IMAP 1 */
   94 
   95 #ifdef  _JFS_DEBUG_IMAP
   96 #define DBG_DIINIT(imap)        DBGdiInit(imap)
   97 #define DBG_DIALLOC(imap, ino)  DBGdiAlloc(imap, ino)
   98 #define DBG_DIFREE(imap, ino)   DBGdiFree(imap, ino)
   99 
  100 static void *DBGdiInit(struct inomap * imap);
  101 static void DBGdiAlloc(struct inomap * imap, ino_t ino);
  102 static void DBGdiFree(struct inomap * imap, ino_t ino);
  103 #else
  104 #define DBG_DIINIT(imap)
  105 #define DBG_DIALLOC(imap, ino)
  106 #define DBG_DIFREE(imap, ino)
  107 #endif                          /* _JFS_DEBUG_IMAP */
  108 
  109 /*
  110  * NAME:        diMount()
  111  *
  112  * FUNCTION:    initialize the incore inode map control structures for
  113  *              a fileset or aggregate init time.
  114  *
  115  *              the inode map's control structure (dinomap) is 
  116  *              brought in from disk and placed in virtual memory.
  117  *
  118  * PARAMETERS:
  119  *      ipimap  - pointer to inode map inode for the aggregate or fileset.
  120  *
  121  * RETURN VALUES:
  122  *      0       - success
  123  *      ENOMEM  - insufficient free virtual memory.
  124  *      EIO     - i/o error.
  125  */
  126 int diMount(struct inode *ipimap)
  127 {
  128         struct inomap *imap;
  129         struct metapage *mp;
  130         int index;
  131         struct dinomap *dinom_le;
  132 
  133         /*
  134          * allocate/initialize the in-memory inode map control structure
  135          */
  136         /* allocate the in-memory inode map control structure. */
  137         imap = (struct inomap *) kmalloc(sizeof(struct inomap), GFP_KERNEL);
  138         if (imap == NULL) {
  139                 jfs_err("diMount: kmalloc returned NULL!");
  140                 return (ENOMEM);
  141         }
  142 
  143         /* read the on-disk inode map control structure. */
  144 
  145         mp = read_metapage(ipimap,
  146                            IMAPBLKNO << JFS_SBI(ipimap->i_sb)->l2nbperpage,
  147                            PSIZE, 0);
  148         if (mp == NULL) {
  149                 kfree(imap);
  150                 return (EIO);
  151         }
  152 
  153         /* copy the on-disk version to the in-memory version. */
  154         dinom_le = (struct dinomap *) mp->data;
  155         imap->im_freeiag = le32_to_cpu(dinom_le->in_freeiag);
  156         imap->im_nextiag = le32_to_cpu(dinom_le->in_nextiag);
  157         atomic_set(&imap->im_numinos, le32_to_cpu(dinom_le->in_numinos));
  158         atomic_set(&imap->im_numfree, le32_to_cpu(dinom_le->in_numfree));
  159         imap->im_nbperiext = le32_to_cpu(dinom_le->in_nbperiext);
  160         imap->im_l2nbperiext = le32_to_cpu(dinom_le->in_l2nbperiext);
  161         for (index = 0; index < MAXAG; index++) {
  162                 imap->im_agctl[index].inofree =
  163                     le32_to_cpu(dinom_le->in_agctl[index].inofree);
  164                 imap->im_agctl[index].extfree =
  165                     le32_to_cpu(dinom_le->in_agctl[index].extfree);
  166                 imap->im_agctl[index].numinos =
  167                     le32_to_cpu(dinom_le->in_agctl[index].numinos);
  168                 imap->im_agctl[index].numfree =
  169                     le32_to_cpu(dinom_le->in_agctl[index].numfree);
  170         }
  171 
  172         /* release the buffer. */
  173         release_metapage(mp);
  174 
  175         /*
  176          * allocate/initialize inode allocation map locks
  177          */
  178         /* allocate and init iag free list lock */
  179         IAGFREE_LOCK_INIT(imap);
  180 
  181         /* allocate and init ag list locks */
  182         for (index = 0; index < MAXAG; index++) {
  183                 AG_LOCK_INIT(imap, index);
  184         }
  185 
  186         /* bind the inode map inode and inode map control structure
  187          * to each other.
  188          */
  189         imap->im_ipimap = ipimap;
  190         JFS_IP(ipimap)->i_imap = imap;
  191 
  192 //      DBG_DIINIT(imap);
  193 
  194         return (0);
  195 }
  196 
  197 
  198 /*
  199  * NAME:        diUnmount()
  200  *
  201  * FUNCTION:    write to disk the incore inode map control structures for
  202  *              a fileset or aggregate at unmount time.
  203  *
  204  * PARAMETERS:
  205  *      ipimap  - pointer to inode map inode for the aggregate or fileset.
  206  *
  207  * RETURN VALUES:
  208  *      0       - success
  209  *      ENOMEM  - insufficient free virtual memory.
  210  *      EIO     - i/o error.
  211  */
  212 int diUnmount(struct inode *ipimap, int mounterror)
  213 {
  214         struct inomap *imap = JFS_IP(ipimap)->i_imap;
  215 
  216         /*
  217          * update the on-disk inode map control structure
  218          */
  219 
  220         if (!(mounterror || isReadOnly(ipimap)))
  221                 diSync(ipimap);
  222 
  223         /*
  224          * Invalidate the page cache buffers
  225          */
  226         truncate_inode_pages(ipimap->i_mapping, 0);
  227 
  228         /*
  229          * free in-memory control structure
  230          */
  231         kfree(imap);
  232 
  233         return (0);
  234 }
  235 
  236 
  237 /*
  238  *      diSync()
  239  */
  240 int diSync(struct inode *ipimap)
  241 {
  242         struct dinomap *dinom_le;
  243         struct inomap *imp = JFS_IP(ipimap)->i_imap;
  244         struct metapage *mp;
  245         int index;
  246 
  247         /*
  248          * write imap global conrol page
  249          */
  250         /* read the on-disk inode map control structure */
  251         mp = get_metapage(ipimap,
  252                           IMAPBLKNO << JFS_SBI(ipimap->i_sb)->l2nbperpage,
  253                           PSIZE, 0);
  254         if (mp == NULL) {
  255                 jfs_err("diSync: get_metapage failed!");
  256                 return EIO;
  257         }
  258 
  259         /* copy the in-memory version to the on-disk version */
  260         dinom_le = (struct dinomap *) mp->data;
  261         dinom_le->in_freeiag = cpu_to_le32(imp->im_freeiag);
  262         dinom_le->in_nextiag = cpu_to_le32(imp->im_nextiag);
  263         dinom_le->in_numinos = cpu_to_le32(atomic_read(&imp->im_numinos));
  264         dinom_le->in_numfree = cpu_to_le32(atomic_read(&imp->im_numfree));
  265         dinom_le->in_nbperiext = cpu_to_le32(imp->im_nbperiext);
  266         dinom_le->in_l2nbperiext = cpu_to_le32(imp->im_l2nbperiext);
  267         for (index = 0; index < MAXAG; index++) {
  268                 dinom_le->in_agctl[index].inofree =
  269                     cpu_to_le32(imp->im_agctl[index].inofree);
  270                 dinom_le->in_agctl[index].extfree =
  271                     cpu_to_le32(imp->im_agctl[index].extfree);
  272                 dinom_le->in_agctl[index].numinos =
  273                     cpu_to_le32(imp->im_agctl[index].numinos);
  274                 dinom_le->in_agctl[index].numfree =
  275                     cpu_to_le32(imp->im_agctl[index].numfree);
  276         }
  277 
  278         /* write out the control structure */
  279         write_metapage(mp);
  280 
  281         /*
  282          * write out dirty pages of imap
  283          */
  284         fsync_inode_data_buffers(ipimap);
  285 
  286         diWriteSpecial(ipimap, 0);
  287 
  288         return (0);
  289 }
  290 
  291 
  292 /*
  293  * NAME:        diRead()
  294  *
  295  * FUNCTION:    initialize an incore inode from disk.
  296  *
  297  *              on entry, the specifed incore inode should itself
  298  *              specify the disk inode number corresponding to the
  299  *              incore inode (i.e. i_number should be initialized).
  300  *              
  301  *              this routine handles incore inode initialization for
  302  *              both "special" and "regular" inodes.  special inodes
  303  *              are those required early in the mount process and
  304  *              require special handling since much of the file system
  305  *              is not yet initialized.  these "special" inodes are
  306  *              identified by a NULL inode map inode pointer and are
  307  *              actually initialized by a call to diReadSpecial().
  308  *              
  309  *              for regular inodes, the iag describing the disk inode
  310  *              is read from disk to determine the inode extent address
  311  *              for the disk inode.  with the inode extent address in
  312  *              hand, the page of the extent that contains the disk
  313  *              inode is read and the disk inode is copied to the
  314  *              incore inode.
  315  *
  316  * PARAMETERS:
  317  *      ip  -  pointer to incore inode to be initialized from disk.
  318  *
  319  * RETURN VALUES:
  320  *      0       - success
  321  *      EIO     - i/o error.
  322  *      ENOMEM  - insufficient memory
  323  *      
  324  */
  325 int diRead(struct inode *ip)
  326 {
  327         struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
  328         int iagno, ino, extno, rc;
  329         struct inode *ipimap;
  330         struct dinode *dp;
  331         struct iag *iagp;
  332         struct metapage *mp;
  333         s64 blkno, agstart;
  334         struct inomap *imap;
  335         int block_offset;
  336         int inodes_left;
  337         uint pageno;
  338         int rel_inode;
  339 
  340         jfs_info("diRead: ino = %ld", ip->i_ino);
  341 
  342         ipimap = sbi->ipimap;
  343         JFS_IP(ip)->ipimap = ipimap;
  344 
  345         /* determine the iag number for this inode (number) */
  346         iagno = INOTOIAG(ip->i_ino);
  347 
  348         /* read the iag */
  349         imap = JFS_IP(ipimap)->i_imap;
  350         IREAD_LOCK(ipimap);
  351         rc = diIAGRead(imap, iagno, &mp);
  352         IREAD_UNLOCK(ipimap);
  353         if (rc) {
  354                 jfs_err("diRead: diIAGRead returned %d", rc);
  355                 return (rc);
  356         }
  357 
  358         iagp = (struct iag *) mp->data;
  359 
  360         /* determine inode extent that holds the disk inode */
  361         ino = ip->i_ino & (INOSPERIAG - 1);
  362         extno = ino >> L2INOSPEREXT;
  363 
  364         if ((lengthPXD(&iagp->inoext[extno]) != imap->im_nbperiext) ||
  365             (addressPXD(&iagp->inoext[extno]) == 0)) {
  366                 release_metapage(mp);
  367                 return ESTALE;
  368         }
  369 
  370         /* get disk block number of the page within the inode extent
  371          * that holds the disk inode.
  372          */
  373         blkno = INOPBLK(&iagp->inoext[extno], ino, sbi->l2nbperpage);
  374 
  375         /* get the ag for the iag */
  376         agstart = le64_to_cpu(iagp->agstart);
  377 
  378         release_metapage(mp);
  379 
  380         rel_inode = (ino & (INOSPERPAGE - 1));
  381         pageno = blkno >> sbi->l2nbperpage;
  382 
  383         if ((block_offset = ((u32) blkno & (sbi->nbperpage - 1)))) {
  384                 /*
  385                  * OS/2 didn't always align inode extents on page boundaries
  386                  */
  387                 inodes_left =
  388                      (sbi->nbperpage - block_offset) << sbi->l2niperblk;
  389 
  390                 if (rel_inode < inodes_left)
  391                         rel_inode += block_offset << sbi->l2niperblk;
  392                 else {
  393                         pageno += 1;
  394                         rel_inode -= inodes_left;
  395                 }
  396         }
  397 
  398         /* read the page of disk inode */
  399         mp = read_metapage(ipimap, pageno << sbi->l2nbperpage, PSIZE, 1);
  400         if (mp == 0) {
  401                 jfs_err("diRead: read_metapage failed");
  402                 return EIO;
  403         }
  404 
  405         /* locate the the disk inode requested */
  406         dp = (struct dinode *) mp->data;
  407         dp += rel_inode;
  408 
  409         if (ip->i_ino != le32_to_cpu(dp->di_number)) {
  410                 jfs_err("diRead: i_ino != di_number");
  411                 updateSuper(ip->i_sb, FM_DIRTY);
  412                 rc = EIO;
  413         } else if (le32_to_cpu(dp->di_nlink) == 0)
  414                 rc = ESTALE;
  415         else
  416                 /* copy the disk inode to the in-memory inode */
  417                 rc = copy_from_dinode(dp, ip);
  418 
  419         release_metapage(mp);
  420 
  421         /* set the ag for the inode */
  422         JFS_IP(ip)->agno = BLKTOAG(agstart, sbi);
  423         JFS_IP(ip)->active_ag = -1;
  424 
  425         return (rc);
  426 }
  427 
  428 
  429 /*
  430  * NAME:        diReadSpecial()
  431  *
  432  * FUNCTION:    initialize a 'special' inode from disk.
  433  *
  434  *              this routines handles aggregate level inodes.  The
  435  *              inode cache cannot differentiate between the
  436  *              aggregate inodes and the filesystem inodes, so we
  437  *              handle these here.  We don't actually use the aggregate
  438  *              inode map, since these inodes are at a fixed location
  439  *              and in some cases the aggregate inode map isn't initialized
  440  *              yet.
  441  *
  442  * PARAMETERS:
  443  *      sb - filesystem superblock
  444  *      inum - aggregate inode number
  445  *      secondary - 1 if secondary aggregate inode table
  446  *
  447  * RETURN VALUES:
  448  *      new inode       - success
  449  *      NULL            - i/o error.
  450  */
  451 struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary)
  452 {
  453         struct jfs_sb_info *sbi = JFS_SBI(sb);
  454         uint address;
  455         struct dinode *dp;
  456         struct inode *ip;
  457         struct metapage *mp;
  458         int rc;
  459 
  460         ip = new_inode(sb);
  461         if (ip == NULL) {
  462                 jfs_err("diReadSpecial: new_inode returned NULL!");
  463                 return ip;
  464         }
  465 
  466         rc = alloc_jfs_inode(ip);
  467         if (rc) {
  468                 make_bad_inode(ip);
  469                 iput(ip);
  470                 return NULL;
  471         }
  472 
  473         if (secondary) {
  474                 address = addressPXD(&sbi->ait2) >> sbi->l2nbperpage;
  475                 JFS_IP(ip)->ipimap = sbi->ipaimap2;
  476         } else {
  477                 address = AITBL_OFF >> L2PSIZE;
  478                 JFS_IP(ip)->ipimap = sbi->ipaimap;
  479         }
  480 
  481         ASSERT(inum < INOSPEREXT);
  482 
  483         ip->i_ino = inum;
  484 
  485         address += inum >> 3;   /* 8 inodes per 4K page */
  486 
  487         /* read the page of fixed disk inode (AIT) in raw mode */
  488         mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1);
  489         if (mp == NULL) {
  490                 ip->i_sb = NULL;
  491                 ip->i_nlink = 1;        /* Don't want iput() deleting it */
  492                 iput(ip);
  493                 return (NULL);
  494         }
  495 
  496         /* get the pointer to the disk inode of interest */
  497         dp = (struct dinode *) (mp->data);
  498         dp += inum % 8;         /* 8 inodes per 4K page */
  499 
  500         /* copy on-disk inode to in-memory inode */
  501         if ((copy_from_dinode(dp, ip)) != 0) {
  502                 /* handle bad return by returning NULL for ip */
  503                 ip->i_sb = NULL;
  504                 ip->i_nlink = 1;        /* Don't want iput() deleting it */
  505                 iput(ip);
  506                 /* release the page */
  507                 release_metapage(mp);
  508                 return (NULL);
  509 
  510         }
  511 
  512         ip->i_mapping->a_ops = &jfs_aops;
  513         ip->i_mapping->gfp_mask = GFP_NOFS;
  514 
  515         if ((inum == FILESYSTEM_I) && (JFS_IP(ip)->ipimap == sbi->ipaimap)) {
  516                 sbi->gengen = le32_to_cpu(dp->di_gengen);
  517                 sbi->inostamp = le32_to_cpu(dp->di_inostamp);
  518         }
  519 
  520         /* release the page */
  521         release_metapage(mp);
  522 
  523         return (ip);
  524 }
  525 
  526 /*
  527  * NAME:        diWriteSpecial()
  528  *
  529  * FUNCTION:    Write the special inode to disk
  530  *
  531  * PARAMETERS:
  532  *      ip - special inode
  533  *      secondary - 1 if secondary aggregate inode table
  534  *
  535  * RETURN VALUES: none
  536  */
  537 
  538 void diWriteSpecial(struct inode *ip, int secondary)
  539 {
  540         struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
  541         uint address;
  542         struct dinode *dp;
  543         ino_t inum = ip->i_ino;
  544         struct metapage *mp;
  545 
  546         ip->i_state &= ~I_DIRTY;
  547 
  548         if (secondary)
  549                 address = addressPXD(&sbi->ait2) >> sbi->l2nbperpage;
  550         else
  551                 address = AITBL_OFF >> L2PSIZE;
  552 
  553         ASSERT(inum < INOSPEREXT);
  554 
  555         address += inum >> 3;   /* 8 inodes per 4K page */
  556 
  557         /* read the page of fixed disk inode (AIT) in raw mode */
  558         mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1);
  559         if (mp == NULL) {
  560                 jfs_err("diWriteSpecial: failed to read aggregate inode "
  561                         "extent!");
  562                 return;
  563         }
  564 
  565         /* get the pointer to the disk inode of interest */
  566         dp = (struct dinode *) (mp->data);
  567         dp += inum % 8;         /* 8 inodes per 4K page */
  568 
  569         /* copy on-disk inode to in-memory inode */
  570         copy_to_dinode(dp, ip);
  571         memcpy(&dp->di_xtroot, &JFS_IP(ip)->i_xtroot, 288);
  572 
  573         if (inum == FILESYSTEM_I)
  574                 dp->di_gengen = cpu_to_le32(sbi->gengen);
  575 
  576         /* write the page */
  577         write_metapage(mp);
  578 }
  579 
  580 /*
  581  * NAME:        diFreeSpecial()
  582  *
  583  * FUNCTION:    Free allocated space for special inode
  584  */
  585 void diFreeSpecial(struct inode *ip)
  586 {
  587         if (ip == NULL) {
  588                 jfs_err("diFreeSpecial called with NULL ip!");
  589                 return;
  590         }
  591         fsync_inode_data_buffers(ip);
  592         truncate_inode_pages(ip->i_mapping, 0);
  593         iput(ip);
  594 }
  595 
  596 
  597 
  598 /*
  599  * NAME:        diWrite()
  600  *
  601  * FUNCTION:    write the on-disk inode portion of the in-memory inode
  602  *              to its corresponding on-disk inode.
  603  *
  604  *              on entry, the specifed incore inode should itself
  605  *              specify the disk inode number corresponding to the
  606  *              incore inode (i.e. i_number should be initialized).
  607  *
  608  *              the inode contains the inode extent address for the disk
  609  *              inode.  with the inode extent address in hand, the
  610  *              page of the extent that contains the disk inode is
  611  *              read and the disk inode portion of the incore inode
  612  *              is copied to the disk inode.
  613  *              
  614  * PARAMETERS:
  615  *      tid -  transacation id
  616  *      ip  -  pointer to incore inode to be written to the inode extent.
  617  *
  618  * RETURN VALUES:
  619  *      0       - success
  620  *      EIO     - i/o error.
  621  */
  622 int diWrite(tid_t tid, struct inode *ip)
  623 {
  624         struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
  625         struct jfs_inode_info *jfs_ip = JFS_IP(ip);
  626         int rc = 0;
  627         s32 ino;
  628         struct dinode *dp;
  629         s64 blkno;
  630         int block_offset;
  631         int inodes_left;
  632         struct metapage *mp;
  633         uint pageno;
  634         int rel_inode;
  635         int dioffset;
  636         struct inode *ipimap;
  637         uint type;
  638         lid_t lid;
  639         struct tlock *ditlck, *tlck;
  640         struct linelock *dilinelock, *ilinelock;
  641         struct lv *lv;
  642         int n;
  643 
  644         ipimap = jfs_ip->ipimap;
  645 
  646         ino = ip->i_ino & (INOSPERIAG - 1);
  647 
  648         assert(lengthPXD(&(jfs_ip->ixpxd)) ==
  649                JFS_IP(ipimap)->i_imap->im_nbperiext);
  650         assert(addressPXD(&(jfs_ip->ixpxd)));
  651 
  652         /*
  653          * read the page of disk inode containing the specified inode:
  654          */
  655         /* compute the block address of the page */
  656         blkno = INOPBLK(&(jfs_ip->ixpxd), ino, sbi->l2nbperpage);
  657 
  658         rel_inode = (ino & (INOSPERPAGE - 1));
  659         pageno = blkno >> sbi->l2nbperpage;
  660 
  661         if ((block_offset = ((u32) blkno & (sbi->nbperpage - 1)))) {
  662                 /*
  663                  * OS/2 didn't always align inode extents on page boundaries
  664                  */
  665                 inodes_left =
  666                     (sbi->nbperpage - block_offset) << sbi->l2niperblk;
  667 
  668                 if (rel_inode < inodes_left)
  669                         rel_inode += block_offset << sbi->l2niperblk;
  670                 else {
  671                         pageno += 1;
  672                         rel_inode -= inodes_left;
  673                 }
  674         }
  675         /* read the page of disk inode */
  676       retry:
  677         mp = read_metapage(ipimap, pageno << sbi->l2nbperpage, PSIZE, 1);
  678         if (mp == 0)
  679                 return (EIO);
  680 
  681         /* get the pointer to the disk inode */
  682         dp = (struct dinode *) mp->data;
  683         dp += rel_inode;
  684 
  685         dioffset = (ino & (INOSPERPAGE - 1)) << L2DISIZE;
  686 
  687         /*
  688          * acquire transaction lock on the on-disk inode;
  689          * N.B. tlock is acquired on ipimap not ip;
  690          */
  691         if ((ditlck =
  692              txLock(tid, ipimap, mp, tlckINODE | tlckENTRY)) == NULL)
  693                 goto retry;
  694         dilinelock = (struct linelock *) & ditlck->lock;
  695 
  696         /*
  697          * copy btree root from in-memory inode to on-disk inode
  698          *
  699          * (tlock is taken from inline B+-tree root in in-memory
  700          * inode when the B+-tree root is updated, which is pointed 
  701          * by jfs_ip->blid as well as being on tx tlock list)
  702          *
  703          * further processing of btree root is based on the copy 
  704          * in in-memory inode, where txLog() will log from, and, 
  705          * for xtree root, txUpdateMap() will update map and reset
  706          * XAD_NEW bit;
  707          */
  708 
  709         if (S_ISDIR(ip->i_mode) && (lid = jfs_ip->xtlid)) {
  710                 /*
  711                  * This is the special xtree inside the directory for storing
  712                  * the directory table
  713                  */
  714                 xtpage_t *p, *xp;
  715                 xad_t *xad;
  716 
  717                 jfs_ip->xtlid = 0;
  718                 tlck = lid_to_tlock(lid);
  719                 assert(tlck->type & tlckXTREE);
  720                 tlck->type |= tlckBTROOT;
  721                 tlck->mp = mp;
  722                 ilinelock = (struct linelock *) & tlck->lock;
  723 
  724                 /*
  725                  * copy xtree root from inode to dinode:
  726                  */
  727                 p = &jfs_ip->i_xtroot;
  728                 xp = (xtpage_t *) &dp->di_dirtable;
  729                 lv = ilinelock->lv;
  730                 for (n = 0; n < ilinelock->index; n++, lv++) {
  731                         memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
  732                                lv->length << L2XTSLOTSIZE);
  733                 }
  734 
  735                 /* reset on-disk (metadata page) xtree XAD_NEW bit */
  736                 xad = &xp->xad[XTENTRYSTART];
  737                 for (n = XTENTRYSTART;
  738                      n < le16_to_cpu(xp->header.nextindex); n++, xad++)
  739                         if (xad->flag & (XAD_NEW | XAD_EXTENDED))
  740                                 xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
  741         }
  742 
  743         if ((lid = jfs_ip->blid) == 0)
  744                 goto inlineData;
  745         jfs_ip->blid = 0;
  746 
  747         tlck = lid_to_tlock(lid);
  748         type = tlck->type;
  749         tlck->type |= tlckBTROOT;
  750         tlck->mp = mp;
  751         ilinelock = (struct linelock *) & tlck->lock;
  752 
  753         /*
  754          *      regular file: 16 byte (XAD slot) granularity
  755          */
  756         if (type & tlckXTREE) {
  757                 xtpage_t *p, *xp;
  758                 xad_t *xad;
  759 
  760                 /*
  761                  * copy xtree root from inode to dinode:
  762                  */
  763                 p = &jfs_ip->i_xtroot;
  764                 xp = &dp->di_xtroot;
  765                 lv = ilinelock->lv;
  766                 for (n = 0; n < ilinelock->index; n++, lv++) {
  767                         memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
  768                                lv->length << L2XTSLOTSIZE);
  769                 }
  770 
  771                 /* reset on-disk (metadata page) xtree XAD_NEW bit */
  772                 xad = &xp->xad[XTENTRYSTART];
  773                 for (n = XTENTRYSTART;
  774                      n < le16_to_cpu(xp->header.nextindex); n++, xad++)
  775                         if (xad->flag & (XAD_NEW | XAD_EXTENDED))
  776                                 xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
  777         }
  778         /*
  779          *      directory: 32 byte (directory entry slot) granularity
  780          */
  781         else if (type & tlckDTREE) {
  782                 dtpage_t *p, *xp;
  783 
  784                 /*
  785                  * copy dtree root from inode to dinode:
  786                  */
  787                 p = (dtpage_t *) &jfs_ip->i_dtroot;
  788                 xp = (dtpage_t *) & dp->di_dtroot;
  789                 lv = ilinelock->lv;
  790                 for (n = 0; n < ilinelock->index; n++, lv++) {
  791                         memcpy(&xp->slot[lv->offset], &p->slot[lv->offset],
  792                                lv->length << L2DTSLOTSIZE);
  793                 }
  794         } else {
  795                 jfs_err("diWrite: UFO tlock");
  796         }
  797 
  798       inlineData:
  799         /*
  800          * copy inline symlink from in-memory inode to on-disk inode
  801          */
  802         if (S_ISLNK(ip->i_mode) && ip->i_size < IDATASIZE) {
  803                 lv = & dilinelock->lv[dilinelock->index];
  804                 lv->offset = (dioffset + 2 * 128) >> L2INODESLOTSIZE;
  805                 lv->length = 2;
  806                 memcpy(&dp->di_fastsymlink, jfs_ip->i_inline, IDATASIZE);
  807                 dilinelock->index++;
  808         }
  809         /*
  810          * copy inline data from in-memory inode to on-disk inode:
  811          * 128 byte slot granularity
  812          */
  813         if (test_cflag(COMMIT_Inlineea, ip)) {
  814                 lv = & dilinelock->lv[dilinelock->index];
  815                 lv->offset = (dioffset + 3 * 128) >> L2INODESLOTSIZE;
  816                 lv->length = 1;
  817                 memcpy(&dp->di_inlineea, jfs_ip->i_inline_ea, INODESLOTSIZE);
  818                 dilinelock->index++;
  819 
  820                 clear_cflag(COMMIT_Inlineea, ip);
  821         }
  822 
  823         /*
  824          *      lock/copy inode base: 128 byte slot granularity
  825          */
  826 // baseDinode:
  827         lv = & dilinelock->lv[dilinelock->index];
  828         lv->offset = dioffset >> L2INODESLOTSIZE;
  829         copy_to_dinode(dp, ip);
  830         if (test_and_clear_cflag(COMMIT_Dirtable, ip)) {
  831                 lv->length = 2;
  832                 memcpy(&dp->di_dirtable, &jfs_ip->i_dirtable, 96);
  833         } else
  834                 lv->length = 1;
  835         dilinelock->index++;
  836 
  837 #ifdef _JFS_FASTDASD
  838         /*
  839          * We aren't logging changes to the DASD used in directory inodes,
  840          * but we need to write them to disk.  If we don't unmount cleanly,
  841          * mount will recalculate the DASD used.
  842          */
  843         if (S_ISDIR(ip->i_mode)
  844             && (ip->i_ipmnt->i_mntflag & JFS_DASD_ENABLED))
  845                 bcopy(&ip->i_DASD, &dp->di_DASD, sizeof(struct dasd));
  846 #endif                          /*  _JFS_FASTDASD */
  847 
  848         /* release the buffer holding the updated on-disk inode. 
  849          * the buffer will be later written by commit processing.
  850          */
  851         write_metapage(mp);
  852 
  853         return (rc);
  854 }
  855 
  856 
  857 /*
  858  * NAME:        diFree(ip)
  859  *
  860  * FUNCTION:    free a specified inode from the inode working map
  861  *              for a fileset or aggregate.
  862  *
  863  *              if the inode to be freed represents the first (only)
  864  *              free inode within the iag, the iag will be placed on
  865  *              the ag free inode list.
  866  *      
  867  *              freeing the inode will cause the inode extent to be
  868  *              freed if the inode is the only allocated inode within
  869  *              the extent.  in this case all the disk resource backing
  870  *              up the inode extent will be freed. in addition, the iag
  871  *              will be placed on the ag extent free list if the extent
  872  *              is the first free extent in the iag.  if freeing the
  873  *              extent also means that no free inodes will exist for
  874  *              the iag, the iag will also be removed from the ag free
  875  *              inode list.
  876  *
  877  *              the iag describing the inode will be freed if the extent
  878  *              is to be freed and it is the only backed extent within
  879  *              the iag.  in this case, the iag will be removed from the
  880  *              ag free extent list and ag free inode list and placed on
  881  *              the inode map's free iag list.
  882  *
  883  *              a careful update approach is used to provide consistency
  884  *              in the face of updates to multiple buffers.  under this
  885  *              approach, all required buffers are obtained before making
  886  *              any updates and are held until all updates are complete.
  887  *
  888  * PARAMETERS:
  889  *      ip      - inode to be freed.
  890  *
  891  * RETURN VALUES:
  892  *      0       - success
  893  *      EIO     - i/o error.
  894  */
  895 int diFree(struct inode *ip)
  896 {
  897         int rc;
  898         ino_t inum = ip->i_ino;
  899         struct iag *iagp, *aiagp, *biagp, *ciagp, *diagp;
  900         struct metapage *mp, *amp, *bmp, *cmp, *dmp;
  901         int iagno, ino, extno, bitno, sword, agno;
  902         int back, fwd;
  903         u32 bitmap, mask;
  904         struct inode *ipimap = JFS_SBI(ip->i_sb)->ipimap;
  905         struct inomap *imap = JFS_IP(ipimap)->i_imap;
  906         pxd_t freepxd;
  907         tid_t tid;
  908         struct inode *iplist[3];
  909         struct tlock *tlck;
  910         struct pxd_lock *pxdlock;
  911 
  912         /*
  913          * This is just to suppress compiler warnings.  The same logic that
  914          * references these variables is used to initialize them.
  915          */
  916         aiagp = biagp = ciagp = diagp = NULL;
  917 
  918         /* get the iag number containing the inode.
  919          */
  920         iagno = INOTOIAG(inum);
  921 
  922         /* make sure that the iag is contained within 
  923          * the map.
  924          */
  925         //assert(iagno < imap->im_nextiag);
  926         if (iagno >= imap->im_nextiag) {
  927                 jfs_err("diFree: inum = %d, iagno = %d, nextiag = %d",
  928                         (uint) inum, iagno, imap->im_nextiag);
  929                 dump_mem("imap", imap, 32);
  930                 updateSuper(ip->i_sb, FM_DIRTY);
  931                 return EIO;
  932         }
  933 
  934         /* get the allocation group for this ino.
  935          */
  936         agno = JFS_IP(ip)->agno;
  937 
  938         /* Lock the AG specific inode map information
  939          */
  940         AG_LOCK(imap, agno);
  941 
  942         /* Obtain read lock in imap inode.  Don't release it until we have
  943          * read all of the IAG's that we are going to.
  944          */
  945         IREAD_LOCK(ipimap);
  946 
  947         /* read the iag.
  948          */
  949         if ((rc = diIAGRead(imap, iagno, &mp))) {
  950                 IREAD_UNLOCK(ipimap);
  951                 AG_UNLOCK(imap, agno);
  952                 return (rc);
  953         }
  954         iagp = (struct iag *) mp->data;
  955 
  956         /* get the inode number and extent number of the inode within
  957          * the iag and the inode number within the extent.
  958          */
  959         ino = inum & (INOSPERIAG - 1);
  960         extno = ino >> L2INOSPEREXT;
  961         bitno = ino & (INOSPEREXT - 1);
  962         mask = HIGHORDER >> bitno;
  963 
  964         assert(le32_to_cpu(iagp->wmap[extno]) & mask);
  965 #ifdef _STILL_TO_PORT
  966         assert((le32_to_cpu(iagp->pmap[extno]) & mask) == 0);
  967 #endif                          /*  _STILL_TO_PORT */
  968         assert(addressPXD(&iagp->inoext[extno]));
  969 
  970         /* compute the bitmap for the extent reflecting the freed inode.
  971          */
  972         bitmap = le32_to_cpu(iagp->wmap[extno]) & ~mask;
  973 
  974         if (imap->im_agctl[agno].numfree > imap->im_agctl[agno].numinos) {
  975                 jfs_err("diFree: numfree > numinos");
  976                 release_metapage(mp);
  977                 IREAD_UNLOCK(ipimap);
  978                 AG_UNLOCK(imap, agno);
  979                 updateSuper(ip->i_sb, FM_DIRTY);
  980                 return EIO;
  981         }
  982         /*
  983          *      inode extent still has some inodes or below low water mark:
  984          *      keep the inode extent;
  985          */
  986         if (bitmap ||
  987             imap->im_agctl[agno].numfree < 96 ||
  988             (imap->im_agctl[agno].numfree < 288 &&
  989              (((imap->im_agctl[agno].numfree * 100) /
  990                imap->im_agctl[agno].numinos) <= 25))) {
  991                 /* if the iag currently has no free inodes (i.e.,
  992                  * the inode being freed is the first free inode of iag),
  993                  * insert the iag at head of the inode free list for the ag.
  994                  */
  995                 if (iagp->nfreeinos == 0) {
  996                         /* check if there are any iags on the ag inode
  997                          * free list.  if so, read the first one so that
  998                          * we can link the current iag onto the list at
  999                          * the head.
 1000                          */
 1001                         if ((fwd = imap->im_agctl[agno].inofree) >= 0) {
 1002                                 /* read the iag that currently is the head
 1003                                  * of the list.
 1004                                  */
 1005                                 if ((rc = diIAGRead(imap, fwd, &amp))) {
 1006                                         IREAD_UNLOCK(ipimap);
 1007                                         AG_UNLOCK(imap, agno);
 1008                                         release_metapage(mp);
 1009                                         return (rc);
 1010                                 }
 1011                                 aiagp = (struct iag *) amp->data;
 1012 
 1013                                 /* make current head point back to the iag.
 1014                                  */
 1015                                 aiagp->inofreeback = cpu_to_le32(iagno);
 1016 
 1017                                 write_metapage(amp);
 1018                         }
 1019 
 1020                         /* iag points forward to current head and iag
 1021                          * becomes the new head of the list.
 1022                          */
 1023                         iagp->inofreefwd =
 1024                             cpu_to_le32(imap->im_agctl[agno].inofree);
 1025                         iagp->inofreeback = -1;
 1026                         imap->im_agctl[agno].inofree = iagno;
 1027                 }
 1028                 IREAD_UNLOCK(ipimap);
 1029 
 1030                 /* update the free inode summary map for the extent if
 1031                  * freeing the inode means the extent will now have free
 1032                  * inodes (i.e., the inode being freed is the first free 
 1033                  * inode of extent),
 1034                  */
 1035                 if (iagp->wmap[extno] == ONES) {
 1036                         sword = extno >> L2EXTSPERSUM;
 1037                         bitno = extno & (EXTSPERSUM - 1);
 1038                         iagp->inosmap[sword] &=
 1039                             cpu_to_le32(~(HIGHORDER >> bitno));
 1040                 }
 1041 
 1042                 /* update the bitmap.
 1043                  */
 1044                 iagp->wmap[extno] = cpu_to_le32(bitmap);
 1045                 DBG_DIFREE(imap, inum);
 1046 
 1047                 /* update the free inode counts at the iag, ag and
 1048                  * map level.
 1049                  */
 1050                 iagp->nfreeinos =
 1051                     cpu_to_le32(le32_to_cpu(iagp->nfreeinos) + 1);
 1052                 imap->im_agctl[agno].numfree += 1;
 1053                 atomic_inc(&imap->im_numfree);
 1054 
 1055                 /* release the AG inode map lock
 1056                  */
 1057                 AG_UNLOCK(imap, agno);
 1058 
 1059                 /* write the iag */
 1060                 write_metapage(mp);
 1061 
 1062                 return (0);
 1063         }
 1064 
 1065 
 1066         /*
 1067          *      inode extent has become free and above low water mark:
 1068          *      free the inode extent;
 1069          */
 1070 
 1071         /*
 1072          *      prepare to update iag list(s) (careful update step 1)
 1073          */
 1074         amp = bmp = cmp = dmp = NULL;
 1075         fwd = back = -1;
 1076 
 1077         /* check if the iag currently has no free extents.  if so,
 1078          * it will be placed on the head of the ag extent free list.
 1079          */
 1080         if (iagp->nfreeexts == 0) {
 1081                 /* check if the ag extent free list has any iags.
 1082                  * if so, read the iag at the head of the list now.
 1083                  * this (head) iag will be updated later to reflect
 1084                  * the addition of the current iag at the head of
 1085                  * the list.
 1086                  */
 1087                 if ((fwd = imap->im_agctl[agno].extfree) >= 0) {
 1088                         if ((rc = diIAGRead(imap, fwd, &amp)))
 1089                                 goto error_out;
 1090                         aiagp = (struct iag *) amp->data;
 1091                 }
 1092         } else {
 1093                 /* iag has free extents. check if the addition of a free
 1094                  * extent will cause all extents to be free within this
 1095                  * iag.  if so, the iag will be removed from the ag extent
 1096                  * free list and placed on the inode map's free iag list.
 1097                  */
 1098                 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG - 1)) {
 1099                         /* in preparation for removing the iag from the
 1100                          * ag extent free list, read the iags preceeding
 1101                          * and following the iag on the ag extent free
 1102                          * list.
 1103                          */
 1104                         if ((fwd = le32_to_cpu(iagp->extfreefwd)) >= 0) {
 1105                                 if ((rc = diIAGRead(imap, fwd, &amp)))
 1106                                         goto error_out;
 1107                                 aiagp = (struct iag *) amp->data;
 1108                         }
 1109 
 1110                         if ((back = le32_to_cpu(iagp->extfreeback)) >= 0) {
 1111                                 if ((rc = diIAGRead(imap, back, &bmp)))
 1112                                         goto error_out;
 1113                                 biagp = (struct iag *) bmp->data;
 1114                         }
 1115                 }
 1116         }
 1117 
 1118         /* remove the iag from the ag inode free list if freeing
 1119          * this extent cause the iag to have no free inodes.
 1120          */
 1121         if (iagp->nfreeinos == cpu_to_le32(INOSPEREXT - 1)) {
 1122                 int inofreeback = le32_to_cpu(iagp->inofreeback);
 1123                 int inofreefwd = le32_to_cpu(iagp->inofreefwd);
 1124 
 1125                 /* in preparation for removing the iag from the
 1126                  * ag inode free list, read the iags preceeding
 1127                  * and following the iag on the ag inode free
 1128                  * list.  before reading these iags, we must make
 1129                  * sure that we already don't have them in hand
 1130                  * from up above, since re-reading an iag (buffer)
 1131                  * we are currently holding would cause a deadlock.
 1132                  */
 1133                 if (inofreefwd >= 0) {
 1134 
 1135                         if (inofreefwd == fwd)
 1136                                 ciagp = (struct iag *) amp->data;
 1137                         else if (inofreefwd == back)
 1138                                 ciagp = (struct iag *) bmp->data;
 1139                         else {
 1140                                 if ((rc =
 1141                                      diIAGRead(imap, inofreefwd, &cmp)))
 1142                                         goto error_out;
 1143                                 assert(cmp != NULL);
 1144                                 ciagp = (struct iag *) cmp->data;
 1145                         }
 1146                         assert(ciagp != NULL);
 1147                 }
 1148 
 1149                 if (inofreeback >= 0) {
 1150                         if (inofreeback == fwd)
 1151                                 diagp = (struct iag *) amp->data;
 1152                         else if (inofreeback == back)
 1153                                 diagp = (struct iag *) bmp->data;
 1154                         else {
 1155                                 if ((rc =
 1156                                      diIAGRead(imap, inofreeback, &dmp)))
 1157                                         goto error_out;
 1158                                 assert(dmp != NULL);
 1159                                 diagp = (struct iag *) dmp->data;
 1160                         }
 1161                         assert(diagp != NULL);
 1162                 }
 1163         }
 1164 
 1165         IREAD_UNLOCK(ipimap);
 1166 
 1167         /*
 1168          * invalidate any page of the inode extent freed from buffer cache;
 1169          */
 1170         freepxd = iagp->inoext[extno];
 1171         invalidate_pxd_metapages(ip, freepxd);
 1172 
 1173         /*
 1174          *      update iag list(s) (careful update step 2)
 1175          */
 1176         /* add the iag to the ag extent free list if this is the
 1177          * first free extent for the iag.
 1178          */
 1179         if (iagp->nfreeexts == 0) {
 1180                 if (fwd >= 0)
 1181                         aiagp->extfreeback = cpu_to_le32(iagno);
 1182 
 1183                 iagp->extfreefwd =
 1184                     cpu_to_le32(imap->im_agctl[agno].extfree);
 1185                 iagp->extfreeback = -1;
 1186                 imap->im_agctl[agno].extfree = iagno;
 1187         } else {
 1188                 /* remove the iag from the ag extent list if all extents
 1189                  * are now free and place it on the inode map iag free list.
 1190                  */
 1191                 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG - 1)) {
 1192                         if (fwd >= 0)
 1193                                 aiagp->extfreeback = iagp->extfreeback;
 1194 
 1195                         if (back >= 0)
 1196                                 biagp->extfreefwd = iagp->extfreefwd;
 1197                         else
 1198                                 imap->im_agctl[agno].extfree =
 1199                                     le32_to_cpu(iagp->extfreefwd);
 1200 
 1201                         iagp->extfreefwd = iagp->extfreeback = -1;
 1202 
 1203                         IAGFREE_LOCK(imap);
 1204                         iagp->iagfree = cpu_to_le32(imap->im_freeiag);
 1205                         imap->im_freeiag = iagno;
 1206                         IAGFREE_UNLOCK(imap);
 1207                 }
 1208         }
 1209 
 1210         /* remove the iag from the ag inode free list if freeing
 1211          * this extent causes the iag to have no free inodes.
 1212          */
 1213         if (iagp->nfreeinos == cpu_to_le32(INOSPEREXT - 1)) {
 1214                 if ((int) le32_to_cpu(iagp->inofreefwd) >= 0)
 1215                         ciagp->inofreeback = iagp->inofreeback;
 1216 
 1217                 if ((int) le32_to_cpu(iagp->inofreeback) >= 0)
 1218                         diagp->inofreefwd = iagp->inofreefwd;
 1219                 else
 1220                         imap->im_agctl[agno].inofree =
 1221                             le32_to_cpu(iagp->inofreefwd);
 1222 
 1223                 iagp->inofreefwd = iagp->inofreeback = -1;
 1224         }
 1225 
 1226         /* update the inode extent address and working map 
 1227          * to reflect the free extent.
 1228          * the permanent map should have been updated already 
 1229          * for the inode being freed.
 1230          */
 1231         assert(iagp->pmap[extno] == 0);
 1232         iagp->wmap[extno] = 0;
 1233         DBG_DIFREE(imap, inum);
 1234         PXDlength(&iagp->inoext[extno], 0);
 1235         PXDaddress(&iagp->inoext[extno], 0);
 1236 
 1237         /* update the free extent and free inode summary maps
 1238          * to reflect the freed extent.
 1239          * the inode summary map is marked to indicate no inodes 
 1240          * available for the freed extent.
 1241          */
 1242         sword = extno >> L2EXTSPERSUM;
 1243         bitno = extno & (EXTSPERSUM - 1);
 1244         mask = HIGHORDER >> bitno;
 1245         iagp->inosmap[sword] |= cpu_to_le32(mask);
 1246         iagp->extsmap[sword] &= cpu_to_le32(~mask);
 1247 
 1248         /* update the number of free inodes and number of free extents
 1249          * for the iag.
 1250          */
 1251         iagp->nfreeinos = cpu_to_le32(le32_to_cpu(iagp->nfreeinos) -
 1252                                       (INOSPEREXT - 1));
 1253         iagp->nfreeexts = cpu_to_le32(le32_to_cpu(iagp->nfreeexts) + 1);
 1254 
 1255         /* update the number of free inodes and backed inodes
 1256          * at the ag and inode map level.
 1257          */
 1258         imap->im_agctl[agno].numfree -= (INOSPEREXT - 1);
 1259         imap->im_agctl[agno].numinos -= INOSPEREXT;
 1260         atomic_sub(INOSPEREXT - 1, &imap->im_numfree);
 1261         atomic_sub(INOSPEREXT, &imap->im_numinos);
 1262 
 1263         if (amp)
 1264                 write_metapage(amp);
 1265         if (bmp)
 1266                 write_metapage(bmp);
 1267         if (cmp)
 1268                 write_metapage(cmp);
 1269         if (dmp)
 1270                 write_metapage(dmp);
 1271 
 1272         /*
 1273          * start transaction to update block allocation map
 1274          * for the inode extent freed;
 1275          *
 1276          * N.B. AG_LOCK is released and iag will be released below, and 
 1277          * other thread may allocate inode from/reusing the ixad freed
 1278          * BUT with new/different backing inode extent from the extent 
 1279          * to be freed by the transaction;  
 1280          */
 1281         tid = txBegin(ipimap->i_sb, COMMIT_FORCE);
 1282 
 1283         /* acquire tlock of the iag page of the freed ixad 
 1284          * to force the page NOHOMEOK (even though no data is
 1285          * logged from the iag page) until NOREDOPAGE|FREEXTENT log 
 1286          * for the free of the extent is committed;
 1287          * write FREEXTENT|NOREDOPAGE log record
 1288          * N.B. linelock is overlaid as freed extent descriptor;
 1289          */
 1290         tlck = txLock(tid, ipimap, mp, tlckINODE | tlckFREE);
 1291         pxdlock = (struct pxd_lock *) & tlck->lock;
 1292         pxdlock->flag = mlckFREEPXD;
 1293         pxdlock->pxd = freepxd;
 1294         pxdlock->index = 1;
 1295 
 1296         write_metapage(mp);
 1297 
 1298         iplist[0] = ipimap;
 1299 
 1300         /*
 1301          * logredo needs the IAG number and IAG extent index in order
 1302          * to ensure that the IMap is consistent.  The least disruptive
 1303          * way to pass these values through  to the transaction manager
 1304          * is in the iplist array.  
 1305          * 
 1306          * It's not pretty, but it works.
 1307          */
 1308         iplist[1] = (struct inode *) (size_t)iagno;
 1309         iplist[2] = (struct inode *) (size_t)extno;
 1310 
 1311         rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);        // D233382
 1312 
 1313         txEnd(tid);
 1314 
 1315         /* unlock the AG inode map information */
 1316         AG_UNLOCK(imap, agno);
 1317 
 1318         return (0);
 1319 
 1320       error_out:
 1321         IREAD_UNLOCK(ipimap);
 1322 
 1323         if (amp)
 1324                 release_metapage(amp);
 1325         if (bmp)
 1326                 release_metapage(bmp);
 1327         if (cmp)
 1328                 release_metapage(cmp);
 1329         if (dmp)
 1330                 release_metapage(dmp);
 1331 
 1332         AG_UNLOCK(imap, agno);
 1333 
 1334         release_metapage(mp);
 1335 
 1336         return (rc);
 1337 }
 1338 
 1339 /*
 1340  * There are several places in the diAlloc* routines where we initialize
 1341  * the inode.
 1342  */
 1343 static inline void
 1344 diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp)
 1345 {
 1346         struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
 1347         struct jfs_inode_info *jfs_ip = JFS_IP(ip);
 1348 
 1349         ip->i_ino = (iagno << L2INOSPERIAG) + ino;
 1350         DBG_DIALLOC(JFS_IP(ipimap)->i_imap, ip->i_ino);
 1351         jfs_ip->ixpxd = iagp->inoext[extno];
 1352         jfs_ip->agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi);
 1353         jfs_ip->active_ag = -1;
 1354 }
 1355 
 1356 
 1357 /*
 1358  * NAME:        diAlloc(pip,dir,ip)
 1359  *
 1360  * FUNCTION:    allocate a disk inode from the inode working map 
 1361  *              for a fileset or aggregate.
 1362  *
 1363  * PARAMETERS:
 1364  *      pip     - pointer to incore inode for the parent inode.
 1365  *      dir     - TRUE if the new disk inode is for a directory.
 1366  *      ip      - pointer to a new inode
 1367  *
 1368  * RETURN VALUES:
 1369  *      0       - success.
 1370  *      ENOSPC  - insufficient disk resources.
 1371  *      EIO     - i/o error.
 1372  */
 1373 int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip)
 1374 {
 1375         int rc, ino, iagno, addext, extno, bitno, sword;
 1376         int nwords, rem, i, agno;
 1377         u32 mask, inosmap, extsmap;
 1378         struct inode *ipimap;
 1379         struct metapage *mp;
 1380         ino_t inum;
 1381         struct iag *iagp;
 1382         struct inomap *imap;
 1383 
 1384         /* get the pointers to the inode map inode and the
 1385          * corresponding imap control structure.
 1386          */
 1387         ipimap = JFS_SBI(pip->i_sb)->ipimap;
 1388         imap = JFS_IP(ipimap)->i_imap;
 1389         JFS_IP(ip)->ipimap = ipimap;
 1390         JFS_IP(ip)->fileset = FILESYSTEM_I;
 1391 
 1392         /* for a directory, the allocation policy is to start 
 1393          * at the ag level using the preferred ag.
 1394          */
 1395         if (dir == TRUE) {
 1396                 agno = dbNextAG(JFS_SBI(pip->i_sb)->ipbmap);
 1397                 AG_LOCK(imap, agno);
 1398                 goto tryag;
 1399         }
 1400 
 1401         /* for files, the policy starts off by trying to allocate from
 1402          * the same iag containing the parent disk inode:
 1403          * try to allocate the new disk inode close to the parent disk
 1404          * inode, using parent disk inode number + 1 as the allocation
 1405          * hint.  (we use a left-to-right policy to attempt to avoid
 1406          * moving backward on the disk.)  compute the hint within the
 1407          * file system and the iag.
 1408          */
 1409 
 1410         /* get the ag number of this iag */
 1411         agno = JFS_IP(pip)->agno;
 1412 
 1413         if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) {
 1414                 /*
 1415                  * There is an open file actively growing.  We want to
 1416                  * allocate new inodes from a different ag to avoid
 1417                  * fragmentation problems.
 1418                  */
 1419                 agno = dbNextAG(JFS_SBI(pip->i_sb)->ipbmap);
 1420                 AG_LOCK(imap, agno);
 1421                 goto tryag;
 1422         }
 1423 
 1424         inum = pip->i_ino + 1;
 1425         ino = inum & (INOSPERIAG - 1);
 1426 
 1427         /* back off the the hint if it is outside of the iag */
 1428         if (ino == 0)
 1429                 inum = pip->i_ino;
 1430 
 1431         /* lock the AG inode map information */
 1432         AG_LOCK(imap, agno);
 1433 
 1434         /* Get read lock on imap inode */
 1435         IREAD_LOCK(ipimap);
 1436 
 1437         /* get the iag number and read the iag */
 1438         iagno = INOTOIAG(inum);
 1439         if ((rc = diIAGRead(imap, iagno, &mp))) {
 1440                 IREAD_UNLOCK(ipimap);
 1441                 return (rc);
 1442         }
 1443         iagp = (struct iag *) mp->data;
 1444 
 1445         /* determine if new inode extent is allowed to be added to the iag.
 1446          * new inode extent can be added to the iag if the ag
 1447          * has less than 32 free disk inodes and the iag has free extents.
 1448          */
 1449         addext = (imap->im_agctl[agno].numfree < 32 && iagp->nfreeexts);
 1450 
 1451         /*
 1452          *      try to allocate from the IAG
 1453          */
 1454         /* check if the inode may be allocated from the iag 
 1455          * (i.e. the inode has free inodes or new extent can be added).
 1456          */
 1457         if (iagp->nfreeinos || addext) {
 1458                 /* determine the extent number of the hint.
 1459                  */
 1460                 extno = ino >> L2INOSPEREXT;
 1461 
 1462                 /* check if the extent containing the hint has backed
 1463                  * inodes.  if so, try to allocate within this extent.
 1464                  */
 1465                 if (addressPXD(&iagp->inoext[extno])) {
 1466                         bitno = ino & (INOSPEREXT - 1);
 1467                         if ((bitno =
 1468                              diFindFree(le32_to_cpu(iagp->wmap[extno]),
 1469                                         bitno))
 1470                             < INOSPEREXT) {
 1471                                 ino = (extno << L2INOSPEREXT) + bitno;
 1472 
 1473                                 /* a free inode (bit) was found within this
 1474                                  * extent, so allocate it.
 1475                                  */
 1476                                 rc = diAllocBit(imap, iagp, ino);
 1477                                 IREAD_UNLOCK(ipimap);
 1478                                 if (rc) {
 1479                                         assert(rc == EIO);
 1480                                 } else {
 1481                                         /* set the results of the allocation
 1482                                          * and write the iag.
 1483                                          */
 1484                                         diInitInode(ip, iagno, ino, extno,
 1485                                                     iagp);
 1486                                         mark_metapage_dirty(mp);
 1487                                 }
 1488                                 release_metapage(mp);
 1489 
 1490                                 /* free the AG lock and return.
 1491                                  */
 1492                                 AG_UNLOCK(imap, agno);
 1493                                 return (rc);
 1494                         }
 1495 
 1496                         if (!addext)
 1497                                 extno =
 1498                                     (extno ==
 1499                                      EXTSPERIAG - 1) ? 0 : extno + 1;
 1500                 }
 1501 
 1502                 /*
 1503                  * no free inodes within the extent containing the hint.
 1504                  *
 1505                  * try to allocate from the backed extents following
 1506                  * hint or, if appropriate (i.e. addext is true), allocate
 1507                  * an extent of free inodes at or following the extent
 1508                  * containing the hint.
 1509                  * 
 1510                  * the free inode and free extent summary maps are used
 1511                  * here, so determine the starting summary map position
 1512                  * and the number of words we'll have to examine.  again,
 1513                  * the approach is to allocate following the hint, so we
 1514                  * might have to initially ignore prior bits of the summary
 1515                  * map that represent extents prior to the extent containing
 1516                  * the hint and later revisit these bits.
 1517                  */
 1518                 bitno = extno & (EXTSPERSUM - 1);
 1519                 nwords = (bitno == 0) ? SMAPSZ : SMAPSZ + 1;
 1520                 sword = extno >> L2EXTSPERSUM;
 1521 
 1522                 /* mask any prior bits for the starting words of the
 1523                  * summary map.
 1524                  */
 1525                 mask = ONES << (EXTSPERSUM - bitno);
 1526                 inosmap = le32_to_cpu(iagp->inosmap[sword]) | mask;
 1527                 extsmap = le32_to_cpu(iagp->extsmap[sword]) | mask;
 1528 
 1529                 /* scan the free inode and free extent summary maps for
 1530                  * free resources.
 1531                  */
 1532                 for (i = 0; i < nwords; i++) {
 1533                         /* check if this word of the free inode summary
 1534                          * map describes an extent with free inodes.
 1535                          */
 1536                         if (~inosmap) {
 1537                                 /* an extent with free inodes has been
 1538                                  * found. determine the extent number
 1539                                  * and the inode number within the extent.
 1540                                  */
 1541                                 rem = diFindFree(inosmap, 0);
 1542                                 extno = (sword << L2EXTSPERSUM) + rem;
 1543                                 rem =
 1544                                     diFindFree(le32_to_cpu
 1545                                                (iagp->wmap[extno]), 0);
 1546                                 assert(rem < INOSPEREXT);
 1547 
 1548                                 /* determine the inode number within the
 1549                                  * iag and allocate the inode from the
 1550                                  * map.
 1551                                  */
 1552                                 ino = (extno << L2INOSPEREXT) + rem;
 1553                                 rc = diAllocBit(imap, iagp, ino);
 1554                                 IREAD_UNLOCK(ipimap);
 1555                                 if (rc) {
 1556                                         assert(rc == EIO);
 1557                                 } else {
 1558                                         /* set the results of the allocation
 1559                                          * and write the iag.
 1560                                          */
 1561                                         diInitInode(ip, iagno, ino, extno,
 1562                                                     iagp);
 1563                                         mark_metapage_dirty(mp);
 1564                                 }
 1565                                 release_metapage(mp);
 1566 
 1567                                 /* free the AG lock and return.
 1568                                  */
 1569                                 AG_UNLOCK(imap, agno);
 1570                                 return (rc);
 1571 
 1572                         }
 1573 
 1574                         /* check if we may allocate an extent of free
 1575                          * inodes and whether this word of the free
 1576                          * extents summary map describes a free extent.
 1577                          */
 1578                         if (addext && ~extsmap) {
 1579                                 /* a free extent has been found.  determine
 1580                                  * the extent number.
 1581                                  */
 1582                                 rem = diFindFree(extsmap, 0);
 1583                                 extno = (sword << L2EXTSPERSUM) + rem;
 1584 
 1585                                 /* allocate an extent of free inodes.
 1586                                  */
 1587                                 if ((rc = diNewExt(imap, iagp, extno))) {
 1588                                         /* if there is no disk space for a
 1589                                          * new extent, try to allocate the
 1590                                          * disk inode from somewhere else.
 1591                                          */
 1592                                         if (rc == ENOSPC)
 1593                                                 break;
 1594 
 1595                                         assert(rc == EIO);
 1596                                 } else {
 1597                                         /* set the results of the allocation
 1598                                          * and write the iag.
 1599                                          */
 1600                                         diInitInode(ip, iagno,
 1601                                                     extno << L2INOSPEREXT,
 1602                                                     extno, iagp);
 1603                                         mark_metapage_dirty(mp);
 1604                                 }
 1605                                 release_metapage(mp);
 1606                                 /* free the imap inode & the AG lock & return.
 1607                                  */
 1608                                 IREAD_UNLOCK(ipimap);
 1609                                 AG_UNLOCK(imap, agno);
 1610                                 return (rc);
 1611                         }
 1612 
 1613                         /* move on to the next set of summary map words.
 1614                          */
 1615                         sword = (sword == SMAPSZ - 1) ? 0 : sword + 1;
 1616                         inosmap = le32_to_cpu(iagp->inosmap[sword]);
 1617                         extsmap = le32_to_cpu(iagp->extsmap[sword]);
 1618                 }
 1619         }
 1620         /* unlock imap inode */
 1621         IREAD_UNLOCK(ipimap);
 1622 
 1623         /* nothing doing in this iag, so release it. */
 1624         release_metapage(mp);
 1625 
 1626       tryag:
 1627         /*
 1628          * try to allocate anywhere within the same AG as the parent inode.
 1629          */
 1630         rc = diAllocAG(imap, agno, dir, ip);
 1631 
 1632         AG_UNLOCK(imap, agno);
 1633 
 1634         if (rc != ENOSPC)
 1635                 return (rc);
 1636 
 1637         /*
 1638          * try to allocate in any AG.
 1639          */
 1640         return (diAllocAny(imap, agno, dir, ip));
 1641 }
 1642 
 1643 
 1644 /*
 1645  * NAME:        diAllocAG(imap,agno,dir,ip)
 1646  *
 1647  * FUNCTION:    allocate a disk inode from the allocation group.
 1648  *
 1649  *              this routine first determines if a new extent of free
 1650  *              inodes should be added for the allocation group, with
 1651  *              the current request satisfied from this extent. if this
 1652  *              is the case, an attempt will be made to do just that.  if
 1653  *              this attempt fails or it has been determined that a new 
 1654  *              extent should not be added, an attempt is made to satisfy
 1655  *              the request by allocating an existing (backed) free inode
 1656  *              from the allocation group.
 1657  *
 1658  * PRE CONDITION: Already have the AG lock for this AG.
 1659  *
 1660  * PARAMETERS:
 1661  *      imap    - pointer to inode map control structure.
 1662  *      agno    - allocation group to allocate from.
 1663  *      dir     - TRUE if the new disk inode is for a directory.
 1664  *      ip      - pointer to the new inode to be filled in on successful return
 1665  *                with the disk inode number allocated, its extent address
 1666  *                and the start of the ag.
 1667  *
 1668  * RETURN VALUES:
 1669  *      0       - success.
 1670  *      ENOSPC  - insufficient disk resources.
 1671  *      EIO     - i/o error.
 1672  */
 1673 static int
 1674 diAllocAG(struct inomap * imap, int agno, boolean_t dir, struct inode *ip)
 1675 {
 1676         int rc, addext, numfree, numinos;
 1677 
 1678         /* get the number of free and the number of backed disk 
 1679          * inodes currently within the ag.
 1680          */
 1681         numfree = imap->im_agctl[agno].numfree;
 1682         numinos = imap->im_agctl[agno].numinos;
 1683 
 1684         if (numfree > numinos) {
 1685                 jfs_err("diAllocAG: numfree > numinos");
 1686                 updateSuper(ip->i_sb, FM_DIRTY);
 1687                 return EIO;
 1688         }
 1689 
 1690         /* determine if we should allocate a new extent of free inodes
 1691          * within the ag: for directory inodes, add a new extent
 1692          * if there are a small number of free inodes or number of free
 1693          * inodes is a small percentage of the number of backed inodes.
 1694          */
 1695         if (dir == TRUE)
 1696                 addext = (numfree < 64 ||
 1697                           (numfree < 256
 1698                            && ((numfree * 100) / numinos) <= 20));
 1699         else
 1700                 addext = (numfree == 0);
 1701 
 1702         /*
 1703          * try to allocate a new extent of free inodes.
 1704          */
 1705         if (addext) {
 1706                 /* if free space is not avaliable for this new extent, try
 1707                  * below to allocate a free and existing (already backed)
 1708                  * inode from the ag.
 1709                  */
 1710                 if ((rc = diAllocExt(imap, agno, ip)) != ENOSPC)
 1711                         return (rc);
 1712         }
 1713 
 1714         /*
 1715          * try to allocate an existing free inode from the ag.
 1716          */
 1717         return (diAllocIno(imap, agno, ip));
 1718 }
 1719 
 1720 
 1721 /*
 1722  * NAME:        diAllocAny(imap,agno,dir,iap)
 1723  *
 1724  * FUNCTION:    allocate a disk inode from any other allocation group.
 1725  *
 1726  *              this routine is called when an allocation attempt within
 1727  *              the primary allocation group has failed. if attempts to
 1728  *              allocate an inode from any allocation group other than the
 1729  *              specified primary group.
 1730  *
 1731  * PARAMETERS:
 1732  *      imap    - pointer to inode map control structure.
 1733  *      agno    - primary allocation group (to avoid).
 1734  *      dir     - TRUE if the new disk inode is for a directory.
 1735  *      ip      - pointer to a new inode to be filled in on successful return
 1736  *                with the disk inode number allocated, its extent address
 1737  *                and the start of the ag.
 1738  *
 1739  * RETURN VALUES:
 1740  *      0       - success.
 1741  *      ENOSPC  - insufficient disk resources.
 1742  *      EIO     - i/o error.
 1743  */
 1744 static int
 1745 diAllocAny(struct inomap * imap, int agno, boolean_t dir, struct inode *ip)
 1746 {
 1747         int ag, rc;
 1748         int maxag = JFS_SBI(imap->im_ipimap->i_sb)->bmap->db_maxag;
 1749 
 1750 
 1751         /* try to allocate from the ags following agno up to 
 1752          * the maximum ag number.
 1753          */
 1754         for (ag = agno + 1; ag <= maxag; ag++) {
 1755                 AG_LOCK(imap, ag);
 1756 
 1757                 rc = diAllocAG(imap, ag, dir, ip);
 1758 
 1759                 AG_UNLOCK(imap, ag);
 1760 
 1761                 if (rc != ENOSPC)
 1762                         return (rc);
 1763         }
 1764 
 1765         /* try to allocate from the ags in front of agno.
 1766          */
 1767         for (ag = 0; ag < agno; ag++) {
 1768                 AG_LOCK(imap, ag);
 1769 
 1770                 rc = diAllocAG(imap, ag, dir, ip);
 1771 
 1772                 AG_UNLOCK(imap, ag);
 1773 
 1774                 if (rc != ENOSPC)
 1775                         return (rc);
 1776         }
 1777 
 1778         /* no free disk inodes.
 1779          */
 1780         return (ENOSPC);
 1781 }
 1782 
 1783 
 1784 /*
 1785  * NAME:        diAllocIno(imap,agno,ip)
 1786  *
 1787  * FUNCTION:    allocate a disk inode from the allocation group's free
 1788  *              inode list, returning an error if this free list is
 1789  *              empty (i.e. no iags on the list).
 1790  *
 1791  *              allocation occurs from the first iag on the list using
 1792  *              the iag's free inode summary map to find the leftmost
 1793  *              free inode in the iag. 
 1794  *              
 1795  * PRE CONDITION: Already have AG lock for this AG.
 1796  *              
 1797  * PARAMETERS:
 1798  *      imap    - pointer to inode map control structure.
 1799  *      agno    - allocation group.
 1800  *      ip      - pointer to new inode to be filled in on successful return
 1801  *                with the disk inode number allocated, its extent address
 1802  *                and the start of the ag.
 1803  *
 1804  * RETURN VALUES:
 1805  *      0       - success.
 1806  *      ENOSPC  - insufficient disk resources.
 1807  *      EIO     - i/o error.
 1808  */
 1809 static int diAllocIno(struct inomap * imap, int agno, struct inode *ip)
 1810 {
 1811         int iagno, ino, rc, rem, extno, sword;
 1812         struct metapage *mp;
 1813         struct iag *iagp;
 1814 
 1815         /* check if there are iags on the ag's free inode list.
 1816          */
 1817         if ((iagno = imap->im_agctl[agno].inofree) < 0)
 1818                 return (ENOSPC);
 1819 
 1820         /* obtain read lock on imap inode */
 1821         IREAD_LOCK(imap->im_ipimap);
 1822 
 1823         /* read the iag at the head of the list.
 1824          */
 1825         if ((rc = diIAGRead(imap, iagno, &mp))) {
 1826                 IREAD_UNLOCK(imap->im_ipimap);
 1827                 return (rc);
 1828         }
 1829         iagp = (struct iag *) mp->data;
 1830 
 1831         /* better be free inodes in this iag if it is on the
 1832          * list.
 1833          */
 1834         //assert(iagp->nfreeinos);
 1835         if (!iagp->nfreeinos) {
 1836                 jfs_err("diAllocIno: nfreeinos = 0, but iag on freelist");
 1837                 jfs_err("  agno = %d, iagno = %d", agno, iagno);
 1838                 dump_mem("iag", iagp, 64);
 1839                 updateSuper(ip->i_sb, FM_DIRTY);
 1840                 return EIO;
 1841         }
 1842 
 1843         /* scan the free inode summary map to find an extent
 1844          * with free inodes.
 1845          */
 1846         for (sword = 0;; sword++) {
 1847                 assert(sword < SMAPSZ);
 1848 
 1849                 if (~iagp->inosmap[sword])
 1850                         break;
 1851         }
 1852 
 1853         /* found a extent with free inodes. determine
 1854          * the extent number.
 1855          */
 1856         rem = diFindFree(le32_to_cpu(iagp->inosmap[sword]), 0);
 1857         assert(rem < EXTSPERSUM);
 1858         extno = (sword << L2EXTSPERSUM) + rem;
 1859 
 1860         /* find the first free inode in the extent.
 1861          */
 1862         rem = diFindFree(le32_to_cpu(iagp->wmap[extno]), 0);
 1863         assert(rem < INOSPEREXT);
 1864 
 1865         /* compute the inode number within the iag. 
 1866          */
 1867         ino = (extno << L2INOSPEREXT) + rem;
 1868 
 1869         /* allocate the inode.
 1870          */
 1871         rc = diAllocBit(imap, iagp, ino);
 1872         IREAD_UNLOCK(imap->im_ipimap);
 1873         if (rc) {
 1874                 release_metapage(mp);
 1875                 return (rc);
 1876         }
 1877 
 1878         /* set the results of the allocation and write the iag.
 1879          */
 1880         diInitInode(ip, iagno, ino, extno, iagp);
 1881         write_metapage(mp);
 1882 
 1883         return (0);
 1884 }
 1885 
 1886 
 1887 /*
 1888  * NAME:        diAllocExt(imap,agno,ip)
 1889  *
 1890  * FUNCTION:    add a new extent of free inodes to an iag, allocating
 1891  *              an inode from this extent to satisfy the current allocation
 1892  *              request.
 1893  *              
 1894  *              this routine first tries to find an existing iag with free
 1895  *              extents through the ag free extent list.  if list is not
 1896  *              empty, the head of the list will be selected as the home
 1897  *              of the new extent of free inodes.  otherwise (the list is
 1898  *              empty), a new iag will be allocated for the ag to contain
 1899  *              the extent.
 1900  *              
 1901  *              once an iag has been selected, the free extent summary map
 1902  *              is used to locate a free extent within the iag and diNewExt()
 1903  *              is called to initialize the extent, with initialization
 1904  *              including the allocation of the first inode of the extent
 1905  *              for the purpose of satisfying this request.
 1906  *
 1907  * PARAMETERS:
 1908  *      imap    - pointer to inode map control structure.
 1909  *      agno    - allocation group number.
 1910  *      ip      - pointer to new inode to be filled in on successful return
 1911  *                with the disk inode number allocated, its extent address
 1912  *                and the start of the ag.
 1913  *
 1914  * RETURN VALUES:
 1915  *      0       - success.
 1916  *      ENOSPC  - insufficient disk resources.
 1917  *      EIO     - i/o error.
 1918  */
 1919 static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
 1920 {
 1921         int rem, iagno, sword, extno, rc;
 1922         struct metapage *mp;
 1923         struct iag *iagp;
 1924 
 1925         /* check if the ag has any iags with free extents.  if not,
 1926          * allocate a new iag for the ag.
 1927          */
 1928         if ((iagno = imap->im_agctl[agno].extfree) < 0) {
 1929                 /* If successful, diNewIAG will obtain the read lock on the
 1930                  * imap inode.
 1931                  */
 1932                 if ((rc = diNewIAG(imap, &iagno, agno, &mp))) {
 1933                         return (rc);
 1934                 }
 1935                 iagp = (struct iag *) mp->data;
 1936 
 1937                 /* set the ag number if this a brand new iag
 1938                  */
 1939                 iagp->agstart =
 1940                     cpu_to_le64(AGTOBLK(agno, imap->im_ipimap));
 1941         } else {
 1942                 /* read the iag.
 1943                  */
 1944                 IREAD_LOCK(imap->im_ipimap);
 1945                 if ((rc = diIAGRead(imap, iagno, &mp))) {
 1946                         assert(0);
 1947                 }
 1948                 iagp = (struct iag *) mp->data;
 1949         }
 1950 
 1951         /* using the free extent summary map, find a free extent.
 1952          */
 1953         for (sword = 0;; sword++) {
 1954                 assert(sword < SMAPSZ);
 1955                 if (~iagp->extsmap[sword])
 1956                         break;
 1957         }
 1958 
 1959         /* determine the extent number of the free extent.
 1960          */
 1961         rem = diFindFree(le32_to_cpu(iagp->extsmap[sword]), 0);
 1962         assert(rem < EXTSPERSUM);
 1963         extno = (sword << L2EXTSPERSUM) + rem;
 1964 
 1965         /* initialize the new extent.
 1966          */
 1967         rc = diNewExt(imap, iagp, extno);
 1968         IREAD_UNLOCK(imap->im_ipimap);
 1969         if (rc) {
 1970                 /* something bad happened.  if a new iag was allocated,
 1971                  * place it back on the inode map's iag free list, and
 1972                  * clear the ag number information.
 1973                  */
 1974                 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
 1975                         IAGFREE_LOCK(imap);
 1976                         iagp->iagfree = cpu_to_le32(imap->im_freeiag);
 1977                         imap->im_freeiag = iagno;
 1978                         IAGFREE_UNLOCK(imap);
 1979                 }
 1980                 write_metapage(mp);
 1981                 return (rc);
 1982         }
 1983 
 1984         /* set the results of the allocation and write the iag.
 1985          */
 1986         diInitInode(ip, iagno, extno << L2INOSPEREXT, extno, iagp);
 1987 
 1988         write_metapage(mp);
 1989 
 1990         return (0);
 1991 }
 1992 
 1993 
 1994 /*
 1995  * NAME:        diAllocBit(imap,iagp,ino)
 1996  *
 1997  * FUNCTION:    allocate a backed inode from an iag.
 1998  *
 1999  *              this routine performs the mechanics of allocating a
 2000  *              specified inode from a backed extent.
 2001  *
 2002  *              if the inode to be allocated represents the last free
 2003  *              inode within the iag, the iag will be removed from the
 2004  *              ag free inode list.
 2005  *
 2006  *              a careful update approach is used to provide consistency
 2007  *              in the face of updates to multiple buffers.  under this
 2008  *              approach, all required buffers are obtained before making
 2009  *              any updates and are held all are updates are complete.
 2010  *              
 2011  * PRE CONDITION: Already have buffer lock on iagp.  Already have AG lock on
 2012  *      this AG.  Must have read lock on imap inode.
 2013  *
 2014  * PARAMETERS:
 2015  *      imap    - pointer to inode map control structure.
 2016  *      iagp    - pointer to iag. 
 2017  *      ino     - inode number to be allocated within the iag.
 2018  *
 2019  * RETURN VALUES:
 2020  *      0       - success.
 2021  *      ENOSPC  - insufficient disk resources.
 2022  *      EIO     - i/o error.
 2023  */
 2024 static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
 2025 {
 2026         int extno, bitno, agno, sword, rc;
 2027         struct metapage *amp, *bmp;
 2028         struct iag *aiagp = 0, *biagp = 0;
 2029         u32 mask;
 2030 
 2031         /* check if this is the last free inode within the iag.
 2032          * if so, it will have to be removed from the ag free
 2033          * inode list, so get the iags preceeding and following
 2034          * it on the list.
 2035          */
 2036         if (iagp->nfreeinos == cpu_to_le32(1)) {
 2037                 amp = bmp = NULL;
 2038 
 2039                 if ((int) le32_to_cpu(iagp->inofreefwd) >= 0) {
 2040                         if ((rc =
 2041                              diIAGRead(imap, le32_to_cpu(iagp->inofreefwd),
 2042                                        &amp)))
 2043                                 return (rc);
 2044                         aiagp = (struct iag *) amp->data;
 2045                 }
 2046 
 2047                 if ((int) le32_to_cpu(iagp->inofreeback) >= 0) {
 2048                         if ((rc =
 2049                              diIAGRead(imap,
 2050                                        le32_to_cpu(iagp->inofreeback),
 2051                                        &bmp))) {
 2052                                 if (amp)
 2053                                         release_metapage(amp);
 2054                                 return (rc);
 2055                         }
 2056                         biagp = (struct iag *) bmp->data;
 2057                 }
 2058         }
 2059 
 2060         /* get the ag number, extent number, inode number within
 2061          * the extent.
 2062          */
 2063         agno = BLKTOAG(le64_to_cpu(iagp->agstart), JFS_SBI(imap->im_ipimap->i_sb));
 2064         extno = ino >> L2INOSPEREXT;
 2065         bitno = ino & (INOSPEREXT - 1);
 2066 
 2067         /* compute the mask for setting the map.
 2068          */
 2069         mask = HIGHORDER >> bitno;
 2070 
 2071         /* the inode should be free and backed.
 2072          */
 2073         assert((le32_to_cpu(iagp->pmap[extno]) & mask) == 0);
 2074         assert((le32_to_cpu(iagp->wmap[extno]) & mask) == 0);
 2075         assert(addressPXD(&iagp->inoext[extno]) != 0);
 2076 
 2077         /* mark the inode as allocated in the working map.
 2078          */
 2079         iagp->wmap[extno] |= cpu_to_le32(mask);
 2080 
 2081         /* check if all inodes within the extent are now
 2082          * allocated.  if so, update the free inode summary
 2083          * map to reflect this.
 2084          */
 2085         if (iagp->wmap[extno] == ONES) {
 2086                 sword = extno >> L2EXTSPERSUM;
 2087                 bitno = extno & (EXTSPERSUM - 1);
 2088                 iagp->inosmap[sword] |= cpu_to_le32(HIGHORDER >> bitno);
 2089         }
 2090 
 2091         /* if this was the last free inode in the iag, remove the
 2092          * iag from the ag free inode list.
 2093          */
 2094         if (iagp->nfreeinos == cpu_to_le32(1)) {
 2095                 if (amp) {
 2096                         aiagp->inofreeback = iagp->inofreeback;
 2097                         write_metapage(amp);
 2098                 }
 2099 
 2100                 if (bmp) {
 2101                         biagp->inofreefwd = iagp->inofreefwd;
 2102                         write_metapage(bmp);
 2103                 } else {
 2104                         imap->im_agctl[agno].inofree =
 2105                             le32_to_cpu(iagp->inofreefwd);
 2106                 }
 2107                 iagp->inofreefwd = iagp->inofreeback = -1;
 2108         }
 2109 
 2110         /* update the free inode count at the iag, ag, inode
 2111          * map levels.
 2112          */
 2113         iagp->nfreeinos = cpu_to_le32(le32_to_cpu(iagp->nfreeinos) - 1);
 2114         imap->im_agctl[agno].numfree -= 1;
 2115         atomic_dec(&imap->im_numfree);
 2116 
 2117         return (0);
 2118 }
 2119 
 2120 
 2121 /*
 2122  * NAME:        diNewExt(imap,iagp,extno)
 2123  *
 2124  * FUNCTION:    initialize a new extent of inodes for an iag, allocating
 2125  *              the first inode of the extent for use for the current
 2126  *              allocation request.
 2127  *
 2128  *              disk resources are allocated for the new extent of inodes
 2129  *              and the inodes themselves are initialized to reflect their
 2130  *              existence within the extent (i.e. their inode numbers and
 2131  *              inode extent addresses are set) and their initial state
 2132  *              (mode and link count are set to zero).
 2133  *
 2134  *              if the iag is new, it is not yet on an ag extent free list
 2135  *              but will now be placed on this list.
 2136  *
 2137  *              if the allocation of the new extent causes the iag to
 2138  *              have no free extent, the iag will be removed from the
 2139  *              ag extent free list.
 2140  *
 2141  *              if the iag has no free backed inodes, it will be placed
 2142  *              on the ag free inode list, since the addition of the new
 2143  *              extent will now cause it to have free inodes.
 2144  *
 2145  *              a careful update approach is used to provide consistency
 2146  *              (i.e. list consistency) in the face of updates to multiple
 2147  *              buffers.  under this approach, all required buffers are
 2148  *              obtained before making any updates and are held until all
 2149  *              updates are complete.
 2150  *              
 2151  * PRE CONDITION: Already have buffer lock on iagp.  Already have AG lock on
 2152  *      this AG.  Must have read lock on imap inode.
 2153  *
 2154  * PARAMETERS:
 2155  *      imap    - pointer to inode map control structure.
 2156  *      iagp    - pointer to iag. 
 2157  *      extno   - extent number.
 2158  *
 2159  * RETURN VALUES:
 2160  *      0       - success.
 2161  *      ENOSPC  - insufficient disk resources.
 2162  *      EIO     - i/o error.
 2163  */
 2164 static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
 2165 {
 2166         int agno, iagno, fwd, back, freei = 0, sword, rc;
 2167         struct iag *aiagp = 0, *biagp = 0, *ciagp = 0;
 2168         struct metapage *amp, *bmp, *cmp, *dmp;
 2169         struct inode *ipimap;
 2170         s64 blkno, hint;
 2171         int i, j;
 2172         u32 mask;
 2173         ino_t ino;
 2174         struct dinode *dp;
 2175         struct jfs_sb_info *sbi;
 2176 
 2177         /* better have free extents.
 2178          */
 2179         assert(iagp->nfreeexts);
 2180 
 2181         /* get the inode map inode.
 2182          */
 2183         ipimap = imap->im_ipimap;
 2184         sbi = JFS_SBI(ipimap->i_sb);
 2185 
 2186         amp = bmp = cmp = NULL;
 2187 
 2188         /* get the ag and iag numbers for this iag.
 2189          */
 2190         agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi);
 2191         iagno = le32_to_cpu(iagp->iagnum);
 2192 
 2193         /* check if this is the last free extent within the
 2194          * iag.  if so, the iag must be removed from the ag
 2195          * free extent list, so get the iags preceeding and
 2196          * following the iag on this list.
 2197          */
 2198         if (iagp->nfreeexts == cpu_to_le32(1)) {
 2199                 if ((fwd = le32_to_cpu(iagp->extfreefwd)) >= 0) {
 2200                         if ((rc = diIAGRead(imap, fwd, &amp)))
 2201                                 return (rc);
 2202                         aiagp = (struct iag *) amp->data;
 2203                 }
 2204 
 2205                 if ((back = le32_to_cpu(iagp->extfreeback)) >= 0) {
 2206                         if ((rc = diIAGRead(imap, back, &bmp)))
 2207                                 goto error_out;
 2208                         biagp = (struct iag *) bmp->data;
 2209                 }
 2210         } else {
 2211                 /* the iag has free extents.  if all extents are free
 2212                  * (as is the case for a newly allocated iag), the iag
 2213                  * must be added to the ag free extent list, so get
 2214                  * the iag at the head of the list in preparation for
 2215                  * adding this iag to this list.
 2216                  */
 2217                 fwd = back = -1;
 2218                 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
 2219                         if ((fwd = imap->im_agctl[agno].extfree) >= 0) {
 2220                                 if ((rc = diIAGRead(imap, fwd, &amp)))
 2221                                         goto error_out;
 2222                                 aiagp = (struct iag *) amp->data;
 2223                         }
 2224                 }
 2225         }
 2226 
 2227         /* check if the iag has no free inodes.  if so, the iag
 2228          * will have to be added to the ag free inode list, so get
 2229          * the iag at the head of the list in preparation for
 2230          * adding this iag to this list.  in doing this, we must
 2231          * check if we already have the iag at the head of
 2232          * the list in hand.
 2233          */
 2234         if (iagp->nfreeinos == 0) {
 2235                 freei = imap->im_agctl[agno].inofree;
 2236 
 2237                 if (freei >= 0) {
 2238                         if (freei == fwd) {
 2239                                 ciagp = aiagp;
 2240                         } else if (freei == back) {
 2241                                 ciagp = biagp;
 2242                         } else {
 2243                                 if ((rc = diIAGRead(imap, freei, &cmp)))
 2244                                         goto error_out;
 2245                                 ciagp = (struct iag *) cmp->data;
 2246                         }
 2247                         assert(ciagp != NULL);
 2248                 }
 2249         }
 2250 
 2251         /* allocate disk space for the inode extent.
 2252          */
 2253         if ((extno == 0) || (addressPXD(&iagp->inoext[extno - 1]) == 0))
 2254                 hint = ((s64) agno << sbi->bmap->db_agl2size) - 1;
 2255         else
 2256                 hint = addressPXD(&iagp->inoext[extno - 1]) +
 2257                     lengthPXD(&iagp->inoext[extno - 1]) - 1;
 2258 
 2259         if ((rc = dbAlloc(ipimap, hint, (s64) imap->im_nbperiext, &blkno)))
 2260                 goto error_out;
 2261 
 2262         /* compute the inode number of the first inode within the
 2263          * extent.
 2264          */
 2265         ino = (iagno << L2INOSPERIAG) + (extno << L2INOSPEREXT);
 2266 
 2267         /* initialize the inodes within the newly allocated extent a
 2268          * page at a time.
 2269          */
 2270         for (i = 0; i < imap->im_nbperiext; i += sbi->nbperpage) {
 2271                 /* get a buffer for this page of disk inodes.
 2272                  */
 2273                 dmp = get_metapage(ipimap, blkno + i, PSIZE, 1);
 2274                 if (dmp == NULL) {
 2275                         rc = EIO;
 2276                         goto error_out;
 2277                 }
 2278                 dp = (struct dinode *) dmp->data;
 2279 
 2280                 /* initialize the inode number, mode, link count and
 2281                  * inode extent address.
 2282                  */
 2283                 for (j = 0; j < INOSPERPAGE; j++, dp++, ino++) {
 2284                         dp->di_inostamp = cpu_to_le32(sbi->inostamp);
 2285                         dp->di_number = cpu_to_le32(ino);
 2286                         dp->di_fileset = cpu_to_le32(FILESYSTEM_I);
 2287                         dp->di_mode = 0;
 2288                         dp->di_nlink = 0;
 2289                         PXDaddress(&(dp->di_ixpxd), blkno);
 2290                         PXDlength(&(dp->di_ixpxd), imap->im_nbperiext);
 2291                 }
 2292                 write_metapage(dmp);
 2293         }
 2294 
 2295         /* if this is the last free extent within the iag, remove the
 2296          * iag from the ag free extent list.
 2297          */
 2298         if (iagp->nfreeexts == cpu_to_le32(1)) {
 2299                 if (fwd >= 0)
 2300                         aiagp->extfreeback = iagp->extfreeback;
 2301 
 2302                 if (back >= 0)
 2303                         biagp->extfreefwd = iagp->extfreefwd;
 2304                 else
 2305                         imap->im_agctl[agno].extfree =
 2306                             le32_to_cpu(iagp->extfreefwd);
 2307 
 2308                 iagp->extfreefwd = iagp->extfreeback = -1;
 2309         } else {
 2310                 /* if the iag has all free extents (newly allocated iag),
 2311                  * add the iag to the ag free extent list.
 2312                  */
 2313                 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
 2314                         if (fwd >= 0)
 2315                                 aiagp->extfreeback = cpu_to_le32(iagno);
 2316 
 2317                         iagp->extfreefwd = cpu_to_le32(fwd);
 2318                         iagp->extfreeback = -1;
 2319                         imap->im_agctl[agno].extfree = iagno;
 2320                 }
 2321         }
 2322 
 2323         /* if the iag has no free inodes, add the iag to the
 2324          * ag free inode list.
 2325          */
 2326         if (iagp->nfreeinos == 0) {
 2327                 if (freei >= 0)
 2328                         ciagp->inofreeback = cpu_to_le32(iagno);
 2329 
 2330                 iagp->inofreefwd =
 2331                     cpu_to_le32(imap->im_agctl[agno].inofree);
 2332                 iagp->inofreeback = -1;
 2333                 imap->im_agctl[agno].inofree = iagno;
 2334         }
 2335 
 2336         /* initialize the extent descriptor of the extent. */
 2337         PXDlength(&iagp->inoext[extno], imap->im_nbperiext);
 2338         PXDaddress(&iagp->inoext[extno], blkno);
 2339 
 2340         /* initialize the working and persistent map of the extent.
 2341          * the working map will be initialized such that
 2342          * it indicates the first inode of the extent is allocated.
 2343          */
 2344         iagp->wmap[extno] = cpu_to_le32(HIGHORDER);
 2345         iagp->pmap[extno] = 0;
 2346 
 2347         /* update the free inode and free extent summary maps
 2348          * for the extent to indicate the extent has free inodes
 2349          * and no longer represents a free extent.
 2350          */
 2351         sword = extno >> L2EXTSPERSUM;
 2352         mask = HIGHORDER >> (extno & (EXTSPERSUM - 1));
 2353         iagp->extsmap[sword] |= cpu_to_le32(mask);
 2354         iagp->inosmap[sword] &= cpu_to_le32(~mask);
 2355 
 2356         /* update the free inode and free extent counts for the
 2357          * iag.
 2358          */
 2359         iagp->nfreeinos = cpu_to_le32(le32_to_cpu(iagp->nfreeinos) +
 2360                                       (INOSPEREXT - 1));
 2361         iagp->nfreeexts = cpu_to_le32(le32_to_cpu(iagp->nfreeexts) - 1);
 2362 
 2363         /* update the free and backed inode counts for the ag.
 2364          */
 2365         imap->im_agctl[agno].numfree += (INOSPEREXT - 1);
 2366         imap->im_agctl[agno].numinos += INOSPEREXT;
 2367 
 2368         /* update the free and backed inode counts for the inode map.
 2369          */
 2370         atomic_add(INOSPEREXT - 1, &imap->im_numfree);
 2371         atomic_add(INOSPEREXT, &imap->im_numinos);
 2372 
 2373         /* write the iags.
 2374          */
 2375         if (amp)
 2376                 write_metapage(amp);
 2377         if (bmp)
 2378                 write_metapage(bmp);
 2379         if (cmp)
 2380                 write_metapage(cmp);
 2381 
 2382         return (0);
 2383 
 2384       error_out:
 2385 
 2386         /* release the iags.
 2387          */
 2388         if (amp)
 2389                 release_metapage(amp);
 2390         if (bmp)
 2391                 release_metapage(bmp);
 2392         if (cmp)
 2393                 release_metapage(cmp);
 2394 
 2395         return (rc);
 2396 }
 2397 
 2398 
 2399 /*
 2400  * NAME:        diNewIAG(imap,iagnop,agno)
 2401  *
 2402  * FUNCTION:    allocate a new iag for an allocation group.
 2403  *              
 2404  *              first tries to allocate the iag from the inode map 
 2405  *              iagfree list:  
 2406  *              if the list has free iags, the head of the list is removed 
 2407  *              and returned to satisfy the request.
 2408  *              if the inode map's iag free list is empty, the inode map
 2409  *              is extended to hold a new iag. this new iag is initialized
 2410  *              and returned to satisfy the request.
 2411  *
 2412  * PARAMETERS:
 2413  *      imap    - pointer to inode map control structure.
 2414  *      iagnop  - pointer to an iag number set with the number of the
 2415  *                newly allocated iag upon successful return.
 2416  *      agno    - allocation group number.
 2417  *      bpp     - Buffer pointer to be filled in with new IAG's buffer
 2418  *
 2419  * RETURN VALUES:
 2420  *      0       - success.
 2421  *      ENOSPC  - insufficient disk resources.
 2422  *      EIO     - i/o error.
 2423  *
 2424  * serialization: 
 2425  *      AG lock held on entry/exit;
 2426  *      write lock on the map is held inside;
 2427  *      read lock on the map is held on successful completion;
 2428  *
 2429  * note: new iag transaction: 
 2430  * . synchronously write iag;
 2431  * . write log of xtree and inode  of imap;
 2432  * . commit;
 2433  * . synchronous write of xtree (right to left, bottom to top);
 2434  * . at start of logredo(): init in-memory imap with one additional iag page;
 2435  * . at end of logredo(): re-read imap inode to determine
 2436  *   new imap size;
 2437  */
 2438 static int
 2439 diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
 2440 {
 2441         int rc;
 2442         int iagno, i, xlen;
 2443         struct inode *ipimap;
 2444         struct super_block *sb;
 2445         struct jfs_sb_info *sbi;
 2446         struct metapage *mp;
 2447         struct iag *iagp;
 2448         s64 xaddr = 0;
 2449         s64 blkno;
 2450         tid_t tid;
 2451 #ifdef _STILL_TO_PORT
 2452         xad_t xad;
 2453 #endif                          /*  _STILL_TO_PORT */
 2454         struct inode *iplist[1];
 2455 
 2456         /* pick up pointers to the inode map and mount inodes */
 2457         ipimap = imap->im_ipimap;
 2458         sb = ipimap->i_sb;
 2459         sbi = JFS_SBI(sb);
 2460 
 2461         /* acquire the free iag lock */
 2462         IAGFREE_LOCK(imap);
 2463 
 2464         /* if there are any iags on the inode map free iag list, 
 2465          * allocate the iag from the head of the list.
 2466          */
 2467         if (imap->im_freeiag >= 0) {
 2468                 /* pick up the iag number at the head of the list */
 2469                 iagno = imap->im_freeiag;
 2470 
 2471                 /* determine the logical block number of the iag */
 2472                 blkno = IAGTOLBLK(iagno, sbi->l2nbperpage);
 2473         } else {
 2474                 /* no free iags. the inode map will have to be extented
 2475                  * to include a new iag.
 2476                  */
 2477 
 2478                 /* acquire inode map lock */
 2479                 IWRITE_LOCK(ipimap);
 2480 
 2481                 assert(ipimap->i_size >> L2PSIZE == imap->im_nextiag + 1);
 2482 
 2483                 /* get the next avaliable iag number */
 2484                 iagno = imap->im_nextiag;
 2485 
 2486                 /* make sure that we have not exceeded the maximum inode
 2487                  * number limit.
 2488                  */
 2489                 if (iagno > (MAXIAGS - 1)) {
 2490                         /* release the inode map lock */
 2491                         IWRITE_UNLOCK(ipimap);
 2492 
 2493                         rc = ENOSPC;
 2494                         goto out;
 2495                 }
 2496 
 2497                 /*
 2498                  * synchronously append new iag page.
 2499                  */
 2500                 /* determine the logical address of iag page to append */
 2501                 blkno = IAGTOLBLK(iagno, sbi->l2nbperpage);
 2502 
 2503                 /* Allocate extent for new iag page */
 2504                 xlen = sbi->nbperpage;
 2505                 if ((rc = dbAlloc(ipimap, 0, (s64) xlen, &xaddr))) {
 2506                         /* release the inode map lock */
 2507                         IWRITE_UNLOCK(ipimap);
 2508 
 2509                         goto out;
 2510                 }
 2511 
 2512                 /* assign a buffer for the page */
 2513                 mp = get_metapage(ipimap, xaddr, PSIZE, 1);
 2514                 //bp = bmAssign(ipimap, blkno, xaddr, PSIZE, bmREAD_PAGE);
 2515                 if (!mp) {
 2516                         /* Free the blocks allocated for the iag since it was
 2517                          * not successfully added to the inode map
 2518                          */
 2519                         dbFree(ipimap, xaddr, (s64) xlen);
 2520 
 2521                         /* release the inode map lock */
 2522                         IWRITE_UNLOCK(ipimap);
 2523 
 2524                         rc = EIO;
 2525                         goto out;
 2526                 }
 2527                 iagp = (struct iag *) mp->data;
 2528 
 2529                 /* init the iag */
 2530                 memset(iagp, 0, sizeof(struct iag));
 2531                 iagp->iagnum = cpu_to_le32(iagno);
 2532                 iagp->inofreefwd = iagp->inofreeback = -1;
 2533                 iagp->extfreefwd = iagp->extfreeback = -1;
 2534                 iagp->iagfree = -1;
 2535                 iagp->nfreeinos = 0;
 2536                 iagp->nfreeexts = cpu_to_le32(EXTSPERIAG);
 2537 
 2538                 /* initialize the free inode summary map (free extent
 2539                  * summary map initialization handled by bzero).
 2540                  */
 2541                 for (i = 0; i < SMAPSZ; i++)
 2542                         iagp->inosmap[i] = ONES;
 2543 
 2544                 flush_metapage(mp);
 2545 #ifdef _STILL_TO_PORT
 2546                 /* synchronously write the iag page */
 2547                 if (bmWrite(bp)) {
 2548                         /* Free the blocks allocated for the iag since it was
 2549                          * not successfully added to the inode map
 2550                          */
 2551                         dbFree(ipimap, xaddr, (s64) xlen);
 2552 
 2553                         /* release the inode map lock */
 2554                         IWRITE_UNLOCK(ipimap);
 2555 
 2556                         rc = EIO;
 2557                         goto out;
 2558                 }
 2559 
 2560                 /* Now the iag is on disk */
 2561 
 2562                 /*
 2563                  * start tyransaction of update of the inode map
 2564                  * addressing structure pointing to the new iag page;
 2565                  */
 2566 #endif                          /*  _STILL_TO_PORT */
 2567                 tid = txBegin(sb, COMMIT_FORCE);
 2568 
 2569                 /* update the inode map addressing structure to point to it */
 2570                 if ((rc =
 2571                      xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) {
 2572                         /* Free the blocks allocated for the iag since it was
 2573                          * not successfully added to the inode map
 2574                          */
 2575                         dbFree(ipimap, xaddr, (s64) xlen);
 2576 
 2577                         /* release the inode map lock */
 2578                         IWRITE_UNLOCK(ipimap);
 2579 
 2580                         goto out;
 2581                 }
 2582 
 2583                 /* update the inode map's inode to reflect the extension */
 2584                 ipimap->i_size += PSIZE;
 2585                 ipimap->i_blocks += LBLK2PBLK(sb, xlen);
 2586 
 2587                 /*
 2588                  * txCommit(COMMIT_FORCE) will synchronously write address 
 2589                  * index pages and inode after commit in careful update order 
 2590                  * of address index pages (right to left, bottom up);
 2591                  */
 2592                 iplist[0] = ipimap;
 2593                 rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
 2594 
 2595                 txEnd(tid);
 2596 
 2597                 duplicateIXtree(sb, blkno, xlen, &xaddr);
 2598 
 2599                 /* update the next avaliable iag number */
 2600                 imap->im_nextiag += 1;
 2601 
 2602                 /* Add the iag to the iag free list so we don't lose the iag
 2603                  * if a failure happens now.
 2604                  */
 2605                 imap->im_freeiag = iagno;
 2606 
 2607                 /* Until we have logredo working, we want the imap inode &
 2608                  * control page to be up to date.
 2609                  */
 2610                 diSync(ipimap);
 2611 
 2612                 /* release the inode map lock */
 2613                 IWRITE_UNLOCK(ipimap);
 2614         }
 2615 
 2616         /* obtain read lock on map */
 2617         IREAD_LOCK(ipimap);
 2618 
 2619         /* read the iag */
 2620         if ((rc = diIAGRead(imap, iagno, &mp))) {
 2621                 IREAD_UNLOCK(ipimap);
 2622                 rc = EIO;
 2623                 goto out;
 2624         }
 2625         iagp = (struct iag *) mp->data;
 2626 
 2627         /* remove the iag from the iag free list */
 2628         imap->im_freeiag = le32_to_cpu(iagp->iagfree);
 2629         iagp->iagfree = -1;
 2630 
 2631         /* set the return iag number and buffer pointer */
 2632         *iagnop = iagno;
 2633         *mpp = mp;
 2634 
 2635       out:
 2636         /* release the iag free lock */
 2637         IAGFREE_UNLOCK(imap);
 2638 
 2639         return (rc);
 2640 }
 2641 
 2642 /*
 2643  * NAME:        diIAGRead()
 2644  *
 2645  * FUNCTION:    get the buffer for the specified iag within a fileset
 2646  *              or aggregate inode map.
 2647  *              
 2648  * PARAMETERS:
 2649  *      imap    - pointer to inode map control structure.
 2650  *      iagno   - iag number.
 2651  *      bpp     - point to buffer pointer to be filled in on successful
 2652  *                exit.
 2653  *
 2654  * SERIALIZATION:
 2655  *      must have read lock on imap inode
 2656  *      (When called by diExtendFS, the filesystem is quiesced, therefore
 2657  *       the read lock is unnecessary.)
 2658  *
 2659  * RETURN VALUES:
 2660  *      0       - success.
 2661  *      EIO     - i/o error.
 2662  */
 2663 static int diIAGRead(struct inomap * imap, int iagno, struct metapage ** mpp)
 2664 {
 2665         struct inode *ipimap = imap->im_ipimap;
 2666         s64 blkno;
 2667 
 2668         /* compute the logical block number of the iag. */
 2669         blkno = IAGTOLBLK(iagno, JFS_SBI(ipimap->i_sb)->l2nbperpage);
 2670 
 2671         /* read the iag. */
 2672         *mpp = read_metapage(ipimap, blkno, PSIZE, 0);
 2673         if (*mpp == NULL) {
 2674                 return (EIO);
 2675         }
 2676 
 2677         return (0);
 2678 }
 2679 
 2680 /*
 2681  * NAME:        diFindFree()
 2682  *
 2683  * FUNCTION:    find the first free bit in a word starting at
 2684  *              the specified bit position.
 2685  *
 2686  * PARAMETERS:
 2687  *      word    - word to be examined.
 2688  *      start   - starting bit position.
 2689  *
 2690  * RETURN VALUES:
 2691  *      bit position of first free bit in the word or 32 if
 2692  *      no free bits were found.
 2693  */
 2694 static int diFindFree(u32 word, int start)
 2695 {
 2696         int bitno;
 2697         assert(start < 32);
 2698         /* scan the word for the first free bit. */
 2699         for (word <<= start, bitno = start; bitno < 32;
 2700              bitno++, word <<= 1) {
 2701                 if ((word & HIGHORDER) == 0)
 2702                         break;
 2703         }
 2704         return (bitno);
 2705 }
 2706 
 2707 /*
 2708  * NAME:        diUpdatePMap()
 2709  *                                                                    
 2710  * FUNCTION: Update the persistent map in an IAG for the allocation or 
 2711  *      freeing of the specified inode.
 2712  *                                                                    
 2713  * PRE CONDITIONS: Working map has already been updated for allocate.
 2714  *
 2715  * PARAMETERS:
 2716  *      ipimap  - Incore inode map inode
 2717  *      inum    - Number of inode to mark in permanent map
 2718  *      is_free - If TRUE indicates inode should be marked freed, otherwise
 2719  *                indicates inode should be marked allocated.
 2720  *
 2721  * RETURNS: 0 for success
 2722  */
 2723 int
 2724 diUpdatePMap(struct inode *ipimap,
 2725              unsigned long inum, boolean_t is_free, struct tblock * tblk)
 2726 {
 2727         int rc;
 2728         struct iag *iagp;
 2729         struct metapage *mp;
 2730         int iagno, ino, extno, bitno;
 2731         struct inomap *imap;
 2732         u32 mask;
 2733         struct jfs_log *log;
 2734         int lsn, difft, diffp;
 2735 
 2736         imap = JFS_IP(ipimap)->i_imap;
 2737         /* get the iag number containing the inode */
 2738         iagno = INOTOIAG(inum);
 2739         /* make sure that the iag is contained within the map */
 2740         assert(iagno < imap->im_nextiag);
 2741         /* read the iag */
 2742         IREAD_LOCK(ipimap);
 2743         rc = diIAGRead(imap, iagno, &mp);
 2744         IREAD_UNLOCK(ipimap);
 2745         if (rc)
 2746                 return (rc);
 2747         iagp = (struct iag *) mp->data;
 2748         /* get the inode number and extent number of the inode within
 2749          * the iag and the inode number within the extent.
 2750          */
 2751         ino = inum & (INOSPERIAG - 1);
 2752         extno = ino >> L2INOSPEREXT;
 2753         bitno = ino & (INOSPEREXT - 1);
 2754         mask = HIGHORDER >> bitno;
 2755         /* 
 2756          * mark the inode free in persistent map:
 2757          */
 2758         if (is_free == TRUE) {
 2759                 /* The inode should have been allocated both in working
 2760                  * map and in persistent map;
 2761                  * the inode will be freed from working map at the release
 2762                  * of last reference release;
 2763                  */
 2764                 if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
 2765                         jfs_err("diUpdatePMap: inode %ld not marked as "
 2766                                 "allocated in wmap!", inum);
 2767                         updateSuper(ipimap->i_sb, FM_DIRTY);
 2768                 }
 2769                 if (!(le32_to_cpu(iagp->pmap[extno]) & mask)) {
 2770                         jfs_err("diUpdatePMap: inode %ld not marked as "
 2771                                 "allocated in pmap!", inum);
 2772                         updateSuper(ipimap->i_sb, FM_DIRTY);
 2773                 }
 2774                 /* update the bitmap for the extent of the freed inode */
 2775                 iagp->pmap[extno] &= cpu_to_le32(~mask);
 2776         }
 2777         /*
 2778          * mark the inode allocated in persistent map:
 2779          */
 2780         else {
 2781                 /* The inode should be already allocated in the working map
 2782                  * and should be free in persistent map;
 2783                  */
 2784                 assert(le32_to_cpu(iagp->wmap[extno]) & mask);
 2785                 assert((le32_to_cpu(iagp->pmap[extno]) & mask) == 0);
 2786                 /* update the bitmap for the extent of the allocated inode */
 2787                 iagp->pmap[extno] |= cpu_to_le32(mask);
 2788         }
 2789         /*
 2790          * update iag lsn
 2791          */
 2792         lsn = tblk->lsn;
 2793         log = JFS_SBI(tblk->sb)->log;
 2794         if (mp->lsn != 0) {
 2795                 /* inherit older/smaller lsn */
 2796                 logdiff(difft, lsn, log);
 2797                 logdiff(diffp, mp->lsn, log);
 2798                 if (difft < diffp) {
 2799                         mp->lsn = lsn;
 2800                         /* move mp after tblock in logsync list */
 2801                         LOGSYNC_LOCK(log);
 2802                         list_del(&mp->synclist);
 2803                         list_add(&mp->synclist, &tblk->synclist);
 2804                         LOGSYNC_UNLOCK(log);
 2805                 }
 2806                 /* inherit younger/larger clsn */
 2807                 LOGSYNC_LOCK(log);
 2808                 assert(mp->clsn);
 2809                 logdiff(difft, tblk->clsn, log);
 2810                 logdiff(diffp, mp->clsn, log);
 2811                 if (difft > diffp)
 2812                         mp->clsn = tblk->clsn;
 2813                 LOGSYNC_UNLOCK(log);
 2814         } else {
 2815                 mp->log = log;
 2816                 mp->lsn = lsn;
 2817                 /* insert mp after tblock in logsync list */
 2818                 LOGSYNC_LOCK(log);
 2819                 log->count++;
 2820                 list_add(&mp->synclist, &tblk->synclist);
 2821                 mp->clsn = tblk->clsn;
 2822                 LOGSYNC_UNLOCK(log);
 2823         }
 2824 //      bmLazyWrite(mp, log->flag & JFS_COMMIT);
 2825         write_metapage(mp);
 2826         return (0);
 2827 }
 2828 
 2829 /*
 2830  *      diExtendFS()
 2831  *
 2832  * function: update imap for extendfs();
 2833  * 
 2834  * note: AG size has been increased s.t. each k old contiguous AGs are 
 2835  * coalesced into a new AG;
 2836  */
 2837 int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
 2838 {
 2839         int rc, rcx = 0;
 2840         struct inomap *imap = JFS_IP(ipimap)->i_imap;
 2841         struct iag *iagp = 0, *hiagp = 0;
 2842         struct bmap *mp = JFS_SBI(ipbmap->i_sb)->bmap;
 2843         struct metapage *bp, *hbp;
 2844         int i, n, head;
 2845         int numinos, xnuminos = 0, xnumfree = 0;
 2846         s64 agstart;
 2847 
 2848         jfs_info("diExtendFS: nextiag:%d numinos:%d numfree:%d",
 2849                    imap->im_nextiag, atomic_read(&imap->im_numinos),
 2850                    atomic_read(&imap->im_numfree));
 2851 
 2852         /*
 2853          *      reconstruct imap 
 2854          *
 2855          * coalesce contiguous k (newAGSize/oldAGSize) AGs;
 2856          * i.e., (AGi, ..., AGj) where i = k*n and j = k*(n+1) - 1 to AGn;
 2857          * note: new AG size = old AG size * (2**x).
 2858          */
 2859 
 2860         /* init per AG control information im_agctl[] */
 2861         for (i = 0; i < MAXAG; i++) {
 2862                 imap->im_agctl[i].inofree = -1; /* free inode list */
 2863                 imap->im_agctl[i].extfree = -1; /* free extent list */
 2864                 imap->im_agctl[i].numinos = 0;  /* number of backed inodes */
 2865                 imap->im_agctl[i].numfree = 0;  /* number of free backed inodes */
 2866         }
 2867 
 2868         /*
 2869          *      process each iag page of the map.
 2870          *
 2871          * rebuild AG Free Inode List, AG Free Inode Extent List;
 2872          */
 2873         for (i = 0; i < imap->im_nextiag; i++) {
 2874                 if ((rc = diIAGRead(imap, i, &bp))) {
 2875                         rcx = rc;
 2876                         continue;
 2877                 }
 2878                 iagp = (struct iag *) bp->data;
 2879                 assert(le32_to_cpu(iagp->iagnum) == i);
 2880 
 2881                 /* leave free iag in the free iag list */
 2882                 if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {  
 2883                         release_metapage(bp);
 2884                         continue;
 2885                 }
 2886 
 2887                 /* agstart that computes to the same ag is treated as same; */
 2888                 agstart = le64_to_cpu(iagp->agstart);
 2889                 /* iagp->agstart = agstart & ~(mp->db_agsize - 1); */
 2890                 n = agstart >> mp->db_agl2size;
 2891 /*
 2892 printf("diExtendFS: iag:%d agstart:%Ld agno:%d\n", i, agstart, n);
 2893 */
 2894 
 2895                 /* compute backed inodes */
 2896                 numinos = (EXTSPERIAG - le32_to_cpu(iagp->nfreeexts))
 2897                     << L2INOSPEREXT;
 2898                 if (numinos > 0) {
 2899                         /* merge AG backed inodes */
 2900                         imap->im_agctl[n].numinos += numinos;
 2901                         xnuminos += numinos;
 2902                 }
 2903 
 2904                 /* if any backed free inodes, insert at AG free inode list */
 2905                 if ((int) le32_to_cpu(iagp->nfreeinos) > 0) {
 2906                         if ((head = imap->im_agctl[n].inofree) == -1)
 2907                                 iagp->inofreefwd = iagp->inofreeback = -1;
 2908                         else {
 2909                                 if ((rc = diIAGRead(imap, head, &hbp))) {
 2910                                         rcx = rc;
 2911                                         goto nextiag;
 2912                                 }
 2913                                 hiagp = (struct iag *) hbp->data;
 2914                                 hiagp->inofreeback =
 2915                                     le32_to_cpu(iagp->iagnum);
 2916                                 iagp->inofreefwd = cpu_to_le32(head);
 2917                                 iagp->inofreeback = -1;
 2918                                 write_metapage(hbp);
 2919                         }
 2920 
 2921                         imap->im_agctl[n].inofree =
 2922                             le32_to_cpu(iagp->iagnum);
 2923 
 2924                         /* merge AG backed free inodes */
 2925                         imap->im_agctl[n].numfree +=
 2926                             le32_to_cpu(iagp->nfreeinos);
 2927                         xnumfree += le32_to_cpu(iagp->nfreeinos);
 2928                 }
 2929 
 2930                 /* if any free extents, insert at AG free extent list */
 2931                 if (le32_to_cpu(iagp->nfreeexts) > 0) {
 2932                         if ((head = imap->im_agctl[n].extfree) == -1)
 2933                                 iagp->extfreefwd = iagp->extfreeback = -1;
 2934                         else {
 2935                                 if ((rc = diIAGRead(imap, head, &hbp))) {
 2936                                         rcx = rc;
 2937                                         goto nextiag;
 2938                                 }
 2939                                 hiagp = (struct iag *) hbp->data;
 2940                                 hiagp->extfreeback = iagp->iagnum;
 2941                                 iagp->extfreefwd = cpu_to_le32(head);
 2942                                 iagp->extfreeback = -1;
 2943                                 write_metapage(hbp);
 2944                         }
 2945 
 2946                         imap->im_agctl[n].extfree =
 2947                             le32_to_cpu(iagp->iagnum);
 2948                 }
 2949 
 2950               nextiag:
 2951                 write_metapage(bp);
 2952         }
 2953 
 2954         ASSERT(xnuminos == atomic_read(&imap->im_numinos) &&
 2955                xnumfree == atomic_read(&imap->im_numfree));
 2956 
 2957         return rcx;
 2958 }
 2959 
 2960 
 2961 /*
 2962  *      duplicateIXtree()
 2963  *
 2964  * serialization: IWRITE_LOCK held on entry/exit
 2965  *
 2966  * note: shadow page with regular inode (rel.2);
 2967  */
 2968 static void duplicateIXtree(struct super_block *sb, s64 blkno,
 2969                             int xlen, s64 *xaddr)
 2970 {
 2971         struct jfs_superblock *j_sb;
 2972         struct buffer_head *bh;
 2973         struct inode *ip;
 2974         tid_t tid;
 2975 
 2976         /* if AIT2 ipmap2 is bad, do not try to update it */
 2977         if (JFS_SBI(sb)->mntflag & JFS_BAD_SAIT)        /* s_flag */
 2978                 return;
 2979         ip = diReadSpecial(sb, FILESYSTEM_I, 1);
 2980         if (ip == NULL) {
 2981                 JFS_SBI(sb)->mntflag |= JFS_BAD_SAIT;
 2982                 if (readSuper(sb, &bh))
 2983                         return;
 2984                 j_sb = (struct jfs_superblock *)bh->b_data;
 2985                 j_sb->s_flag |= JFS_BAD_SAIT;
 2986 
 2987                 mark_buffer_dirty(bh);
 2988                 ll_rw_block(WRITE, 1, &bh);
 2989                 wait_on_buffer(bh);
 2990                 brelse(bh);
 2991                 return;
 2992         }
 2993 
 2994         /* start transaction */
 2995         tid = txBegin(sb, COMMIT_FORCE);
 2996         /* update the inode map addressing structure to point to it */
 2997         if (xtInsert(tid, ip, 0, blkno, xlen, xaddr, 0)) {
 2998                 JFS_SBI(sb)->mntflag |= JFS_BAD_SAIT;
 2999                 txAbort(tid, 1);
 3000                 goto cleanup;
 3001 
 3002         }
 3003         /* update the inode map's inode to reflect the extension */
 3004         ip->i_size += PSIZE;
 3005         ip->i_blocks += LBLK2PBLK(sb, xlen);
 3006         txCommit(tid, 1, &ip, COMMIT_FORCE);
 3007       cleanup:
 3008         txEnd(tid);
 3009         diFreeSpecial(ip);
 3010 }
 3011 
 3012 /*
 3013  * NAME:        copy_from_dinode()
 3014  *
 3015  * FUNCTION:    Copies inode info from disk inode to in-memory inode
 3016  *
 3017  * RETURN VALUES:
 3018  *      0       - success
 3019  *      ENOMEM  - insufficient memory
 3020  */
 3021 static int copy_from_dinode(struct dinode * dip, struct inode *ip)
 3022 {
 3023         struct jfs_inode_info *jfs_ip = JFS_IP(ip);
 3024 
 3025         jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
 3026         jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
 3027 
 3028         ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff;
 3029         ip->i_nlink = le32_to_cpu(dip->di_nlink);
 3030         ip->i_uid = le32_to_cpu(dip->di_uid);
 3031         ip->i_gid = le32_to_cpu(dip->di_gid);
 3032         ip->i_size = le64_to_cpu(dip->di_size);
 3033         ip->i_atime = le32_to_cpu(dip->di_atime.tv_sec);
 3034         ip->i_mtime = le32_to_cpu(dip->di_mtime.tv_sec);
 3035         ip->i_ctime = le32_to_cpu(dip->di_ctime.tv_sec);
 3036         ip->i_blksize = ip->i_sb->s_blocksize;
 3037         ip->i_blocks = LBLK2PBLK(ip->i_sb, le64_to_cpu(dip->di_nblocks));
 3038         ip->i_generation = le32_to_cpu(dip->di_gen);
 3039 
 3040         jfs_ip->ixpxd = dip->di_ixpxd;  /* in-memory pxd's are little-endian */
 3041         jfs_ip->acl = dip->di_acl;      /* as are dxd's */
 3042         jfs_ip->ea = dip->di_ea;
 3043         jfs_ip->next_index = le32_to_cpu(dip->di_next_index);
 3044         jfs_ip->otime = le32_to_cpu(dip->di_otime.tv_sec);
 3045         jfs_ip->acltype = le32_to_cpu(dip->di_acltype);
 3046 
 3047         if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
 3048                 ip->i_rdev = to_kdev_t(le32_to_cpu(dip->di_rdev));
 3049 
 3050         if (S_ISDIR(ip->i_mode)) {
 3051                 memcpy(&jfs_ip->i_dirtable, &dip->di_dirtable, 384);
 3052         } else if (S_ISREG(ip->i_mode) || S_ISLNK(ip->i_mode)) {
 3053                 memcpy(&jfs_ip->i_xtroot, &dip->di_xtroot, 288);
 3054         } else
 3055                 memcpy(&jfs_ip->i_inline_ea, &dip->di_inlineea, 128);
 3056 
 3057         /* Zero the in-memory-only stuff */
 3058         jfs_ip->cflag = 0;
 3059         jfs_ip->btindex = 0;
 3060         jfs_ip->btorder = 0;
 3061         jfs_ip->bxflag = 0;
 3062         jfs_ip->blid = 0;
 3063         jfs_ip->atlhead = 0;
 3064         jfs_ip->atltail = 0;
 3065         jfs_ip->xtlid = 0;
 3066         return (0);
 3067 }
 3068 
 3069 /*
 3070  * NAME:        copy_to_dinode()
 3071  *
 3072  * FUNCTION:    Copies inode info from in-memory inode to disk inode
 3073  */
 3074 static void copy_to_dinode(struct dinode * dip, struct inode *ip)
 3075 {
 3076         struct jfs_inode_info *jfs_ip = JFS_IP(ip);
 3077 
 3078         dip->di_fileset = cpu_to_le32(jfs_ip->fileset);
 3079         dip->di_inostamp = cpu_to_le32(JFS_SBI(ip->i_sb)->inostamp);
 3080         dip->di_number = cpu_to_le32(ip->i_ino);
 3081         dip->di_gen = cpu_to_le32(ip->i_generation);
 3082         dip->di_size = cpu_to_le64(ip->i_size);
 3083         dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
 3084         dip->di_nlink = cpu_to_le32(ip->i_nlink);
 3085         dip->di_uid = cpu_to_le32(ip->i_uid);
 3086         dip->di_gid = cpu_to_le32(ip->i_gid);
 3087         /*
 3088          * mode2 is only needed for storing the higher order bits.
 3089          * Trust i_mode for the lower order ones
 3090          */
 3091         dip->di_mode = cpu_to_le32((jfs_ip->mode2 & 0xffff0000) | ip->i_mode);
 3092         dip->di_atime.tv_sec = cpu_to_le32(ip->i_atime);
 3093         dip->di_atime.tv_nsec = 0;
 3094         dip->di_ctime.tv_sec = cpu_to_le32(ip->i_ctime);
 3095         dip->di_ctime.tv_nsec = 0;
 3096         dip->di_mtime.tv_sec = cpu_to_le32(ip->i_mtime);
 3097         dip->di_mtime.tv_nsec = 0;
 3098         dip->di_ixpxd = jfs_ip->ixpxd;  /* in-memory pxd's are little-endian */
 3099         dip->di_acl = jfs_ip->acl;      /* as are dxd's */
 3100         dip->di_ea = jfs_ip->ea;
 3101         dip->di_next_index = cpu_to_le32(jfs_ip->next_index);
 3102         dip->di_otime.tv_sec = cpu_to_le32(jfs_ip->otime);
 3103         dip->di_otime.tv_nsec = 0;
 3104         dip->di_acltype = cpu_to_le32(jfs_ip->acltype);
 3105 
 3106         if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
 3107                 dip->di_rdev = cpu_to_le32(kdev_t_to_nr(ip->i_rdev));
 3108 }
 3109 
 3110 #ifdef  _JFS_DEBUG_IMAP
 3111 /*
 3112  *      DBGdiInit()
 3113  */
 3114 static void *DBGdiInit(struct inomap * imap)
 3115 {
 3116         u32 *dimap;
 3117         int size;
 3118         size = 64 * 1024;
 3119         if ((dimap = (u32 *) xmalloc(size, L2PSIZE, kernel_heap)) == NULL)
 3120                 assert(0);
 3121         bzero((void *) dimap, size);
 3122         imap->im_DBGdimap = dimap;
 3123 }
 3124 
 3125 /*
 3126  *      DBGdiAlloc()
 3127  */
 3128 static void DBGdiAlloc(struct inomap * imap, ino_t ino)
 3129 {
 3130         u32 *dimap = imap->im_DBGdimap;
 3131         int w, b;
 3132         u32 m;
 3133         w = ino >> 5;
 3134         b = ino & 31;
 3135         m = 0x80000000 >> b;
 3136         assert(w < 64 * 256);
 3137         if (dimap[w] & m) {
 3138                 printk("DEBUG diAlloc: duplicate alloc ino:0x%x\n", ino);
 3139         }
 3140         dimap[w] |= m;
 3141 }
 3142 
 3143 /*
 3144  *      DBGdiFree()
 3145  */
 3146 static void DBGdiFree(struct inomap * imap, ino_t ino)
 3147 {
 3148         u32 *dimap = imap->im_DBGdimap;
 3149         int w, b;
 3150         u32 m;
 3151         w = ino >> 5;
 3152         b = ino & 31;
 3153         m = 0x80000000 >> b;
 3154         assert(w < 64 * 256);
 3155         if ((dimap[w] & m) == 0) {
 3156                 printk("DEBUG diFree: duplicate free ino:0x%x\n", ino);
 3157         }
 3158         dimap[w] &= ~m;
 3159 }
 3160 
 3161 static void dump_cp(struct inomap * ipimap, char *function, int line)
 3162 {
 3163         printk("\n* ********* *\nControl Page %s %d\n", function, line);
 3164         printk("FreeIAG %d\tNextIAG %d\n", ipimap->im_freeiag,
 3165                ipimap->im_nextiag);
 3166         printk("NumInos %d\tNumFree %d\n",
 3167                atomic_read(&ipimap->im_numinos),
 3168                atomic_read(&ipimap->im_numfree));
 3169         printk("AG InoFree %d\tAG ExtFree %d\n",
 3170                ipimap->im_agctl[0].inofree, ipimap->im_agctl[0].extfree);
 3171         printk("AG NumInos %d\tAG NumFree %d\n",
 3172                ipimap->im_agctl[0].numinos, ipimap->im_agctl[0].numfree);
 3173 }
 3174 
 3175 static void dump_iag(struct iag * iag, char *function, int line)
 3176 {
 3177         printk("\n* ********* *\nIAG %s %d\n", function, line);
 3178         printk("IagNum %d\tIAG Free %d\n", le32_to_cpu(iag->iagnum),
 3179                le32_to_cpu(iag->iagfree));
 3180         printk("InoFreeFwd %d\tInoFreeBack %d\n",
 3181                le32_to_cpu(iag->inofreefwd),
 3182                le32_to_cpu(iag->inofreeback));
 3183         printk("ExtFreeFwd %d\tExtFreeBack %d\n",
 3184                le32_to_cpu(iag->extfreefwd),
 3185                le32_to_cpu(iag->extfreeback));
 3186         printk("NFreeInos %d\tNFreeExts %d\n", le32_to_cpu(iag->nfreeinos),
 3187                le32_to_cpu(iag->nfreeexts));
 3188 }
 3189 #endif                          /* _JFS_DEBUG_IMAP */

Cache object: cc052998f2c833672c4c5d9aa320f3d5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.