version 1.13, 1997/01/27 10:30:14 |
version 1.14, 1997/06/11 10:09:43 |
|
|
return (0); |
return (0); |
ip = VTOI(ap->a_vp); |
ip = VTOI(ap->a_vp); |
TIMEVAL_TO_TIMESPEC(&time, &ts); |
TIMEVAL_TO_TIMESPEC(&time, &ts); |
ITIMES(ip, ap->a_access, ap->a_modify, &ts); |
FFS_ITIMES(ip, ap->a_access, ap->a_modify, &ts); |
if ((ip->i_flag & IN_MODIFIED) == 0) |
if ((ip->i_flag & IN_MODIFIED) == 0) |
return (0); |
return (0); |
ip->i_flag &= ~IN_MODIFIED; |
ip->i_flag &= ~IN_MODIFIED; |
|
|
* fix until fsck has been changed to do the update. |
* fix until fsck has been changed to do the update. |
*/ |
*/ |
if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ |
if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ |
ip->i_din.di_ouid = ip->i_uid; /* XXX */ |
ip->i_din.ffs_din.di_ouid = ip->i_ffs_uid; /* XXX */ |
ip->i_din.di_ogid = ip->i_gid; /* XXX */ |
ip->i_din.ffs_din.di_ogid = ip->i_ffs_gid; /* XXX */ |
} /* XXX */ |
} /* XXX */ |
error = bread(ip->i_devvp, |
error = bread(ip->i_devvp, |
fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), |
fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), |
|
|
return (error); |
return (error); |
} |
} |
*((struct dinode *)bp->b_data + |
*((struct dinode *)bp->b_data + |
ino_to_fsbo(fs, ip->i_number)) = ip->i_din; |
ino_to_fsbo(fs, ip->i_number)) = ip->i_din.ffs_din; |
if (ap->a_waitfor) |
if (ap->a_waitfor) |
return (bwrite(bp)); |
return (bwrite(bp)); |
else { |
else { |
|
|
oip = VTOI(ovp); |
oip = VTOI(ovp); |
TIMEVAL_TO_TIMESPEC(&time, &ts); |
TIMEVAL_TO_TIMESPEC(&time, &ts); |
if (ovp->v_type == VLNK && |
if (ovp->v_type == VLNK && |
(oip->i_size < ovp->v_mount->mnt_maxsymlinklen || |
(oip->i_ffs_size < ovp->v_mount->mnt_maxsymlinklen || |
(ovp->v_mount->mnt_maxsymlinklen == 0 && |
(ovp->v_mount->mnt_maxsymlinklen == 0 && |
oip->i_din.di_blocks == 0))) { |
oip->i_din.ffs_din.di_blocks == 0))) { |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
if (length != 0) |
if (length != 0) |
panic("ffs_truncate: partial truncate of symlink"); |
panic("ffs_truncate: partial truncate of symlink"); |
#endif |
#endif |
bzero((char *)&oip->i_shortlink, (u_int)oip->i_size); |
bzero((char *)&oip->i_ffs_shortlink, (u_int)oip->i_ffs_size); |
oip->i_size = 0; |
oip->i_ffs_size = 0; |
oip->i_flag |= IN_CHANGE | IN_UPDATE; |
oip->i_flag |= IN_CHANGE | IN_UPDATE; |
return (VOP_UPDATE(ovp, &ts, &ts, 1)); |
return (VOP_UPDATE(ovp, &ts, &ts, 1)); |
} |
} |
if (oip->i_size == length) { |
if (oip->i_ffs_size == length) { |
oip->i_flag |= IN_CHANGE | IN_UPDATE; |
oip->i_flag |= IN_CHANGE | IN_UPDATE; |
return (VOP_UPDATE(ovp, &ts, &ts, 0)); |
return (VOP_UPDATE(ovp, &ts, &ts, 0)); |
} |
} |
|
|
#endif |
#endif |
vnode_pager_setsize(ovp, (u_long)length); |
vnode_pager_setsize(ovp, (u_long)length); |
fs = oip->i_fs; |
fs = oip->i_fs; |
osize = oip->i_size; |
osize = oip->i_ffs_size; |
/* |
/* |
* Lengthen the size of the file. We must ensure that the |
* Lengthen the size of the file. We must ensure that the |
* last byte of the file is allocated. Since the smallest |
* last byte of the file is allocated. Since the smallest |
|
|
aflags); |
aflags); |
if (error) |
if (error) |
return (error); |
return (error); |
oip->i_size = length; |
oip->i_ffs_size = length; |
(void) vnode_pager_uncache(ovp); |
(void) vnode_pager_uncache(ovp); |
if (aflags & B_SYNC) |
if (aflags & B_SYNC) |
bwrite(bp); |
bwrite(bp); |
|
|
*/ |
*/ |
offset = blkoff(fs, length); |
offset = blkoff(fs, length); |
if (offset == 0) { |
if (offset == 0) { |
oip->i_size = length; |
oip->i_ffs_size = length; |
} else { |
} else { |
lbn = lblkno(fs, length); |
lbn = lblkno(fs, length); |
aflags = B_CLRBUF; |
aflags = B_CLRBUF; |
|
|
error = ffs_balloc(oip, lbn, offset, ap->a_cred, &bp, aflags); |
error = ffs_balloc(oip, lbn, offset, ap->a_cred, &bp, aflags); |
if (error) |
if (error) |
return (error); |
return (error); |
oip->i_size = length; |
oip->i_ffs_size = length; |
size = blksize(fs, oip, lbn); |
size = blksize(fs, oip, lbn); |
(void) vnode_pager_uncache(ovp); |
(void) vnode_pager_uncache(ovp); |
bzero((char *)bp->b_data + offset, (u_int)(size - offset)); |
bzero((char *)bp->b_data + offset, (u_int)(size - offset)); |
|
|
* will be returned to the free list. lastiblock values are also |
* will be returned to the free list. lastiblock values are also |
* normalized to -1 for calls to ffs_indirtrunc below. |
* normalized to -1 for calls to ffs_indirtrunc below. |
*/ |
*/ |
bcopy((caddr_t)&oip->i_db[0], (caddr_t)oldblks, sizeof oldblks); |
bcopy((caddr_t)&oip->i_ffs_db[0], (caddr_t)oldblks, sizeof oldblks); |
for (level = TRIPLE; level >= SINGLE; level--) |
for (level = TRIPLE; level >= SINGLE; level--) |
if (lastiblock[level] < 0) { |
if (lastiblock[level] < 0) { |
oip->i_ib[level] = 0; |
oip->i_ffs_ib[level] = 0; |
lastiblock[level] = -1; |
lastiblock[level] = -1; |
} |
} |
for (i = NDADDR - 1; i > lastblock; i--) |
for (i = NDADDR - 1; i > lastblock; i--) |
oip->i_db[i] = 0; |
oip->i_ffs_db[i] = 0; |
oip->i_flag |= IN_CHANGE | IN_UPDATE; |
oip->i_flag |= IN_CHANGE | IN_UPDATE; |
if ((error = VOP_UPDATE(ovp, &ts, &ts, 1)) != 0) |
if ((error = VOP_UPDATE(ovp, &ts, &ts, 1)) != 0) |
allerror = error; |
allerror = error; |
|
|
* Note that we save the new block configuration so we can check it |
* Note that we save the new block configuration so we can check it |
* when we are done. |
* when we are done. |
*/ |
*/ |
bcopy((caddr_t)&oip->i_db[0], (caddr_t)newblks, sizeof newblks); |
bcopy((caddr_t)&oip->i_ffs_db[0], (caddr_t)newblks, sizeof newblks); |
bcopy((caddr_t)oldblks, (caddr_t)&oip->i_db[0], sizeof oldblks); |
bcopy((caddr_t)oldblks, (caddr_t)&oip->i_ffs_db[0], sizeof oldblks); |
oip->i_size = osize; |
oip->i_ffs_size = osize; |
vflags = ((length > 0) ? V_SAVE : 0) | V_SAVEMETA; |
vflags = ((length > 0) ? V_SAVE : 0) | V_SAVEMETA; |
allerror = vinvalbuf(ovp, vflags, ap->a_cred, ap->a_p, 0, 0); |
allerror = vinvalbuf(ovp, vflags, ap->a_cred, ap->a_p, 0, 0); |
|
|
|
|
indir_lbn[DOUBLE] = indir_lbn[SINGLE] - NINDIR(fs) - 1; |
indir_lbn[DOUBLE] = indir_lbn[SINGLE] - NINDIR(fs) - 1; |
indir_lbn[TRIPLE] = indir_lbn[DOUBLE] - NINDIR(fs) * NINDIR(fs) - 1; |
indir_lbn[TRIPLE] = indir_lbn[DOUBLE] - NINDIR(fs) * NINDIR(fs) - 1; |
for (level = TRIPLE; level >= SINGLE; level--) { |
for (level = TRIPLE; level >= SINGLE; level--) { |
bn = oip->i_ib[level]; |
bn = oip->i_ffs_ib[level]; |
if (bn != 0) { |
if (bn != 0) { |
error = ffs_indirtrunc(oip, indir_lbn[level], |
error = ffs_indirtrunc(oip, indir_lbn[level], |
fsbtodb(fs, bn), lastiblock[level], level, &count); |
fsbtodb(fs, bn), lastiblock[level], level, &count); |
|
|
allerror = error; |
allerror = error; |
blocksreleased += count; |
blocksreleased += count; |
if (lastiblock[level] < 0) { |
if (lastiblock[level] < 0) { |
oip->i_ib[level] = 0; |
oip->i_ffs_ib[level] = 0; |
ffs_blkfree(oip, bn, fs->fs_bsize); |
ffs_blkfree(oip, bn, fs->fs_bsize); |
blocksreleased += nblocks; |
blocksreleased += nblocks; |
} |
} |
|
|
for (i = NDADDR - 1; i > lastblock; i--) { |
for (i = NDADDR - 1; i > lastblock; i--) { |
register long bsize; |
register long bsize; |
|
|
bn = oip->i_db[i]; |
bn = oip->i_ffs_db[i]; |
if (bn == 0) |
if (bn == 0) |
continue; |
continue; |
oip->i_db[i] = 0; |
oip->i_ffs_db[i] = 0; |
bsize = blksize(fs, oip, i); |
bsize = blksize(fs, oip, i); |
ffs_blkfree(oip, bn, bsize); |
ffs_blkfree(oip, bn, bsize); |
blocksreleased += btodb(bsize); |
blocksreleased += btodb(bsize); |
|
|
* Finally, look for a change in size of the |
* Finally, look for a change in size of the |
* last direct block; release any frags. |
* last direct block; release any frags. |
*/ |
*/ |
bn = oip->i_db[lastblock]; |
bn = oip->i_ffs_db[lastblock]; |
if (bn != 0) { |
if (bn != 0) { |
long oldspace, newspace; |
long oldspace, newspace; |
|
|
|
|
* back as old block size minus new block size. |
* back as old block size minus new block size. |
*/ |
*/ |
oldspace = blksize(fs, oip, lastblock); |
oldspace = blksize(fs, oip, lastblock); |
oip->i_size = length; |
oip->i_ffs_size = length; |
newspace = blksize(fs, oip, lastblock); |
newspace = blksize(fs, oip, lastblock); |
if (newspace == 0) |
if (newspace == 0) |
panic("itrunc: newspace"); |
panic("itrunc: newspace"); |
|
|
done: |
done: |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
for (level = SINGLE; level <= TRIPLE; level++) |
for (level = SINGLE; level <= TRIPLE; level++) |
if (newblks[NDADDR + level] != oip->i_ib[level]) |
if (newblks[NDADDR + level] != oip->i_ffs_ib[level]) |
panic("itrunc1"); |
panic("itrunc1"); |
for (i = 0; i < NDADDR; i++) |
for (i = 0; i < NDADDR; i++) |
if (newblks[i] != oip->i_db[i]) |
if (newblks[i] != oip->i_ffs_db[i]) |
panic("itrunc2"); |
panic("itrunc2"); |
if (length == 0 && |
if (length == 0 && |
(ovp->v_dirtyblkhd.lh_first || ovp->v_cleanblkhd.lh_first)) |
(ovp->v_dirtyblkhd.lh_first || ovp->v_cleanblkhd.lh_first)) |
|
|
/* |
/* |
* Put back the real size. |
* Put back the real size. |
*/ |
*/ |
oip->i_size = length; |
oip->i_ffs_size = length; |
oip->i_blocks -= blocksreleased; |
oip->i_ffs_blocks -= blocksreleased; |
if (oip->i_blocks < 0) /* sanity */ |
if (oip->i_ffs_blocks < 0) /* sanity */ |
oip->i_blocks = 0; |
oip->i_ffs_blocks = 0; |
oip->i_flag |= IN_CHANGE; |
oip->i_flag |= IN_CHANGE; |
#ifdef QUOTA |
#ifdef QUOTA |
(void) chkdq(oip, -blocksreleased, NOCRED, 0); |
(void) chkdq(oip, -blocksreleased, NOCRED, 0); |