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