Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/tmpfs - tmpfs_lookup: cache (cnp->cn_flags & ISLASTCN...
details: https://anonhg.NetBSD.org/src/rev/cc1aa623e6cc
branches: trunk
changeset: 765389:cc1aa623e6cc
user: rmind <rmind%NetBSD.org@localhost>
date: Tue May 24 23:16:16 2011 +0000
description:
- tmpfs_lookup: cache (cnp->cn_flags & ISLASTCN) in const bool; de-indent.
- Group tmpfs_{alloc,free}_dirent() with other dirent routines.
No functional changes.
diffstat:
sys/fs/tmpfs/tmpfs_subr.c | 148 ++++++++++++++++++++++----------------------
sys/fs/tmpfs/tmpfs_vnops.c | 98 ++++++++++++++---------------
2 files changed, 121 insertions(+), 125 deletions(-)
diffs (truncated from 339 to 300 lines):
diff -r ff06135fd3bd -r cc1aa623e6cc sys/fs/tmpfs/tmpfs_subr.c
--- a/sys/fs/tmpfs/tmpfs_subr.c Tue May 24 22:46:42 2011 +0000
+++ b/sys/fs/tmpfs/tmpfs_subr.c Tue May 24 23:16:16 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tmpfs_subr.c,v 1.67 2011/05/24 20:17:49 rmind Exp $ */
+/* $NetBSD: tmpfs_subr.c,v 1.68 2011/05/24 23:16:16 rmind Exp $ */
/*
* Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.67 2011/05/24 20:17:49 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.68 2011/05/24 23:16:16 rmind Exp $");
#include <sys/param.h>
#include <sys/dirent.h>
@@ -212,77 +212,6 @@
}
/*
- * tmpfs_alloc_dirent: allocates a new directory entry for the inode.
- *
- * The link count of node is increased by one to reflect the new object
- * referencing it. This takes care of notifying kqueue listeners about
- * this change.
- */
-int
-tmpfs_alloc_dirent(tmpfs_mount_t *tmp, tmpfs_node_t *node,
- const char *name, uint16_t len, tmpfs_dirent_t **de)
-{
- tmpfs_dirent_t *nde;
-
- nde = tmpfs_dirent_get(tmp);
- if (nde == NULL)
- return ENOSPC;
-
- nde->td_name = tmpfs_strname_alloc(tmp, len);
- if (nde->td_name == NULL) {
- tmpfs_dirent_put(tmp, nde);
- return ENOSPC;
- }
- nde->td_namelen = len;
- memcpy(nde->td_name, name, len);
- nde->td_node = node;
-
- if (node != TMPFS_NODE_WHITEOUT) {
- node->tn_links++;
- if (node->tn_links > 1 && node->tn_vnode != NULL)
- VN_KNOTE(node->tn_vnode, NOTE_LINK);
- }
-
- *de = nde;
- return 0;
-}
-
-/*
- * tmpfs_free_dirent: free a directory entry.
- *
- * => It is the caller's responsibility to destroy the referenced inode.
- * => The link count of inode is decreased by one to reflect the removal of
- * an object that referenced it. This only happens if 'node_exists' is true;
- * otherwise the function will not access the node referred to by the
- * directory entry, as it may already have been released from the outside.
- *
- * Interested parties (kqueue) are notified of the link count change; note
- * that this can include both the node pointed to by the directory entry
- * as well as its parent.
- */
-void
-tmpfs_free_dirent(tmpfs_mount_t *tmp, tmpfs_dirent_t *de, bool node_exists)
-{
-
- if (node_exists && de->td_node != TMPFS_NODE_WHITEOUT) {
- tmpfs_node_t *node = de->td_node;
-
- KASSERT(node->tn_links > 0);
- node->tn_links--;
- if (node->tn_vnode != NULL) {
- VN_KNOTE(node->tn_vnode, node->tn_links == 0 ?
- NOTE_DELETE : NOTE_LINK);
- }
- if (node->tn_type == VDIR) {
- VN_KNOTE(node->tn_spec.tn_dir.tn_parent->tn_vnode,
- NOTE_LINK);
- }
- }
- tmpfs_strname_free(tmp, de->td_name, de->td_namelen);
- tmpfs_dirent_put(tmp, de);
-}
-
-/*
* tmpfs_alloc_vp: allocate or reclaim a vnode for a specified inode.
*
* => Returns vnode (*vpp) locked.
@@ -429,10 +358,81 @@
}
/*
+ * tmpfs_alloc_dirent: allocates a new directory entry for the inode.
+ *
+ * The link count of node is increased by one to reflect the new object
+ * referencing it. This takes care of notifying kqueue listeners about
+ * this change.
+ */
+int
+tmpfs_alloc_dirent(tmpfs_mount_t *tmp, tmpfs_node_t *node,
+ const char *name, uint16_t len, tmpfs_dirent_t **de)
+{
+ tmpfs_dirent_t *nde;
+
+ nde = tmpfs_dirent_get(tmp);
+ if (nde == NULL)
+ return ENOSPC;
+
+ nde->td_name = tmpfs_strname_alloc(tmp, len);
+ if (nde->td_name == NULL) {
+ tmpfs_dirent_put(tmp, nde);
+ return ENOSPC;
+ }
+ nde->td_namelen = len;
+ memcpy(nde->td_name, name, len);
+ nde->td_node = node;
+
+ if (node != TMPFS_NODE_WHITEOUT) {
+ node->tn_links++;
+ if (node->tn_links > 1 && node->tn_vnode != NULL)
+ VN_KNOTE(node->tn_vnode, NOTE_LINK);
+ }
+
+ *de = nde;
+ return 0;
+}
+
+/*
+ * tmpfs_free_dirent: free a directory entry.
+ *
+ * => It is the caller's responsibility to destroy the referenced inode.
+ * => The link count of inode is decreased by one to reflect the removal of
+ * an object that referenced it. This only happens if 'node_exists' is true;
+ * otherwise the function will not access the node referred to by the
+ * directory entry, as it may already have been released from the outside.
+ *
+ * Interested parties (kqueue) are notified of the link count change; note
+ * that this can include both the node pointed to by the directory entry
+ * as well as its parent.
+ */
+void
+tmpfs_free_dirent(tmpfs_mount_t *tmp, tmpfs_dirent_t *de, bool node_exists)
+{
+
+ if (node_exists && de->td_node != TMPFS_NODE_WHITEOUT) {
+ tmpfs_node_t *node = de->td_node;
+
+ KASSERT(node->tn_links > 0);
+ node->tn_links--;
+ if (node->tn_vnode != NULL) {
+ VN_KNOTE(node->tn_vnode, node->tn_links == 0 ?
+ NOTE_DELETE : NOTE_LINK);
+ }
+ if (node->tn_type == VDIR) {
+ VN_KNOTE(node->tn_spec.tn_dir.tn_parent->tn_vnode,
+ NOTE_LINK);
+ }
+ }
+ tmpfs_strname_free(tmp, de->td_name, de->td_namelen);
+ tmpfs_dirent_put(tmp, de);
+}
+
+/*
* tmpfs_dir_attach: attach the directory entry to the specified vnode.
*
* => The link count of inode is not changed; done by tmpfs_alloc_dirent().
- * => Triggers NOTE_WRITE ecent here.
+ * => Triggers NOTE_WRITE event here.
*/
void
tmpfs_dir_attach(vnode_t *vp, tmpfs_dirent_t *de)
diff -r ff06135fd3bd -r cc1aa623e6cc sys/fs/tmpfs/tmpfs_vnops.c
--- a/sys/fs/tmpfs/tmpfs_vnops.c Tue May 24 22:46:42 2011 +0000
+++ b/sys/fs/tmpfs/tmpfs_vnops.c Tue May 24 23:16:16 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tmpfs_vnops.c,v 1.83 2011/05/24 20:17:49 rmind Exp $ */
+/* $NetBSD: tmpfs_vnops.c,v 1.84 2011/05/24 23:16:16 rmind Exp $ */
/*
* Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.83 2011/05/24 20:17:49 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.84 2011/05/24 23:16:16 rmind Exp $");
#include <sys/param.h>
#include <sys/dirent.h>
@@ -132,8 +132,9 @@
} */ *ap = v;
vnode_t *dvp = ap->a_dvp, **vpp = ap->a_vpp;
struct componentname *cnp = ap->a_cnp;
+ const bool lastcn = (cnp->cn_flags & ISLASTCN) != 0;
+ tmpfs_node_t *dnode, *tnode;
tmpfs_dirent_t *de;
- tmpfs_node_t *dnode;
int error;
KASSERT(VOP_ISLOCKED(dvp));
@@ -150,8 +151,7 @@
* If requesting the last path component on a read-only file system
* with a write operation, deny it.
*/
- if ((cnp->cn_flags & ISLASTCN) &&
- (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
+ if (lastcn && (dvp->v_mount->mnt_flag & MNT_RDONLY) != 0 &&
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
error = EROFS;
goto out;
@@ -186,8 +186,7 @@
/*
* Lookup of "." case.
*/
- if ((cnp->cn_flags & ISLASTCN) &&
- (cnp->cn_nameiop == RENAME)) {
+ if (lastcn && cnp->cn_nameiop == RENAME) {
error = EISDIR;
goto out;
}
@@ -207,7 +206,7 @@
* if we are creating or renaming an entry and are working
* on the last component of the path name.
*/
- if ((cnp->cn_flags & ISLASTCN) && (cnp->cn_nameiop == CREATE ||
+ if (lastcn && (cnp->cn_nameiop == CREATE ||
cnp->cn_nameiop == RENAME)) {
error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred);
if (error) {
@@ -221,53 +220,50 @@
KASSERT(de->td_node == TMPFS_NODE_WHITEOUT);
cnp->cn_flags |= ISWHITEOUT;
}
- } else {
- tmpfs_node_t *tnode = de->td_node;
+ goto done;
+ }
+
+ tnode = de->td_node;
- /*
- * If we are not at the last path component and found a
- * non-directory or non-link entry (which may itself be
- * pointing to a directory), raise an error.
- */
- if ((tnode->tn_type != VDIR && tnode->tn_type != VLNK) &&
- (cnp->cn_flags & ISLASTCN) == 0) {
- error = ENOTDIR;
- goto out;
+ /*
+ * If it is not the last path component and found a non-directory
+ * or non-link entry (which may itself be pointing to a directory),
+ * raise an error.
+ */
+ if (!lastcn && tnode->tn_type != VDIR && tnode->tn_type != VLNK) {
+ error = ENOTDIR;
+ goto out;
+ }
+
+ /* Check the permissions. */
+ if (lastcn && (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
+ kauth_action_t action = 0;
+
+ /* This is the file-system's decision. */
+ if ((dnode->tn_mode & S_ISTXT) != 0 &&
+ kauth_cred_geteuid(cnp->cn_cred) != dnode->tn_uid &&
+ kauth_cred_geteuid(cnp->cn_cred) != tnode->tn_uid) {
+ error = EPERM;
+ } else {
+ error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred);
}
- /* Check permissions. */
- if ((cnp->cn_flags & ISLASTCN) && (cnp->cn_nameiop == DELETE ||
- cnp->cn_nameiop == RENAME)) {
- kauth_action_t action = 0;
-
- /* This is the file-system's decision. */
- if ((dnode->tn_mode & S_ISTXT) != 0 &&
- kauth_cred_geteuid(cnp->cn_cred) != dnode->tn_uid &&
- kauth_cred_geteuid(cnp->cn_cred) != tnode->tn_uid)
- error = EPERM;
- else
- error = 0;
+ if (cnp->cn_nameiop == DELETE) {
+ action |= KAUTH_VNODE_DELETE;
+ } else {
+ KASSERT(cnp->cn_nameiop == RENAME);
+ action |= KAUTH_VNODE_RENAME;
+ }
+ error = kauth_authorize_vnode(cnp->cn_cred,
+ action, *vpp, dvp, error);
Home |
Main Index |
Thread Index |
Old Index