]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/hfs/hfs.h
xnu-1504.9.37.tar.gz
[apple/xnu.git] / bsd / hfs / hfs.h
index 5568cf9c50b3cf89f7c0b31c5bf44cfd6adefb64..89f97ebc19fd1d6cb68a1def29d735a85809f110 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2009 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -31,7 +31,7 @@
 
 #define HFS_SPARSE_DEV 1
 
-#ifdef DEBUG
+#if DEBUG
 #define HFS_CHECK_LOCK_ORDER 1
 #endif
 
@@ -46,6 +46,7 @@
 #include <sys/quota.h>
 #include <sys/dirent.h>
 #include <sys/event.h>
+#include <kern/thread_call.h>
 
 #include <kern/locks.h>
 
@@ -107,15 +108,19 @@ extern struct timezone gTimeZone;
  * volume size, all capped at a certain fixed level
  */
  
-#define HFS_ROOTLOWDISKTRIGGERFRACTION 5
+#define HFS_ROOTVERYLOWDISKTRIGGERFRACTION 5
+#define HFS_ROOTVERYLOWDISKTRIGGERLEVEL ((u_int64_t)(125*1024*1024))
+#define HFS_ROOTLOWDISKTRIGGERFRACTION 10
 #define HFS_ROOTLOWDISKTRIGGERLEVEL ((u_int64_t)(250*1024*1024))
-#define HFS_ROOTLOWDISKSHUTOFFFRACTION 6
+#define HFS_ROOTLOWDISKSHUTOFFFRACTION 11
 #define HFS_ROOTLOWDISKSHUTOFFLEVEL ((u_int64_t)(375*1024*1024))
 
-#define HFS_LOWDISKTRIGGERFRACTION 1
-#define HFS_LOWDISKTRIGGERLEVEL ((u_int64_t)(50*1024*1024))
-#define HFS_LOWDISKSHUTOFFFRACTION 2
-#define HFS_LOWDISKSHUTOFFLEVEL ((u_int64_t)(75*1024*1024))
+#define HFS_VERYLOWDISKTRIGGERFRACTION 1
+#define HFS_VERYLOWDISKTRIGGERLEVEL ((u_int64_t)(100*1024*1024))
+#define HFS_LOWDISKTRIGGERFRACTION 2
+#define HFS_LOWDISKTRIGGERLEVEL ((u_int64_t)(150*1024*1024))
+#define HFS_LOWDISKSHUTOFFFRACTION 3
+#define HFS_LOWDISKSHUTOFFLEVEL ((u_int64_t)(200*1024*1024))
 
 /* Internal Data structures*/
 
@@ -124,9 +129,11 @@ typedef struct hfsmount {
        u_int32_t     hfs_flags;              /* see below */
 
        /* Physical Description */
-       u_long        hfs_phys_block_size;    /* Always a multiple of 512 */
-       daddr64_t     hfs_phys_block_count;   /* Num of PHYSICAL blocks of volume */
-       daddr64_t     hfs_alt_id_sector;      /* location of alternate VH/MDB */
+       u_int32_t     hfs_logical_block_size;   /* Logical block size of the disk as reported by ioctl(DKIOCGETBLOCKSIZE), always a multiple of 512 */
+       daddr64_t     hfs_logical_block_count;  /* Number of logical blocks on the disk */
+       daddr64_t     hfs_alt_id_sector;        /* location of alternate VH/MDB */
+       u_int32_t     hfs_physical_block_size;  /* Physical block size of the disk as reported by ioctl(DKIOCGETPHYSICALBLOCKSIZE) */ 
+       u_int32_t     hfs_log_per_phys;         /* Number of logical blocks per physical block size */
 
        /* Access to VFS and devices */
        struct mount            *hfs_mp;                                /* filesystem vfs structure */
@@ -150,7 +157,7 @@ typedef struct hfsmount {
        gid_t         hfs_gid;            /* gid to set as owner of the files */
        mode_t        hfs_dir_mask;       /* mask to and with directory protection bits */
        mode_t        hfs_file_mask;      /* mask to and with file protection bits */
-       u_long        hfs_encoding;       /* Default encoding for non hfs+ volumes */   
+       u_int32_t        hfs_encoding;       /* Default encoding for non hfs+ volumes */        
 
        /* Persistent fields (on disk, dynamic) */
        time_t        hfs_mtime;          /* file system last modification time */
@@ -158,6 +165,7 @@ typedef struct hfsmount {
        u_int32_t     hfs_dircount;       /* number of directories in file system */
        u_int32_t     freeBlocks;         /* free allocation blocks */
        u_int32_t     nextAllocation;     /* start of next allocation search */
+       u_int32_t     sparseAllocation;   /* start of allocations for sparse devices */
        u_int32_t     vcbNxtCNID;         /* next unused catalog node ID - protected by catalog lock */
        u_int32_t     vcbWrCnt;           /* file system write count */
        u_int64_t     encodingsBitmap;    /* in-use encodings */
@@ -227,7 +235,8 @@ typedef struct hfsmount {
        u_int32_t            hfs_global_lock_nesting;
        
        /* Notification variables: */
-       unsigned long           hfs_notification_conditions;
+       u_int32_t               hfs_notification_conditions;
+       u_int32_t               hfs_freespace_notify_dangerlimit;
        u_int32_t               hfs_freespace_notify_warninglimit;
        u_int32_t               hfs_freespace_notify_desiredlevel;
 
@@ -240,6 +249,8 @@ typedef struct hfsmount {
        u_int32_t       hfs_metazone_end;
        u_int32_t       hfs_hotfile_start;
        u_int32_t       hfs_hotfile_end;
+        u_int32_t       hfs_min_alloc_start;
+       u_int32_t       hfs_freed_block_count;
        int             hfs_hotfile_freeblks;
        int             hfs_hotfile_maxblks;
        int             hfs_overflow_maxblks;
@@ -259,18 +270,54 @@ typedef struct hfsmount {
        struct vnode * hfs_backingfs_rootvp;
        u_int32_t      hfs_last_backingstatfs;
        int            hfs_sparsebandblks;
+       u_int64_t      hfs_backingfs_maxblocks;
 #endif
        size_t         hfs_max_inline_attrsize;
 
        lck_mtx_t      hfs_mutex;      /* protects access to hfsmount data */
        void          *hfs_freezing_proc;  /* who froze the fs */
+       void          *hfs_downgrading_proc; /* process who's downgrading to rdonly */
        lck_rw_t       hfs_insync;     /* protects sync/freeze interaction */
 
        /* Resize variables: */
        u_int32_t               hfs_resize_filesmoved;
        u_int32_t               hfs_resize_totalfiles;
+
+       /* Per mount cnode hash variables: */
+       lck_mtx_t      hfs_chash_mutex; /* protects access to cnode hash table */
+       u_long         hfs_cnodehash;   /* size of cnode hash table - 1 */
+       LIST_HEAD(cnodehashhead, cnode) *hfs_cnodehashtbl;      /* base of cnode hash */
+                                       
+
+       /*
+        * About the sync counters:
+        * hfs_sync_scheduled  keeps track whether a timer was scheduled but we
+        *                     haven't started processing the callback (i.e. we
+        *                     haven't begun the flush).  This will be non-zero
+        *                     even if the callback has been invoked, before we
+        *                    start the flush.
+        * hfs_sync_incomplete keeps track of the number of callbacks that have
+        *                     not completed yet (including callbacks not yet
+        *                     invoked).  We cannot safely unmount until this
+        *                     drops to zero.
+        *
+        * In both cases, we use counters, not flags, so that we can avoid
+        * taking locks.
+        */
+       int32_t         hfs_sync_scheduled;
+       int32_t         hfs_sync_incomplete;
+       u_int64_t       hfs_last_sync_request_time;
+       u_int64_t       hfs_last_sync_time;
+       u_int32_t       hfs_active_threads;
+       u_int64_t       hfs_max_pending_io;
+                                       
+       thread_call_t   hfs_syncer;           // removeable devices get sync'ed by this guy
+
 } hfsmount_t;
 
+#define HFS_META_DELAY     (100)
+#define HFS_MILLISEC_SCALE (1000*1000)
+
 typedef hfsmount_t  ExtendedVCB;
 
 /* Aliases for legacy (Mac OS 9) field names */
@@ -337,6 +384,13 @@ enum privdirtype {FILE_HARDLINKS, DIR_HARDLINKS};
 #define        HFS_FOLDERCOUNT           0x10000
 /* When set, the file system exists on a virtual device, like disk image */
 #define HFS_VIRTUAL_DEVICE        0x20000
+/* When set, we're in hfs_changefs, so hfs_sync should do nothing. */
+#define HFS_IN_CHANGEFS           0x40000
+/* When set, we are in process of downgrading or have downgraded to read-only, 
+ * so hfs_start_transaction should return EROFS.
+ */
+#define HFS_RDONLY_DOWNGRADE      0x80000
+#define HFS_DID_CONTIG_SCAN      0x100000
 
 
 /* Macro to update next allocation block in the HFS mount structure.  If 
@@ -442,9 +496,6 @@ enum { kHFSPlusMaxFileNameBytes = kHFSPlusMaxFileNameChars * 3 };
 #define FCBTOVCB(FCB)    FCBTOHFS(FCB)
 
 
-#define HFS_KNOTE(vp, hint) KNOTE(&VTOC(vp)->c_knotes, (hint))
-
-
 #define E_NONE 0
 #define kHFSBlockSize 512
 
@@ -457,6 +508,10 @@ enum { kHFSPlusMaxFileNameBytes = kHFSPlusMaxFileNameChars * 3 };
 #define HFS_ALT_SECTOR(blksize, blkcnt)  (((blkcnt) - 1) - (512 / (blksize)))
 #define HFS_ALT_OFFSET(blksize)          ((blksize) > 1024 ? (blksize) - 1024 : 0)
 
+/* Convert the logical sector number to be aligned on physical block size boundary.  
+ * We are assuming the partition is a multiple of physical block size.
+ */
+#define HFS_PHYSBLK_ROUNDDOWN(sector_num, log_per_phys)        ((sector_num / log_per_phys) * log_per_phys)
 
 /*
  * HFS specific fcntl()'s
@@ -575,7 +630,7 @@ void hfs_generate_volume_notifications(struct hfsmount *hfsmp);
 ******************************************************************************/
 extern int  hfs_relocate(struct  vnode *, u_int32_t, kauth_cred_t, struct  proc *);
 
-extern int hfs_truncate(struct vnode *, off_t, int, int, vfs_context_t);
+extern int hfs_truncate(struct vnode *, off_t, int, int, int, vfs_context_t);
 
 extern int hfs_bmap(struct vnode *, daddr_t, struct vnode **, daddr64_t *, unsigned int *);
 
@@ -589,7 +644,7 @@ extern int hfs_set_volxattr(struct hfsmount *hfsmp, unsigned int xattrtype, int
 
 extern void hfs_check_volxattr(struct hfsmount *hfsmp, unsigned int xattrtype);
 
-extern int  hfs_isallocated(struct hfsmount *, u_long, u_long);
+extern int  hfs_isallocated(struct hfsmount *, u_int32_t, u_int32_t);
 
 
 /*****************************************************************************
@@ -622,9 +677,9 @@ void hfs_mark_volume_inconsistent(struct hfsmount *hfsmp);
 /*****************************************************************************
        Functions from hfs_vfsutils.c
 ******************************************************************************/
-unsigned long BestBlockSizeFit(unsigned long allocationBlockSize,
-                               unsigned long blockSizeLimit,
-                               unsigned long baseMultiple);
+u_int32_t BestBlockSizeFit(u_int32_t allocationBlockSize,
+                               u_int32_t blockSizeLimit,
+                               u_int32_t baseMultiple);
 
 OSErr  hfs_MountHFSVolume(struct hfsmount *hfsmp, HFSMasterDirectoryBlock *mdb,
                struct proc *p);
@@ -650,7 +705,7 @@ extern int hfs_owner_rights(struct hfsmount *hfsmp, uid_t cnode_uid, kauth_cred_
 extern int  hfs_systemfile_lock(struct hfsmount *, int, enum hfslocktype);
 extern void hfs_systemfile_unlock(struct hfsmount *, int);
 
-extern u_long  GetFileInfo(ExtendedVCB *vcb, u_int32_t dirid, const char *name,
+extern u_int32_t  GetFileInfo(ExtendedVCB *vcb, u_int32_t dirid, const char *name,
                                                   struct cat_attr *fattr, struct cat_fork *forkinfo);
 
 extern void hfs_remove_orphans(struct hfsmount *);
@@ -661,6 +716,8 @@ extern u_int32_t hfs_freeblks(struct hfsmount * hfsmp, int wantreserve);
 
 short MacToVFSError(OSErr err);
 
+void hfs_metadatazone_init(struct hfsmount *hfsmp);
+
 /* HFS directory hint functions. */
 extern directoryhint_t * hfs_getdirhint(struct cnode *, int, int);
 extern void  hfs_reldirhint(struct cnode *, directoryhint_t *);
@@ -677,6 +734,11 @@ extern int  hfs_virtualmetafile(struct cnode *);
 
 extern int hfs_start_transaction(struct hfsmount *hfsmp);
 extern int hfs_end_transaction(struct hfsmount *hfsmp);
+extern int hfs_journal_flush(struct hfsmount *hfsmp);
+extern void hfs_sync_ejectable(struct hfsmount *hfsmp);
+
+/* Erase unused Catalog nodes due to <rdar://problem/6947811>. */
+extern int hfs_erase_unused_nodes(struct hfsmount *hfsmp);
 
 
 /*****************************************************************************
@@ -695,7 +757,7 @@ extern int hfs_btsync(struct vnode *vp, int sync_transaction);
 extern void replace_desc(struct cnode *cp, struct cat_desc *cdp);
 
 extern int hfs_vgetrsrc(struct hfsmount *hfsmp, struct vnode *vp,
-                       struct vnode **rvpp, int can_drop_lock);
+                       struct vnode **rvpp, int can_drop_lock, int error_on_unlinked);
 
 extern int hfs_update(struct vnode *, int);