diff options
| author | mishra <none@none> | 2007-06-12 15:11:05 -0700 |
|---|---|---|
| committer | mishra <none@none> | 2007-06-12 15:11:05 -0700 |
| commit | 33c22cb3ef1e3a08bec4eecf1326255f46bf5e68 (patch) | |
| tree | 332e9427fd0ea8dab0833d43e75c4005e64da14d /usr/src | |
| parent | 58c0eeecf3809d173057fc5a445f5de64d590d9f (diff) | |
| download | illumos-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.c | 20 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/ufs/ufs_bmap.c | 18 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/fs/ufs_inode.h | 4 |
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 { |
