Changeset View
Changeset View
Standalone View
Standalone View
sys/ufs/ffs/ffs_inode.c
Show First 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||
#include <ufs/ufs/ufs_extern.h> | #include <ufs/ufs/ufs_extern.h> | ||||
#include <ufs/ffs/fs.h> | #include <ufs/ffs/fs.h> | ||||
#include <ufs/ffs/ffs_extern.h> | #include <ufs/ffs/ffs_extern.h> | ||||
static int ffs_indirtrunc(struct inode *, ufs2_daddr_t, ufs2_daddr_t, | static int ffs_indirtrunc(struct inode *, ufs2_daddr_t, ufs2_daddr_t, | ||||
ufs2_daddr_t, int, ufs2_daddr_t *); | ufs2_daddr_t, int, ufs2_daddr_t *); | ||||
static void | |||||
ffs_inode_bwrite(struct vnode *vp, struct buf *bp, int flags) | |||||
{ | |||||
if ((flags & IO_SYNC) != 0) | |||||
bwrite(bp); | |||||
else if (DOINGASYNC(vp)) | |||||
bdwrite(bp); | |||||
else | |||||
bawrite(bp); | |||||
} | |||||
/* | /* | ||||
* Update the access, modified, and inode change times as specified by the | * Update the access, modified, and inode change times as specified by the | ||||
* IN_ACCESS, IN_UPDATE, and IN_CHANGE flags respectively. Write the inode | * IN_ACCESS, IN_UPDATE, and IN_CHANGE flags respectively. Write the inode | ||||
* to disk if the IN_MODIFIED flag is set (it may be set initially, or by | * to disk if the IN_MODIFIED flag is set (it may be set initially, or by | ||||
* the timestamp update). The IN_LAZYMOD flag is set to force a write | * the timestamp update). The IN_LAZYMOD flag is set to force a write | ||||
* later if not now. The IN_LAZYACCESS is set instead of IN_MODIFIED if the fs | * later if not now. The IN_LAZYACCESS is set instead of IN_MODIFIED if the fs | ||||
* is currently being suspended (or is suspended) and vnode has been accessed. | * is currently being suspended (or is suspended) and vnode has been accessed. | ||||
* If we write now, then clear IN_MODIFIED, IN_LAZYACCESS and IN_LAZYMOD to | * If we write now, then clear IN_MODIFIED, IN_LAZYACCESS and IN_LAZYMOD to | ||||
▲ Show 20 Lines • Show All 274 Lines • ▼ Show 20 Lines | if (osize < length) { | ||||
if (error) { | if (error) { | ||||
vnode_pager_setsize(vp, osize); | vnode_pager_setsize(vp, osize); | ||||
return (error); | return (error); | ||||
} | } | ||||
ip->i_size = length; | ip->i_size = length; | ||||
DIP_SET(ip, i_size, length); | DIP_SET(ip, i_size, length); | ||||
if (bp->b_bufsize == fs->fs_bsize) | if (bp->b_bufsize == fs->fs_bsize) | ||||
bp->b_flags |= B_CLUSTEROK; | bp->b_flags |= B_CLUSTEROK; | ||||
if (flags & IO_SYNC) | ffs_inode_bwrite(vp, bp, flags); | ||||
bwrite(bp); | |||||
else if (DOINGASYNC(vp)) | |||||
bdwrite(bp); | |||||
else | |||||
bawrite(bp); | |||||
UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); | UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); | ||||
return (ffs_update(vp, waitforupdate)); | return (ffs_update(vp, waitforupdate)); | ||||
} | } | ||||
/* | /* | ||||
* Lookup block number for a given offset. Zero length files | * Lookup block number for a given offset. Zero length files | ||||
* have no blocks, so return a blkno of -1. | * have no blocks, so return a blkno of -1. | ||||
*/ | */ | ||||
lbn = lblkno(fs, length - 1); | lbn = lblkno(fs, length - 1); | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | if (blkno != 0 && offset == 0) { | ||||
DIP_SET(ip, i_size, length); | DIP_SET(ip, i_size, length); | ||||
UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); | UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); | ||||
} else { | } else { | ||||
lbn = lblkno(fs, length); | lbn = lblkno(fs, length); | ||||
flags |= BA_CLRBUF; | flags |= BA_CLRBUF; | ||||
error = UFS_BALLOC(vp, length - 1, 1, cred, flags, &bp); | error = UFS_BALLOC(vp, length - 1, 1, cred, flags, &bp); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
ffs_inode_bwrite(vp, bp, flags); | |||||
/* | /* | ||||
* When we are doing soft updates and the UFS_BALLOC | * When we are doing soft updates and the UFS_BALLOC | ||||
* above fills in a direct block hole with a full sized | * above fills in a direct block hole with a full sized | ||||
* block that will be truncated down to a fragment below, | * block that will be truncated down to a fragment below, | ||||
* we must flush out the block dependency with an FSYNC | * we must flush out the block dependency with an FSYNC | ||||
* so that we do not get a soft updates inconsistency | * so that we do not get a soft updates inconsistency | ||||
* when we create the fragment below. | * when we create the fragment below. | ||||
*/ | */ | ||||
if (DOINGSOFTDEP(vp) && lbn < UFS_NDADDR && | if (DOINGSOFTDEP(vp) && lbn < UFS_NDADDR && | ||||
fragroundup(fs, blkoff(fs, length)) < fs->fs_bsize && | fragroundup(fs, blkoff(fs, length)) < fs->fs_bsize && | ||||
(error = ffs_syncvnode(vp, MNT_WAIT, 0)) != 0) | (error = ffs_syncvnode(vp, MNT_WAIT, 0)) != 0) | ||||
return (error); | return (error); | ||||
error = UFS_BALLOC(vp, length - 1, 1, cred, flags, &bp); | |||||
if (error) | |||||
return (error); | |||||
ip->i_size = length; | ip->i_size = length; | ||||
DIP_SET(ip, i_size, length); | DIP_SET(ip, i_size, length); | ||||
size = blksize(fs, ip, lbn); | size = blksize(fs, ip, lbn); | ||||
if (vp->v_type != VDIR && offset != 0) | if (vp->v_type != VDIR && offset != 0) | ||||
bzero((char *)bp->b_data + offset, | bzero((char *)bp->b_data + offset, | ||||
(u_int)(size - offset)); | (u_int)(size - offset)); | ||||
/* Kirk's code has reallocbuf(bp, size, 1) here */ | /* Kirk's code has reallocbuf(bp, size, 1) here */ | ||||
allocbuf(bp, size); | allocbuf(bp, size); | ||||
if (bp->b_bufsize == fs->fs_bsize) | if (bp->b_bufsize == fs->fs_bsize) | ||||
bp->b_flags |= B_CLUSTEROK; | bp->b_flags |= B_CLUSTEROK; | ||||
if (flags & IO_SYNC) | ffs_inode_bwrite(vp, bp, flags); | ||||
bwrite(bp); | |||||
else if (DOINGASYNC(vp)) | |||||
bdwrite(bp); | |||||
else | |||||
bawrite(bp); | |||||
UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); | UFS_INODE_SET_FLAG(ip, IN_SIZEMOD | IN_CHANGE | IN_UPDATE); | ||||
} | } | ||||
/* | /* | ||||
* Calculate index into inode's block list of | * Calculate index into inode's block list of | ||||
* last direct and indirect blocks (if any) | * last direct and indirect blocks (if any) | ||||
* which we want to keep. Lastblock is -1 when | * which we want to keep. Lastblock is -1 when | ||||
* the file is truncated to 0. | * the file is truncated to 0. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 303 Lines • Show Last 20 Lines |