/*
- * Copyright (c) 2004-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2008 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
#define NR_CACHE 17
#define NR_HASH(btvp, tag) \
- (&nr_hashtbl[((((int)(btvp)) >> 8) ^ ((int)(tag) >> 4)) & nr_hashmask])
+ (&nr_hashtbl[((((intptr_t)(btvp)) >> 8) ^ ((intptr_t)(tag) >> 4)) & nr_hashmask])
LIST_HEAD(nodereserve, nreserve) *nr_hashtbl;
BTReserveSetup()
{
if (sizeof(struct nreserve) != sizeof(cat_cookie_t))
- panic("BTReserveSetup: nreserve size != opaque struct size");
+ panic("hfs: BTReserveSetup: nreserve size != opaque struct size");
nr_hashtbl = hashinit(NR_CACHE, M_HFSMNT, &nr_hashmask);
if (rsrvNodes > availNodes) {
u_int32_t reqblks, freeblks, rsrvblks;
+ uint32_t bt_rsrv;
struct hfsmount *hfsmp;
- /* Try and reserve the last 5% of the disk space for file blocks. */
+ /*
+ * For UNIX conformance, we try and reserve the MIN of either 5% of
+ * total file blocks or 10MB worth of blocks, for growing existing
+ * files. On non-HFS filesystems, creating a new directory entry may
+ * not cause additional disk space to be allocated, but on HFS, creating
+ * a new entry could cause the b-tree to grow. As a result, we take
+ * some precautions here to prevent that on configurations that try to
+ * satisfy conformance.
+ */
hfsmp = VTOVCB(btree->fileRefNum);
rsrvblks = ((u_int64_t)hfsmp->allocLimit * 5) / 100;
- rsrvblks = MIN(rsrvblks, HFS_MAXRESERVE / hfsmp->blockSize);
+ if (hfsmp->blockSize > HFS_BT_MAXRESERVE) {
+ bt_rsrv = 1;
+ }
+ else {
+ bt_rsrv = (HFS_BT_MAXRESERVE / hfsmp->blockSize);
+ }
+ rsrvblks = MIN(rsrvblks, bt_rsrv);
+
freeblks = hfs_freeblks(hfsmp, 0);
if (freeblks <= rsrvblks) {
/* When running low, disallow adding new items. */
lck_mtx_lock(&nr_mutex);
if (nrp->nr_tag) {
if ((nrp->nr_tag != tag) || (nrp->nr_btvp != btvp))
- panic("nr_delete: invalid NR (%p)", nrp);
+ panic("hfs: nr_delete: invalid NR (%p)", nrp);
LIST_REMOVE(nrp, nr_hash);
*nodecnt = nrp->nr_nodecnt;
bzero(nrp, sizeof(struct nreserve));