X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/0b4e3aa066abc0728aacb4bbeb86f53f9737156e..3e170ce000f1506b7b5d2c5c7faec85ceabb573d:/bsd/miscfs/devfs/devfsdefs.h diff --git a/bsd/miscfs/devfs/devfsdefs.h b/bsd/miscfs/devfs/devfsdefs.h index 6f5ef57a9..79e99f512 100644 --- a/bsd/miscfs/devfs/devfsdefs.h +++ b/bsd/miscfs/devfs/devfsdefs.h @@ -1,23 +1,29 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * Copyright 1997,1998 Julian Elischer. All rights reserved. @@ -46,6 +52,12 @@ * * devfsdefs.h */ +/* + * NOTICE: This file was modified by McAfee Research in 2004 to introduce + * support for mandatory and extensible security protections. This notice + * is included in support of clause 2.2 (b) of the Apple Public License, + * Version 2.0. + */ /* * HISTORY @@ -55,7 +67,15 @@ * Renamed structures/elements to clarify usage in code. */ +#ifndef __DEVFS_DEVFSDEFS_H__ +#define __DEVFS_DEVFSDEFS_H__ + +#include +#include + +__BEGIN_DECLS +#ifdef __APPLE_API_PRIVATE #define DEVMAXNAMESIZE 32 /* XXX */ #define DEVMAXPATHSIZE 128 /* XXX */ @@ -64,6 +84,9 @@ typedef enum { DEV_BDEV, DEV_CDEV, DEV_SLNK, +#if FDESC + DEV_DEVFD +#endif /* FDESC */ } devfstype_t; extern int (**devfs_vnodeop_p)(void *); /* our own vector array for dirs */ @@ -96,16 +119,23 @@ union devnode_type { }Slnk; }; -#define DN_ACCESS 0x0001 /* Access time update request. */ -#define DN_CHANGE 0x0002 /* Inode change time update request. */ -#define DN_UPDATE 0x0004 /* Modification time update request. */ -#define DN_MODIFIED 0x0008 /* Inode has been modified. */ -#define DN_RENAME 0x0010 /* Inode is being renamed. */ - +#define DEV_MAX_VNODE_RETRY 8 /* Max number of retries when we try to + get a vnode for the devnode */ struct devnode { devfstype_t dn_type; - int dn_flags; + /* + * Number of vnodes that point to this devnode. Note, we do not + * add another reference for a lookup which finds an existing + * vnode; a reference is added when a vnode is created and removed + * when a vnode is reclaimed. A devnode will not be freed while + * there are outstanding references. A refcount can be added to + * prevent the free of a devnode in situations where there is not + * guaranteed to be a vnode holding a ref, but it is important to + * make sure that a deferred delete eventually happens if it is + * blocked behind that reference. + */ + int dn_refcount; u_short dn_mode; uid_t dn_uid; gid_t dn_gid; @@ -118,13 +148,23 @@ struct devnode struct vnode * dn_vn; /* address of last vnode that represented us */ int dn_len; /* of any associated info (e.g. dir data) */ devdirent_t * dn_linklist;/* circular list of hardlinks to this node */ - devdirent_t * dn_last_lookup; /* name I was last looked up from */ devnode_t * dn_nextsibling; /* the list of equivalent nodes */ devnode_t * * dn_prevsiblingp;/* backpointer for the above */ devnode_type_t dn_typeinfo; - int dn_delete; /* mark for deletion */ + int dn_change; + int dn_update; + int dn_access; + int dn_lflags; + ino_t dn_ino; + int (*dn_clone)(dev_t dev, int action); /* get minor # */ + struct label * dn_label; /* security label */ }; +#define DN_DELETE 0x02 +#define DN_CREATE 0x04 +#define DN_CREATEWAIT 0x08 + + struct devdirent { /*-----------------------directory entry fields-------------*/ @@ -138,8 +178,9 @@ struct devdirent }; extern devdirent_t * dev_root; -extern struct lock__bsd__ devfs_lock; extern struct devfs_stats devfs_stats; +extern lck_mtx_t devfs_mutex; +extern lck_mtx_t devfs_attr_mutex; /* * Rules for front nodes: @@ -164,6 +205,7 @@ struct devfsmount */ #include #include +#include /* required for OSAddAtomic() */ //#define HIDDEN_MOUNTPOINT 1 @@ -172,111 +214,100 @@ struct devfsmount #define M_DEVFSNODE M_DEVFS #define M_DEVFSMNT M_DEVFS -static __inline__ void -getnanotime(struct timespec * t_p) -{ - struct timeval tv; - - microtime(&tv); - t_p->tv_sec = tv.tv_sec; - t_p->tv_nsec = tv.tv_usec * 1000; - return; -} - #define VTODN(vp) ((devnode_t *)(vp)->v_data) -extern void cache_purge(struct vnode *vp); /* vfs_cache.c */ -static __inline__ int -DEVFS_LOCK(struct proc * p) -{ - return (lockmgr(&devfs_lock, LK_EXCLUSIVE, NULL, p)); -} +#define DEVFS_LOCK() lck_mtx_lock(&devfs_mutex) +#define DEVFS_UNLOCK() lck_mtx_unlock(&devfs_mutex) -static __inline__ int -DEVFS_UNLOCK(struct proc * p) -{ - return (lockmgr(&devfs_lock, LK_RELEASE, NULL, p)); -} +#define DEVFS_ATTR_LOCK_SPIN() lck_mtx_lock_spin(&devfs_attr_mutex); +#define DEVFS_ATTR_UNLOCK() lck_mtx_unlock(&devfs_attr_mutex); +/* + * XXX all the (SInt32 *) casts below assume sizeof(int) == sizeof(long) + */ static __inline__ void -DEVFS_INCR_ENTRIES() +DEVFS_INCR_ENTRIES(void) { - devfs_stats.entries++; + OSAddAtomic(1, &devfs_stats.entries); } static __inline__ void -DEVFS_DECR_ENTRIES() +DEVFS_DECR_ENTRIES(void) { - devfs_stats.entries--; + OSAddAtomic(-1, &devfs_stats.entries); } static __inline__ void -DEVFS_INCR_NODES() +DEVFS_INCR_NODES(void) { - devfs_stats.nodes++; + OSAddAtomic(1, &devfs_stats.nodes); } static __inline__ void -DEVFS_DECR_NODES() +DEVFS_DECR_NODES(void) { - devfs_stats.nodes--; + OSAddAtomic(-1, &devfs_stats.nodes); } static __inline__ void -DEVFS_INCR_MOUNTS() +DEVFS_INCR_MOUNTS(void) { - devfs_stats.mounts++; + OSAddAtomic(1, &devfs_stats.mounts); } static __inline__ void -DEVFS_DECR_MOUNTS() +DEVFS_DECR_MOUNTS(void) { - devfs_stats.mounts--; + OSAddAtomic(-1, &devfs_stats.mounts); } static __inline__ void DEVFS_INCR_STRINGSPACE(int space) { - devfs_stats.stringspace += space; + OSAddAtomic(space, &devfs_stats.stringspace); } static __inline__ void DEVFS_DECR_STRINGSPACE(int space) { - devfs_stats.stringspace -= space; - if (devfs_stats.stringspace < 0) { - printf("DEVFS_DECR_STRINGSPACE: (%d - %d < 0)\n", - devfs_stats.stringspace + space, space); - devfs_stats.stringspace = 0; - } + OSAddAtomic(-space, &devfs_stats.stringspace); } -static __inline__ void -dn_times(devnode_t * dnp, struct timeval t1, struct timeval t2) -{ - if (dnp->dn_flags & (DN_ACCESS | DN_CHANGE | DN_UPDATE)) { - if (dnp->dn_flags & DN_ACCESS) { - dnp->dn_atime.tv_sec = t1.tv_sec; - dnp->dn_atime.tv_nsec = t1.tv_usec * 1000; - } - if (dnp->dn_flags & DN_UPDATE) { - dnp->dn_mtime.tv_sec = t2.tv_sec; - dnp->dn_mtime.tv_nsec = t2.tv_usec * 1000; - } - if (dnp->dn_flags & DN_CHANGE) { - dnp->dn_ctime.tv_sec = time.tv_sec; - dnp->dn_ctime.tv_nsec = time.tv_usec * 1000; - } - dnp->dn_flags &= ~(DN_ACCESS | DN_CHANGE | DN_UPDATE); - } - return; -} +/* + * Access, change, and modify times are protected by a separate lock, + * which allows tty times to be updated (no more than once per second) + * in the I/O path without too much fear of contention. + * + * For getattr, update times to current time if the last update was recent; + * preserve legacy behavior that frequent stats can yield sub-second resolutions. + * If the last time is old, however, we know that the event that triggered + * the need for an update was no more than 1s after the last update. In that case, + * use (last update + 1s) as the time, avoiding the illusion that last update happened + * much later than it really did. + */ +#define DEVFS_LAZY_UPDATE_SECONDS 1 + +#define DEVFS_UPDATE_CHANGE 0x1 +#define DEVFS_UPDATE_MOD 0x2 +#define DEVFS_UPDATE_ACCESS 0x4 static __inline__ void dn_copy_times(devnode_t * target, devnode_t * source) { + DEVFS_ATTR_LOCK_SPIN(); target->dn_atime = source->dn_atime; target->dn_mtime = source->dn_mtime; target->dn_ctime = source->dn_ctime; + DEVFS_ATTR_UNLOCK(); return; } + +#ifdef BSD_KERNEL_PRIVATE +int devfs_make_symlink(devnode_t *dir_p, char *name, int mode, char *target, devdirent_t **newent); +#endif /* BSD_KERNEL_PRIVATE */ + +#endif /* __APPLE_API_PRIVATE */ + +__END_DECLS + +#endif /* __DEVFS_DEVFSDEFS_H__ */