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_alloc_node/tmpfs_free_node: move inode ...



details:   https://anonhg.NetBSD.org/src/rev/2785f1af7962
branches:  trunk
changeset: 765293:2785f1af7962
user:      rmind <rmind%NetBSD.org@localhost>
date:      Tue May 24 01:09:47 2011 +0000

description:
- tmpfs_alloc_node/tmpfs_free_node: move inode limiting into tmpfs_node_get()
  and tmpfs_node_put(), update outdated/wrong comments and move/add asserts.
- tmpfs_mount: check for the version of arguments a bit earlier.

diffstat:

 sys/fs/tmpfs/tmpfs_mem.c    |   14 ++++-
 sys/fs/tmpfs/tmpfs_subr.c   |  105 ++++++++++++-------------------------------
 sys/fs/tmpfs/tmpfs_vfsops.c |   22 +++-----
 3 files changed, 50 insertions(+), 91 deletions(-)

diffs (truncated from 339 to 300 lines):

diff -r 921674fcd8be -r 2785f1af7962 sys/fs/tmpfs/tmpfs_mem.c
--- a/sys/fs/tmpfs/tmpfs_mem.c  Mon May 23 23:13:10 2011 +0000
+++ b/sys/fs/tmpfs/tmpfs_mem.c  Tue May 24 01:09:47 2011 +0000
@@ -1,9 +1,12 @@
-/*     $NetBSD: tmpfs_mem.c,v 1.3 2011/05/19 03:21:23 rmind Exp $      */
+/*     $NetBSD: tmpfs_mem.c,v 1.4 2011/05/24 01:09:47 rmind Exp $      */
 
 /*
- * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Mindaugas Rasiukevicius.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -32,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_mem.c,v 1.3 2011/05/19 03:21:23 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_mem.c,v 1.4 2011/05/24 01:09:47 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -161,6 +164,10 @@
 tmpfs_node_get(struct tmpfs_mount *mp)
 {
 
+       if (atomic_inc_uint_nv(&mp->tm_nodes_cnt) >= mp->tm_nodes_max) {
+               atomic_dec_uint(&mp->tm_nodes_cnt);
+               return NULL;
+       }
        if (!tmpfs_mem_incr(mp, sizeof(struct tmpfs_node))) {
                return NULL;
        }
@@ -171,6 +178,7 @@
 tmpfs_node_put(struct tmpfs_mount *mp, struct tmpfs_node *tn)
 {
 
+       atomic_dec_uint(&mp->tm_nodes_cnt);
        tmpfs_mem_decr(mp, sizeof(struct tmpfs_node));
        pool_put(&tmpfs_node_pool, tn);
 }
diff -r 921674fcd8be -r 2785f1af7962 sys/fs/tmpfs/tmpfs_subr.c
--- a/sys/fs/tmpfs/tmpfs_subr.c Mon May 23 23:13:10 2011 +0000
+++ b/sys/fs/tmpfs/tmpfs_subr.c Tue May 24 01:09:47 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tmpfs_subr.c,v 1.64 2011/05/22 04:20:50 rmind Exp $    */
+/*     $NetBSD: tmpfs_subr.c,v 1.65 2011/05/24 01:09:47 rmind Exp $    */
 
 /*
  * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.64 2011/05/22 04:20:50 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.65 2011/05/24 01:09:47 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/dirent.h>
@@ -61,29 +61,9 @@
 #include <fs/tmpfs/tmpfs_specops.h>
 #include <fs/tmpfs/tmpfs_vnops.h>
 
-/* --------------------------------------------------------------------- */
-
 /*
- * Allocates a new node of type 'type' inside the 'tmp' mount point, with
- * its owner set to 'uid', its group to 'gid' and its mode set to 'mode',
- * using the credentials of the process 'p'.
- *
- * If the node type is set to 'VDIR', then the parent parameter must point
- * to the parent directory of the node being created.  It may only be NULL
- * while allocating the root node.
- *
- * If the node type is set to 'VBLK' or 'VCHR', then the rdev parameter
- * specifies the device the node represents.
- *
- * If the node type is set to 'VLNK', then the parameter target specifies
- * the file name of the target file for the symbolic link that is being
- * created.
- *
- * Note that new nodes are retrieved from the available list if it has
- * items or, if it is empty, from the node pool as long as there is enough
- * space to create them.
- *
- * Returns zero on success or an appropriate error code on failure.
+ * tmpfs_alloc_node: allocate a new inode of a specified type and
+ * insert it into the list of specified mount point.
  */
 int
 tmpfs_alloc_node(struct tmpfs_mount *tmp, enum vtype type,
@@ -92,24 +72,8 @@
 {
        struct tmpfs_node *nnode;
 
-       /* If the root directory of the 'tmp' file system is not yet
-        * allocated, this must be the request to do it. */
-       KASSERT(IMPLIES(tmp->tm_root == NULL, parent == NULL && type == VDIR));
-
-       KASSERT(IFF(type == VLNK, target != NULL));
-       KASSERT(IFF(type == VBLK || type == VCHR, rdev != VNOVAL));
-
-       KASSERT(uid != VNOVAL && gid != VNOVAL && mode != VNOVAL);
-
-       nnode = NULL;
-       if (atomic_inc_uint_nv(&tmp->tm_nodes_cnt) >= tmp->tm_nodes_max) {
-               atomic_dec_uint(&tmp->tm_nodes_cnt);
-               return ENOSPC;
-       }
-
        nnode = tmpfs_node_get(tmp);
        if (nnode == NULL) {
-               atomic_dec_uint(&tmp->tm_nodes_cnt);
                return ENOSPC;
        }
 
@@ -127,26 +91,35 @@
        nnode->tn_status = 0;
        nnode->tn_flags = 0;
        nnode->tn_links = 0;
+       nnode->tn_lockf = NULL;
+       nnode->tn_vnode = NULL;
 
        vfs_timestamp(&nnode->tn_atime);
        nnode->tn_birthtime = nnode->tn_atime;
        nnode->tn_ctime = nnode->tn_atime;
        nnode->tn_mtime = nnode->tn_atime;
 
+       KASSERT(uid != VNOVAL && gid != VNOVAL && mode != VNOVAL);
        nnode->tn_uid = uid;
        nnode->tn_gid = gid;
        nnode->tn_mode = mode;
-       nnode->tn_lockf = NULL;
-       nnode->tn_vnode = NULL;
 
        /* Type-specific initialization. */
        switch (nnode->tn_type) {
        case VBLK:
        case VCHR:
+               /* Character/block special device. */
+               KASSERT(rdev != VNOVAL);
                nnode->tn_spec.tn_dev.tn_rdev = rdev;
                break;
+       case VDIR:
+               /*
+                * Directory.  Parent must be specified, unless allocating
+                * the root inode.
+                */
+               KASSERT(parent || tmp->tm_root == NULL);
+               KASSERT(parent != nnode);
 
-       case VDIR:
                TAILQ_INIT(&nnode->tn_spec.tn_dir.tn_dir);
                nnode->tn_spec.tn_dir.tn_parent =
                    (parent == NULL) ? nnode : parent;
@@ -154,14 +127,13 @@
                nnode->tn_spec.tn_dir.tn_readdir_lastp = NULL;
                nnode->tn_links++;
                break;
-
        case VFIFO:
-               /* FALLTHROUGH */
        case VSOCK:
                break;
+       case VLNK:
+               /* Symbolic link.  Target specifies the file name. */
+               KASSERT(target && strlen(target) < MAXPATHLEN);
 
-       case VLNK:
-               KASSERT(strlen(target) < MAXPATHLEN);
                nnode->tn_size = strlen(target);
                if (nnode->tn_size == 0) {
                        nnode->tn_spec.tn_lnk.tn_link = NULL;
@@ -170,21 +142,19 @@
                nnode->tn_spec.tn_lnk.tn_link =
                    tmpfs_strname_alloc(tmp, nnode->tn_size);
                if (nnode->tn_spec.tn_lnk.tn_link == NULL) {
-                       atomic_dec_uint(&tmp->tm_nodes_cnt);
                        tmpfs_node_put(tmp, nnode);
                        return ENOSPC;
                }
                memcpy(nnode->tn_spec.tn_lnk.tn_link, target, nnode->tn_size);
                break;
-
        case VREG:
+               /* Regular file.  Create an underlying UVM object. */
                nnode->tn_spec.tn_reg.tn_aobj =
                    uao_create(INT32_MAX - PAGE_SIZE, 0);
                nnode->tn_spec.tn_reg.tn_aobj_pages = 0;
                break;
-
        default:
-               KASSERT(0);
+               KASSERT(false);
        }
 
        mutex_init(&nnode->tn_vlock, MUTEX_DEFAULT, IPL_NONE);
@@ -197,24 +167,9 @@
        return 0;
 }
 
-/* --------------------------------------------------------------------- */
-
 /*
- * Destroys the node pointed to by node from the file system 'tmp'.
- * If the node does not belong to the given mount point, the results are
- * unpredicted.
- *
- * If the node references a directory; no entries are allowed because
- * their removal could need a recursive algorithm, something forbidden in
- * kernel space.  Furthermore, there is not need to provide such
- * functionality (recursive removal) because the only primitives offered
- * to the user are the removal of empty directories and the deletion of
- * individual files.
- *
- * Note that nodes are not really deleted; in fact, when a node has been
- * allocated, it cannot be deleted during the whole life of the file
- * system.  Instead, they are moved to the available list and remain there
- * until reused.
+ * tmpfs_free_node: remove the inode from a list in the mount point and
+ * destroy the inode structures.
  */
 void
 tmpfs_free_node(struct tmpfs_mount *tmp, struct tmpfs_node *node)
@@ -224,18 +179,18 @@
        mutex_enter(&tmp->tm_lock);
        LIST_REMOVE(node, tn_entries);
        mutex_exit(&tmp->tm_lock);
-       atomic_dec_uint(&tmp->tm_nodes_cnt);
 
        switch (node->tn_type) {
        case VLNK:
-               if (node->tn_size > 0)
+               if (node->tn_size > 0) {
                        tmpfs_strname_free(tmp, node->tn_spec.tn_lnk.tn_link,
                            node->tn_size);
+               }
                break;
        case VREG:
                /*
-                * Calculate the size of node data, decrease the used-memory
-                * counter, and destroy the memory object (if any).
+                * Calculate the size of inode data, decrease the used-memory
+                * counter, and destroy the unerlying UVM object (if any).
                 */
                objsz = PAGE_SIZE * node->tn_spec.tn_reg.tn_aobj_pages;
                if (objsz != 0) {
@@ -245,6 +200,10 @@
                        uao_detach(node->tn_spec.tn_reg.tn_aobj);
                }
                break;
+       case VDIR:
+               KASSERT(TAILQ_EMPTY(&node->tn_spec.tn_dir.tn_dir));
+               KASSERT(node->tn_spec.tn_dir.tn_parent || node == tmp->tm_root);
+               break;
        default:
                break;
        }
@@ -253,8 +212,6 @@
        tmpfs_node_put(tmp, node);
 }
 
-/* --------------------------------------------------------------------- */
-
 /*
  * Allocates a new directory entry for the node node with a name of name.
  * The new directory entry is returned in *de.
diff -r 921674fcd8be -r 2785f1af7962 sys/fs/tmpfs/tmpfs_vfsops.c
--- a/sys/fs/tmpfs/tmpfs_vfsops.c       Mon May 23 23:13:10 2011 +0000
+++ b/sys/fs/tmpfs/tmpfs_vfsops.c       Tue May 24 01:09:47 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tmpfs_vfsops.c,v 1.48 2011/05/19 03:21:23 rmind Exp $  */
+/*     $NetBSD: tmpfs_vfsops.c,v 1.49 2011/05/24 01:09:47 rmind Exp $  */
 
 /*
  * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_vfsops.c,v 1.48 2011/05/19 03:21:23 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_vfsops.c,v 1.49 2011/05/24 01:09:47 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -105,7 +105,9 @@
        ino_t nodes;
        int error;
 
-       if (*data_len < sizeof *args)
+       /* Validate the version. */
+       if (*data_len < sizeof(*args) ||
+           args->ta_version != TMPFS_ARGS_VERSION)
                return EINVAL;
 



Home | Main Index | Thread Index | Old Index