]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/hfs/hfs_catalog.c
xnu-344.32.tar.gz
[apple/xnu.git] / bsd / hfs / hfs_catalog.c
index 7d6999e6528b25563aa0e60a9452802e8c93e882..769576d7ecf3d4edc8e4954af96732eaacc192ae 100644 (file)
@@ -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);
 }