X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/9bccf70c0258c7cac2dcb80011b2a964d884c552..d12e16782ebf8bb779633dff9e14486293bf6d07:/bsd/hfs/hfs_catalog.c diff --git a/bsd/hfs/hfs_catalog.c b/bsd/hfs/hfs_catalog.c index 7d6999e65..769576d7e 100644 --- a/bsd/hfs/hfs_catalog.c +++ b/bsd/hfs/hfs_catalog.c @@ -261,6 +261,11 @@ cat_insertfilethread(struct hfsmount *hfsmp, struct cat_desc *descp) if (result) goto exit; + // XXXdbg - preflight all btree operations to make sure there's enough space + result = BTCheckFreeSpace(fcb); + if (result) + goto exit; + BDINIT(file_data, &file_rec); result = BTSearchRecord(fcb, &iterator[0], &file_data, &datasize, &iterator[0]); if (result) @@ -288,6 +293,7 @@ cat_insertfilethread(struct hfsmount *hfsmp, struct cat_desc *descp) (void) BTFlushPath(fcb); } exit: + (void) BTFlushPath(fcb); FREE(iterator, M_TEMP); return MacToVFSError(result); @@ -426,6 +432,15 @@ cat_lookupbykey(struct hfsmount *hfsmp, CatalogKey *keyp, u_long hint, int wantr encoding = getencoding(recp); hint = iterator->hint.nodeNum; + /* Hide the journal files (if any) */ + if (hfsmp->jnl && + ((cnid == hfsmp->hfs_jnlfileid) || + (cnid == hfsmp->hfs_jnlinfoblkid))) { + + result = ENOENT; + goto exit; + } + /* * When a hardlink link is encountered, auto resolve it */ @@ -529,6 +544,11 @@ cat_create(struct hfsmount *hfsmp, struct cat_desc *descp, struct cat_attr *attr hfs_setencodingbits(hfsmp, encoding); } + // XXXdbg - preflight all btree operations to make sure there's enough space + result = BTCheckFreeSpace(fcb); + if (result) + goto exit; + /* * Insert the thread record first */ @@ -617,9 +637,8 @@ cat_create(struct hfsmount *hfsmp, struct cat_desc *descp, struct cat_attr *attr vcb->vcbNxtCNID = nextCNID; vcb->vcbFlags |= 0xFF00; - (void) BTFlushPath(fcb); - exit: + (void) BTFlushPath(fcb); FREE(bto, M_TEMP); return MacToVFSError(result); @@ -678,6 +697,11 @@ cat_rename ( if ((result = buildkey(hfsmp, to_cdp, (HFSPlusCatalogKey *)&to_iterator->key, 0))) goto exit; + // XXXdbg - preflight all btree operations to make sure there's enough space + result = BTCheckFreeSpace(fcb); + if (result) + goto exit; + to_key = (HFSPlusCatalogKey *)&to_iterator->key; MALLOC(recp, CatalogRecord *, sizeof(CatalogRecord), M_TEMP, M_WAITOK); BDINIT(btdata, recp); @@ -781,7 +805,17 @@ cat_rename ( result = BTInsertRecord(fcb, to_iterator, &btdata, datasize); if (result) { /* Try and restore original before leaving */ + // XXXdbg + #if 1 + { + int err; + err = BTInsertRecord(fcb, from_iterator, &btdata, datasize); + if (err) + panic("cat_create: could not undo (BTInsert = %d)", err); + } + #else (void) BTInsertRecord(fcb, from_iterator, &btdata, datasize); + #endif goto exit; } sourcegone = 1; @@ -794,7 +828,17 @@ cat_rename ( result = BTDeleteRecord(fcb, from_iterator); if (result) { /* Try and delete new record before leaving */ + // XXXdbg + #if 1 + { + int err; + err = BTDeleteRecord(fcb, to_iterator); + if (err) + panic("cat_create: could not undo (BTDelete = %d)", err); + } + #else (void) BTDeleteRecord(fcb, to_iterator); + #endif goto exit; } } @@ -834,8 +878,8 @@ cat_rename ( FREE(pluskey, M_TEMP); } } - (void) BTFlushPath(fcb); exit: + (void) BTFlushPath(fcb); if (from_iterator) FREE(from_iterator, M_TEMP); if (to_iterator) @@ -874,7 +918,6 @@ cat_delete(struct hfsmount *hfsmp, struct cat_desc *descp, struct cat_attr *attr * A directory must be empty * A file must be zero length (no blocks) */ - if (descp->cd_cnid < kHFSFirstUserCatalogNodeID || descp->cd_parentcnid == kRootParID) return (EINVAL); @@ -899,6 +942,11 @@ cat_delete(struct hfsmount *hfsmp, struct cat_desc *descp, struct cat_attr *attr if (result) goto exit; + // XXXdbg - preflight all btree operations to make sure there's enough space + result = BTCheckFreeSpace(fcb); + if (result) + goto exit; + /* Delete record */ result = BTDeleteRecord(fcb, iterator); if (result) @@ -910,8 +958,8 @@ cat_delete(struct hfsmount *hfsmp, struct cat_desc *descp, struct cat_attr *attr TrashCatalogIterator(vcb, descp->cd_parentcnid); - (void) BTFlushPath(fcb); exit: + (void) BTFlushPath(fcb); FREE(iterator, M_TEMP); return MacToVFSError(result); @@ -973,9 +1021,8 @@ cat_update(struct hfsmount *hfsmp, struct cat_desc *descp, struct cat_attr *attr /* Update the node hint. */ descp->cd_hint = iterator->hint.nodeNum; - (void) BTFlushPath(fcb); - exit: + (void) BTFlushPath(fcb); FREE(iterator, M_TEMP); return MacToVFSError(result); @@ -1242,13 +1289,22 @@ catrec_readattr(const CatalogKey *key, const CatalogRecord *rec, return (0); /* stop */ } - /* Hide the private meta data directory. */ - if (parentcnid == kRootDirID && - rec->recordType == kHFSPlusFolderRecord && - rec->hfsPlusFolder.folderID == hfsmp->hfs_private_metadata_dir) { - return (1); /* continue */ + /* Hide the private meta data directory and journal files */ + if (parentcnid == kRootDirID) { + if ((rec->recordType == kHFSPlusFolderRecord) && + (rec->hfsPlusFolder.folderID == hfsmp->hfs_private_metadata_dir)) { + return (1); /* continue */ + } + if (hfsmp->jnl && + (rec->recordType == kHFSPlusFileRecord) && + ((rec->hfsPlusFile.fileID == hfsmp->hfs_jnlfileid) || + (rec->hfsPlusFile.fileID == hfsmp->hfs_jnlinfoblkid))) { + + return (1); /* continue */ + } } + cep = &list->entry[list->realentries++]; if (state->stdhfs) { @@ -1408,6 +1464,8 @@ exit: struct read_state { u_int32_t cbs_parentID; u_int32_t cbs_hiddenDirID; + u_int32_t cbs_hiddenJournalID; + u_int32_t cbs_hiddenInfoBlkID; off_t cbs_lastoffset; struct uio * cbs_uio; ExtendedVCB * cbs_vcb; @@ -1517,6 +1575,15 @@ lastitem: catent.d_type == DT_DIR) goto lastitem; + /* Hide the journal files */ + if ((curID == kRootDirID) && + (catent.d_type == DT_REG) && + ((catent.d_fileno == state->cbs_hiddenJournalID) || + (catent.d_fileno == state->cbs_hiddenInfoBlkID))) { + + return (1); /* skip and continue */ + } + state->cbs_lastoffset = state->cbs_uio->uio_offset; /* if this entry won't fit then we're done */ @@ -1565,6 +1632,11 @@ cat_getdirentries(struct hfsmount *hfsmp, struct cat_desc *descp, goto cleanup; state.cbs_hiddenDirID = hfsmp->hfs_private_metadata_dir; + if (hfsmp->jnl) { + state.cbs_hiddenJournalID = hfsmp->hfs_jnlfileid; + state.cbs_hiddenInfoBlkID = hfsmp->hfs_jnlinfoblkid; + } + state.cbs_lastoffset = cip->currentOffset; state.cbs_vcb = vcb; state.cbs_uio = uio; @@ -2203,7 +2275,11 @@ getcnid(const CatalogRecord *crp) case kHFSPlusFileRecord: cnid = crp->hfsPlusFile.fileID; break; + default: + panic("hfs: getcnid: unknown recordType (crp @ 0x%x)\n", crp); + break; } + return (cnid); } @@ -2225,7 +2301,11 @@ getparentcnid(const CatalogRecord *recp) case kHFSPlusFolderThreadRecord: cnid = recp->hfsPlusThread.parentID; break; + default: + panic("hfs: getparentcnid: unknown recordType (crp @ 0x%x)\n", recp); + break; } + return (cnid); }