summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authormishra <none@none>2007-06-12 15:11:05 -0700
committermishra <none@none>2007-06-12 15:11:05 -0700
commit33c22cb3ef1e3a08bec4eecf1326255f46bf5e68 (patch)
tree332e9427fd0ea8dab0833d43e75c4005e64da14d /usr/src
parent58c0eeecf3809d173057fc5a445f5de64d590d9f (diff)
downloadillumos-joyent-33c22cb3ef1e3a08bec4eecf1326255f46bf5e68.tar.gz
6411034 posix_fallocate() at times doesn't extend the file due to ufs_allocsp() returning failure
6432412 posix_fallocate() moves holes instead of filling them 6436393 posix_fallocate() can cause freeing free block panic 6493590 bmap_set_bn() does not take care of second level indirection leading to UFS_HOLE/freeing free panics
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/fs/ufs/ufs_alloc.c20
-rw-r--r--usr/src/uts/common/fs/ufs/ufs_bmap.c18
-rw-r--r--usr/src/uts/common/sys/fs/ufs_inode.h4
3 files changed, 26 insertions, 16 deletions
diff --git a/usr/src/uts/common/fs/ufs/ufs_alloc.c b/usr/src/uts/common/fs/ufs/ufs_alloc.c
index 714ebe6134..c643cb2035 100644
--- a/usr/src/uts/common/fs/ufs/ufs_alloc.c
+++ b/usr/src/uts/common/fs/ufs/ufs_alloc.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -637,7 +636,7 @@ free(struct inode *ip, daddr_t bno, off_t size, int flags)
* fallocate'd files will have negative block address.
* So negate it again to get original block address.
*/
- if (bno < 0 && bno % fs->fs_bsize == 0 && bno != UFS_HOLE) {
+ if (bno < 0 && (bno % fs->fs_frag == 0) && bno != UFS_HOLE) {
bno = -bno;
}
@@ -1590,7 +1589,7 @@ ufs_allocsp(struct vnode *vp, struct flock64 *lp, cred_t *cr)
rw_enter(&ufsvfsp->vfs_dqrwlock, RW_READER);
rw_enter(&ip->i_contents, RW_WRITER);
- for (i = start; (i < len) && (lblkno(fs, i) < NDADDR);
+ for (i = start; (i < (start + len)) && (lblkno(fs, i) < NDADDR);
i += fs->fs_bsize) {
berr = bmap_write(ip, i, fs->fs_bsize, BI_FALLOCATE,
&allocblk, cr);
@@ -1606,7 +1605,8 @@ ufs_allocsp(struct vnode *vp, struct flock64 *lp, cred_t *cr)
if (allocblk) {
totblks++;
- ip->i_size += fs->fs_bsize;
+ if (i >= ip->i_size)
+ ip->i_size += fs->fs_bsize;
}
}
@@ -1631,7 +1631,7 @@ ufs_allocsp(struct vnode *vp, struct flock64 *lp, cred_t *cr)
rw_enter(&ip->i_contents, RW_WRITER);
/* Now go about fallocating necessary indirect blocks */
- for (i = istart; i < len; i += fs->fs_bsize) {
+ for (i = istart; i < (start + len); i += fs->fs_bsize) {
berr = bmap_write(ip, i, fs->fs_bsize, BI_FALLOCATE,
&allocblk, cr);
if (berr) {
@@ -1654,7 +1654,9 @@ ufs_allocsp(struct vnode *vp, struct flock64 *lp, cred_t *cr)
undo->next = ib_undo;
ib_undo = undo;
totblks++;
- ip->i_size += fs->fs_bsize;
+
+ if (i >= ip->i_size)
+ ip->i_size += fs->fs_bsize;
}
cnt++;
diff --git a/usr/src/uts/common/fs/ufs/ufs_bmap.c b/usr/src/uts/common/fs/ufs/ufs_bmap.c
index 2a08768b40..9933ff219a 100644
--- a/usr/src/uts/common/fs/ufs/ufs_bmap.c
+++ b/usr/src/uts/common/fs/ufs/ufs_bmap.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1376,8 +1375,10 @@ bmap_set_bn(struct vnode *vp, u_offset_t off, daddr32_t bn)
* Fetch the first indirect block.
*/
nb = ip->i_ib[NIADDR - j];
- if (nb == 0)
+ if (nb == 0) {
err = ufs_fault(ITOV(ip), "ufs_set_bn: nb == UFS_HOLE");
+ return (err);
+ }
/*
* Fetch through the indirect blocks.
@@ -1398,11 +1399,18 @@ bmap_set_bn(struct vnode *vp, u_offset_t off, daddr32_t bn)
shft -= nindirshift; /* sh / nindir */
i = (tbn >> shft) & nindiroffset; /* (tbn / sh) % nindir */
+ nb = bap[i];
+ if (nb == 0) {
+ err = ufs_fault(ITOV(ip), "ufs_set_bn: nb == UFS_HOLE");
+ return (err);
+ }
+
if (j == NIADDR) {
bap[i] = bn;
bdrwrite(bp);
return (0);
}
+
brelse(bp);
}
return (0);
diff --git a/usr/src/uts/common/sys/fs/ufs_inode.h b/usr/src/uts/common/sys/fs/ufs_inode.h
index 5b0d7375b8..effc5aa9f6 100644
--- a/usr/src/uts/common/sys/fs/ufs_inode.h
+++ b/usr/src/uts/common/sys/fs/ufs_inode.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -807,7 +807,7 @@ typedef struct ufsvfs {
#define INOHASH(ino) (((int)ino) & (inohsz - 1))
#define ISFALLOCBLK(ip, bn) \
- (((bn) < 0) && ((bn) % ip->i_fs->fs_bsize == 0) && \
+ (((bn) < 0) && ((bn) % ip->i_fs->fs_frag == 0) && \
((ip)->i_cflags & IFALLOCATE && (bn) != UFS_HOLE))
union ihead {