Skip to content

Commit

Permalink
xnu-344.12.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Darwin authored and das committed Jun 4, 2017
1 parent 5bc19c0 commit e0c84ff
Show file tree
Hide file tree
Showing 58 changed files with 5,937 additions and 487 deletions.
3 changes: 3 additions & 0 deletions bsd/conf/files
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ bsd/vfs/vfs_support.c standard
bsd/vfs/vfs_utfconv.c standard
bsd/vfs/vfs_vnops.c standard
bsd/vfs/vnode_if.c standard
bsd/vfs/vfs_journal.c standard

bsd/miscfs/deadfs/dead_vnops.c standard
bsd/miscfs/fdesc/fdesc_vfsops.c optional fdesc
Expand Down Expand Up @@ -501,6 +502,8 @@ bsd/kern/mach_header.c standard
bsd/kern/mach_loader.c standard
bsd/kern/posix_sem.c standard
bsd/kern/posix_shm.c standard
# XXXdbg - I need this in the journaling and block cache code
bsd/kern/qsort.c standard

bsd/vm/vnode_pager.c standard
bsd/vm/vm_unix.c standard
Expand Down
2 changes: 1 addition & 1 deletion bsd/conf/version.minor
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1
2
63 changes: 62 additions & 1 deletion bsd/hfs/hfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#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>
Expand Down Expand Up @@ -108,6 +110,7 @@ struct vcb_t {
int16_t vcbAtrb;
int16_t vcbFlags;
int16_t vcbspare;
u_int32_t vcbJinfoBlock;

u_int32_t vcbCrDate;
u_int32_t vcbLsMod;
Expand Down Expand Up @@ -180,6 +183,7 @@ typedef struct hfsmount {
u_int8_t hfs_fs_ronly; /* Whether this was mounted as read-initially */
u_int8_t hfs_unknownpermissions; /* Whether this was mounted with MNT_UNKNOWNPERMISSIONS */
u_int8_t hfs_media_writeable;
u_int8_t hfs_orphans_cleaned;

/* Physical Description */
u_long hfs_phys_block_count; /* Num of PHYSICAL blocks of volume */
Expand Down Expand Up @@ -211,10 +215,55 @@ typedef struct hfsmount {
unicode_to_hfs_func_t hfs_get_hfsname;

struct quotafile hfs_qfiles[MAXQUOTAS]; /* quota files */

// XXXdbg
void *jnl; // the journal for this volume (if one exists)
struct vnode *jvp; // device where the journal lives (may be equal to devvp)
u_int32_t jnl_start; // start block of the journal file (so we don't delete it)
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


Expand Down Expand Up @@ -325,13 +374,15 @@ enum { kdirentMaxNameBytes = NAME_MAX };
#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)

/*
* Various ways to acquire a VCB pointer:
*/
#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
Expand Down Expand Up @@ -376,6 +427,8 @@ extern int hfs_metafilelocking(struct hfsmount *hfsmp, u_long fileID, u_int flag

extern u_int32_t hfs_freeblks(struct hfsmount * hfsmp, int wantreserve);

extern void hfs_remove_orphans(struct hfsmount *);


short MacToVFSError(OSErr err);

Expand All @@ -388,6 +441,8 @@ u_long FindMetaDataDirectory(ExtendedVCB *vcb);
#define HFS_SYNCTRANS 1

extern int hfs_btsync(struct vnode *vp, int sync_transaction);
// used as a callback by the journaling code
extern void hfs_sync_metadata(void *arg);

short make_dir_entry(FCB **fileptr, char *name, u_int32_t fileID);

Expand All @@ -399,7 +454,13 @@ unsigned long BestBlockSizeFit(unsigned long allocationBlockSize,
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);
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);
Expand Down
93 changes: 77 additions & 16 deletions bsd/hfs/hfs_attrlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,35 @@ hfs_getattrlist(ap)
if ((error = hfs_write_access(vp, ap->a_cred, ap->a_p, false)) != 0)
return (error);

// XXXdbg
hfs_global_shared_lock_acquire(hfsmp);
if (hfsmp->jnl) {
if ((error = journal_start_transaction(hfsmp->jnl)) != 0) {
hfs_global_shared_lock_release(hfsmp);
return error;
}
}

/* Lock catalog b-tree */
error = hfs_metafilelocking(hfsmp, kHFSCatalogFileID, LK_SHARED, ap->a_p);
if (error)
return (error);
if (error) {
if (hfsmp->jnl) {
journal_end_transaction(hfsmp->jnl);
}
hfs_global_shared_lock_release(hfsmp);
return (error);
}

error = cat_insertfilethread(hfsmp, &cp->c_desc);

/* Unlock catalog b-tree */
(void) hfs_metafilelocking(hfsmp, kHFSCatalogFileID, LK_RELEASE, ap->a_p);

if (hfsmp->jnl) {
journal_end_transaction(hfsmp->jnl);
}
hfs_global_shared_lock_release(hfsmp);

if (error)
return (error);
}
Expand Down Expand Up @@ -350,6 +370,17 @@ hfs_setattrlist(ap)
}
if (cp->c_flag & (C_NOEXISTS | C_DELETED))
return (ENOENT);

// XXXdbg - don't allow modifying the journal or journal_info_block
if (hfsmp->jnl && cp->c_datafork) {
struct HFSPlusExtentDescriptor *extd;

extd = &cp->c_datafork->ff_data.cf_extents[0];
if (extd->startBlock == HFSTOVCB(hfsmp)->vcbJinfoBlock || extd->startBlock == hfsmp->jnl_start) {
return EPERM;
}
}

/*
* Ownership of a file is required in one of two classes of calls:
*
Expand Down Expand Up @@ -447,14 +478,12 @@ hfs_setattrlist(ap)
* If any cnode attributes changed then do an update.
*/
if (alist->volattr == 0) {
struct timeval atime, mtime;
struct timeval tv;

atime.tv_sec = cp->c_atime;
atime.tv_usec = 0;
mtime.tv_sec = cp->c_mtime;
mtime.tv_usec = cp->c_mtime_nsec / 1000;
cp->c_flag |= C_MODIFIED;
if ((error = VOP_UPDATE(vp, &atime, &mtime, 1)))
tv = time;
CTIMES(cp, &tv, &tv);
if ((error = VOP_UPDATE(vp, &tv, &tv, 1)))
goto ErrorExit;
}
/* Volume Rename */
Expand Down Expand Up @@ -482,9 +511,28 @@ hfs_setattrlist(ap)
to_desc.cd_cnid = cp->c_cnid;
to_desc.cd_flags = CD_ISDIR;

// XXXdbg
hfs_global_shared_lock_acquire(hfsmp);
if (hfsmp->jnl) {
if (journal_start_transaction(hfsmp->jnl) != 0) {
hfs_global_shared_lock_release(hfsmp);
error = EINVAL;
/* Restore the old name in the VCB */
copystr(cp->c_desc.cd_nameptr, vcb->vcbVN, sizeof(vcb->vcbVN), NULL);
vcb->vcbFlags |= 0xFF00;
goto ErrorExit;
}
}


/* Lock catalog b-tree */
error = hfs_metafilelocking(hfsmp, kHFSCatalogFileID, LK_EXCLUSIVE, p);
if (error) {
if (hfsmp->jnl) {
journal_end_transaction(hfsmp->jnl);
}
hfs_global_shared_lock_release(hfsmp);

/* Restore the old name in the VCB */
copystr(cp->c_desc.cd_nameptr, vcb->vcbVN, sizeof(vcb->vcbVN), NULL);
vcb->vcbFlags |= 0xFF00;
Expand All @@ -495,7 +543,12 @@ hfs_setattrlist(ap)

/* Unlock the Catalog */
(void) hfs_metafilelocking(hfsmp, kHFSCatalogFileID, LK_RELEASE, p);


if (hfsmp->jnl) {
journal_end_transaction(hfsmp->jnl);
}
hfs_global_shared_lock_release(hfsmp);

if (error) {
/* Restore the old name in the VCB */
copystr(cp->c_desc.cd_nameptr, vcb->vcbVN, sizeof(vcb->vcbVN), NULL);
Expand Down Expand Up @@ -601,12 +654,17 @@ hfs_readdirattr(ap)
int error = 0;
int depleted = 0;
int index, startindex;
int i;
int i, dir_entries;
struct cat_desc *lastdescp = NULL;
struct cat_desc prevdesc;
char * prevnamebuf = NULL;
struct cat_entrylist *ce_list = NULL;

dir_entries = dcp->c_entries;
if (dcp->c_attr.ca_fileid == kHFSRootFolderID && hfsmp->jnl) {
dir_entries -= 3;
}

*(ap->a_actualcount) = 0;
*(ap->a_eofflag) = 0;

Expand Down Expand Up @@ -639,7 +697,7 @@ hfs_readdirattr(ap)

/* Convert uio_offset into a directory index. */
startindex = index = uio->uio_offset / sizeof(struct dirent);
if ((index + 1) > dcp->c_entries) {
if ((index + 1) > dir_entries) {
*(ap->a_eofflag) = 1;
error = 0;
goto exit;
Expand Down Expand Up @@ -781,15 +839,15 @@ hfs_readdirattr(ap)
/* Termination checks */
if ((--maxcount <= 0) ||
(uio->uio_resid < (fixedblocksize + HFS_AVERAGE_NAME_SIZE)) ||
(index >= dcp->c_entries)) {
(index >= dir_entries)) {
depleted = 1;
break;
}
}
} /* for each catalog entry */

/* If there are more entries then save the last name. */
if (index < dcp->c_entries
if (index < dir_entries
&& !(*(ap->a_eofflag))
&& lastdescp != NULL) {
if (prevnamebuf == NULL)
Expand Down Expand Up @@ -1408,9 +1466,12 @@ packdirattr(
if (ATTR_DIR_ENTRYCOUNT & attr) {
u_long entries = cattrp->ca_entries;

if ((descp->cd_parentcnid == kRootParID) &&
(hfsmp->hfs_private_metadata_dir != 0))
--entries; /* hide private dir */
if (descp->cd_parentcnid == kRootParID) {
if (hfsmp->hfs_private_metadata_dir != 0)
--entries; /* hide private dir */
if (hfsmp->jnl)
entries -= 2; /* hide the journal files */
}

*((u_long *)attrbufptr)++ = entries;
}
Expand Down
Loading

0 comments on commit e0c84ff

Please sign in to comment.