Skip to content

Commit

Permalink
xnu-2422.100.13
Browse files Browse the repository at this point in the history
  • Loading branch information
Darwin authored and das committed Jun 4, 2017
1 parent 777415e commit d48495c
Show file tree
Hide file tree
Showing 36 changed files with 1,753 additions and 334 deletions.
59 changes: 31 additions & 28 deletions bsd/hfs/hfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,39 +325,33 @@ typedef struct hfsmount {
u_long hfs_idhash; /* size of cnid/fileid hash table -1 */
LIST_HEAD(idhashhead, cat_preflightid) *hfs_idhashtbl; /* base of ID 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_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
// Records the oldest outstanding sync request
struct timeval hfs_sync_req_oldest;

// Records whether a sync has been queued or is in progress
boolean_t hfs_sync_incomplete;

thread_call_t hfs_syncer; // removeable devices get sync'ed by this guy

/* Records the syncer thread so that we can avoid the syncer
queing more syncs. */
thread_t hfs_syncer_thread;

// Not currently used except for debugging purposes
uint32_t hfs_active_threads;
} hfsmount_t;

/*
* HFS_META_DELAY is a duration (0.1 seconds, expressed in microseconds)
* used for triggering the hfs_syncer() routine. It is used in two ways:
* as the delay between ending a transaction and firing hfs_syncer(), and
* the delay in re-firing hfs_syncer() when it decides to back off (for
* example, due to in-progress writes).
* HFS_META_DELAY is a duration (in usecs) used for triggering the
* hfs_syncer() routine. We will back off if writes are in
* progress, but...
* HFS_MAX_META_DELAY is the maximum time we will allow the
* syncer to be delayed.
*/
enum { HFS_META_DELAY = 100 * 1000ULL };
enum {
HFS_META_DELAY = 100 * 1000, // 0.1 secs
HFS_MAX_META_DELAY = 5000 * 1000 // 5 secs
};

typedef hfsmount_t ExtendedVCB;

Expand Down Expand Up @@ -743,6 +737,8 @@ extern int hfs_owner_rights(struct hfsmount *hfsmp, uid_t cnode_uid, kauth_cred_

extern int check_for_tracked_file(struct vnode *vp, time_t ctime, uint64_t op_type, void *arg);
extern int check_for_dataless_file(struct vnode *vp, uint64_t op_type);
extern int hfs_generate_document_id(struct hfsmount *hfsmp, uint32_t *docid);


/*
* Journal lock function prototypes
Expand Down Expand Up @@ -796,13 +792,20 @@ 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, boolean_t wait_for_IO);
extern void hfs_syncer_lock(struct hfsmount *hfsmp);
extern void hfs_syncer_unlock(struct hfsmount *hfsmp);
extern void hfs_syncer_wait(struct hfsmount *hfsmp);
extern void hfs_syncer_wakeup(struct hfsmount *hfsmp);
extern void hfs_syncer_queue(thread_call_t syncer);
extern void hfs_sync_ejectable(struct hfsmount *hfsmp);

extern void hfs_trim_callback(void *arg, uint32_t extent_count, const dk_extent_t *extents);

/* Erase unused Catalog nodes due to <rdar://problem/6947811>. */
extern int hfs_erase_unused_nodes(struct hfsmount *hfsmp);

extern uint64_t hfs_usecs_to_deadline(uint64_t usecs);


/*****************************************************************************
Functions from hfs_vnops.c
Expand Down
6 changes: 5 additions & 1 deletion bsd/hfs/hfs_attrlist.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2012 Apple Inc. All rights reserved.
* Copyright (c) 2000-2014 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
Expand Down Expand Up @@ -686,12 +686,15 @@ packcommonattr(
/* also don't expose the date_added or write_gen_counter fields */
if (S_ISREG(cap->ca_mode) || S_ISLNK(cap->ca_mode)) {
struct FndrExtendedFileInfo *extinfo = (struct FndrExtendedFileInfo *)finfo;
extinfo->document_id = 0;
extinfo->date_added = 0;
extinfo->write_gen_counter = 0;
}
else if (S_ISDIR(cap->ca_mode)) {
struct FndrExtendedDirInfo *extinfo = (struct FndrExtendedDirInfo *)finfo;
extinfo->document_id = 0;
extinfo->date_added = 0;
extinfo->write_gen_counter = 0;
}

attrbufptr = (char *)attrbufptr + sizeof(u_int8_t) * 32;
Expand Down Expand Up @@ -739,6 +742,7 @@ packcommonattr(
*((u_int32_t *)attrbufptr) = cap->ca_flags;
attrbufptr = ((u_int32_t *)attrbufptr) + 1;
}

if (ATTR_CMN_USERACCESS & attr) {
u_int32_t user_access;

Expand Down
33 changes: 27 additions & 6 deletions bsd/hfs/hfs_cnode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1743,20 +1743,25 @@ uint32_t hfs_incr_gencount (struct cnode *cp) {
return gcount;
}

/* Getter for the gen count */
u_int32_t hfs_get_gencount (struct cnode *cp) {
static u_int32_t
hfs_get_gencount_internal(const uint8_t *finderinfo, mode_t mode)
{
u_int8_t *finfo = NULL;
u_int32_t gcount = 0;

/* overlay the FinderInfo to the correct pointer, and advance */
finfo = (u_int8_t*)cp->c_finderinfo;
finfo = (u_int8_t*)finderinfo;
finfo = finfo + 16;

/*
* FinderInfo is written out in big endian... make sure to convert it to host
* native before we use it.
*
* NOTE: the write_gen_counter is stored in the same location in both the
* FndrExtendedFileInfo and FndrExtendedDirInfo structs (it's the
* last 32-bit word) so it is safe to have one code path here.
*/
if (S_ISREG(cp->c_attr.ca_mode)) {
if (S_ISDIR(mode) || S_ISREG(mode)) {
struct FndrExtendedFileInfo *extinfo = (struct FndrExtendedFileInfo *)finfo;
gcount = OSSwapBigToHostInt32 (extinfo->write_gen_counter);

Expand All @@ -1768,14 +1773,30 @@ u_int32_t hfs_get_gencount (struct cnode *cp) {
if (gcount == 0) {
gcount++;
}
}
else {
} else if (S_ISDIR(mode)) {
struct FndrExtendedDirInfo *extinfo = (struct FndrExtendedDirInfo *)((u_int8_t*)finderinfo + 16);
gcount = OSSwapBigToHostInt32 (extinfo->write_gen_counter);

if (gcount == 0) {
gcount++;
}
} else {
gcount = 0;
}

return gcount;
}

/* Getter for the gen count */
u_int32_t hfs_get_gencount (struct cnode *cp) {
return hfs_get_gencount_internal(cp->c_finderinfo, cp->c_attr.ca_mode);
}

/* Getter for the gen count from a buffer (currently pointer to finderinfo)*/
u_int32_t hfs_get_gencount_from_blob (const uint8_t *finfoblob, mode_t mode) {
return hfs_get_gencount_internal(finfoblob, mode);
}

/*
* Touch cnode times based on c_touch_xxx flags
*
Expand Down
5 changes: 5 additions & 0 deletions bsd/hfs/hfs_cnode.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,13 @@ extern u_int32_t hfs_get_dateadded (struct cnode *cp);
/* Gen counter methods */
extern void hfs_write_gencount(struct cat_attr *cattrp, uint32_t gencount);
extern uint32_t hfs_get_gencount(struct cnode *cp);
extern uint32_t hfs_get_gencount_from_blob (const uint8_t *finfoblob, mode_t mode);
extern uint32_t hfs_incr_gencount (struct cnode *cp);

/* Document id methods */
extern uint32_t hfs_get_document_id(struct cnode * /* cp */);
extern uint32_t hfs_get_document_id_from_blob(const uint8_t * /* finderinfo */, mode_t /* mode */);

/* Zero-fill file and push regions out to disk */
extern int hfs_filedone(struct vnode *vp, vfs_context_t context);

Expand Down
6 changes: 3 additions & 3 deletions bsd/hfs/hfs_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,15 +225,15 @@ struct FndrOpaqueInfo {
typedef struct FndrOpaqueInfo FndrOpaqueInfo;

struct FndrExtendedDirInfo {
u_int32_t point;
u_int32_t document_id;
u_int32_t date_added;
u_int16_t extended_flags;
u_int16_t reserved3;
u_int32_t reserved4;
u_int32_t write_gen_counter;
} __attribute__((aligned(2), packed));

struct FndrExtendedFileInfo {
u_int32_t reserved1;
u_int32_t document_id;
u_int32_t date_added;
u_int16_t extended_flags;
u_int16_t reserved2;
Expand Down
9 changes: 9 additions & 0 deletions bsd/hfs/hfs_fsctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,15 @@ struct hfs_journal_info {
#define HFSIOC_GET_WRITE_GEN_COUNTER _IOR('h', 30, u_int32_t)
#define HFS_GET_WRITE_GEN_COUNTER IOCBASECMD(HFSIOC_GET_WRITE_GEN_COUNTER)

#define HFS_DOCUMENT_ID_ALLOCATE 0x1

#define HFSIOC_GET_DOCUMENT_ID _IOR('h', 31, u_int32_t)
#define HFS_GET_DOCUMENT_ID IOCBASECMD(HFSIOC_GET_DOCUMENT_ID)

/* revisiond only uses this when something transforms in a way the kernel can't track such as "foo.rtf" -> "foo.rtfd" */
#define HFSIOC_TRANSFER_DOCUMENT_ID _IOW('h', 32, u_int32_t)
#define HFS_TRANSFER_DOCUMENT_ID IOCBASECMD(HFSIOC_TRANSFER_DOCUMENT_ID)

#endif /* __APPLE_API_UNSTABLE */

#endif /* ! _HFS_FSCTL_H_ */
3 changes: 3 additions & 0 deletions bsd/hfs/hfs_link.c
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,7 @@ hfs_vnop_link(struct vnop_link_args *ap)
}
}
tdcp->c_dirchangecnt++;
hfs_incr_gencount(tdcp);
tdcp->c_touch_chgtime = TRUE;
tdcp->c_touch_modtime = TRUE;
tdcp->c_flag |= C_FORCEUPDATE;
Expand Down Expand Up @@ -758,6 +759,7 @@ hfs_unlink(struct hfsmount *hfsmp, struct vnode *dvp, struct vnode *vp, struct c
DEC_FOLDERCOUNT(hfsmp, dcp->c_attr);
}
dcp->c_dirchangecnt++;
hfs_incr_gencount(dcp);
microtime(&tv);
dcp->c_ctime = tv.tv_sec;
dcp->c_mtime = tv.tv_sec;
Expand Down Expand Up @@ -1015,6 +1017,7 @@ hfs_privatedir_init(struct hfsmount * hfsmp, enum privdirtype type)
dcp->c_entries++;
INC_FOLDERCOUNT(hfsmp, dcp->c_attr);
dcp->c_dirchangecnt++;
hfs_incr_gencount(dcp);
microtime(&tv);
dcp->c_ctime = tv.tv_sec;
dcp->c_mtime = tv.tv_sec;
Expand Down
Loading

0 comments on commit d48495c

Please sign in to comment.