/* * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. * * 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. 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, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #ifndef _HFS_CNODE_H_ #define _HFS_CNODE_H_ #include #ifdef KERNEL #ifdef __APPLE_API_PRIVATE #include #include #include #include #include #include #include #include /* * The filefork is used to represent an HFS file fork (data or resource). * Reading or writing any of these fields requires holding cnode lock. */ struct filefork { struct cnode *ff_cp; /* cnode associated with this fork */ struct rl_head ff_invalidranges; /* Areas of disk that should read back as zeroes */ long ff_evtonly_refs; /* number of vnode references used solely for events (O_EVTONLY) */ union { struct hfslockf *ffu_lockf; /* Head of byte-level lock list. */ void *ffu_sysdata; /* private data for system files */ char *ffu_symlinkptr; /* symbolic link pathname */ } ff_un; struct cat_fork ff_data; }; typedef struct filefork filefork_t; /* Aliases for common fields */ #define ff_size ff_data.cf_size #define ff_clumpsize ff_data.cf_clump #define ff_bytesread ff_data.cf_bytesread #define ff_blocks ff_data.cf_blocks #define ff_extents ff_data.cf_extents #define ff_unallocblocks ff_data.cf_vblocks #define ff_symlinkptr ff_un.ffu_symlinkptr #define ff_lockf ff_un.ffu_lockf /* The btree code still needs these... */ #define fcbEOF ff_size #define fcbExtents ff_extents #define fcbBTCBPtr ff_un.ffu_sysdata /* * Directory index entry */ struct hfs_index { SLIST_ENTRY(hfs_index) hi_link; int hi_index; void *hi_thread; /* thread that created index entry */ char hi_name[1]; }; /* * The cnode is used to represent each active (or recently active) * file or directory in the HFS filesystem. * * Reading or writing any of these fields requires holding c_lock. */ struct cnode { struct lock__bsd__ c_lock; /* cnode's lock */ LIST_ENTRY(cnode) c_hash; /* cnode's hash chain */ u_int32_t c_flag; /* cnode's runtime flags */ struct vnode *c_vp; /* vnode for data fork or dir */ struct vnode *c_rsrc_vp; /* vnode for resource fork */ struct vnode *c_devvp; /* vnode for block I/O */ dev_t c_dev; /* cnode's device */ struct dquot *c_dquot[MAXQUOTAS]; /* cnode's quota info */ struct klist c_knotes; /* knotes attached to this vnode */ cnid_t c_childhint; /* catalog hint for children */ struct cat_desc c_desc; /* cnode's descriptor */ struct cat_attr c_attr; /* cnode's attributes */ SLIST_HEAD(hfs_indexhead, hfs_index) c_indexlist; /* directory index list */ long c_evtonly_refs; /* number of vnode references used solely for events (O_EVTONLY) */ struct filefork *c_datafork; /* cnode's data fork */ struct filefork *c_rsrcfork; /* cnode's rsrc fork */ }; typedef struct cnode cnode_t; /* Aliases for common cnode fields */ #define c_cnid c_desc.cd_cnid #define c_hint c_desc.cd_hint #define c_parentcnid c_desc.cd_parentcnid #define c_encoding c_desc.cd_encoding #define c_fileid c_attr.ca_fileid #define c_mode c_attr.ca_mode #define c_nlink c_attr.ca_nlink #define c_uid c_attr.ca_uid #define c_gid c_attr.ca_gid #define c_rdev c_attr.ca_rdev #define c_atime c_attr.ca_atime #define c_mtime c_attr.ca_mtime #define c_mtime_nsec c_attr.ca_mtime_nsec #define c_ctime c_attr.ca_ctime #define c_itime c_attr.ca_itime #define c_btime c_attr.ca_btime #define c_flags c_attr.ca_flags #define c_finderinfo c_attr.ca_finderinfo #define c_blocks c_attr.ca_blocks #define c_entries c_attr.ca_entries #define c_zftimeout c_childhint /* Runtime cnode flags (kept in c_flag) */ #define C_ACCESS 0x00001 /* Access time update request */ #define C_CHANGE 0x00002 /* Change time update request */ #define C_UPDATE 0x00004 /* Modification time update request */ #define C_MODIFIED 0x00008 /* CNode has been modified */ #define C_RELOCATING 0x00010 /* CNode's fork is being relocated */ #define C_NOEXISTS 0x00020 /* CNode has been deleted, catalog entry is gone */ #define C_DELETED 0x00040 /* CNode has been marked to be deleted */ #define C_HARDLINK 0x00080 /* CNode is a hard link */ #define C_ALLOC 0x00100 /* CNode is being allocated */ #define C_WALLOC 0x00200 /* Waiting for allocation to finish */ #define C_TRANSIT 0x00400 /* CNode is getting recycled */ #define C_WTRANSIT 0x00800 /* Waiting for cnode getting recycled */ #define C_NOBLKMAP 0x01000 /* CNode blocks cannot be mapped */ #define C_WBLKMAP 0x02000 /* Waiting for block map */ #define C_ZFWANTSYNC 0x04000 /* fsync requested and file has holes */ #define C_VPREFHELD 0x08000 /* resource fork has done a vget() on c_vp (for its parent ptr) */ #define C_FROMSYNC 0x10000 /* fsync was called from sync */ #define C_FORCEUPDATE 0x20000 /* force the catalog entry update */ #define ZFTIMELIMIT (5 * 60) /* * Convert between cnode pointers and vnode pointers */ #define VTOC(vp) ((struct cnode *)(vp)->v_data) #define CTOV(cp,rsrc) (((rsrc) && S_ISREG((cp)->c_mode)) ? \ (cp)->c_rsrc_vp : (cp)->c_vp) /* * Convert between vnode pointers and file forks * * Note: no CTOF since that is ambiguous */ #define FTOC(fp) ((fp)->ff_cp) #define VTOF(vp) ((vp) == VTOC((vp))->c_rsrc_vp ? \ VTOC((vp))->c_rsrcfork : \ VTOC((vp))->c_datafork) #define FTOV(fp) ((fp) == FTOC(fp)->c_rsrcfork ? \ FTOC(fp)->c_rsrc_vp : \ FTOC(fp)->c_vp) #define EVTONLYREFS(vp) ((vp->v_type == VREG) ? VTOF(vp)->ff_evtonly_refs : VTOC(vp)->c_evtonly_refs) /* * Test for a resource fork */ #define FORK_IS_RSRC(fp) ((fp) == FTOC(fp)->c_rsrcfork) #define VNODE_IS_RSRC(vp) ((vp) == VTOC((vp))->c_rsrc_vp) /* * CTIMES should be an inline function... */ #define C_TIMEMASK (C_ACCESS | C_CHANGE | C_UPDATE) #define C_CHANGEMASK (C_ACCESS | C_CHANGE | C_UPDATE | C_MODIFIED) #define ATIME_ACCURACY 1 #define ATIME_ONDISK_ACCURACY 300 #define CTIMES(cp, t1, t2) { \ if ((cp)->c_flag & C_TIMEMASK) { \ /* \ * Only do the update if it is more than just \ * the C_ACCESS field being updated. \ */ \ if (((cp)->c_flag & C_CHANGEMASK) != C_ACCESS) { \ if ((cp)->c_flag & C_ACCESS) { \ (cp)->c_atime = (t1)->tv_sec; \ } \ if ((cp)->c_flag & C_UPDATE) { \ (cp)->c_mtime = (t2)->tv_sec; \ (cp)->c_mtime_nsec = (t2)->tv_usec * 1000; \ } \ if ((cp)->c_flag & C_CHANGE) { \ (cp)->c_ctime = time.tv_sec; \ } \ (cp)->c_flag |= C_MODIFIED; \ (cp)->c_flag &= ~C_TIMEMASK; \ } \ } \ } /* This overlays the fid structure (see mount.h). */ struct hfsfid { u_int16_t hfsfid_len; /* Length of structure. */ u_int16_t hfsfid_pad; /* Force 32-bit alignment. */ /* The following data is filesystem-dependent, up to MAXFIDSZ (16) bytes: */ u_int32_t hfsfid_cnid; /* Catalog node ID. */ u_int32_t hfsfid_gen; /* Generation number (create date). */ }; /* * HFS cnode hash functions. */ extern void hfs_chashinit(void); extern void hfs_chashinsert(struct cnode *cp); extern void hfs_chashremove(struct cnode *cp); extern struct cnode * hfs_chashget(dev_t dev, ino_t inum, int wantrsrc, struct vnode **vpp, struct vnode **rvpp); #endif /* __APPLE_API_PRIVATE */ #endif /* KERNEL */ #endif /* ! _HFS_CNODE_H_ */