~ubuntu-branches/ubuntu/trusty/hfsprogs/trusty-proposed

« back to all changes in this revision

Viewing changes to .pc/0010-Rename-custom-macro-nil-with-NULL.patch/fsck_hfs.tproj/dfalib/BTreeAllocate.c

  • Committer: Package Import Robot
  • Author(s): Rogério Brito
  • Date: 2013-10-24 01:20:15 UTC
  • Revision ID: package-import@ubuntu.com-20131024012015-qsncxmr4cielybvz
Tags: 332.25-11
* debian/control: Remove DMUA flag.
* debian/rules: Override rules for which we don't have makefiles.
  (Closes: #724195)
* debian/patches:
  + Change the headers to be friendlier with gbp pq.
  + Remove unreferenced patches in series file.
  + Coalesce all patches touching man pages into one.
  + Regenerate everything from patch-queue branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
 
3
 *
 
4
 * @APPLE_LICENSE_HEADER_START@
 
5
 * 
 
6
 * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
 
7
 * Reserved.  This file contains Original Code and/or Modifications of
 
8
 * Original Code as defined in and that are subject to the Apple Public
 
9
 * Source License Version 1.0 (the 'License').  You may not use this file
 
10
 * except in compliance with the License.  Please obtain a copy of the
 
11
 * License at http://www.apple.com/publicsource and read it before using
 
12
 * this file.
 
13
 * 
 
14
 * The Original Code and all software distributed under the License are
 
15
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 
16
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 
17
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 
18
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
 
19
 * License for the specific language governing rights and limitations
 
20
 * under the License."
 
21
 * 
 
22
 * @APPLE_LICENSE_HEADER_END@
 
23
 */
 
24
/*
 
25
        File:           BTreeAllocate.c
 
26
 
 
27
        Contains:       BTree Node Allocation routines for the BTree Module.
 
28
 
 
29
        Version:        xxx put the technology version here xxx
 
30
 
 
31
        Written by:     Gordon Sheridan and Bill Bruffey
 
32
 
 
33
        Copyright:      � 1992-1999 by Apple Computer, Inc., all rights reserved.
 
34
*/
 
35
 
 
36
#include "BTreePrivate.h"
 
37
#include "hfs_endian.h"
 
38
 
 
39
///////////////////// Routines Internal To BTreeAllocate.c //////////////////////
 
40
 
 
41
OSStatus        GetMapNode (BTreeControlBlockPtr          btreePtr,
 
42
                                                BlockDescriptor                  *nodePtr,
 
43
                                                UInt16                                  **mapPtr,
 
44
                                                UInt16                                   *mapSize );
 
45
 
 
46
/////////////////////////////////////////////////////////////////////////////////
 
47
 
 
48
/*-------------------------------------------------------------------------------
 
49
 
 
50
Routine:        AllocateNode    -       Find Free Node, Mark It Used, and Return Node Number.
 
51
 
 
52
Function:       Searches the map records for the first free node, marks it "in use" and
 
53
                        returns the node number found. This routine should really only be called
 
54
                        when we know there are free blocks, otherwise it's just a waste of time.
 
55
 
 
56
Note:           We have to examine map nodes a word at a time rather than a long word
 
57
                        because the External BTree Mgr used map records that were not an integral
 
58
                        number of long words. Too bad. In our spare time could develop a more
 
59
                        sophisticated algorithm that read map records by long words (and long
 
60
                        word aligned) and handled the spare bytes at the beginning and end
 
61
                        appropriately.
 
62
 
 
63
Input:          btreePtr        - pointer to control block for BTree file               
 
64
 
 
65
Output:         nodeNum         - number of node allocated
 
66
                        
 
67
                        
 
68
Result:         noErr                   - success
 
69
                        fsBTNoMoreMapNodesErr   - no free blocks were found
 
70
                        != noErr                - failure
 
71
-------------------------------------------------------------------------------*/
 
72
 
 
73
OSStatus        AllocateNode (BTreeControlBlockPtr              btreePtr, UInt32        *nodeNum)
 
74
{
 
75
        OSStatus                 err;
 
76
        BlockDescriptor  node;
 
77
        UInt16                  *mapPtr, *pos;
 
78
        UInt16                   mapSize, size;
 
79
        UInt16                   freeWord;
 
80
        UInt16                   mask;
 
81
        UInt16                   bitOffset;
 
82
        UInt32                   nodeNumber;
 
83
        
 
84
        
 
85
        nodeNumber              = 0;                            // first node number of header map record
 
86
        node.buffer             = nil;                          // clear node.buffer to get header node
 
87
                                                                                //      - and for ErrorExit
 
88
        
 
89
        while (true)
 
90
        {
 
91
                err = GetMapNode (btreePtr, &node, &mapPtr, &mapSize);
 
92
                M_ExitOnError (err);
 
93
                
 
94
        //////////////////////// Find Word with Free Bit ////////////////////////////
 
95
 
 
96
                pos             = mapPtr;
 
97
                size    = mapSize;
 
98
                size  >>= 1;                                            // convert to number of words
 
99
                                                //�� assumes mapRecords contain an integral number of words
 
100
 
 
101
                while ( size-- )
 
102
                {
 
103
                        if ( *pos++ != 0xFFFF )                 // assume test fails, and increment pos
 
104
                                break;
 
105
                }
 
106
 
 
107
                --pos;                                                          // whoa! backup
 
108
 
 
109
                if (*pos != 0xFFFF)                                     // hey, we got one!
 
110
                        break;
 
111
                
 
112
                nodeNumber += mapSize << 3;                     // covert to number of bits (nodes)
 
113
        }
 
114
        
 
115
        ///////////////////////// Find Free Bit in Word /////////////////////////////
 
116
 
 
117
        freeWord        = SWAP_BE16 (*pos);
 
118
        bitOffset       =  15;
 
119
        mask            =  0x8000;
 
120
        
 
121
        do {
 
122
                if ( (freeWord & mask) == 0)
 
123
                        break;
 
124
                mask >>= 1;
 
125
        } while (--bitOffset);
 
126
 
 
127
        ////////////////////// Calculate Free Node Number ///////////////////////////
 
128
        
 
129
        nodeNumber += ((pos - mapPtr) << 4) + (15 - bitOffset); // (pos-mapPtr) = # of words!
 
130
        
 
131
        
 
132
        ///////////////////////// Check for End of Map //////////////////////////////
 
133
 
 
134
        if (nodeNumber >= btreePtr->totalNodes)
 
135
        {
 
136
                err = fsBTFullErr;
 
137
                goto ErrorExit;
 
138
        }
 
139
 
 
140
        /////////////////////////// Allocate the Node ///////////////////////////////
 
141
 
 
142
        *pos |= SWAP_BE16 (mask);                               // set the map bit for the node
 
143
 
 
144
        err = UpdateNode (btreePtr, &node);
 
145
        M_ExitOnError (err);
 
146
        
 
147
        --btreePtr->freeNodes;
 
148
        btreePtr->flags |= kBTHeaderDirty;
 
149
        *nodeNum = nodeNumber;
 
150
        
 
151
        return noErr;
 
152
 
 
153
////////////////////////////////// Error Exit ///////////////////////////////////
 
154
 
 
155
ErrorExit:
 
156
        
 
157
        (void) ReleaseNode (btreePtr, &node);
 
158
        *nodeNum = 0;
 
159
        
 
160
        return  err;
 
161
}
 
162
 
 
163
 
 
164
 
 
165
/*-------------------------------------------------------------------------------
 
166
 
 
167
Routine:        FreeNode        -       Clear allocation bit for node.
 
168
 
 
169
Function:       Finds the bit representing the node specified by nodeNum in the node
 
170
                        map and clears the bit.
 
171
 
 
172
 
 
173
Input:          btreePtr        - pointer to control block for BTree file
 
174
                        nodeNum         - number of node to mark free
 
175
 
 
176
Output:         none                    
 
177
                        
 
178
Result:         noErr                   - success
 
179
                        fsBTNoMoreMapNodesErr   - node number is beyond end of node map
 
180
                        != noErr                - GetNode or ReleaseNode encountered some difficulty
 
181
-------------------------------------------------------------------------------*/
 
182
 
 
183
OSStatus        FreeNode (BTreeControlBlockPtr          btreePtr, UInt32        nodeNum)
 
184
{
 
185
        OSStatus                 err;
 
186
        BlockDescriptor  node;
 
187
        UInt32                   nodeIndex;
 
188
        UInt16                   mapSize;
 
189
        UInt16                  *mapPos;
 
190
        UInt16                   bitOffset;
 
191
        
 
192
 
 
193
        //////////////////////////// Find Map Record ////////////////////////////////
 
194
        nodeIndex                       = 0;                            // first node number of header map record
 
195
        node.buffer                     = nil;                          // invalidate node.buffer to get header node
 
196
        
 
197
        while (nodeNum >= nodeIndex)
 
198
        {
 
199
                err = GetMapNode (btreePtr, &node, &mapPos, &mapSize);
 
200
                M_ExitOnError (err);
 
201
                
 
202
                nodeIndex += mapSize << 3;                      // covert to number of bits (nodes)
 
203
        }
 
204
        
 
205
        //////////////////////////// Mark Node Free /////////////////////////////////
 
206
 
 
207
        nodeNum -= (nodeIndex - (mapSize << 3));                        // relative to this map record
 
208
        bitOffset = 15 - (nodeNum & 0x0000000F);                        // last 4 bits are bit offset
 
209
        mapPos += nodeNum >> 4;                                                         // point to word containing map bit
 
210
        M_SWAP_BE16_ClearBitNum (*mapPos, bitOffset);           // clear it
 
211
        
 
212
        err = UpdateNode (btreePtr, &node);
 
213
        M_ExitOnError (err);
 
214
        
 
215
 
 
216
        ++btreePtr->freeNodes;
 
217
        btreePtr->flags |= kBTHeaderDirty;                                      //�� how about a macro for this
 
218
 
 
219
        return noErr;
 
220
 
 
221
ErrorExit:
 
222
 
 
223
        (void) ReleaseNode (btreePtr, &node);
 
224
 
 
225
        return  err;
 
226
}
 
227
 
 
228
 
 
229
 
 
230
/*-------------------------------------------------------------------------------
 
231
 
 
232
Routine:        ExtendBTree     -       Call FSAgent to extend file, and allocate necessary map nodes.
 
233
 
 
234
Function:       This routine calls the the FSAgent to extend the end of fork, if necessary,
 
235
                        to accomodate the number of nodes requested. It then allocates as many
 
236
                        map nodes as are necessary to account for all the nodes in the B*Tree.
 
237
                        If newTotalNodes is less than the current number of nodes, no action is
 
238
                        taken.
 
239
 
 
240
Note:           Internal HFS File Manager BTree Module counts on an integral number of
 
241
                        long words in map records, although they are not long word aligned.
 
242
 
 
243
Input:          btreePtr                - pointer to control block for BTree file
 
244
                        newTotalNodes   - total number of nodes the B*Tree is to extended to
 
245
                        
 
246
Output:         none
 
247
                        
 
248
Result:         noErr           - success
 
249
                        != noErr        - failure
 
250
-------------------------------------------------------------------------------*/
 
251
 
 
252
OSStatus        ExtendBTree     (BTreeControlBlockPtr   btreePtr,
 
253
                                                 UInt32                                 newTotalNodes )
 
254
{
 
255
        OSStatus                                 err;
 
256
        SFCB                                    *filePtr;
 
257
        FSSize                                   minEOF, maxEOF;        
 
258
        UInt16                                   nodeSize;
 
259
        UInt32                                   oldTotalNodes;
 
260
        UInt32                                   newMapNodes;
 
261
        UInt32                                   mapBits, totalMapBits;
 
262
        UInt32                                   recStartBit;
 
263
        UInt32                                   nodeNum, nextNodeNum;
 
264
        UInt32                                   firstNewMapNodeNum, lastNewMapNodeNum;
 
265
        BlockDescriptor                  mapNode, newNode;
 
266
        UInt16                                  *mapPos;
 
267
        UInt16                                  *mapStart;
 
268
        UInt16                                   mapSize;
 
269
        UInt16                                   mapNodeRecSize;
 
270
        UInt32                                   bitInWord, bitInRecord;
 
271
        UInt16                                   mapIndex;
 
272
 
 
273
 
 
274
        oldTotalNodes           = btreePtr->totalNodes;
 
275
        if (newTotalNodes  <= oldTotalNodes)                            // we're done!
 
276
                return  noErr;
 
277
 
 
278
        nodeSize                        = btreePtr->nodeSize;
 
279
        filePtr                         = btreePtr->fcbPtr;
 
280
        
 
281
        mapNode.buffer          = nil;
 
282
        newNode.buffer          = nil;
 
283
 
 
284
        mapNodeRecSize  = nodeSize - sizeof(BTNodeDescriptor) - 6;      // 2 bytes of free space (see note)
 
285
 
 
286
        //�� update for proper 64 bit arithmetic!!
 
287
 
 
288
 
 
289
        //////////////////////// Count Bits In Node Map /////////////////////////////
 
290
        
 
291
        totalMapBits = 0;
 
292
        do {
 
293
                err = GetMapNode (btreePtr, &mapNode, &mapStart, &mapSize);
 
294
                M_ExitOnError (err);
 
295
                
 
296
                mapBits         = mapSize << 3;                         // mapSize (in bytes) * 8
 
297
                recStartBit     = totalMapBits;                         // bit number of first bit in map record
 
298
                totalMapBits  += mapBits;
 
299
                
 
300
        } while ( ((BTNodeDescriptor*)mapNode.buffer)->fLink != 0 );
 
301
 
 
302
        if (DEBUG_BUILD && totalMapBits != CalcMapBits (btreePtr))
 
303
                Panic ("\pExtendBTree: totalMapBits != CalcMapBits");
 
304
                
 
305
        /////////////////////// Extend LEOF If Necessary ////////////////////////////
 
306
 
 
307
        minEOF = (UInt64)newTotalNodes * (UInt64)nodeSize;
 
308
        if ( filePtr->fcbLogicalSize < minEOF )
 
309
        {
 
310
                maxEOF = 0xFFFFFFFFFFFFFFFFULL;  
 
311
 
 
312
                err = btreePtr->setEndOfForkProc (btreePtr->fcbPtr, minEOF, maxEOF);
 
313
                M_ExitOnError (err);
 
314
        }
 
315
 
 
316
        
 
317
        //////////////////// Calc New Total Number Of Nodes /////////////////////////
 
318
        
 
319
        newTotalNodes = filePtr->fcbLogicalSize / nodeSize;             //�� hack!
 
320
        //�� do we wish to perform any verification of newTotalNodes at this point?
 
321
 
 
322
        btreePtr->totalNodes = newTotalNodes;           //�� do we need to update freeNodes here too?
 
323
 
 
324
 
 
325
        ////////////// Calculate Number Of New Map Nodes Required ///////////////////
 
326
 
 
327
        newMapNodes             = 0;
 
328
        if (newTotalNodes > totalMapBits)
 
329
        {
 
330
                newMapNodes                     = (((newTotalNodes - totalMapBits) >> 3) / mapNodeRecSize) + 1;
 
331
                firstNewMapNodeNum      = oldTotalNodes;
 
332
                lastNewMapNodeNum       = firstNewMapNodeNum + newMapNodes - 1;
 
333
        }
 
334
        else
 
335
        {
 
336
                err = ReleaseNode (btreePtr, &mapNode);
 
337
                M_ExitOnError (err);
 
338
        
 
339
                goto Success;
 
340
        }
 
341
        
 
342
 
 
343
        /////////////////////// Initialize New Map Nodes ////////////////////////////
 
344
 
 
345
        ((BTNodeDescriptor*)mapNode.buffer)->fLink = firstNewMapNodeNum;
 
346
 
 
347
        nodeNum         = firstNewMapNodeNum;
 
348
        while (true)
 
349
        {
 
350
                err = GetNewNode (btreePtr, nodeNum, &newNode);
 
351
                M_ExitOnError (err);
 
352
                
 
353
                ((NodeDescPtr)newNode.buffer)->numRecords       = 1;
 
354
                ((NodeDescPtr)newNode.buffer)->kind                     = kBTMapNode;
 
355
                
 
356
                // set free space offset
 
357
                *(UInt16 *)((Ptr)newNode.buffer + nodeSize - 4) = nodeSize - 6;
 
358
 
 
359
                if (nodeNum++ == lastNewMapNodeNum)
 
360
                        break;
 
361
 
 
362
                ((BTNodeDescriptor*)newNode.buffer)->fLink = nodeNum;   // point to next map node
 
363
                        
 
364
                err = UpdateNode (btreePtr, &newNode);
 
365
                M_ExitOnError (err);
 
366
        }
 
367
        
 
368
        err = UpdateNode (btreePtr, &newNode);
 
369
        M_ExitOnError (err);
 
370
                
 
371
 
 
372
        ///////////////////// Mark New Map Nodes Allocated //////////////////////////
 
373
 
 
374
        nodeNum = firstNewMapNodeNum;
 
375
        do {    
 
376
                bitInRecord     = nodeNum - recStartBit;
 
377
 
 
378
                while (bitInRecord >= mapBits)
 
379
                {
 
380
                        nextNodeNum = ((NodeDescPtr)mapNode.buffer)->fLink;
 
381
                        if ( nextNodeNum == 0)
 
382
                        {
 
383
                                err = fsBTNoMoreMapNodesErr;
 
384
                                goto ErrorExit;
 
385
                        }
 
386
                        
 
387
                        err = UpdateNode (btreePtr, &mapNode);
 
388
                        M_ExitOnError (err);
 
389
                        
 
390
                        err = GetNode (btreePtr, nextNodeNum, &mapNode);
 
391
                        M_ExitOnError (err);
 
392
                        
 
393
                        mapIndex = 0;
 
394
                        
 
395
                        mapStart         = (UInt16 *) GetRecordAddress (btreePtr, mapNode.buffer, mapIndex);
 
396
                        mapSize          = GetRecordSize (btreePtr, mapNode.buffer, mapIndex);
 
397
                        
 
398
                        if (DEBUG_BUILD && mapSize != M_MapRecordSize (btreePtr->nodeSize) )
 
399
                        {
 
400
                                Panic ("\pExtendBTree: mapSize != M_MapRecordSize");
 
401
                        }
 
402
                        
 
403
                        mapBits         = mapSize << 3;         // mapSize (in bytes) * 8
 
404
                        recStartBit     = totalMapBits;         // bit number of first bit in map record
 
405
                        totalMapBits  += mapBits;
 
406
 
 
407
                        bitInRecord     = nodeNum - recStartBit;
 
408
                }
 
409
 
 
410
                mapPos          = mapStart + ((nodeNum - recStartBit) >> 4);
 
411
                bitInWord       = 15 - ((nodeNum - recStartBit) & 0x0000000F);
 
412
                M_SWAP_BE16_SetBitNum (*mapPos, bitInWord);
 
413
                
 
414
                ++nodeNum;
 
415
                
 
416
        } while (nodeNum <= lastNewMapNodeNum);
 
417
 
 
418
        err = UpdateNode (btreePtr, &mapNode);
 
419
        M_ExitOnError (err);
 
420
 
 
421
        
 
422
        //////////////////////////////// Success ////////////////////////////////////
 
423
 
 
424
Success:
 
425
        
 
426
        btreePtr->totalNodes     =  newTotalNodes;
 
427
        btreePtr->freeNodes             += (newTotalNodes - oldTotalNodes) - newMapNodes;
 
428
 
 
429
        btreePtr->flags                 |= kBTHeaderDirty;              //�� how about a macro for this
 
430
        
 
431
        return  noErr;
 
432
 
 
433
 
 
434
        ////////////////////////////// Error Exit ///////////////////////////////////
 
435
 
 
436
ErrorExit:
 
437
 
 
438
        (void) ReleaseNode (btreePtr, &mapNode);
 
439
        (void) ReleaseNode (btreePtr, &newNode);
 
440
        
 
441
        return  err;
 
442
}
 
443
 
 
444
 
 
445
 
 
446
/*-------------------------------------------------------------------------------
 
447
 
 
448
Routine:        GetMapNode      -       Get the next map node and pointer to the map record.
 
449
 
 
450
Function:       Given a BlockDescriptor to a map node in nodePtr, GetMapNode releases
 
451
                        it and gets the next node. If nodePtr->buffer is nil, then the header
 
452
                        node is retrieved.
 
453
 
 
454
 
 
455
Input:          btreePtr        - pointer to control block for BTree file
 
456
                        nodePtr         - pointer to a BlockDescriptor of a map node
 
457
                        
 
458
Output:         nodePtr         - pointer to the BlockDescriptor for the next map node
 
459
                        mapPtr          - pointer to the map record within the map node
 
460
                        mapSize         - number of bytes in the map record
 
461
                        
 
462
Result:         noErr                   - success
 
463
                        fsBTNoMoreMapNodesErr   - we've run out of map nodes
 
464
                        fsBTInvalidNodeErr                      - bad node, or not node type kMapNode
 
465
                        != noErr                - failure
 
466
-------------------------------------------------------------------------------*/
 
467
 
 
468
OSStatus        GetMapNode (BTreeControlBlockPtr          btreePtr,
 
469
                                                BlockDescriptor                  *nodePtr,
 
470
                                                UInt16                                  **mapPtr,
 
471
                                                UInt16                                   *mapSize )
 
472
{
 
473
        OSStatus        err;
 
474
        UInt16          mapIndex;
 
475
        UInt32          nextNodeNum;
 
476
        
 
477
        if (nodePtr->buffer != nil)             // if iterator is valid...
 
478
        {
 
479
                nextNodeNum = ((NodeDescPtr)nodePtr->buffer)->fLink;
 
480
                if (nextNodeNum == 0)
 
481
                {
 
482
                        err = fsBTNoMoreMapNodesErr;
 
483
                        goto ErrorExit;
 
484
                }
 
485
                
 
486
                err = ReleaseNode (btreePtr, nodePtr);
 
487
                M_ExitOnError (err);
 
488
                
 
489
                err = GetNode (btreePtr, nextNodeNum, nodePtr);
 
490
                M_ExitOnError (err);
 
491
                
 
492
                if ( ((NodeDescPtr)nodePtr->buffer)->kind != kBTMapNode)
 
493
                {
 
494
                        err = fsBTBadNodeType;
 
495
                        goto ErrorExit;
 
496
                }
 
497
                
 
498
                ++btreePtr->numMapNodesRead;
 
499
                mapIndex = 0;
 
500
        } else {
 
501
                err = GetNode (btreePtr, kHeaderNodeNum, nodePtr);
 
502
                M_ExitOnError (err);
 
503
                
 
504
                if ( ((NodeDescPtr)nodePtr->buffer)->kind != kBTHeaderNode)
 
505
                {
 
506
                        err = fsBTInvalidHeaderErr;                             //�� or fsBTBadNodeType
 
507
                        goto ErrorExit;
 
508
                }
 
509
                
 
510
                mapIndex = 2;
 
511
        }
 
512
        
 
513
                
 
514
        *mapPtr         = (UInt16 *) GetRecordAddress (btreePtr, nodePtr->buffer, mapIndex);
 
515
        *mapSize        = GetRecordSize (btreePtr, nodePtr->buffer, mapIndex);
 
516
        
 
517
        return noErr;
 
518
        
 
519
        
 
520
ErrorExit:
 
521
        
 
522
        (void) ReleaseNode (btreePtr, nodePtr);
 
523
        
 
524
        *mapPtr         = nil;
 
525
        *mapSize        = 0;
 
526
        
 
527
        return  err;
 
528
}
 
529
 
 
530
 
 
531
 
 
532
////////////////////////////////// CalcMapBits //////////////////////////////////
 
533
 
 
534
UInt32          CalcMapBits     (BTreeControlBlockPtr    btreePtr)
 
535
{
 
536
        UInt32          mapBits;
 
537
        
 
538
        mapBits         = M_HeaderMapRecordSize (btreePtr->nodeSize) << 3;
 
539
        
 
540
        while (mapBits < btreePtr->totalNodes)
 
541
                mapBits += M_MapRecordSize (btreePtr->nodeSize) << 3;
 
542
        
 
543
        return  mapBits;
 
544
}