/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
- *
- * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* Please see the License for the specific language governing rights and
* limitations under the License.
*
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
/*
#include <rev_endian_fs.h>
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/buf.h>
+#include <sys/buf_internal.h>
#include <sys/proc.h>
+#include <sys/kauth.h>
#include <sys/file.h>
-#include <sys/vnode.h>
+#include <sys/vnode_internal.h>
#include <sys/ubc.h>
#include <sys/quota.h>
#if REV_ENDIAN_FS
-#include <sys/mount.h>
+#include <sys/mount_internal.h>
#endif /* REV_ENDIAN_FS */
#include <sys/vm.h>
#if REV_ENDIAN_FS
#include <ufs/ufs/ufs_byte_order.h>
-#include <architecture/byte_order.h>
+#include <libkern/OSByteOrder.h>
#endif /* REV_ENDIAN_FS */
/*
* by allocating the physical blocks on a device given
* the inode and the logical block number in a file.
*/
-ffs_balloc(ip, lbn, size, cred, bpp, flags, blk_alloc)
- register struct inode *ip;
- register ufs_daddr_t lbn;
- int size;
- struct ucred *cred;
- struct buf **bpp;
- int flags;
- int * blk_alloc;
+ffs_balloc(
+ register struct inode *ip,
+ register ufs_daddr_t lbn,
+ int size,
+ kauth_cred_t cred,
+ struct buf **bpp,
+ int flags,
+ int * blk_alloc)
{
register struct fs *fs;
register ufs_daddr_t nb;
ufs_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1];
int devBlockSize=0;
int alloc_buffer = 1;
-#if REV_ENDIAN_FS
struct mount *mp=vp->v_mount;
+#if REV_ENDIAN_FS
int rev_endian=(mp->mnt_flag & MNT_REVEND);
#endif /* REV_ENDIAN_FS */
osize, (int)fs->fs_bsize, cred, &bp);
if (error)
return (error);
- /* adjust the innode size we just grew */
+ /* adjust the inode size we just grew */
/* it is in nb+1 as nb starts from 0 */
ip->i_size = (nb + 1) * fs->fs_bsize;
- if (UBCISVALID(vp))
- ubc_setsize(vp, (off_t)ip->i_size); /* XXX check error */
- ip->i_db[nb] = dbtofsb(fs, bp->b_blkno);
+ ubc_setsize(vp, (off_t)ip->i_size);
+
+ ip->i_db[nb] = dbtofsb(fs, (ufs_daddr_t)buf_blkno(bp));
ip->i_flag |= IN_CHANGE | IN_UPDATE;
+
if ((flags & B_SYNC) || (!alloc_buffer)) {
if (!alloc_buffer)
- SET(bp->b_flags, B_INVAL);
- bwrite(bp);
+ buf_setflags(bp, B_NOCACHE);
+ buf_bwrite(bp);
} else
- bawrite(bp);
+ buf_bdwrite(bp);
/* note that bp is already released here */
}
}
nb = ip->i_db[lbn];
if (nb != 0 && ip->i_size >= (lbn + 1) * fs->fs_bsize) {
if (alloc_buffer) {
- error = bread(vp, lbn, fs->fs_bsize, NOCRED, &bp);
+ error = (int)buf_bread(vp, (daddr64_t)((unsigned)lbn), fs->fs_bsize, NOCRED, &bp);
if (error) {
- brelse(bp);
+ buf_brelse(bp);
return (error);
}
*bpp = bp;
nsize = fragroundup(fs, size);
if (nsize <= osize) {
if (alloc_buffer) {
- error = bread(vp, lbn, osize, NOCRED, &bp);
+ error = (int)buf_bread(vp, (daddr64_t)((unsigned)lbn), osize, NOCRED, &bp);
if (error) {
- brelse(bp);
+ buf_brelse(bp);
return (error);
}
ip->i_flag |= IN_CHANGE | IN_UPDATE;
&ip->i_db[0]), osize, nsize, cred, &bp);
if (error)
return (error);
- ip->i_db[lbn] = dbtofsb(fs, bp->b_blkno);
+ ip->i_db[lbn] = dbtofsb(fs, (ufs_daddr_t)buf_blkno(bp));
ip->i_flag |= IN_CHANGE | IN_UPDATE;
- if(!alloc_buffer) {
- SET(bp->b_flags, B_INVAL);
- bwrite(bp);
+
+ /* adjust the inode size we just grew */
+ ip->i_size = (lbn * fs->fs_bsize) + size;
+ ubc_setsize(vp, (off_t)ip->i_size);
+
+ if (!alloc_buffer) {
+ buf_setflags(bp, B_NOCACHE);
+ if (flags & B_SYNC)
+ buf_bwrite(bp);
+ else
+ buf_bdwrite(bp);
} else
*bpp = bp;
return (0);
if (error)
return (error);
if (alloc_buffer) {
- bp = getblk(vp, lbn, nsize, 0, 0, BLK_WRITE);
- bp->b_blkno = fsbtodb(fs, newb);
- if (flags & B_CLRBUF)
- clrbuf(bp);
+ bp = buf_getblk(vp, (daddr64_t)((unsigned)lbn), nsize, 0, 0, BLK_WRITE);
+ buf_setblkno(bp, (daddr64_t)((unsigned)fsbtodb(fs, newb)));
+
+ if (flags & B_CLRBUF)
+ buf_clear(bp);
}
ip->i_db[lbn] = newb;
ip->i_flag |= IN_CHANGE | IN_UPDATE;
return(error);
#if DIAGNOSTIC
if (num < 1)
- panic ("ffs_balloc: ufs_bmaparray returned indirect block\n");
+ panic ("ffs_balloc: ufs_bmaparray returned indirect block");
#endif
/*
* Fetch the first indirect block allocating if necessary.
return (error);
nb = newb;
*allocblk++ = nb;
- bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0, BLK_META);
- bp->b_blkno = fsbtodb(fs, nb);
- clrbuf(bp);
+ bp = buf_getblk(vp, (daddr64_t)((unsigned)(indirs[1].in_lbn)), fs->fs_bsize, 0, 0, BLK_META);
+ buf_setblkno(bp, (daddr64_t)((unsigned)fsbtodb(fs, nb)));
+ buf_clear(bp);
/*
- * Write synchronously so that indirect blocks
- * never point at garbage.
+ * Write synchronously conditional on mount flags.
*/
- if (error = bwrite(bp))
+ if ((vp)->v_mount->mnt_flag & MNT_ASYNC) {
+ error = 0;
+ buf_bdwrite(bp);
+ } else if ((error = buf_bwrite(bp)) != 0) {
goto fail;
+ }
allocib = &ip->i_ib[indirs[0].in_off];
*allocib = nb;
ip->i_flag |= IN_CHANGE | IN_UPDATE;
* Fetch through the indirect blocks, allocating as necessary.
*/
for (i = 1;;) {
- error = meta_bread(vp,
- indirs[i].in_lbn, (int)fs->fs_bsize, NOCRED, &bp);
+ error = (int)buf_meta_bread(vp, (daddr64_t)((unsigned)(indirs[i].in_lbn)), (int)fs->fs_bsize, NOCRED, &bp);
if (error) {
- brelse(bp);
+ buf_brelse(bp);
goto fail;
}
- bap = (ufs_daddr_t *)bp->b_data;
+ bap = (ufs_daddr_t *)buf_dataptr(bp);
#if REV_ENDIAN_FS
if (rev_endian)
- nb = NXSwapLong(bap[indirs[i].in_off]);
+ nb = OSSwapInt32(bap[indirs[i].in_off]);
else {
#endif /* REV_ENDIAN_FS */
nb = bap[indirs[i].in_off];
break;
i += 1;
if (nb != 0) {
- brelse(bp);
+ buf_brelse(bp);
continue;
}
if (pref == 0)
pref = ffs_blkpref(ip, lbn, 0, (ufs_daddr_t *)0);
if (error =
ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, &newb)) {
- brelse(bp);
+ buf_brelse(bp);
goto fail;
}
nb = newb;
*allocblk++ = nb;
- nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0, BLK_META);
- nbp->b_blkno = fsbtodb(fs, nb);
- clrbuf(nbp);
+ nbp = buf_getblk(vp, (daddr64_t)((unsigned)(indirs[i].in_lbn)), fs->fs_bsize, 0, 0, BLK_META);
+ buf_setblkno(nbp, (daddr64_t)((unsigned)fsbtodb(fs, nb)));
+ buf_clear(nbp);
/*
- * Write synchronously so that indirect blocks
- * never point at garbage.
+ * Write synchronously conditional on mount flags.
*/
- if (error = bwrite(nbp)) {
- brelse(bp);
+ if ((vp)->v_mount->mnt_flag & MNT_ASYNC) {
+ error = 0;
+ buf_bdwrite(nbp);
+ } else if (error = buf_bwrite(nbp)) {
+ buf_brelse(bp);
goto fail;
}
#if REV_ENDIAN_FS
if (rev_endian)
- bap[indirs[i - 1].in_off] = NXSwapLong(nb);
+ bap[indirs[i - 1].in_off] = OSSwapInt32(nb);
else {
#endif /* REV_ENDIAN_FS */
bap[indirs[i - 1].in_off] = nb;
* delayed write.
*/
if (flags & B_SYNC) {
- bwrite(bp);
+ buf_bwrite(bp);
} else {
- bdwrite(bp);
+ buf_bdwrite(bp);
}
}
/*
pref = ffs_blkpref(ip, lbn, indirs[i].in_off, &bap[0]);
if (error = ffs_alloc(ip,
lbn, pref, (int)fs->fs_bsize, cred, &newb)) {
- brelse(bp);
+ buf_brelse(bp);
goto fail;
}
nb = newb;
*allocblk++ = nb;
#if REV_ENDIAN_FS
if (rev_endian)
- bap[indirs[i].in_off] = NXSwapLong(nb);
+ bap[indirs[i].in_off] = OSSwapInt32(nb);
else {
#endif /* REV_ENDIAN_FS */
bap[indirs[i].in_off] = nb;
* delayed write.
*/
if ((flags & B_SYNC)) {
- bwrite(bp);
+ buf_bwrite(bp);
} else {
- bdwrite(bp);
+ buf_bdwrite(bp);
}
if(alloc_buffer ) {
- nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, BLK_WRITE);
- nbp->b_blkno = fsbtodb(fs, nb);
+ nbp = buf_getblk(vp, (daddr64_t)((unsigned)lbn), fs->fs_bsize, 0, 0, BLK_WRITE);
+ buf_setblkno(nbp, (daddr64_t)((unsigned)fsbtodb(fs, nb)));
+
if (flags & B_CLRBUF)
- clrbuf(nbp);
+ buf_clear(nbp);
}
if (blk_alloc) {
*blk_alloc = fs->fs_bsize;
return (0);
}
- brelse(bp);
+ buf_brelse(bp);
if (alloc_buffer) {
- if (flags & B_CLRBUF) {
- error = bread(vp, lbn, (int)fs->fs_bsize, NOCRED, &nbp);
- if (error) {
- brelse(nbp);
- goto fail;
+ if (flags & B_CLRBUF) {
+ error = (int)buf_bread(vp, (daddr64_t)((unsigned)lbn), (int)fs->fs_bsize, NOCRED, &nbp);
+ if (error) {
+ buf_brelse(nbp);
+ goto fail;
+ }
+ } else {
+ nbp = buf_getblk(vp, (daddr64_t)((unsigned)lbn), fs->fs_bsize, 0, 0, BLK_WRITE);
+ buf_setblkno(nbp, (daddr64_t)((unsigned)fsbtodb(fs, nb)));
}
- } else {
- nbp = getblk(vp, lbn, fs->fs_bsize, 0, 0, BLK_WRITE);
- nbp->b_blkno = fsbtodb(fs, nb);
- }
- *bpp = nbp;
+ *bpp = nbp;
}
return (0);
fail:
if (allocib != NULL)
*allocib = 0;
if (deallocated) {
- VOP_DEVBLOCKSIZE(ip->i_devvp,&devBlockSize);
-
+ devBlockSize = vfs_devblocksize(mp);
#if QUOTA
/*
* Restore user's disk quota because allocation failed.
/*
* ffs_blkalloc allocates a disk block for ffs_pageout(), as a consequence
- * it does no breads (that could lead to deadblock as the page may be already
+ * it does no buf_breads (that could lead to deadblock as the page may be already
* marked busy as it is being paged out. Also important to note that we are not
* growing the file in pageouts. So ip->i_size cannot increase by this call
* due to the way UBC works.
* Do not call with B_CLRBUF flags as this should only be called only
* from pageouts
*/
-ffs_blkalloc(ip, lbn, size, cred, flags)
- register struct inode *ip;
- ufs_daddr_t lbn;
- int size;
- struct ucred *cred;
- int flags;
+ffs_blkalloc(
+ struct inode *ip,
+ ufs_daddr_t lbn,
+ int size,
+ kauth_cred_t cred,
+ int flags)
{
register struct fs *fs;
register ufs_daddr_t nb;
int deallocated, osize, nsize, num, i, error;
ufs_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1];
int devBlockSize=0;
-#if REV_ENDIAN_FS
struct mount *mp=vp->v_mount;
+#if REV_ENDIAN_FS
int rev_endian=(mp->mnt_flag & MNT_REVEND);
#endif /* REV_ENDIAN_FS */
fs = ip->i_fs;
if(size > fs->fs_bsize)
- panic("ffs_blkalloc: too large for allocation\n");
+ panic("ffs_blkalloc: too large for allocation");
/*
* If the next write will extend the file into a new block,
*/
nb = lblkno(fs, ip->i_size);
if (nb < NDADDR && nb < lbn) {
- panic("ffs_blkalloc():cannot extend file: i_size %d, lbn %d\n", ip->i_size, lbn);
+ panic("ffs_blkalloc():cannot extend file: i_size %d, lbn %d", ip->i_size, lbn);
}
/*
* The first NDADDR blocks are direct blocks
osize = fragroundup(fs, blkoff(fs, ip->i_size));
nsize = fragroundup(fs, size);
if (nsize > osize) {
- panic("ffs_allocblk: trying to extend
- a fragment \n");
+ panic("ffs_allocblk: trying to extend a fragment");
}
return(0);
} else {
return(error);
if(num == 0) {
- panic("ffs_blkalloc: file with direct blocks only\n");
+ panic("ffs_blkalloc: file with direct blocks only");
}
/*
return (error);
nb = newb;
*allocblk++ = nb;
- bp = getblk(vp, indirs[1].in_lbn, fs->fs_bsize, 0, 0, BLK_META);
- bp->b_blkno = fsbtodb(fs, nb);
- clrbuf(bp);
+ bp = buf_getblk(vp, (daddr64_t)((unsigned)(indirs[1].in_lbn)), fs->fs_bsize, 0, 0, BLK_META);
+ buf_setblkno(bp, (daddr64_t)((unsigned)fsbtodb(fs, nb)));
+ buf_clear(bp);
/*
- * Write synchronously so that indirect blocks
- * never point at garbage.
+ * Write synchronously conditional on mount flags.
*/
- if (error = bwrite(bp))
+ if ((vp)->v_mount->mnt_flag & MNT_ASYNC) {
+ error = 0;
+ buf_bdwrite(bp);
+ } else if (error = buf_bwrite(bp)) {
goto fail;
+ }
allocib = &ip->i_ib[indirs[0].in_off];
*allocib = nb;
ip->i_flag |= IN_CHANGE | IN_UPDATE;
* Fetch through the indirect blocks, allocating as necessary.
*/
for (i = 1;;) {
- error = meta_bread(vp,
- indirs[i].in_lbn, (int)fs->fs_bsize, NOCRED, &bp);
+ error = (int)buf_meta_bread(vp, (daddr64_t)((unsigned)(indirs[i].in_lbn)), (int)fs->fs_bsize, NOCRED, &bp);
if (error) {
- brelse(bp);
+ buf_brelse(bp);
goto fail;
}
- bap = (ufs_daddr_t *)bp->b_data;
+ bap = (ufs_daddr_t *)buf_dataptr(bp);
#if REV_ENDIAN_FS
if (rev_endian)
- nb = NXSwapLong(bap[indirs[i].in_off]);
+ nb = OSSwapInt32(bap[indirs[i].in_off]);
else {
#endif /* REV_ENDIAN_FS */
nb = bap[indirs[i].in_off];
break;
i += 1;
if (nb != 0) {
- brelse(bp);
+ buf_brelse(bp);
continue;
}
if (pref == 0)
pref = ffs_blkpref(ip, lbn, 0, (ufs_daddr_t *)0);
if (error =
ffs_alloc(ip, lbn, pref, (int)fs->fs_bsize, cred, &newb)) {
- brelse(bp);
+ buf_brelse(bp);
goto fail;
}
nb = newb;
*allocblk++ = nb;
- nbp = getblk(vp, indirs[i].in_lbn, fs->fs_bsize, 0, 0, BLK_META);
- nbp->b_blkno = fsbtodb(fs, nb);
- clrbuf(nbp);
+ nbp = buf_getblk(vp, (daddr64_t)((unsigned)(indirs[i].in_lbn)), fs->fs_bsize, 0, 0, BLK_META);
+ buf_setblkno(nbp, (daddr64_t)((unsigned)fsbtodb(fs, nb)));
+ buf_clear(nbp);
/*
- * Write synchronously so that indirect blocks
- * never point at garbage.
+ * Write synchronously conditional on mount flags.
*/
- if (error = bwrite(nbp)) {
- brelse(bp);
+ if ((vp)->v_mount->mnt_flag & MNT_ASYNC) {
+ error = 0;
+ buf_bdwrite(nbp);
+ } else if (error = buf_bwrite(nbp)) {
+ buf_brelse(bp);
goto fail;
}
#if REV_ENDIAN_FS
if (rev_endian)
- bap[indirs[i - 1].in_off] = NXSwapLong(nb);
+ bap[indirs[i - 1].in_off] = OSSwapInt32(nb);
else {
#endif /* REV_ENDIAN_FS */
bap[indirs[i - 1].in_off] = nb;
* delayed write.
*/
if (flags & B_SYNC) {
- bwrite(bp);
+ buf_bwrite(bp);
} else {
- bdwrite(bp);
+ buf_bdwrite(bp);
}
}
/*
pref = ffs_blkpref(ip, lbn, indirs[i].in_off, &bap[0]);
if (error = ffs_alloc(ip,
lbn, pref, (int)fs->fs_bsize, cred, &newb)) {
- brelse(bp);
+ buf_brelse(bp);
goto fail;
}
nb = newb;
*allocblk++ = nb;
#if REV_ENDIAN_FS
if (rev_endian)
- bap[indirs[i].in_off] = NXSwapLong(nb);
+ bap[indirs[i].in_off] = OSSwapInt32(nb);
else {
#endif /* REV_ENDIAN_FS */
bap[indirs[i].in_off] = nb;
* delayed write.
*/
if (flags & B_SYNC) {
- bwrite(bp);
+ buf_bwrite(bp);
} else {
- bdwrite(bp);
+ buf_bdwrite(bp);
}
return (0);
}
- brelse(bp);
+ buf_brelse(bp);
return (0);
fail:
/*
if (allocib != NULL)
*allocib = 0;
if (deallocated) {
- VOP_DEVBLOCKSIZE(ip->i_devvp,&devBlockSize);
-
+ devBlockSize = vfs_devblocksize(mp);
#if QUOTA
/*
* Restore user's disk quota because allocation failed.