summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ffs/ffs_balloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/ufs/ffs/ffs_balloc.c')
-rw-r--r--sys/ufs/ffs/ffs_balloc.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c
index ebd630f..a40915d 100644
--- a/sys/ufs/ffs/ffs_balloc.c
+++ b/sys/ufs/ffs/ffs_balloc.c
@@ -56,7 +56,7 @@
int
ffs_balloc(ap)
struct vop_balloc_args /* {
- struct inode *a_ip;
+ struct vnode *a_vp;
ufs_daddr_t a_lbn;
int a_size;
struct ucred *a_cred;
@@ -64,8 +64,8 @@ ffs_balloc(ap)
struct buf *a_bpp;
} */ *ap;
{
- register struct inode *ip;
- register ufs_daddr_t lbn;
+ struct inode *ip;
+ ufs_daddr_t lbn;
int size;
struct ucred *cred;
int flags;
@@ -77,6 +77,7 @@ ffs_balloc(ap)
ufs_daddr_t newb, *bap, pref;
int deallocated, osize, nsize, num, i, error;
ufs_daddr_t *allocib, *blkp, *allocblk, allociblk[NIADDR + 1];
+ struct proc *p = curproc; /* XXX */
vp = ap->a_vp;
ip = VTOI(vp);
@@ -335,7 +336,15 @@ fail:
/*
* If we have failed part way through block allocation, we
* have to deallocate any indirect blocks that we have allocated.
+ * We have to fsync the file before we start to get rid of all
+ * of its dependencies so that we do not leave them dangling.
+ * We have to sync it at the end so that the soft updates code
+ * does not find any untracked changes. Although this is really
+ * slow, running out of disk space is not expected to be a common
+ * occurence. The error return from fsync is ignored as we already
+ * have an error to return to the user.
*/
+ (void) VOP_FSYNC(vp, cred, MNT_WAIT, p);
for (deallocated = 0, blkp = allociblk; blkp < allocblk; blkp++) {
ffs_blkfree(ip, *blkp, fs->fs_bsize);
deallocated += fs->fs_bsize;
@@ -352,5 +361,6 @@ fail:
ip->i_blocks -= btodb(deallocated);
ip->i_flag |= IN_CHANGE | IN_UPDATE;
}
+ (void) VOP_FSYNC(vp, cred, MNT_WAIT, p);
return (error);
}
OpenPOWER on IntegriCloud