Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/ufs more deduplication.
details: https://anonhg.NetBSD.org/src/rev/46fee119810e
branches: trunk
changeset: 344721:46fee119810e
user: christos <christos%NetBSD.org@localhost>
date: Wed Apr 13 00:09:26 2016 +0000
description:
more deduplication.
diffstat:
sys/ufs/ufs/ufs_lookup.c | 143 +++++++++++++++++++++++++---------------------
1 files changed, 77 insertions(+), 66 deletions(-)
diffs (219 lines):
diff -r c99aa6075370 -r 46fee119810e sys/ufs/ufs/ufs_lookup.c
--- a/sys/ufs/ufs/ufs_lookup.c Tue Apr 12 23:07:25 2016 +0000
+++ b/sys/ufs/ufs/ufs_lookup.c Wed Apr 13 00:09:26 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_lookup.c,v 1.140 2016/04/12 16:12:22 christos Exp $ */
+/* $NetBSD: ufs_lookup.c,v 1.141 2016/04/13 00:09:26 christos Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_lookup.c,v 1.140 2016/04/12 16:12:22 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_lookup.c,v 1.141 2016/04/13 00:09:26 christos Exp $");
#ifdef _KERNEL_OPT
#include "opt_ffs.h"
@@ -109,6 +109,15 @@
};
static void
+calc_count(struct ufs_lookup_results *results, int dirblksiz, doff_t prevoff)
+{
+ if ((results->ulr_offset & (dirblksiz - 1)) == 0)
+ results->ulr_count = 0;
+ else
+ results->ulr_count = results->ulr_offset - prevoff;
+}
+
+static void
slot_init(struct slotinfo *slot)
{
slot->status = FOUND;
@@ -181,10 +190,7 @@
enduseful = results->ulr_offset;
} else if (nameiop == DELETE) {
results->ulr_offset = slot->offset;
- if ((results->ulr_offset & (dirblksiz - 1)) == 0)
- results->ulr_count = 0;
- else
- results->ulr_count = results->ulr_offset - prevoff;
+ calc_count(results, dirblksiz, prevoff);
} else {
results->ulr_offset = slot->offset;
results->ulr_count = slot->size;
@@ -199,6 +205,57 @@
}
/*
+ * Check if we can delete inode tdp in directory vdp with inode ip and creds.
+ */
+static int
+ufs_can_delete(struct vnode *tdp, struct vnode *vdp, struct inode *ip,
+ kauth_cred_t cred)
+{
+ int error;
+ /*
+ * Write access to directory required to delete files.
+ */
+ error = VOP_ACCESS(vdp, VWRITE, cred);
+ if (error)
+ goto out;
+
+ if (!(ip->i_mode & ISVTX))
+ return 0;
+
+ /*
+ * If directory is "sticky", then user must own
+ * the directory, or the file in it, else she
+ * may not delete it (unless she's root). This
+ * implements append-only directories.
+ */
+ error = kauth_authorize_vnode(cred, KAUTH_VNODE_DELETE, tdp, vdp,
+ genfs_can_sticky(cred, ip->i_uid, VTOI(tdp)->i_uid));
+ if (error) {
+ error = EPERM; // Why override?
+ goto out;
+ }
+ return 0;
+out:
+ vrele(tdp);
+ return error;
+}
+
+static int
+ufs_getino(struct vnode *vdp, struct inode *ip, ino_t foundino,
+ struct vnode **tdp, int same)
+{
+ if (ip->i_number == foundino) {
+ if (same)
+ return EISDIR;
+ vref(vdp);
+ *tdp = vdp;
+ return 0;
+ }
+ return vcache_get(vdp->v_mount, &foundino, sizeof(foundino), tdp);
+}
+
+
+/*
* Convert a component of a pathname into a pointer to a locked inode.
* This is a very central and rather complicated routine.
* If the file system is not maintained in a strict tree hierarchy,
@@ -299,7 +356,7 @@
* we are looking for is known already.
*/
if (cache_lookup(vdp, cnp->cn_nameptr, cnp->cn_namelen,
- cnp->cn_nameiop, cnp->cn_flags, &iswhiteout, vpp)) {
+ cnp->cn_nameiop, cnp->cn_flags, &iswhiteout, vpp)) {
if (iswhiteout) {
cnp->cn_flags |= ISWHITEOUT;
}
@@ -464,8 +521,7 @@
*/
const uint16_t namlen = NAMLEN(fsfmt, needswap, ep);
if (namlen != cnp->cn_namelen ||
- memcmp(cnp->cn_nameptr, ep->d_name,
- (unsigned)namlen))
+ memcmp(cnp->cn_nameptr, ep->d_name, (size_t)namlen))
goto next;
#ifdef UFS_DIRHASH
@@ -597,45 +653,15 @@
* is a previous entry in this block) in results->ulr_count.
* Save directory inode pointer in ndp->ni_dvp for dirremove().
*/
- if ((results->ulr_offset & (dirblksiz - 1)) == 0)
- results->ulr_count = 0;
- else
- results->ulr_count = results->ulr_offset - prevoff;
- if (dp->i_number == foundino) {
- vref(vdp);
- tdp = vdp;
- } else {
- error = vcache_get(vdp->v_mount,
- &foundino, sizeof(foundino), &tdp);
- if (error)
- goto out;
- }
- /*
- * Write access to directory required to delete files.
- */
- error = VOP_ACCESS(vdp, VWRITE, cred);
- if (error) {
- vrele(tdp);
+ calc_count(results, dirblksiz, prevoff);
+
+ if ((error = ufs_getino(vdp, dp, foundino, &tdp, FALSE)) != 0)
goto out;
- }
- /*
- * If directory is "sticky", then user must own
- * the directory, or the file in it, else she
- * may not delete it (unless she's root). This
- * implements append-only directories.
- */
- if (dp->i_mode & ISVTX) {
- error = kauth_authorize_vnode(cred, KAUTH_VNODE_DELETE,
- tdp, vdp, genfs_can_sticky(cred, dp->i_uid,
- VTOI(tdp)->i_uid));
- if (error) {
- vrele(tdp);
- error = EPERM;
- goto out;
- }
- }
+
+ if ((error = ufs_can_delete(tdp, vdp, dp, cred)) != 0)
+ goto out;
+
*vpp = tdp;
- error = 0;
goto out;
}
@@ -646,37 +672,22 @@
* regular file, or empty directory.
*/
if (nameiop == RENAME && (flags & ISLASTCN)) {
- error = VOP_ACCESS(vdp, VWRITE, cred);
- if (error)
+ if ((error = VOP_ACCESS(vdp, VWRITE, cred)) != 0)
goto out;
/*
* Careful about locking second inode.
* This can only occur if the target is ".".
*/
- if (dp->i_number == foundino) {
- error = EISDIR;
- goto out;
- }
- error = vcache_get(vdp->v_mount,
- &foundino, sizeof(foundino), &tdp);
- if (error)
+ if ((error = ufs_getino(vdp, dp, foundino, &tdp, TRUE)) != 0)
goto out;
*vpp = tdp;
- error = 0;
goto out;
}
- if (dp->i_number == foundino) {
- vref(vdp); /* we want ourself, ie "." */
- *vpp = vdp;
- } else {
- error = vcache_get(vdp->v_mount,
- &foundino, sizeof(foundino), &tdp);
- if (error)
- goto out;
- *vpp = tdp;
- }
+ if ((error = ufs_getino(vdp, dp, foundino, &tdp, FALSE)) != 0)
+ goto out;
+ *vpp = tdp;
/*
* Insert name into cache if appropriate.
*/
Home |
Main Index |
Thread Index |
Old Index