Skip to content

Commit

Permalink
xnu-201.19.3
Browse files Browse the repository at this point in the history
  • Loading branch information
Darwin authored and das committed Jun 4, 2017
1 parent bfd5905 commit 2359fe3
Show file tree
Hide file tree
Showing 31 changed files with 655 additions and 5,827 deletions.
1 change: 1 addition & 0 deletions bsd/conf/files
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ bsd/hfs/hfscommon/BTree/BTree.c optional hfs
bsd/hfs/hfscommon/BTree/BTreeAllocate.c optional hfs
bsd/hfs/hfscommon/BTree/BTreeMiscOps.c optional hfs
bsd/hfs/hfscommon/BTree/BTreeNodeOps.c optional hfs
bsd/hfs/hfscommon/BTree/BTreeScanner.c optional hfs
bsd/hfs/hfscommon/BTree/BTreeTreeOps.c optional hfs
bsd/hfs/hfscommon/Catalog/Catalog.c optional hfs
bsd/hfs/hfscommon/Catalog/CatalogIterators.c optional hfs
Expand Down
2 changes: 1 addition & 1 deletion bsd/conf/version.minor
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3
4
176 changes: 103 additions & 73 deletions bsd/hfs/hfs_search.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
* Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
Expand Down Expand Up @@ -47,25 +47,13 @@
#include "hfscommon/headers/FileMgrInternal.h"
#include "hfscommon/headers/CatalogPrivate.h"
#include "hfscommon/headers/HFSUnicodeWrappers.h"


/* Private description used in hfs_search */
/*
* ============ W A R N I N G ! ============
* DO NOT INCREASE THE SIZE OF THIS STRUCT!
* It must match the size of the opaque
* searchstate struct (in sys/attr.h).
*/
struct SearchState {
long searchBits;
BTreeIterator btreeIterator;
};
typedef struct SearchState SearchState;
#include "hfscommon/headers/BTreesPrivate.h"
#include "hfscommon/headers/BTreeScanner.h"


static int UnpackSearchAttributeBlock(struct vnode *vp, struct attrlist *alist, searchinfospec_t *searchInfo, void *attributeBuffer);

Boolean CheckCriteria(ExtendedVCB *vcb, const SearchState *searchState,
Boolean CheckCriteria(ExtendedVCB *vcb,
u_long searchBits, struct attrlist *attrList,
CatalogNodeData *cnp, CatalogKey *key,
searchinfospec_t *searchInfo1, searchinfospec_t *searchInfo2);
Expand Down Expand Up @@ -129,11 +117,7 @@ struct vop_searchfs_args *ap; /*
struct searchstate *a_searchstate;
*/
{
CatalogNodeData cnode;
BTreeKey *key;
FSBufferDescriptor btRecord;
FCB* catalogFCB;
SearchState *searchState;
searchinfospec_t searchInfo1;
searchinfospec_t searchInfo2;
void *attributesBuffer;
Expand All @@ -143,7 +127,13 @@ struct vop_searchfs_args *ap; /*
u_long fixedBlockSize;
u_long eachReturnBufferSize;
struct proc *p = current_proc();
u_long nodesToCheck = 30; /* After we search 30 nodes we must give up time */
CatalogNodeData myCNodeData;
CatalogNodeData * myCNodeDataPtr;
CatalogKey * myCurrentKeyPtr;
CatalogRecord * myCurrentDataPtr;
CatPosition * myCatPositionPtr;
BTScanState myBTScanState;
Boolean timerExpired = false;
u_long lastNodeNum = 0XFFFFFFFF;
ExtendedVCB *vcb = VTOVCB(ap->a_vp);
int err = E_NONE;
Expand All @@ -160,36 +150,13 @@ struct vop_searchfs_args *ap; /*
return (EINVAL);

isHFSPlus = (vcb->vcbSigWord == kHFSPlusSigWord);
searchState = (SearchState *)ap->a_searchstate;

/*
* Check if this is the first time we are being called.
* If it is, allocate SearchState and we'll move it to the users space on exit
*/
if ( ap->a_options & SRCHFS_START ) {
bzero( (caddr_t)searchState, sizeof(SearchState) );
operation = kBTreeFirstRecord;
ap->a_options &= ~SRCHFS_START;
} else {
operation = kBTreeCurrentRecord;
}

/* UnPack the search boundries, searchInfo1, searchInfo2 */
err = UnpackSearchAttributeBlock( ap->a_vp, ap->a_searchattrs, &searchInfo1, ap->a_searchparams1 );
if (err) return err;
err = UnpackSearchAttributeBlock( ap->a_vp, ap->a_searchattrs, &searchInfo2, ap->a_searchparams2 );
if (err) return err;

btRecord.itemCount = 1;
if (isHFSPlus) {
btRecord.itemSize = sizeof(cnode);
btRecord.bufferAddress = &cnode;
} else {
btRecord.itemSize = sizeof(HFSCatalogFile);
btRecord.bufferAddress = &cnode.cnd_extra;
}
catalogFCB = VTOFCB( vcb->catalogRefNum );
key = (BTreeKey*) &(searchState->btreeIterator.key);
fixedBlockSize = sizeof(u_long) + AttributeBlockSize( ap->a_returnattrs ); /* u_long for length longword */
eachReturnBufferSize = fixedBlockSize;

Expand All @@ -205,41 +172,102 @@ struct vop_searchfs_args *ap; /*
goto ExitThisRoutine;
};

catalogFCB = VTOFCB( vcb->catalogRefNum );
myCurrentKeyPtr = NULL;
myCurrentDataPtr = NULL;
myCatPositionPtr = (CatPosition *)ap->a_searchstate;

if (ap->a_options & SRCHFS_START) {
/* Starting a new search. */
ap->a_options &= ~SRCHFS_START;
bzero( (caddr_t)myCatPositionPtr, sizeof( *myCatPositionPtr ) );
err = BTScanInitialize(catalogFCB, 0, 0, 0, kCatSearchBufferSize, &myBTScanState);
} else {
/* Resuming a search. */
err = BTScanInitialize(catalogFCB, myCatPositionPtr->nextNode,
myCatPositionPtr->nextRecord,
myCatPositionPtr->recordsFound,
kCatSearchBufferSize,
&myBTScanState);
#if 0
/* Make sure Catalog hasn't changed. */
if (err == 0
&& myCatPositionPtr->writeCount != myBTScanState.btcb->writeCount) {
myCatPositionPtr->writeCount = myBTScanState.btcb->writeCount;
err = EBUSY; /* catChangedErr */
}
#endif
}

/* Unlock catalog b-tree */
(void) hfs_metafilelocking(VTOHFS(ap->a_vp), kHFSCatalogFileID, LK_RELEASE, p);
if (err)
goto ExitThisRoutine;

/*
* Iterate over all the catalog btree records
* Check all the catalog btree records...
* return the attributes for matching items
*/

err = BTIterateRecord( catalogFCB, operation, &(searchState->btreeIterator), &btRecord, &recordSize );
for (;;) {
struct timeval myCurrentTime;
struct timeval myElapsedTime;

err = BTScanNextRecord(&myBTScanState, timerExpired,
(void **)&myCurrentKeyPtr, (void **)&myCurrentDataPtr,
NULL);
if (err)
break;

while( err == E_NONE ) {
if (!isHFSPlus)
CopyCatalogNodeData(vcb, (CatalogRecord*)&cnode.cnd_extra, &cnode);

if ( CheckCriteria( vcb, searchState, ap->a_options, ap->a_searchattrs, &cnode,
(CatalogKey *)key, &searchInfo1, &searchInfo2 ) &&
CheckAccess(&cnode, (CatalogKey *)key, ap->a_uio->uio_procp)) {
err = InsertMatch(ap->a_vp, ap->a_uio, &cnode, (CatalogKey *)key,
ap->a_returnattrs, attributesBuffer, variableBuffer,
eachReturnBufferSize, ap->a_nummatches);
if ( err != E_NONE )
break;
if ( isHFSPlus ) {
// HFSPlus vols have CatalogRecords that map exactly to CatalogNodeData so there is no need
// to copy.
myCNodeDataPtr = (CatalogNodeData *) myCurrentDataPtr;
} else {
CopyCatalogNodeData( vcb, myCurrentDataPtr, &myCNodeData );
myCNodeDataPtr = &myCNodeData;
}

err = BTIterateRecord( catalogFCB, kBTreeNextRecord, &(searchState->btreeIterator), &btRecord, &recordSize );

if ( *(ap->a_nummatches) >= ap->a_maxmatches )

if (CheckCriteria(vcb, ap->a_options, ap->a_searchattrs, myCNodeDataPtr,
myCurrentKeyPtr, &searchInfo1, &searchInfo2) &&
CheckAccess(myCNodeDataPtr, myCurrentKeyPtr, ap->a_uio->uio_procp)) {

err = InsertMatch(ap->a_vp, ap->a_uio, myCNodeDataPtr,
myCurrentKeyPtr, ap->a_returnattrs,
attributesBuffer, variableBuffer,
eachReturnBufferSize, ap->a_nummatches);
if (err) {
/*
* The last match didn't fit so come back
* to this record on the next trip.
*/
--myBTScanState.recordsFound;
--myBTScanState.recordNum;
break;
}
if (*(ap->a_nummatches) >= ap->a_maxmatches)
break;
}

if ( searchState->btreeIterator.hint.nodeNum != lastNodeNum ) {
lastNodeNum = searchState->btreeIterator.hint.nodeNum;
if ( --nodesToCheck == 0 )
break; /* We must leave the kernel to give up time */
/*
* Check our elapsed time and bail if we've hit the max.
* The idea here is to throttle the amount of time we
* spend in the kernel.
*/
myCurrentTime = time;
timersub(&myCurrentTime, &myBTScanState.startTime, &myElapsedTime);
/* Note: assumes kMaxMicroSecsInKernel is less than 1,000,000 */
if (myElapsedTime.tv_sec > 0
|| myElapsedTime.tv_usec >= kMaxMicroSecsInKernel) {
timerExpired = true;
}
}

/* Unlock catalog b-tree */
(void) hfs_metafilelocking( VTOHFS(ap->a_vp), kHFSCatalogFileID, LK_RELEASE, p );
/* Update catalog position */
myCatPositionPtr->writeCount = myBTScanState.btcb->writeCount;

BTScanTerminate(&myBTScanState, &myCatPositionPtr->nextNode,
&myCatPositionPtr->nextRecord,
&myCatPositionPtr->recordsFound);

if ( err == E_NONE ) {
err = EAGAIN; /* signal to the user to call searchfs again */
Expand All @@ -250,12 +278,14 @@ struct vop_searchfs_args *ap; /*
err = ENOBUFS;
} else if ( err == btNotFound ) {
err = E_NONE; /* the entire disk has been searched */
} else if ( err == fsBTTimeOutErr ) {
err = EAGAIN;
}

ExitThisRoutine:
FREE( attributesBuffer, M_TEMP );

return( err );
return (MacToVFSError(err));
}


Expand Down Expand Up @@ -330,7 +360,7 @@ CheckAccess(CatalogNodeData *cnp, CatalogKey *key, struct proc *p)
}

Boolean
CheckCriteria( ExtendedVCB *vcb, const SearchState *searchState, u_long searchBits,
CheckCriteria( ExtendedVCB *vcb, u_long searchBits,
struct attrlist *attrList, CatalogNodeData *cnp, CatalogKey *key,
searchinfospec_t *searchInfo1, searchinfospec_t *searchInfo2 )
{
Expand Down Expand Up @@ -395,11 +425,11 @@ CheckCriteria( ExtendedVCB *vcb, const SearchState *searchState, u_long searchBi

/* Now that we have a record worth searching, see if it matches the search attributes */
if (cnp->cnd_type == kCatalogFileNode) {
if ((attrList->dirattr & ~ATTR_FILE_VALIDMASK) != 0) { /* attr we do know about */
if ((attrList->fileattr & ~ATTR_FILE_VALIDMASK) != 0) { /* attr we do know about */
matched = false;
goto TestDone;
}
else if ((attrList->dirattr & ATTR_FILE_VALIDMASK) != 0) {
else if ((attrList->fileattr & ATTR_FILE_VALIDMASK) != 0) {
searchAttributes = attrList->fileattr;

/* File logical length (data fork) */
Expand Down
Loading

0 comments on commit 2359fe3

Please sign in to comment.