^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) International Business Machines Corp., 2000-2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/quotaops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "jfs_incore.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "jfs_inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "jfs_superblock.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "jfs_dmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "jfs_extent.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "jfs_debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * forward references
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static int extBalloc(struct inode *, s64, s64 *, s64 *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #ifdef _NOTYET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static int extBrealloc(struct inode *, s64, s64, s64 *, s64 *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static s64 extRoundDown(s64 nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define DPD(a) (printk("(a): %d\n",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define DPC(a) (printk("(a): %c\n",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define DPL1(a) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) if ((a) >> 32) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) printk("(a): %x%08x ",(a)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) else \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) printk("(a): %x ",(a) << 32); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define DPL(a) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) if ((a) >> 32) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) printk("(a): %x%08x\n",(a)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) else \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) printk("(a): %x\n",(a) << 32); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define DPD1(a) (printk("(a): %d ",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define DPX(a) (printk("(a): %08x\n",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define DPX1(a) (printk("(a): %08x ",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define DPS(a) (printk("%s\n",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define DPE(a) (printk("\nENTERING: %s\n",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define DPE1(a) (printk("\nENTERING: %s",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define DPS1(a) (printk(" %s ",(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * NAME: extAlloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * FUNCTION: allocate an extent for a specified page range within a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * ip - the inode of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * xlen - requested extent length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * pno - the starting page number with the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * xp - pointer to an xad. on entry, xad describes an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * extent that is used as an allocation hint if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * xaddr of the xad is non-zero. on successful exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * the xad describes the newly allocated extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * abnr - bool indicating whether the newly allocated extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * should be marked as allocated but not recorded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * RETURN VALUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * 0 - success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * -EIO - i/o error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * -ENOSPC - insufficient disk resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) s64 nxlen, nxaddr, xoff, hint, xaddr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int xflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* This blocks if we are low on resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) txBeginAnon(ip->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* Avoid race with jfs_commit_inode() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) mutex_lock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* validate extent length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (xlen > MAXXLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) xlen = MAXXLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* get the page's starting extent offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) xoff = pno << sbi->l2nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* check if an allocation hint was provided */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if ((hint = addressXAD(xp))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* get the size of the extent described by the hint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) nxlen = lengthXAD(xp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* check if the hint is for the portion of the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * immediately previous to the current allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * request and if hint extent has the same abnr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * value as the current request. if so, we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * extend the hint extent to include the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * extent if we can allocate the blocks immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * following the hint extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (offsetXAD(xp) + nxlen == xoff &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) abnr == ((xp->flag & XAD_NOTRECORDED) ? true : false))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) xaddr = hint + nxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* adjust the hint to the last block of the extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) hint += (nxlen - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* allocate the disk blocks for the extent. initially, extBalloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * will try to allocate disk blocks for the requested size (xlen).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * if this fails (xlen contiguous free blocks not available), it'll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * try to allocate a smaller number of blocks (producing a smaller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * extent), with this smaller number of blocks consisting of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * requested number of blocks rounded down to the next smaller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * power of 2 number (i.e. 16 -> 8). it'll continue to round down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * and retry the allocation until the number of blocks to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * is smaller than the number of blocks per page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) nxlen = xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if ((rc = extBalloc(ip, hint ? hint : INOHINT(ip), &nxlen, &nxaddr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* Allocate blocks to quota. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) rc = dquot_alloc_block(ip, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) dbFree(ip, nxaddr, (s64) nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* determine the value of the extent flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) xflag = abnr ? XAD_NOTRECORDED : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* if we can extend the hint extent to cover the current request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * extend it. otherwise, insert a new extent to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * cover the current request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (xaddr && xaddr == nxaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) rc = xtExtend(0, ip, xoff, (int) nxlen, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) rc = xtInsert(0, ip, xflag, xoff, (int) nxlen, &nxaddr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* if the extend or insert failed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * free the newly allocated blocks and return the error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) dbFree(ip, nxaddr, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) dquot_free_block(ip, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* set the results of the extent allocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) XADaddress(xp, nxaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) XADlength(xp, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) XADoffset(xp, xoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) xp->flag = xflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) mark_inode_dirty(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * COMMIT_SyncList flags an anonymous tlock on page that is on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * sync list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * We need to commit the inode to get the page written disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (test_and_clear_cflag(COMMIT_Synclist,ip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) jfs_commit_inode(ip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #ifdef _NOTYET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * NAME: extRealloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * FUNCTION: extend the allocation of a file extent containing a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * partial back last page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * ip - the inode of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * cp - cbuf for the partial backed last page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * xlen - request size of the resulting extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * xp - pointer to an xad. on successful exit, the xad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * describes the newly allocated extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * abnr - bool indicating whether the newly allocated extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * should be marked as allocated but not recorded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * RETURN VALUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * 0 - success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * -EIO - i/o error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * -ENOSPC - insufficient disk resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct super_block *sb = ip->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) s64 xaddr, xlen, nxaddr, delta, xoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) s64 ntail, nextend, ninsert;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int rc, nbperpage = JFS_SBI(sb)->nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int xflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* This blocks if we are low on resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) txBeginAnon(ip->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) mutex_lock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* validate extent length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (nxlen > MAXXLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) nxlen = MAXXLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* get the extend (partial) page's disk block address and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * number of blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) xaddr = addressXAD(xp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) xlen = lengthXAD(xp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) xoff = offsetXAD(xp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* if the extend page is abnr and if the request is for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * the extent to be allocated and recorded,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * make the page allocated and recorded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if ((xp->flag & XAD_NOTRECORDED) && !abnr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) xp->flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if ((rc = xtUpdate(0, ip, xp)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* try to allocated the request number of blocks for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * extent. dbRealloc() first tries to satisfy the request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * by extending the allocation in place. otherwise, it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * try to allocate a new set of blocks large enough for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * request. in satisfying a request, dbReAlloc() may allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * less than what was request but will always allocate enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * space as to satisfy the extend page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if ((rc = extBrealloc(ip, xaddr, xlen, &nxlen, &nxaddr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* Allocat blocks to quota. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) rc = dquot_alloc_block(ip, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) dbFree(ip, nxaddr, (s64) nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) delta = nxlen - xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* check if the extend page is not abnr but the request is abnr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * and the allocated disk space is for more than one page. if this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * is the case, there is a miss match of abnr between the extend page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * and the one or more pages following the extend page. as a result,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * two extents will have to be manipulated. the first will be that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * of the extent of the extend page and will be manipulated thru
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * an xtExtend() or an xtTailgate(), depending upon whether the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * disk allocation occurred as an inplace extension. the second
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * extent will be manipulated (created) through an xtInsert() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * will be for the pages following the extend page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (abnr && (!(xp->flag & XAD_NOTRECORDED)) && (nxlen > nbperpage)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ntail = nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) nextend = ntail - xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ninsert = nxlen - nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) xflag = XAD_NOTRECORDED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ntail = nxlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) nextend = delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ninsert = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) xflag = xp->flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* if we were able to extend the disk allocation in place,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * extend the extent. otherwise, move the extent to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * new disk location.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (xaddr == nxaddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* extend the extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) dbFree(ip, xaddr + xlen, delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dquot_free_block(ip, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * move the extent to a new location:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * xtTailgate() accounts for relocated tail extent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) dbFree(ip, nxaddr, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) dquot_free_block(ip, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /* check if we need to also insert a new extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (ninsert) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* perform the insert. if it fails, free the blocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * to be inserted and make it appear that we only did
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * the xtExtend() or xtTailgate() above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) xaddr = nxaddr + ntail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (xtInsert (0, ip, xflag, xoff + ntail, (int) ninsert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) &xaddr, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) dbFree(ip, xaddr, (s64) ninsert);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) delta = nextend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) nxlen = ntail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) xflag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* set the return results */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) XADaddress(xp, nxaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) XADlength(xp, nxlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) XADoffset(xp, xoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) xp->flag = xflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) mark_inode_dirty(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) #endif /* _NOTYET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * NAME: extHint()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * FUNCTION: produce an extent allocation hint for a file offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) * ip - the inode of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * offset - file offset for which the hint is needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * xp - pointer to the xad that is to be filled in with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * the hint.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * RETURN VALUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * 0 - success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * -EIO - i/o error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int extHint(struct inode *ip, s64 offset, xad_t * xp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct super_block *sb = ip->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int nbperpage = JFS_SBI(sb)->nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) s64 prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) s64 xaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) int xlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) int xflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* init the hint as "no hint provided" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) XADaddress(xp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /* determine the starting extent offset of the page previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * to the page containing the offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) prev = ((offset & ~POFFSET) >> JFS_SBI(sb)->l2bsize) - nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /* if the offset is in the first page of the file, no hint provided.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (prev < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) rc = xtLookup(ip, prev, nbperpage, &xflag, &xaddr, &xlen, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if ((rc == 0) && xlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (xlen != nbperpage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) jfs_error(ip->i_sb, "corrupt xtree\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) XADaddress(xp, xaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) XADlength(xp, xlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) XADoffset(xp, prev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * only preserve the abnr flag within the xad flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * of the returned hint.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) xp->flag = xflag & XAD_NOTRECORDED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * NAME: extRecord()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * FUNCTION: change a page with a file from not recorded to recorded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * ip - inode of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * cp - cbuf of the file page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * RETURN VALUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * 0 - success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * -EIO - i/o error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * -ENOSPC - insufficient disk resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) int extRecord(struct inode *ip, xad_t * xp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) txBeginAnon(ip->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) mutex_lock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* update the extent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) rc = xtUpdate(0, ip, xp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) mutex_unlock(&JFS_IP(ip)->commit_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) #ifdef _NOTYET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * NAME: extFill()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * FUNCTION: allocate disk space for a file page that represents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * a file hole.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * ip - the inode of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * cp - cbuf of the file page represent the hole.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * RETURN VALUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * 0 - success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * -EIO - i/o error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * -ENOSPC - insufficient disk resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int extFill(struct inode *ip, xad_t * xp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) int rc, nbperpage = JFS_SBI(ip->i_sb)->nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) s64 blkno = offsetXAD(xp) >> ip->i_blkbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) // assert(ISSPARSE(ip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /* initialize the extent allocation hint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) XADaddress(xp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) /* allocate an extent to fill the hole */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if ((rc = extAlloc(ip, nbperpage, blkno, xp, false)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) assert(lengthPXD(xp) == nbperpage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) #endif /* _NOTYET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * NAME: extBalloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * FUNCTION: allocate disk blocks to form an extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * initially, we will try to allocate disk blocks for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * requested size (nblocks). if this fails (nblocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * contiguous free blocks not available), we'll try to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * a smaller number of blocks (producing a smaller extent), with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * this smaller number of blocks consisting of the requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * number of blocks rounded down to the next smaller power of 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * number (i.e. 16 -> 8). we'll continue to round down and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * retry the allocation until the number of blocks to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * is smaller than the number of blocks per page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * ip - the inode of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * hint - disk block number to be used as an allocation hint.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * *nblocks - pointer to an s64 value. on entry, this value specifies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * the desired number of block to be allocated. on successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * exit, this value is set to the number of blocks actually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * blkno - pointer to a block address that is filled in on successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * return with the starting block number of the newly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * allocated block range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * RETURN VALUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * 0 - success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * -EIO - i/o error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * -ENOSPC - insufficient disk resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct jfs_inode_info *ji = JFS_IP(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) s64 nb, nblks, daddr, max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) int rc, nbperpage = sbi->nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct bmap *bmp = sbi->bmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) int ag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) /* get the number of blocks to initially attempt to allocate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * we'll first try the number of blocks requested unless this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * number is greater than the maximum number of contiguous free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * blocks in the map. in that case, we'll start off with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * maximum free.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) max = (s64) 1 << bmp->db_maxfreebud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (*nblocks >= max && *nblocks > nbperpage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) nb = nblks = (max > nbperpage) ? max : nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) nb = nblks = *nblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /* try to allocate blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) while ((rc = dbAlloc(ip, hint, nb, &daddr)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) /* if something other than an out of space error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * stop and return this error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (rc != -ENOSPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /* decrease the allocation request size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) nb = min(nblks, extRoundDown(nb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /* give up if we cannot cover a page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (nb < nbperpage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) *nblocks = nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) *blkno = daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (S_ISREG(ip->i_mode) && (ji->fileset == FILESYSTEM_I)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ag = BLKTOAG(daddr, sbi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) spin_lock_irq(&ji->ag_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (ji->active_ag == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) atomic_inc(&bmp->db_active[ag]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) ji->active_ag = ag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) } else if (ji->active_ag != ag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) atomic_dec(&bmp->db_active[ji->active_ag]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) atomic_inc(&bmp->db_active[ag]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ji->active_ag = ag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) spin_unlock_irq(&ji->ag_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) #ifdef _NOTYET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * NAME: extBrealloc()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * FUNCTION: attempt to extend an extent's allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * Initially, we will try to extend the extent's allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * in place. If this fails, we'll try to move the extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * to a new set of blocks. If moving the extent, we initially
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * will try to allocate disk blocks for the requested size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * (newnblks). if this fails (new contiguous free blocks not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * available), we'll try to allocate a smaller number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * blocks (producing a smaller extent), with this smaller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * number of blocks consisting of the requested number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * blocks rounded down to the next smaller power of 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * number (i.e. 16 -> 8). We'll continue to round down and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * retry the allocation until the number of blocks to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * is smaller than the number of blocks per page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * ip - the inode of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * blkno - starting block number of the extents current allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * nblks - number of blocks within the extents current allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * newnblks - pointer to a s64 value. on entry, this value is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * the new desired extent size (number of blocks). on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * successful exit, this value is set to the extent's actual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * new size (new number of blocks).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * newblkno - the starting block number of the extents new allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * RETURN VALUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * 0 - success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * -EIO - i/o error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * -ENOSPC - insufficient disk resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) extBrealloc(struct inode *ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) s64 blkno, s64 nblks, s64 * newnblks, s64 * newblkno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /* try to extend in place */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if ((rc = dbExtend(ip, blkno, nblks, *newnblks - nblks)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) *newblkno = blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (rc != -ENOSPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) return (rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) /* in place extension not possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * try to move the extent to a new set of blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return (extBalloc(ip, blkno, newnblks, newblkno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) #endif /* _NOTYET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * NAME: extRoundDown()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * FUNCTION: round down a specified number of blocks to the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * smallest power of 2 number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * nb - the inode of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * RETURN VALUES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * next smallest power of 2 number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static s64 extRoundDown(s64 nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) u64 m, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) for (i = 0, m = (u64) 1 << 63; i < 64; i++, m >>= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (m & nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) i = 63 - i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) k = (u64) 1 << i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) k = ((k - 1) & nb) ? k : k >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return (k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }