#ifndef __HFS__
#define __HFS__
#include <sys/appleapiopts.h>
#ifdef KERNEL
#ifdef __APPLE_API_PRIVATE
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/queue.h>
#include <sys/mount.h>
#include <sys/namei.h>
#include <sys/vnode.h>
#include <sys/quota.h>
#include <sys/dirent.h>
#include <vfs/vfs_journal.h>
#include <hfs/hfs_format.h>
#include <hfs/hfs_catalog.h>
#include <hfs/hfs_cnode.h>
#include <hfs/hfs_macos_defs.h>
#include <hfs/hfs_encodings.h>
struct uio; struct hfslockf;
#define VERSION_STRING "hfs-2 (4-12-99)"
#define HFS_LINK_MAX 32767
#define HFS_MAX_DEFERED_ALLOC (1024*1024)
enum { kMDBSize = 512 };
enum { kMasterDirectoryBlock = 2 };
enum { kMDBOffset = kMasterDirectoryBlock * 512 };
enum {
kUnknownID = 0,
kRootParID = 1,
kRootDirID = 2
};
enum {
kDataFork,
kRsrcFork,
kDirectory
};
#define kMaxLockedMetaBuffers 32
enum {
kSymLinkFileType = 0x736C6E6B,
kSymLinkCreator = 0x72686170
};
extern struct timezone gTimeZone;
#define kMaxFreeExtents 10
#define HFS_MINFREE 1
#define HFS_MAXRESERVE (u_int64_t)(250*1024*1024)
struct vcb_t {
u_int16_t vcbSigWord;
int16_t vcbAtrb;
int16_t vcbFlags;
int16_t vcbspare;
u_int32_t vcbJinfoBlock;
u_int32_t vcbCrDate;
u_int32_t vcbLsMod;
u_int32_t vcbVolBkUp;
int32_t vcbFilCnt;
int32_t vcbDirCnt;
u_int32_t blockSize;
u_int32_t totalBlocks;
u_int32_t freeBlocks;
u_int32_t nextAllocation;
int32_t vcbClpSiz;
u_int32_t vcbNxtCNID;
u_int32_t vcbCNIDGen;
int32_t vcbWrCnt;
int32_t vcbFndrInfo[8];
u_int64_t encodingsBitmap;
u_int16_t vcbNmFls;
u_int16_t vcbNmRtDirs;
int16_t vcbVBMSt;
int16_t vcbAlBlSt;
struct vnode * extentsRefNum;
struct vnode * catalogRefNum;
struct vnode * allocationsRefNum;
u_int8_t vcbVN[256];
u_int32_t volumeNameEncodingHint;
u_int32_t hfsPlusIOPosOffset;
u_int32_t vcbVBMIOSize;
u_int32_t vcbFreeExtCnt;
HFSPlusExtentDescriptor vcbFreeExt[kMaxFreeExtents];
u_int32_t reserveBlocks;
u_int32_t loanedBlocks;
u_int32_t localCreateDate;
simple_lock_data_t vcbSimpleLock;
};
typedef struct vcb_t ExtendedVCB;
#define kHFS_DamagedVolume 0x1
#define MARK_VOLUMEDAMAGED(fcb)
typedef struct vfsVCB {
ExtendedVCB vcb_vcb;
struct hfsmount *vcb_hfsmp;
} vfsVCB_t;
typedef struct hfsmount {
u_int8_t hfs_fs_ronly;
u_int8_t hfs_unknownpermissions;
u_int8_t hfs_media_writeable;
u_int8_t hfs_orphans_cleaned;
u_long hfs_phys_block_count;
u_long hfs_phys_block_size;
struct mount *hfs_mp;
struct vnode *hfs_devvp;
dev_t hfs_raw_dev;
struct netexport hfs_export;
u_int32_t hfs_logBlockSize;
uid_t hfs_uid;
gid_t hfs_gid;
mode_t hfs_dir_mask;
mode_t hfs_file_mask;
u_long hfs_encoding;
simple_lock_data_t hfs_renamelock;
struct vfsVCB hfs_vcb;
struct cat_desc hfs_privdir_desc;
struct cat_attr hfs_privdir_attr;
u_int32_t hfs_metadata_createdate;
hfs_to_unicode_func_t hfs_get_unicode;
unicode_to_hfs_func_t hfs_get_hfsname;
struct quotafile hfs_qfiles[MAXQUOTAS];
void *jnl; struct vnode *jvp; u_int32_t jnl_start; u_int32_t hfs_jnlfileid;
u_int32_t hfs_jnlinfoblkid;
volatile int readers;
volatile int blocker;
} hfsmount_t;
#define hfs_private_metadata_dir hfs_privdir_desc.cd_cnid
#define hfs_global_shared_lock_acquire(hfsmp) \
do { \
if (hfsmp->blocker) { \
tsleep((caddr_t)&hfsmp->blocker, PRIBIO, "journal_blocker", 0); \
continue; \
} \
hfsmp->readers++; \
break; \
} while (1)
#define hfs_global_shared_lock_release(hfsmp) \
do { \
hfsmp->readers--; \
if (hfsmp->readers == 0) { \
wakeup((caddr_t)&hfsmp->readers); \
} \
} while (0)
#define hfs_global_exclusive_lock_acquire(hfsmp) \
do { \
if (hfsmp->blocker) { \
tsleep((caddr_t)&hfsmp->blocker, PRIBIO, "journal_blocker", 0); \
continue; \
} \
if (hfsmp->readers != 0) { \
tsleep((caddr_t)&hfsmp->readers, PRIBIO, "journal_enable/disble", 0); \
continue; \
} \
hfsmp->blocker = 1; \
break; \
} while (1)
#define hfs_global_exclusive_lock_release(hfsmp) \
hfsmp->blocker = 0; \
wakeup((caddr_t)&hfsmp->blocker)
#define MAXHFSVNODELEN 31
typedef struct filefork FCB;
#define MAKE_INODE_NAME(name,linkno) \
(void) sprintf((name), "%s%d", HFS_INODE_PREFIX, (linkno))
#define WRITE_CK(VNODE, FUNC_NAME) { \
if ((VNODE)->v_mount->mnt_flag & MNT_RDONLY) { \
DBG_ERR(("%s: ATTEMPT TO WRITE A READONLY VOLUME\n", \
FUNC_NAME)); \
return(EROFS); \
} \
}
typedef struct hfsdotentry {
u_int32_t d_fileno;
u_int16_t d_reclen;
u_int8_t d_type;
u_int8_t d_namelen;
char d_name[4];
} hfsdotentry;
#define HFS_AVERAGE_NAME_SIZE 22
#define AVERAGE_HFSDIRENTRY_SIZE (8+HFS_AVERAGE_NAME_SIZE+4)
#define MAX_HFSDIRENTRY_SIZE sizeof(struct dirent)
#define DIRENTRY_SIZE(namlen) \
((sizeof(struct dirent) - (NAME_MAX+1)) + (((namlen)+1 + 3) &~ 3))
enum {
kCatalogFolderNode = 1,
kCatalogFileNode = 2
};
struct CatalogNodeData {
int16_t cnd_type;
u_int16_t cnd_flags;
u_int32_t cnd_valence;
u_int32_t cnd_nodeID;
u_int32_t cnd_createDate;
u_int32_t cnd_contentModDate;
u_int32_t cnd_attributeModDate;
u_int32_t cnd_accessDate;
u_int32_t cnd_backupDate;
u_int32_t cnd_ownerID;
u_int32_t cnd_groupID;
u_int8_t cnd_adminFlags;
u_int8_t cnd_ownerFlags;
u_int16_t cnd_mode;
union {
u_int32_t cndu_iNodeNum;
u_int32_t cndu_linkCount;
u_int32_t cndu_rawDevice;
} cnd_un;
u_int8_t cnd_finderInfo[32];
u_int32_t cnd_textEncoding;
u_int32_t cnd_reserved;
HFSPlusForkData cnd_datafork;
HFSPlusForkData cnd_rsrcfork;
u_int32_t cnd_iNodeNumCopy;
u_int32_t cnd_linkCNID;
u_int8_t cnd_extra[264];
};
typedef struct CatalogNodeData CatalogNodeData;
#define cnd_iNodeNum cnd_un.cndu_iNodeNum
#define cnd_linkCount cnd_un.cndu_linkCount
#define cnd_rawDevice cnd_un.cndu_rawDevice
enum { kHFSPlusMaxFileNameBytes = kHFSPlusMaxFileNameChars * 3 };
enum { kdirentMaxNameBytes = NAME_MAX };
#define ISHFSPLUS(VCB) ((VCB)->vcbSigWord == kHFSPlusSigWord)
#define ISHFS(VCB) ((VCB)->vcbSigWord == kHFSSigWord)
#define VTOVFS(VP) ((VP)->v_mount)
#define HFSTOVFS(HFSMP) ((HFSMP)->hfs_mp)
#define VCBTOVFS(VCB) (((struct vfsVCB *)(VCB))->vcb_hfsmp->hfs_mp)
#define VTOHFS(VP) ((struct hfsmount *)((VP)->v_mount->mnt_data))
#define VFSTOHFS(MP) ((struct hfsmount *)(MP)->mnt_data)
#define VCBTOHFS(VCB) (((struct vfsVCB *)(VCB))->vcb_hfsmp)
#define FCBTOHFS(FCB) ((struct hfsmount *)(FCB)->ff_cp->c_vp->v_mount->mnt_data)
#define VTOVCB(VP) (&(((struct hfsmount *)((VP)->v_mount->mnt_data))->hfs_vcb.vcb_vcb))
#define VFSTOVCB(MP) (&(((struct hfsmount *)(MP)->mnt_data)->hfs_vcb.vcb_vcb))
#define HFSTOVCB(HFSMP) (&(HFSMP)->hfs_vcb.vcb_vcb)
#define FCBTOVCB(FCB) (&(((struct hfsmount *)((FCB)->ff_cp->c_vp->v_mount->mnt_data))->hfs_vcb.vcb_vcb))
#define E_NONE 0
#define kHFSBlockSize 512
#define HFS_PRI_SECTOR(blksize) (1024 / (blksize))
#define HFS_PRI_OFFSET(blksize) ((blksize) > 1024 ? 1024 : 0)
#define HFS_ALT_SECTOR(blksize, blkcnt) (((blkcnt) - 1) - (512 / (blksize)))
#define HFS_ALT_OFFSET(blksize) ((blksize) > 1024 ? (blksize) - 1024 : 0)
#define MAC_GMT_FACTOR 2082844800UL
u_int32_t to_bsd_time(u_int32_t hfs_time);
u_int32_t to_hfs_time(u_int32_t bsd_time);
int hfs_flushfiles(struct mount *mp, int flags, struct proc *p);
int hfs_flushvolumeheader(struct hfsmount *hfsmp, int waitfor, int altflush);
#define HFS_ALTFLUSH 1
short hfsUnmount(struct hfsmount *hfsmp, struct proc *p);
extern int hfs_getcnode(struct hfsmount *hfsmp, cnid_t cnid, struct cat_desc *descp,
int wantrsrc, struct cat_attr *attrp, struct cat_fork *forkp,
struct vnode **vpp);
extern int hfs_getnewvnode(struct hfsmount *hfsmp, struct cnode *cp,
struct cat_desc *descp, int wantrsrc, struct cat_attr *attrp,
struct cat_fork *forkp, struct vnode **vpp);
extern int hfs_metafilelocking(struct hfsmount *hfsmp, u_long fileID, u_int flags, struct proc *p);
extern u_int32_t hfs_freeblks(struct hfsmount * hfsmp, int wantreserve);
extern void hfs_remove_orphans(struct hfsmount *);
short MacToVFSError(OSErr err);
extern int hfs_owner_rights(struct hfsmount *hfsmp, uid_t cnode_uid, struct ucred *cred,
struct proc *p, int invokesuperuserstatus);
u_long FindMetaDataDirectory(ExtendedVCB *vcb);
#define kMaxSecsForFsync 5
#define HFS_SYNCTRANS 1
extern int hfs_btsync(struct vnode *vp, int sync_transaction);
extern void hfs_sync_metadata(void *arg);
short make_dir_entry(FCB **fileptr, char *name, u_int32_t fileID);
unsigned long BestBlockSizeFit(unsigned long allocationBlockSize,
unsigned long blockSizeLimit,
unsigned long baseMultiple);
OSErr hfs_MountHFSVolume(struct hfsmount *hfsmp, HFSMasterDirectoryBlock *mdb,
struct proc *p);
OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp,
off_t embeddedOffset, u_int64_t disksize, struct proc *p, void *args);
extern int hfs_early_journal_init(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp,
void *_args, int embeddedOffset, int mdb_offset,
HFSMasterDirectoryBlock *mdbp, struct ucred *cred);
extern u_long GetFileInfo(ExtendedVCB *vcb, u_int32_t dirid, char *name,
struct cat_attr *fattr, struct cat_fork *forkinfo);
int hfs_getconverter(u_int32_t encoding, hfs_to_unicode_func_t *get_unicode,
unicode_to_hfs_func_t *get_hfsname);
int hfs_relconverter(u_int32_t encoding);
int hfs_to_utf8(ExtendedVCB *vcb, Str31 hfs_str, ByteCount maxDstLen,
ByteCount *actualDstLen, unsigned char* dstStr);
int utf8_to_hfs(ExtendedVCB *vcb, ByteCount srcLen, const unsigned char* srcStr,
Str31 dstStr);
int mac_roman_to_utf8(Str31 hfs_str, ByteCount maxDstLen, ByteCount *actualDstLen,
unsigned char* dstStr);
int utf8_to_mac_roman(ByteCount srcLen, const unsigned char* srcStr, Str31 dstStr);
u_int32_t hfs_pickencoding(const u_int16_t *src, int len);
enum volop {VOL_UPDATE, VOL_MKDIR, VOL_RMDIR, VOL_MKFILE, VOL_RMFILE};
extern int hfs_volupdate(struct hfsmount *hfsmp, enum volop op, int inroot);
extern void hfs_setencodingbits(struct hfsmount *hfsmp, u_int32_t encoding);
extern void replace_desc(struct cnode *cp, struct cat_desc *cdp);
extern int hfs_namecmp(const char *, size_t, const char *, size_t);
#endif
#endif
#endif