[BACK]Return to tmpfs.h CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / fs / tmpfs

Annotation of src/sys/fs/tmpfs/tmpfs.h, Revision 1.33.2.2

1.33.2.2! wrstuden    1: /*     $NetBSD: tmpfs.h,v 1.33.2.1 2008/06/23 04:31:49 wrstuden Exp $  */
1.1       jmmv        2:
                      3: /*
1.30      ad          4:  * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
1.1       jmmv        5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
1.6       jmmv        8:  * by Julio M. Merino Vidal, developed as part of Google's Summer of Code
                      9:  * 2005 program.
1.1       jmmv       10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     21:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     22:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     23:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     24:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     25:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     26:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     27:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     28:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     29:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     30:  * POSSIBILITY OF SUCH DAMAGE.
                     31:  */
                     32:
1.10      christos   33: #ifndef _FS_TMPFS_TMPFS_H_
                     34: #define _FS_TMPFS_TMPFS_H_
1.1       jmmv       35:
                     36: #include <sys/dirent.h>
                     37: #include <sys/mount.h>
                     38: #include <sys/queue.h>
                     39: #include <sys/vnode.h>
                     40:
1.33.2.2! wrstuden   41: /* --------------------------------------------------------------------- */
        !            42: /* For the kernel and anyone who likes peeking into kernel memory        */
        !            43: /* --------------------------------------------------------------------- */
        !            44:
1.20      yamt       45: #if defined(_KERNEL)
1.1       jmmv       46: #include <fs/tmpfs/tmpfs_pool.h>
1.20      yamt       47: #endif /* defined(_KERNEL) */
1.1       jmmv       48:
                     49: /* --------------------------------------------------------------------- */
                     50:
                     51: /*
1.6       jmmv       52:  * Internal representation of a tmpfs directory entry.
1.1       jmmv       53:  */
                     54: struct tmpfs_dirent {
                     55:        TAILQ_ENTRY(tmpfs_dirent)       td_entries;
1.6       jmmv       56:
                     57:        /* Length of the name stored in this directory entry.  This avoids
                     58:         * the need to recalculate it every time the name is used. */
1.1       jmmv       59:        uint16_t                        td_namelen;
1.6       jmmv       60:
                     61:        /* The name of the entry, allocated from a string pool.  This
                     62:        * string is not required to be zero-terminated; therefore, the
                     63:        * td_namelen field must always be used when accessing its value. */
1.1       jmmv       64:        char *                          td_name;
1.6       jmmv       65:
                     66:        /* Pointer to the node this entry refers to. */
1.1       jmmv       67:        struct tmpfs_node *             td_node;
                     68: };
1.6       jmmv       69:
                     70: /* A directory in tmpfs holds a sorted list of directory entries, which in
                     71:  * turn point to other files (which can be directories themselves).
                     72:  *
                     73:  * In tmpfs, this list is managed by a tail queue, whose head is defined by
                     74:  * the struct tmpfs_dir type.
                     75:  *
                     76:  * It is imporant to notice that directories do not have entries for . and
                     77:  * .. as other file systems do.  These can be generated when requested
                     78:  * based on information available by other means, such as the pointer to
                     79:  * the node itself in the former case or the pointer to the parent directory
                     80:  * in the latter case.  This is done to simplify tmpfs's code and, more
                     81:  * importantly, to remove redundancy. */
1.1       jmmv       82: TAILQ_HEAD(tmpfs_dir, tmpfs_dirent);
                     83:
1.22      jmmv       84: /* Each entry in a directory has a cookie that identifies it.  Cookies
                     85:  * supersede offsets within directories because, given how tmpfs stores
                     86:  * directories in memory, there is no such thing as an offset.  (Emulating
                     87:  * a real offset could be very difficult.)
1.31      jmmv       88:  *
1.22      jmmv       89:  * The '.', '..' and the end of directory markers have fixed cookies which
                     90:  * cannot collide with the cookies generated by other entries.  The cookies
                     91:  * fot the other entries are generated based on the memory address on which
                     92:  * stores their information is stored.
                     93:  *
                     94:  * Ideally, using the entry's memory pointer as the cookie would be enough
                     95:  * to represent it and it wouldn't cause collisions in any system.
                     96:  * Unfortunately, this results in "offsets" with very large values which
                     97:  * later raise problems in the Linux compatibility layer (and maybe in other
                     98:  * places) as described in PR kern/32034.  Hence we need to workaround this
                     99:  * with a rather ugly hack.
                    100:  *
                    101:  * Linux 32-bit binaries, unless built with _FILE_OFFSET_BITS=64, have off_t
                    102:  * set to 'long', which is a 32-bit *signed* long integer.  Regardless of
                    103:  * the macro value, GLIBC (2.3 at least) always uses the getdents64
                    104:  * system call (when calling readdir) which internally returns off64_t
                    105:  * offsets.  In order to make 32-bit binaries work, *GLIBC* converts the
                    106:  * 64-bit values returned by the kernel to 32-bit ones and aborts with
                    107:  * EOVERFLOW if the conversion results in values that won't fit in 32-bit
                    108:  * integers (which it assumes is because the directory is extremely large).
                    109:  * This wouldn't cause problems if we were dealing with unsigned integers,
                    110:  * but as we have signed integers, this check fails due to sign expansion.
                    111:  *
                    112:  * For example, consider that the kernel returns the 0xc1234567 cookie to
                    113:  * userspace in a off64_t integer.  Later on, GLIBC casts this value to
                    114:  * off_t (remember, signed) with code similar to:
                    115:  *     system call returns the offset in kernel_value;
                    116:  *     off_t casted_value = kernel_value;
                    117:  *     if (sizeof(off_t) != sizeof(off64_t) &&
                    118:  *         kernel_value != casted_value)
                    119:  *             error!
                    120:  * In this case, casted_value still has 0xc1234567, but when it is compared
                    121:  * for equality against kernel_value, it is promoted to a 64-bit integer and
                    122:  * becomes 0xffffffffc1234567, which is different than 0x00000000c1234567.
                    123:  * Then, GLIBC assumes this is because the directory is very large.
                    124:  *
                    125:  * Given that all the above happens in user-space, we have no control over
                    126:  * it; therefore we must workaround the issue here.  We do this by
                    127:  * truncating the pointer value to a 32-bit integer and hope that there
                    128:  * won't be collisions.  In fact, this will not cause any problems in
                    129:  * 32-bit platforms but some might arise in 64-bit machines (I'm not sure
                    130:  * if they can happen at all in practice).
                    131:  *
                    132:  * XXX A nicer solution shall be attempted. */
1.23      jmmv      133: #if defined(_KERNEL)
1.4       yamt      134: #define        TMPFS_DIRCOOKIE_DOT     0
                    135: #define        TMPFS_DIRCOOKIE_DOTDOT  1
                    136: #define        TMPFS_DIRCOOKIE_EOF     2
1.22      jmmv      137: static __inline
                    138: off_t
                    139: tmpfs_dircookie(struct tmpfs_dirent *de)
                    140: {
                    141:        off_t cookie;
                    142:
                    143:        cookie = ((off_t)(uintptr_t)de >> 1) & 0x7FFFFFFF;
                    144:        KASSERT(cookie != TMPFS_DIRCOOKIE_DOT);
                    145:        KASSERT(cookie != TMPFS_DIRCOOKIE_DOTDOT);
                    146:        KASSERT(cookie != TMPFS_DIRCOOKIE_EOF);
                    147:
                    148:        return cookie;
                    149: }
1.23      jmmv      150: #endif /* defined(_KERNEL) */
1.4       yamt      151:
1.1       jmmv      152: /* --------------------------------------------------------------------- */
                    153:
                    154: /*
1.6       jmmv      155:  * Internal representation of a tmpfs file system node.
                    156:  *
                    157:  * This structure is splitted in two parts: one holds attributes common
                    158:  * to all file types and the other holds data that is only applicable to
                    159:  * a particular type.  The code must be careful to only access those
                    160:  * attributes that are actually allowed by the node's type.
1.1       jmmv      161:  */
                    162: struct tmpfs_node {
1.6       jmmv      163:        /* Doubly-linked list entry which links all existing nodes for a
                    164:         * single file system.  This is provided to ease the removal of
                    165:         * all nodes during the unmount operation. */
1.1       jmmv      166:        LIST_ENTRY(tmpfs_node)  tn_entries;
                    167:
1.6       jmmv      168:        /* The node's type.  Any of 'VBLK', 'VCHR', 'VDIR', 'VFIFO',
                    169:         * 'VLNK', 'VREG' and 'VSOCK' is allowed.  The usage of vnode
                    170:         * types instead of a custom enumeration is to make things simpler
                    171:         * and faster, as we do not need to convert between two types. */
1.1       jmmv      172:        enum vtype              tn_type;
1.6       jmmv      173:
                    174:        /* Node identifier. */
1.1       jmmv      175:        ino_t                   tn_id;
                    176:
1.6       jmmv      177:        /* Node's internal status.  This is used by several file system
                    178:         * operations to do modifications to the node in a delayed
                    179:         * fashion. */
                    180:        int                     tn_status;
1.1       jmmv      181: #define        TMPFS_NODE_ACCESSED     (1 << 1)
                    182: #define        TMPFS_NODE_MODIFIED     (1 << 2)
                    183: #define        TMPFS_NODE_CHANGED      (1 << 3)
                    184:
1.6       jmmv      185:        /* The node size.  It does not necessarily match the real amount
                    186:         * of memory consumed by it. */
1.1       jmmv      187:        off_t                   tn_size;
                    188:
1.6       jmmv      189:        /* Generic node attributes. */
1.1       jmmv      190:        uid_t                   tn_uid;
                    191:        gid_t                   tn_gid;
                    192:        mode_t                  tn_mode;
                    193:        int                     tn_flags;
                    194:        nlink_t                 tn_links;
                    195:        struct timespec         tn_atime;
                    196:        struct timespec         tn_mtime;
                    197:        struct timespec         tn_ctime;
                    198:        struct timespec         tn_birthtime;
                    199:        unsigned long           tn_gen;
                    200:
1.8       jmmv      201:        /* Head of byte-level lock list (used by tmpfs_advlock). */
                    202:        struct lockf *          tn_lockf;
                    203:
1.6       jmmv      204:        /* As there is a single vnode for each active file within the
                    205:         * system, care has to be taken to avoid allocating more than one
                    206:         * vnode per file.  In order to do this, a bidirectional association
                    207:         * is kept between vnodes and nodes.
                    208:         *
                    209:         * Whenever a vnode is allocated, its v_data field is updated to
                    210:         * point to the node it references.  At the same time, the node's
                    211:         * tn_vnode field is modified to point to the new vnode representing
                    212:         * it.  Further attempts to allocate a vnode for this same node will
                    213:         * result in returning a new reference to the value stored in
                    214:         * tn_vnode.
                    215:         *
                    216:         * May be NULL when the node is unused (that is, no vnode has been
                    217:         * allocated for it or it has been reclaimed). */
1.30      ad        218:        kmutex_t                tn_vlock;
1.1       jmmv      219:        struct vnode *          tn_vnode;
                    220:
                    221:        union {
                    222:                /* Valid when tn_type == VBLK || tn_type == VCHR. */
                    223:                struct {
                    224:                        dev_t                   tn_rdev;
1.15      jmmv      225:                } tn_dev;
1.1       jmmv      226:
                    227:                /* Valid when tn_type == VDIR. */
                    228:                struct {
1.6       jmmv      229:                        /* Pointer to the parent directory.  The root
                    230:                         * directory has a pointer to itself in this field;
                    231:                         * this property identifies the root node. */
1.1       jmmv      232:                        struct tmpfs_node *     tn_parent;
1.6       jmmv      233:
                    234:                        /* Head of a tail-queue that links the contents of
                    235:                         * the directory together.  See above for a
                    236:                         * description of its contents. */
1.1       jmmv      237:                        struct tmpfs_dir        tn_dir;
                    238:
1.6       jmmv      239:                        /* Number and pointer of the first directory entry
                    240:                         * returned by the readdir operation if it were
                    241:                         * called again to continue reading data from the
                    242:                         * same directory as before.  This is used to speed
                    243:                         * up reads of long directories, assuming that no
                    244:                         * more than one read is in progress at a given time.
                    245:                         * Otherwise, these values are discarded and a linear
                    246:                         * scan is performed from the beginning up to the
                    247:                         * point where readdir starts returning values. */
1.4       yamt      248:                        off_t                   tn_readdir_lastn;
1.1       jmmv      249:                        struct tmpfs_dirent *   tn_readdir_lastp;
1.15      jmmv      250:                } tn_dir;
1.1       jmmv      251:
                    252:                /* Valid when tn_type == VLNK. */
1.15      jmmv      253:                struct tn_lnk {
1.6       jmmv      254:                        /* The link's target, allocated from a string pool. */
1.1       jmmv      255:                        char *                  tn_link;
1.15      jmmv      256:                } tn_lnk;
1.1       jmmv      257:
                    258:                /* Valid when tn_type == VREG. */
1.15      jmmv      259:                struct tn_reg {
1.6       jmmv      260:                        /* The contents of regular files stored in a tmpfs
                    261:                         * file system are represented by a single anonymous
                    262:                         * memory object (aobj, for short).  The aobj provides
                    263:                         * direct access to any position within the file,
                    264:                         * because its contents are always mapped in a
                    265:                         * contiguous region of virtual memory.  It is a task
                    266:                         * of the memory management subsystem (see uvm(9)) to
                    267:                         * issue the required page ins or page outs whenever
                    268:                         * a position within the file is accessed. */
1.1       jmmv      269:                        struct uvm_object *     tn_aobj;
                    270:                        size_t                  tn_aobj_pages;
1.15      jmmv      271:                } tn_reg;
                    272:        } tn_spec;
1.1       jmmv      273: };
1.20      yamt      274:
                    275: #if defined(_KERNEL)
1.1       jmmv      276: LIST_HEAD(tmpfs_node_list, tmpfs_node);
                    277:
                    278: /* --------------------------------------------------------------------- */
                    279:
                    280: /*
1.6       jmmv      281:  * Internal representation of a tmpfs mount point.
1.1       jmmv      282:  */
                    283: struct tmpfs_mount {
1.6       jmmv      284:        /* Maximum number of memory pages available for use by the file
                    285:         * system, set during mount time.  This variable must never be
1.24      jmmv      286:         * used directly as it may be bigger than the current amount of
1.6       jmmv      287:         * free memory; in the extreme case, it will hold the SIZE_MAX
                    288:         * value.  Instead, use the TMPFS_PAGES_MAX macro. */
1.32      jmmv      289:        unsigned int            tm_pages_max;
1.6       jmmv      290:
                    291:        /* Number of pages in use by the file system.  Cannot be bigger
                    292:         * than the value returned by TMPFS_PAGES_MAX in any case. */
1.32      jmmv      293:        unsigned int            tm_pages_used;
1.1       jmmv      294:
1.6       jmmv      295:        /* Pointer to the node representing the root directory of this
                    296:         * file system. */
1.1       jmmv      297:        struct tmpfs_node *     tm_root;
                    298:
1.6       jmmv      299:        /* Maximum number of possible nodes for this file system; set
                    300:         * during mount time.  We need a hard limit on the maximum number
                    301:         * of nodes to avoid allocating too much of them; their objects
                    302:         * cannot be released until the file system is unmounted.
                    303:         * Otherwise, we could easily run out of memory by creating lots
                    304:         * of empty files and then simply removing them. */
1.32      jmmv      305:        unsigned int            tm_nodes_max;
1.6       jmmv      306:
                    307:        /* Number of nodes currently allocated.  This number only grows.
                    308:         * When it reaches tm_nodes_max, no more new nodes can be allocated.
                    309:         * Of course, the old, unused ones can be reused. */
1.32      jmmv      310:        unsigned int            tm_nodes_cnt;
1.6       jmmv      311:
1.30      ad        312:        /* Node list. */
                    313:        kmutex_t                tm_lock;
                    314:        struct tmpfs_node_list  tm_nodes;
1.1       jmmv      315:
1.6       jmmv      316:        /* Pools used to store file system meta data.  These are not shared
                    317:         * across several instances of tmpfs for the reasons described in
                    318:         * tmpfs_pool.c. */
1.1       jmmv      319:        struct tmpfs_pool       tm_dirent_pool;
                    320:        struct tmpfs_pool       tm_node_pool;
                    321:        struct tmpfs_str_pool   tm_str_pool;
                    322: };
                    323:
                    324: /* --------------------------------------------------------------------- */
                    325:
                    326: /*
                    327:  * This structure maps a file identifier to a tmpfs node.  Used by the
                    328:  * NFS code.
                    329:  */
                    330: struct tmpfs_fid {
                    331:        uint16_t                tf_len;
                    332:        uint16_t                tf_pad;
1.18      riz       333:        uint32_t                tf_gen;
1.1       jmmv      334:        ino_t                   tf_id;
                    335: };
                    336:
                    337: /* --------------------------------------------------------------------- */
                    338:
                    339: /*
                    340:  * Prototypes for tmpfs_subr.c.
                    341:  */
                    342:
                    343: int    tmpfs_alloc_node(struct tmpfs_mount *, enum vtype,
                    344:            uid_t uid, gid_t gid, mode_t mode, struct tmpfs_node *,
1.29      pooka     345:            char *, dev_t, struct tmpfs_node **);
1.1       jmmv      346: void   tmpfs_free_node(struct tmpfs_mount *, struct tmpfs_node *);
                    347: int    tmpfs_alloc_dirent(struct tmpfs_mount *, struct tmpfs_node *,
                    348:            const char *, uint16_t, struct tmpfs_dirent **);
                    349: void   tmpfs_free_dirent(struct tmpfs_mount *, struct tmpfs_dirent *,
1.25      thorpej   350:            bool);
1.1       jmmv      351: int    tmpfs_alloc_vp(struct mount *, struct tmpfs_node *, struct vnode **);
                    352: void   tmpfs_free_vp(struct vnode *);
                    353: int    tmpfs_alloc_file(struct vnode *, struct vnode **, struct vattr *,
                    354:            struct componentname *, char *);
                    355: void   tmpfs_dir_attach(struct vnode *, struct tmpfs_dirent *);
                    356: void   tmpfs_dir_detach(struct vnode *, struct tmpfs_dirent *);
                    357: struct tmpfs_dirent *  tmpfs_dir_lookup(struct tmpfs_node *node,
                    358:                            struct componentname *cnp);
                    359: int    tmpfs_dir_getdotdent(struct tmpfs_node *, struct uio *);
                    360: int    tmpfs_dir_getdotdotdent(struct tmpfs_node *, struct uio *);
1.4       yamt      361: struct tmpfs_dirent *  tmpfs_dir_lookupbycookie(struct tmpfs_node *, off_t);
                    362: int    tmpfs_dir_getdents(struct tmpfs_node *, struct uio *, off_t *);
1.1       jmmv      363: int    tmpfs_reg_resize(struct vnode *, off_t);
1.25      thorpej   364: size_t tmpfs_mem_info(bool);
1.21      ad        365: int    tmpfs_chflags(struct vnode *, int, kauth_cred_t, struct lwp *);
                    366: int    tmpfs_chmod(struct vnode *, mode_t, kauth_cred_t, struct lwp *);
                    367: int    tmpfs_chown(struct vnode *, uid_t, gid_t, kauth_cred_t, struct lwp *);
                    368: int    tmpfs_chsize(struct vnode *, u_quad_t, kauth_cred_t, struct lwp *);
1.33.2.1  wrstuden  369: int    tmpfs_chtimes(struct vnode *, const struct timespec *,
                    370:     const struct timespec *, const struct timespec *, int, kauth_cred_t,
                    371:     struct lwp *);
1.7       yamt      372: void   tmpfs_itimes(struct vnode *, const struct timespec *,
1.33.2.1  wrstuden  373:            const struct timespec *, const struct timespec *);
1.1       jmmv      374:
1.9       yamt      375: void   tmpfs_update(struct vnode *, const struct timespec *,
1.33.2.1  wrstuden  376:            const struct timespec *, const struct timespec *, int);
1.9       yamt      377: int    tmpfs_truncate(struct vnode *, off_t);
                    378:
1.1       jmmv      379: /* --------------------------------------------------------------------- */
                    380:
                    381: /*
                    382:  * Convenience macros to simplify some logical expressions.
                    383:  */
                    384: #define IMPLIES(a, b) (!(a) || (b))
                    385: #define IFF(a, b) (IMPLIES(a, b) && IMPLIES(b, a))
                    386:
                    387: /* --------------------------------------------------------------------- */
                    388:
                    389: /*
                    390:  * Checks that the directory entry pointed by 'de' matches the name 'name'
                    391:  * with a length of 'len'.
                    392:  */
                    393: #define TMPFS_DIRENT_MATCHES(de, name, len) \
                    394:     (de->td_namelen == (uint16_t)len && \
                    395:     memcmp((de)->td_name, (name), (de)->td_namelen) == 0)
                    396:
                    397: /* --------------------------------------------------------------------- */
                    398:
                    399: /*
                    400:  * Ensures that the node pointed by 'node' is a directory and that its
                    401:  * contents are consistent with respect to directories.
                    402:  */
                    403: #define TMPFS_VALIDATE_DIR(node) \
                    404:     KASSERT((node)->tn_type == VDIR); \
1.4       yamt      405:     KASSERT((node)->tn_size % sizeof(struct tmpfs_dirent) == 0); \
1.15      jmmv      406:     KASSERT((node)->tn_spec.tn_dir.tn_readdir_lastp == NULL || \
1.22      jmmv      407:         tmpfs_dircookie((node)->tn_spec.tn_dir.tn_readdir_lastp) == \
1.15      jmmv      408:         (node)->tn_spec.tn_dir.tn_readdir_lastn);
1.1       jmmv      409:
                    410: /* --------------------------------------------------------------------- */
                    411:
                    412: /*
                    413:  * Memory management stuff.
                    414:  */
                    415:
                    416: /* Amount of memory pages to reserve for the system (e.g., to not use by
                    417:  * tmpfs).
                    418:  * XXX: Should this be tunable through sysctl, for instance? */
                    419: #define TMPFS_PAGES_RESERVED (4 * 1024 * 1024 / PAGE_SIZE)
                    420:
1.6       jmmv      421: /* Returns the maximum size allowed for a tmpfs file system.  This macro
                    422:  * must be used instead of directly retrieving the value from tm_pages_max.
                    423:  * The reason is that the size of a tmpfs file system is dynamic: it lets
                    424:  * the user store files as long as there is enough free memory (including
                    425:  * physical memory and swap space).  Therefore, the amount of memory to be
                    426:  * used is either the limit imposed by the user during mount time or the
                    427:  * amount of available memory, whichever is lower.  To avoid consuming all
                    428:  * the memory for a given mount point, the system will always reserve a
                    429:  * minimum of TMPFS_PAGES_RESERVED pages, which is also taken into account
                    430:  * by this macro (see above). */
1.16      perry     431: static __inline size_t
1.1       jmmv      432: TMPFS_PAGES_MAX(struct tmpfs_mount *tmp)
                    433: {
                    434:        size_t freepages;
                    435:
1.26      thorpej   436:        freepages = tmpfs_mem_info(false);
1.1       jmmv      437:        if (freepages < TMPFS_PAGES_RESERVED)
                    438:                freepages = 0;
                    439:        else
                    440:                freepages -= TMPFS_PAGES_RESERVED;
                    441:
                    442:        return MIN(tmp->tm_pages_max, freepages + tmp->tm_pages_used);
                    443: }
                    444:
1.6       jmmv      445: /* Returns the available space for the given file system. */
1.30      ad        446: #define TMPFS_PAGES_AVAIL(tmp)         \
                    447:     ((ssize_t)(TMPFS_PAGES_MAX(tmp) - (tmp)->tm_pages_used))
1.1       jmmv      448:
                    449: /* --------------------------------------------------------------------- */
                    450:
                    451: /*
                    452:  * Macros/functions to convert from generic data structures to tmpfs
                    453:  * specific ones.
                    454:  */
                    455:
1.16      perry     456: static __inline
1.1       jmmv      457: struct tmpfs_mount *
                    458: VFS_TO_TMPFS(struct mount *mp)
                    459: {
                    460:        struct tmpfs_mount *tmp;
                    461:
1.14      christos  462: #ifdef KASSERT
1.1       jmmv      463:        KASSERT((mp) != NULL && (mp)->mnt_data != NULL);
1.14      christos  464: #endif
1.1       jmmv      465:        tmp = (struct tmpfs_mount *)(mp)->mnt_data;
                    466:        return tmp;
                    467: }
                    468:
1.20      yamt      469: #endif /* defined(_KERNEL) */
                    470:
1.16      perry     471: static __inline
1.1       jmmv      472: struct tmpfs_node *
                    473: VP_TO_TMPFS_NODE(struct vnode *vp)
                    474: {
                    475:        struct tmpfs_node *node;
                    476:
1.14      christos  477: #ifdef KASSERT
1.1       jmmv      478:        KASSERT((vp) != NULL && (vp)->v_data != NULL);
1.14      christos  479: #endif
1.1       jmmv      480:        node = (struct tmpfs_node *)vp->v_data;
                    481:        return node;
                    482: }
                    483:
1.20      yamt      484: #if defined(_KERNEL)
                    485:
1.16      perry     486: static __inline
1.1       jmmv      487: struct tmpfs_node *
                    488: VP_TO_TMPFS_DIR(struct vnode *vp)
                    489: {
                    490:        struct tmpfs_node *node;
                    491:
                    492:        node = VP_TO_TMPFS_NODE(vp);
1.14      christos  493: #ifdef KASSERT
1.1       jmmv      494:        TMPFS_VALIDATE_DIR(node);
1.14      christos  495: #endif
1.1       jmmv      496:        return node;
                    497: }
                    498:
1.20      yamt      499: #endif /* defined(_KERNEL) */
1.10      christos  500: #endif /* _FS_TMPFS_TMPFS_H_ */

CVSweb <webmaster@jp.NetBSD.org>