Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/ufs Split ufs_direnter futher and turn off tree-vrp ...
details: https://anonhg.NetBSD.org/src/rev/1447ffdc5b79
branches: trunk
changeset: 815092:1447ffdc5b79
user: christos <christos%NetBSD.org@localhost>
date: Fri Apr 29 02:16:53 2016 +0000
description:
Split ufs_direnter futher and turn off tree-vrp for the broken function.
diffstat:
sys/ufs/ufs/ufs_lookup.c | 227 ++++++++++++++++++++++++++--------------------
1 files changed, 127 insertions(+), 100 deletions(-)
diffs (truncated from 317 to 300 lines):
diff -r 49a53745c685 -r 1447ffdc5b79 sys/ufs/ufs/ufs_lookup.c
--- a/sys/ufs/ufs/ufs_lookup.c Fri Apr 29 01:14:23 2016 +0000
+++ b/sys/ufs/ufs/ufs_lookup.c Fri Apr 29 02:16:53 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_lookup.c,v 1.143 2016/04/14 03:25:28 christos Exp $ */
+/* $NetBSD: ufs_lookup.c,v 1.144 2016/04/29 02:16:53 christos Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_lookup.c,v 1.143 2016/04/14 03:25:28 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_lookup.c,v 1.144 2016/04/29 02:16:53 christos Exp $");
#ifdef _KERNEL_OPT
#include "opt_ffs.h"
@@ -807,102 +807,85 @@
newdirp->d_type = IFTODT(ip->i_mode);
}
-/*
- * Write a directory entry after a call to namei, using the parameters
- * that ufs_lookup left in nameidata and in the ufs_lookup_results.
- *
- * DVP is the directory to be updated. It must be locked.
- * ULR is the ufs_lookup_results structure from the final lookup step.
- * TVP is not used. (XXX: why is it here? remove it)
- * DIRP is the new directory entry contents.
- * CNP is the componentname from the final lookup step.
- * NEWDIRBP is not used and (XXX) should be removed. The previous
- * comment here said it was used by the now-removed softupdates code.
- *
- * The link count of the target inode is *not* incremented; the
- * caller does that.
- *
- * If ulr->ulr_count is 0, ufs_lookup did not find space to insert the
- * directory entry. ulr_offset, which is the place to put the entry,
- * should be on a block boundary (and should be at the end of the
- * directory AFAIK) and a fresh block is allocated to put the new
- * directory entry in.
- *
- * If ulr->ulr_count is not zero, ufs_lookup found a slot to insert
- * the entry into. This slot ranges from ulr_offset to ulr_offset +
- * ulr_count. However, this slot may already be partially populated
- * requiring compaction. See notes below.
- *
- * Furthermore, if ulr_count is not zero and ulr_endoff is not the
- * same as i_size, the directory is truncated to size ulr_endoff.
- */
-int
-ufs_direnter(struct vnode *dvp, const struct ufs_lookup_results *ulr,
+
+static int
+ufs_dirgrow(struct vnode *dvp, const struct ufs_lookup_results *ulr,
struct vnode *tvp, struct direct *dirp,
struct componentname *cnp, struct buf *newdirbp)
{
- kauth_cred_t cr;
- int newentrysize;
- struct inode *dp;
+ const kauth_cred_t cr = cnp->cn_cred;
+ const struct ufsmount *ump = VFSTOUFS(dvp->v_mount);
+ const int needswap = UFS_MPNEEDSWAP(ump);
+ const int dirblksiz = ump->um_dirblksiz;
+ const int fsfmt = FSFMT(dvp);
+ const u_int newentrysize = UFS_DIRSIZ(0, dirp, 0);
+ struct inode *dp = VTOI(dvp);
+ int error, ret, blkoff;
+ struct timespec ts;
+ struct buf *bp;
+
+ /*
+ * If ulr_count is 0, then namei could find no
+ * space in the directory. Here, ulr_offset will
+ * be on a directory block boundary and we will write the
+ * new entry into a fresh block.
+ */
+ if (ulr->ulr_offset & (dirblksiz - 1))
+ panic("%s: newblk", __func__);
+ if ((error = UFS_BALLOC(dvp, (off_t)ulr->ulr_offset, dirblksiz,
+ cr, B_CLRBUF | B_SYNC, &bp)) != 0) {
+ return error;
+ }
+
+ dp->i_size = ulr->ulr_offset + dirblksiz;
+ DIP_ASSIGN(dp, size, dp->i_size);
+ dp->i_flag |= IN_CHANGE | IN_UPDATE;
+ uvm_vnp_setsize(dvp, dp->i_size);
+ dirp->d_reclen = ufs_rw16(dirblksiz, needswap);
+ dirp->d_ino = ufs_rw32(dirp->d_ino, needswap);
+ if (fsfmt && ENDIANSWAP(needswap))
+ ufs_dirswap(dirp);
+ blkoff = ulr->ulr_offset & (ump->um_mountp->mnt_stat.f_iosize - 1);
+ memcpy((char *)bp->b_data + blkoff, dirp, newentrysize);
+#ifdef UFS_DIRHASH
+ if (dp->i_dirhash != NULL) {
+ ufsdirhash_newblk(dp, ulr->ulr_offset);
+ ufsdirhash_add(dp, dirp, ulr->ulr_offset);
+ ufsdirhash_checkblock(dp, (char *)bp->b_data + blkoff,
+ ulr->ulr_offset);
+ }
+#endif
+ error = VOP_BWRITE(bp->b_vp, bp);
+ vfs_timestamp(&ts);
+ ret = UFS_UPDATE(dvp, &ts, &ts, UPDATE_DIROP);
+ if (error == 0)
+ return ret;
+ return error;
+}
+
+static int
+#if __GNUC_PREREQ__(5, 3)
+/* This gets miscompiled by gcc 5.3 */
+__attribute__((__optimize__("no-tree-vrp")))
+#endif
+ufs_dircompact(struct vnode *dvp, const struct ufs_lookup_results *ulr,
+ struct vnode *tvp, struct direct *dirp,
+ struct componentname *cnp, struct buf *newdirbp)
+{
+ const struct ufsmount *ump = VFSTOUFS(dvp->v_mount);
+ const int needswap = UFS_MPNEEDSWAP(ump);
+ const int fsfmt = FSFMT(dvp);
+ const u_int newentrysize = UFS_DIRSIZ(0, dirp, 0);
+ struct inode *dp = VTOI(dvp);
struct buf *bp;
u_int dsize;
struct direct *ep, *nep;
- int error, ret, blkoff, loc, spacefree;
+ int error, loc, spacefree;
char *dirbuf;
- struct timespec ts;
- struct ufsmount *ump = VFSTOUFS(dvp->v_mount);
- const int needswap = UFS_MPNEEDSWAP(ump);
- int dirblksiz = ump->um_dirblksiz;
- const int fsfmt = FSFMT(dvp);
uint16_t reclen;
UFS_WAPBL_JLOCK_ASSERT(dvp->v_mount);
- error = 0;
- cr = cnp->cn_cred;
-
- dp = VTOI(dvp);
- newentrysize = UFS_DIRSIZ(0, dirp, 0);
-
- if (ulr->ulr_count == 0) {
- /*
- * If ulr_count is 0, then namei could find no
- * space in the directory. Here, ulr_offset will
- * be on a directory block boundary and we will write the
- * new entry into a fresh block.
- */
- if (ulr->ulr_offset & (dirblksiz - 1))
- panic("ufs_direnter: newblk");
- if ((error = UFS_BALLOC(dvp, (off_t)ulr->ulr_offset, dirblksiz,
- cr, B_CLRBUF | B_SYNC, &bp)) != 0) {
- return (error);
- }
- dp->i_size = ulr->ulr_offset + dirblksiz;
- DIP_ASSIGN(dp, size, dp->i_size);
- dp->i_flag |= IN_CHANGE | IN_UPDATE;
- uvm_vnp_setsize(dvp, dp->i_size);
- dirp->d_reclen = ufs_rw16(dirblksiz, needswap);
- dirp->d_ino = ufs_rw32(dirp->d_ino, needswap);
- if (fsfmt && ENDIANSWAP(needswap))
- ufs_dirswap(dirp);
- blkoff = ulr->ulr_offset & (ump->um_mountp->mnt_stat.f_iosize - 1);
- memcpy((char *)bp->b_data + blkoff, dirp, newentrysize);
-#ifdef UFS_DIRHASH
- if (dp->i_dirhash != NULL) {
- ufsdirhash_newblk(dp, ulr->ulr_offset);
- ufsdirhash_add(dp, dirp, ulr->ulr_offset);
- ufsdirhash_checkblock(dp, (char *)bp->b_data + blkoff,
- ulr->ulr_offset);
- }
-#endif
- error = VOP_BWRITE(bp->b_vp, bp);
- vfs_timestamp(&ts);
- ret = UFS_UPDATE(dvp, &ts, &ts, UPDATE_DIROP);
- if (error == 0)
- return (ret);
- return (error);
- }
-
/*
* If ulr_count is non-zero, then namei found space for the new
* entry in the range ulr_offset to ulr_offset + ulr_count
@@ -921,8 +904,8 @@
*/
if (ulr->ulr_offset + ulr->ulr_count > dp->i_size) {
#ifdef DIAGNOSTIC
- printf("ufs_direnter: reached 4.2-only block, "
- "not supposed to happen\n");
+ printf("%s: reached 4.2-only block, not supposed to happen\n",
+ __func__);
#endif
dp->i_size = ulr->ulr_offset + ulr->ulr_count;
DIP_ASSIGN(dp, size, dp->i_size);
@@ -933,9 +916,9 @@
* Get the block containing the space for the new directory entry.
*/
error = ufs_blkatoff(dvp, (off_t)ulr->ulr_offset, &dirbuf, &bp, true);
- if (error) {
- return (error);
- }
+ if (error)
+ return error;
+
/*
* Find space for the new entry. In the simple case, the entry at
* offset base will have the space. If it does not, then namei
@@ -992,15 +975,16 @@
(ufs_rw32(ep->d_ino, needswap) == UFS_WINO &&
memcmp(ep->d_name, dirp->d_name, dirp->d_namlen) == 0)) {
if (spacefree + dsize < newentrysize)
- panic("ufs_direnter: compact1");
+ panic("%s: too big", __func__);
dirp->d_reclen = spacefree + dsize;
} else {
if (spacefree < newentrysize)
- panic("ufs_direnter: compact2");
+ panic("%s: nospace", __func__);
dirp->d_reclen = spacefree;
ep->d_reclen = ufs_rw16(dsize, needswap);
ep = (void *)((char *)ep + dsize);
}
+
dirp->d_reclen = ufs_rw16(dirp->d_reclen, needswap);
dirp->d_ino = ufs_rw32(dirp->d_ino, needswap);
if (fsfmt && ENDIANSWAP(needswap))
@@ -1010,12 +994,14 @@
dirp->d_reclen == spacefree))
ufsdirhash_add(dp, dirp, ulr->ulr_offset + ((char *)ep - dirbuf));
#endif
- memcpy(ep, dirp, (u_int)newentrysize);
+ memcpy(ep, dirp, newentrysize);
#ifdef UFS_DIRHASH
- if (dp->i_dirhash != NULL)
+ if (dp->i_dirhash != NULL) {
+ const int dirblkmsk = ump->um_dirblksiz - 1;
ufsdirhash_checkblock(dp, dirbuf -
- (ulr->ulr_offset & (dirblksiz - 1)),
- ulr->ulr_offset & ~(dirblksiz - 1));
+ (ulr->ulr_offset & dirblkmsk),
+ ulr->ulr_offset & ~dirblkmsk);
+ }
#endif
error = VOP_BWRITE(bp->b_vp, bp);
dp->i_flag |= IN_CHANGE | IN_UPDATE;
@@ -1027,6 +1013,7 @@
* lock on the newly entered node.
*/
if (error == 0 && ulr->ulr_endoff && ulr->ulr_endoff < dp->i_size) {
+ const kauth_cred_t cr = cnp->cn_cred;
#ifdef UFS_DIRHASH
if (dp->i_dirhash != NULL)
ufsdirhash_dirtrunc(dp, ulr->ulr_endoff);
@@ -1034,7 +1021,47 @@
(void) UFS_TRUNCATE(dvp, (off_t)ulr->ulr_endoff, IO_SYNC, cr);
}
UFS_WAPBL_UPDATE(dvp, NULL, NULL, UPDATE_DIROP);
- return (error);
+ return error;
+}
+
+/*
+ * Write a directory entry after a call to namei, using the parameters
+ * that ufs_lookup left in nameidata and in the ufs_lookup_results.
+ *
+ * DVP is the directory to be updated. It must be locked.
+ * ULR is the ufs_lookup_results structure from the final lookup step.
+ * TVP is not used. (XXX: why is it here? remove it)
+ * DIRP is the new directory entry contents.
+ * CNP is the componentname from the final lookup step.
+ * NEWDIRBP is not used and (XXX) should be removed. The previous
+ * comment here said it was used by the now-removed softupdates code.
+ *
+ * The link count of the target inode is *not* incremented; the
+ * caller does that.
+ *
+ * If ulr->ulr_count is 0, ufs_lookup did not find space to insert the
+ * directory entry. ulr_offset, which is the place to put the entry,
+ * should be on a block boundary (and should be at the end of the
+ * directory AFAIK) and a fresh block is allocated to put the new
+ * directory entry in.
+ *
+ * If ulr->ulr_count is not zero, ufs_lookup found a slot to insert
+ * the entry into. This slot ranges from ulr_offset to ulr_offset +
+ * ulr_count. However, this slot may already be partially populated
+ * requiring compaction. See notes below.
+ *
+ * Furthermore, if ulr_count is not zero and ulr_endoff is not the
+ * same as i_size, the directory is truncated to size ulr_endoff.
+ */
+int
+ufs_direnter(struct vnode *dvp, const struct ufs_lookup_results *ulr,
+ struct vnode *tvp, struct direct *dirp,
+ struct componentname *cnp, struct buf *newdirbp)
Home |
Main Index |
Thread Index |
Old Index