X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/b4c24cb9d3df001f2892dc4ed451bc769ff28a9f..483a1d1004b64bbaaef2c64c17c6b999009a54d2:/bsd/hfs/hfs_link.c?ds=inline diff --git a/bsd/hfs/hfs_link.c b/bsd/hfs/hfs_link.c index 97a36516c..97dfde7bb 100644 --- a/bsd/hfs/hfs_link.c +++ b/bsd/hfs/hfs_link.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved. + * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -113,6 +113,7 @@ hfs_makelink(struct hfsmount *hfsmp, struct cnode *cp, struct cnode *dcp, struct cat_desc to_desc; int newlink = 0; int retval; + cat_cookie_t cookie = {0}; /* We don't allow link nodes in our Private Meta Data folder! */ @@ -122,10 +123,15 @@ hfs_makelink(struct hfsmount *hfsmp, struct cnode *cp, struct cnode *dcp, if (hfs_freeblks(hfsmp, 0) == 0) return (ENOSPC); + /* Reserve some space in the Catalog file. */ + if ((retval = cat_preflight(hfsmp, (2 * CAT_CREATE)+ CAT_RENAME, &cookie, p))) { + return (retval); + } + /* Lock catalog b-tree */ retval = hfs_metafilelocking(hfsmp, kHFSCatalogFileID, LK_EXCLUSIVE, p); if (retval) { - return retval; + goto out2; } /* @@ -216,7 +222,8 @@ hfs_makelink(struct hfsmount *hfsmp, struct cnode *cp, struct cnode *dcp, out: /* Unlock catalog b-tree */ (void) hfs_metafilelocking(hfsmp, kHFSCatalogFileID, LK_RELEASE, p); - +out2: + cat_postflight(hfsmp, &cookie, p); return (retval); } @@ -232,6 +239,7 @@ out: IN struct componentname *cnp; */ +__private_extern__ int hfs_link(ap) struct vop_link_args /* { @@ -264,7 +272,7 @@ hfs_link(ap) if (VTOVCB(tdvp)->vcbSigWord != kHFSPlusSigWord) return err_link(ap); /* hfs disks don't support hard links */ - if (hfsmp->hfs_private_metadata_dir == 0) + if (hfsmp->hfs_privdir_desc.cd_cnid == 0) return err_link(ap); /* no private metadata dir, no links possible */ if (tdvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE, p))) { @@ -294,7 +302,9 @@ hfs_link(ap) if (hfsmp->jnl) { if (journal_start_transaction(hfsmp->jnl) != 0) { hfs_global_shared_lock_release(hfsmp); - return EINVAL; + VOP_ABORTOP(tdvp, cnp); + error = EINVAL; /* cannot link to a special file */ + goto out1; } } @@ -322,15 +332,25 @@ hfs_link(ap) } // XXXdbg - need to do this here as well because cp could have changed - error = VOP_UPDATE(vp, &tv, &tv, 1); + (void) VOP_UPDATE(vp, &tv, &tv, 1); - FREE_ZONE(cnp->cn_pnbuf, cnp->cn_pnlen, M_NAMEI); if (hfsmp->jnl) { journal_end_transaction(hfsmp->jnl); } hfs_global_shared_lock_release(hfsmp); + /* free the pathname buffer */ + { + char *tmp = cnp->cn_pnbuf; + cnp->cn_pnbuf = NULL; + cnp->cn_flags &= ~HASBUF; + FREE_ZONE(tmp, cnp->cn_pnlen, M_NAMEI); + } + + HFS_KNOTE(vp, NOTE_LINK); + HFS_KNOTE(tdvp, NOTE_WRITE); + out1: if (tdvp != vp) VOP_UNLOCK(vp, 0, p);