jfs_imap.c (185a257f2f73bcd89050ad02da5bedbc28fc43fa) jfs_imap.c (4d81715fc5dfa1680ad47d7edf3ac4a74c5bf104)
1/*
2 * Copyright (C) International Business Machines Corp., 2000-2004
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 *

--- 64 unchanged lines hidden (view full) ---

73/* per ag iag list locks */
74#define AG_LOCK_INIT(imap,index) mutex_init(&(imap->im_aglock[index]))
75#define AG_LOCK(imap,agno) mutex_lock(&imap->im_aglock[agno])
76#define AG_UNLOCK(imap,agno) mutex_unlock(&imap->im_aglock[agno])
77
78/*
79 * forward references
80 */
1/*
2 * Copyright (C) International Business Machines Corp., 2000-2004
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 *

--- 64 unchanged lines hidden (view full) ---

73/* per ag iag list locks */
74#define AG_LOCK_INIT(imap,index) mutex_init(&(imap->im_aglock[index]))
75#define AG_LOCK(imap,agno) mutex_lock(&imap->im_aglock[agno])
76#define AG_UNLOCK(imap,agno) mutex_unlock(&imap->im_aglock[agno])
77
78/*
79 * forward references
80 */
81static int diAllocAG(struct inomap *, int, boolean_t, struct inode *);
82static int diAllocAny(struct inomap *, int, boolean_t, struct inode *);
81static int diAllocAG(struct inomap *, int, bool, struct inode *);
82static int diAllocAny(struct inomap *, int, bool, struct inode *);
83static int diAllocBit(struct inomap *, struct iag *, int);
84static int diAllocExt(struct inomap *, int, struct inode *);
85static int diAllocIno(struct inomap *, int, struct inode *);
86static int diFindFree(u32, int);
87static int diNewExt(struct inomap *, struct iag *, int);
88static int diNewIAG(struct inomap *, int *, int, struct metapage **);
89static void duplicateIXtree(struct super_block *, s64, int, s64 *);
90

--- 1249 unchanged lines hidden (view full) ---

1340/*
1341 * NAME: diAlloc(pip,dir,ip)
1342 *
1343 * FUNCTION: allocate a disk inode from the inode working map
1344 * for a fileset or aggregate.
1345 *
1346 * PARAMETERS:
1347 * pip - pointer to incore inode for the parent inode.
83static int diAllocBit(struct inomap *, struct iag *, int);
84static int diAllocExt(struct inomap *, int, struct inode *);
85static int diAllocIno(struct inomap *, int, struct inode *);
86static int diFindFree(u32, int);
87static int diNewExt(struct inomap *, struct iag *, int);
88static int diNewIAG(struct inomap *, int *, int, struct metapage **);
89static void duplicateIXtree(struct super_block *, s64, int, s64 *);
90

--- 1249 unchanged lines hidden (view full) ---

1340/*
1341 * NAME: diAlloc(pip,dir,ip)
1342 *
1343 * FUNCTION: allocate a disk inode from the inode working map
1344 * for a fileset or aggregate.
1345 *
1346 * PARAMETERS:
1347 * pip - pointer to incore inode for the parent inode.
1348 * dir - TRUE if the new disk inode is for a directory.
1348 * dir - 'true' if the new disk inode is for a directory.
1349 * ip - pointer to a new inode
1350 *
1351 * RETURN VALUES:
1352 * 0 - success.
1353 * -ENOSPC - insufficient disk resources.
1354 * -EIO - i/o error.
1355 */
1349 * ip - pointer to a new inode
1350 *
1351 * RETURN VALUES:
1352 * 0 - success.
1353 * -ENOSPC - insufficient disk resources.
1354 * -EIO - i/o error.
1355 */
1356int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip)
1356int diAlloc(struct inode *pip, bool dir, struct inode *ip)
1357{
1358 int rc, ino, iagno, addext, extno, bitno, sword;
1359 int nwords, rem, i, agno;
1360 u32 mask, inosmap, extsmap;
1361 struct inode *ipimap;
1362 struct metapage *mp;
1363 ino_t inum;
1364 struct iag *iagp;

--- 5 unchanged lines hidden (view full) ---

1370 ipimap = JFS_SBI(pip->i_sb)->ipimap;
1371 imap = JFS_IP(ipimap)->i_imap;
1372 JFS_IP(ip)->ipimap = ipimap;
1373 JFS_IP(ip)->fileset = FILESYSTEM_I;
1374
1375 /* for a directory, the allocation policy is to start
1376 * at the ag level using the preferred ag.
1377 */
1357{
1358 int rc, ino, iagno, addext, extno, bitno, sword;
1359 int nwords, rem, i, agno;
1360 u32 mask, inosmap, extsmap;
1361 struct inode *ipimap;
1362 struct metapage *mp;
1363 ino_t inum;
1364 struct iag *iagp;

--- 5 unchanged lines hidden (view full) ---

1370 ipimap = JFS_SBI(pip->i_sb)->ipimap;
1371 imap = JFS_IP(ipimap)->i_imap;
1372 JFS_IP(ip)->ipimap = ipimap;
1373 JFS_IP(ip)->fileset = FILESYSTEM_I;
1374
1375 /* for a directory, the allocation policy is to start
1376 * at the ag level using the preferred ag.
1377 */
1378 if (dir == TRUE) {
1378 if (dir) {
1379 agno = dbNextAG(JFS_SBI(pip->i_sb)->ipbmap);
1380 AG_LOCK(imap, agno);
1381 goto tryag;
1382 }
1383
1384 /* for files, the policy starts off by trying to allocate from
1385 * the same iag containing the parent disk inode:
1386 * try to allocate the new disk inode close to the parent disk

--- 259 unchanged lines hidden (view full) ---

1646 * the request by allocating an existing (backed) free inode
1647 * from the allocation group.
1648 *
1649 * PRE CONDITION: Already have the AG lock for this AG.
1650 *
1651 * PARAMETERS:
1652 * imap - pointer to inode map control structure.
1653 * agno - allocation group to allocate from.
1379 agno = dbNextAG(JFS_SBI(pip->i_sb)->ipbmap);
1380 AG_LOCK(imap, agno);
1381 goto tryag;
1382 }
1383
1384 /* for files, the policy starts off by trying to allocate from
1385 * the same iag containing the parent disk inode:
1386 * try to allocate the new disk inode close to the parent disk

--- 259 unchanged lines hidden (view full) ---

1646 * the request by allocating an existing (backed) free inode
1647 * from the allocation group.
1648 *
1649 * PRE CONDITION: Already have the AG lock for this AG.
1650 *
1651 * PARAMETERS:
1652 * imap - pointer to inode map control structure.
1653 * agno - allocation group to allocate from.
1654 * dir - TRUE if the new disk inode is for a directory.
1654 * dir - 'true' if the new disk inode is for a directory.
1655 * ip - pointer to the new inode to be filled in on successful return
1656 * with the disk inode number allocated, its extent address
1657 * and the start of the ag.
1658 *
1659 * RETURN VALUES:
1660 * 0 - success.
1661 * -ENOSPC - insufficient disk resources.
1662 * -EIO - i/o error.
1663 */
1664static int
1655 * ip - pointer to the new inode to be filled in on successful return
1656 * with the disk inode number allocated, its extent address
1657 * and the start of the ag.
1658 *
1659 * RETURN VALUES:
1660 * 0 - success.
1661 * -ENOSPC - insufficient disk resources.
1662 * -EIO - i/o error.
1663 */
1664static int
1665diAllocAG(struct inomap * imap, int agno, boolean_t dir, struct inode *ip)
1665diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip)
1666{
1667 int rc, addext, numfree, numinos;
1668
1669 /* get the number of free and the number of backed disk
1670 * inodes currently within the ag.
1671 */
1672 numfree = imap->im_agctl[agno].numfree;
1673 numinos = imap->im_agctl[agno].numinos;
1674
1675 if (numfree > numinos) {
1676 jfs_error(ip->i_sb, "diAllocAG: numfree > numinos");
1677 return -EIO;
1678 }
1679
1680 /* determine if we should allocate a new extent of free inodes
1681 * within the ag: for directory inodes, add a new extent
1682 * if there are a small number of free inodes or number of free
1683 * inodes is a small percentage of the number of backed inodes.
1684 */
1666{
1667 int rc, addext, numfree, numinos;
1668
1669 /* get the number of free and the number of backed disk
1670 * inodes currently within the ag.
1671 */
1672 numfree = imap->im_agctl[agno].numfree;
1673 numinos = imap->im_agctl[agno].numinos;
1674
1675 if (numfree > numinos) {
1676 jfs_error(ip->i_sb, "diAllocAG: numfree > numinos");
1677 return -EIO;
1678 }
1679
1680 /* determine if we should allocate a new extent of free inodes
1681 * within the ag: for directory inodes, add a new extent
1682 * if there are a small number of free inodes or number of free
1683 * inodes is a small percentage of the number of backed inodes.
1684 */
1685 if (dir == TRUE)
1685 if (dir)
1686 addext = (numfree < 64 ||
1687 (numfree < 256
1688 && ((numfree * 100) / numinos) <= 20));
1689 else
1690 addext = (numfree == 0);
1691
1692 /*
1693 * try to allocate a new extent of free inodes.

--- 22 unchanged lines hidden (view full) ---

1716 * this routine is called when an allocation attempt within
1717 * the primary allocation group has failed. if attempts to
1718 * allocate an inode from any allocation group other than the
1719 * specified primary group.
1720 *
1721 * PARAMETERS:
1722 * imap - pointer to inode map control structure.
1723 * agno - primary allocation group (to avoid).
1686 addext = (numfree < 64 ||
1687 (numfree < 256
1688 && ((numfree * 100) / numinos) <= 20));
1689 else
1690 addext = (numfree == 0);
1691
1692 /*
1693 * try to allocate a new extent of free inodes.

--- 22 unchanged lines hidden (view full) ---

1716 * this routine is called when an allocation attempt within
1717 * the primary allocation group has failed. if attempts to
1718 * allocate an inode from any allocation group other than the
1719 * specified primary group.
1720 *
1721 * PARAMETERS:
1722 * imap - pointer to inode map control structure.
1723 * agno - primary allocation group (to avoid).
1724 * dir - TRUE if the new disk inode is for a directory.
1724 * dir - 'true' if the new disk inode is for a directory.
1725 * ip - pointer to a new inode to be filled in on successful return
1726 * with the disk inode number allocated, its extent address
1727 * and the start of the ag.
1728 *
1729 * RETURN VALUES:
1730 * 0 - success.
1731 * -ENOSPC - insufficient disk resources.
1732 * -EIO - i/o error.
1733 */
1734static int
1725 * ip - pointer to a new inode to be filled in on successful return
1726 * with the disk inode number allocated, its extent address
1727 * and the start of the ag.
1728 *
1729 * RETURN VALUES:
1730 * 0 - success.
1731 * -ENOSPC - insufficient disk resources.
1732 * -EIO - i/o error.
1733 */
1734static int
1735diAllocAny(struct inomap * imap, int agno, boolean_t dir, struct inode *ip)
1735diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip)
1736{
1737 int ag, rc;
1738 int maxag = JFS_SBI(imap->im_ipimap->i_sb)->bmap->db_maxag;
1739
1740
1741 /* try to allocate from the ags following agno up to
1742 * the maximum ag number.
1743 */

--- 1000 unchanged lines hidden (view full) ---

2744 * FUNCTION: Update the persistent map in an IAG for the allocation or
2745 * freeing of the specified inode.
2746 *
2747 * PRE CONDITIONS: Working map has already been updated for allocate.
2748 *
2749 * PARAMETERS:
2750 * ipimap - Incore inode map inode
2751 * inum - Number of inode to mark in permanent map
1736{
1737 int ag, rc;
1738 int maxag = JFS_SBI(imap->im_ipimap->i_sb)->bmap->db_maxag;
1739
1740
1741 /* try to allocate from the ags following agno up to
1742 * the maximum ag number.
1743 */

--- 1000 unchanged lines hidden (view full) ---

2744 * FUNCTION: Update the persistent map in an IAG for the allocation or
2745 * freeing of the specified inode.
2746 *
2747 * PRE CONDITIONS: Working map has already been updated for allocate.
2748 *
2749 * PARAMETERS:
2750 * ipimap - Incore inode map inode
2751 * inum - Number of inode to mark in permanent map
2752 * is_free - If TRUE indicates inode should be marked freed, otherwise
2752 * is_free - If 'true' indicates inode should be marked freed, otherwise
2753 * indicates inode should be marked allocated.
2754 *
2755 * RETURN VALUES:
2756 * 0 for success
2757 */
2758int
2759diUpdatePMap(struct inode *ipimap,
2753 * indicates inode should be marked allocated.
2754 *
2755 * RETURN VALUES:
2756 * 0 for success
2757 */
2758int
2759diUpdatePMap(struct inode *ipimap,
2760 unsigned long inum, boolean_t is_free, struct tblock * tblk)
2760 unsigned long inum, bool is_free, struct tblock * tblk)
2761{
2762 int rc;
2763 struct iag *iagp;
2764 struct metapage *mp;
2765 int iagno, ino, extno, bitno;
2766 struct inomap *imap;
2767 u32 mask;
2768 struct jfs_log *log;

--- 22 unchanged lines hidden (view full) ---

2791 */
2792 ino = inum & (INOSPERIAG - 1);
2793 extno = ino >> L2INOSPEREXT;
2794 bitno = ino & (INOSPEREXT - 1);
2795 mask = HIGHORDER >> bitno;
2796 /*
2797 * mark the inode free in persistent map:
2798 */
2761{
2762 int rc;
2763 struct iag *iagp;
2764 struct metapage *mp;
2765 int iagno, ino, extno, bitno;
2766 struct inomap *imap;
2767 u32 mask;
2768 struct jfs_log *log;

--- 22 unchanged lines hidden (view full) ---

2791 */
2792 ino = inum & (INOSPERIAG - 1);
2793 extno = ino >> L2INOSPEREXT;
2794 bitno = ino & (INOSPEREXT - 1);
2795 mask = HIGHORDER >> bitno;
2796 /*
2797 * mark the inode free in persistent map:
2798 */
2799 if (is_free == TRUE) {
2799 if (is_free) {
2800 /* The inode should have been allocated both in working
2801 * map and in persistent map;
2802 * the inode will be freed from working map at the release
2803 * of last reference release;
2804 */
2805 if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
2806 jfs_error(ipimap->i_sb,
2807 "diUpdatePMap: inode %ld not marked as "

--- 395 unchanged lines hidden ---
2800 /* The inode should have been allocated both in working
2801 * map and in persistent map;
2802 * the inode will be freed from working map at the release
2803 * of last reference release;
2804 */
2805 if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
2806 jfs_error(ipimap->i_sb,
2807 "diUpdatePMap: inode %ld not marked as "

--- 395 unchanged lines hidden ---