~ubuntu-branches/ubuntu/quantal/zfs-fuse/quantal

« back to all changes in this revision

Viewing changes to src/lib/libzpool/zap_leaf.c

  • Committer: Bazaar Package Importer
  • Author(s): Mike Hommey, Mike Hommey, Seth Heeren
  • Date: 2010-06-30 18:03:52 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20100630180352-d3jq25ytbcl23q3y
Tags: 0.6.9-1
* New upstream release.

[ Mike Hommey ]
* debian/control:
  - Build depend on libssl-dev and libattr1-dev, now required to build.
  - Build depend on docbook-xml to avoid xsltproc I/O error loading
    docbook DTD.
  - Add suggestions for a NFS server and kpartx.
* debian/man/*, debian/copyright, debian/rules: Remove manual pages, they
  are now shipped upstream.
* debian/copyright: Change download link.
* src/SConstruct:
  - Add an optim option to the build system.
  - Add support for DESTDIR.
  - Force debug=1 to mean optim, no strip, no debug.
  - Use -ffunction-sections, -fdata-sections, and --gc-sections flags to
    reduce the binary sizes.
* src/lib/libumem/SConscript: Cleanup src/lib/libumem when cleaning up
  build directory.
* src/cmd/*/SConscript: Don't link zfs, zpool and zdb against libssl.
* src/lib/libumem/SConscript: Only build static libumem.
* src/lib/libumem/sol_compat.h:
  - Add atomic cas support for sparc.
  - Use atomic functions from libsolcompat in libumem on unsupported
    platforms.
* debian/rules:
  - Set optimization level in build system according to DEB_BUILD_OPTIONS.
  - Build with debug=1 to have unstripped binaries ; dh_strip will do the
    right thing.
  - Don't depend on the local location of the docbook XSLT stylesheets.
    Use the catalogged url in place of the full path.
  - Don't clean src/.sconsign.dblite and src/path.pyc.
  - Set all destination directories when installing with scons.
  - Install bash completion and zfsrc files.
  - Don't use scons cache when building.
* debian/prerm: Remove /var/lib/zfs/zpool.cache in prerm.
* debian/dirs: Create /etc/bash_completion.d.
* debian/watch: Fix watch file.
* debian/rules, debian/control, debian/compat: Switch to dh.
* debian/README.Debian: Update README.Debian.
* debian/zfs-fuse.man.xml: Update zfs-fuse manual page.
* debian/zfs-fuse.init: Start sharing datasets marked as such at daemon
  startup.
* debian/rules, debian/control: Use config.guess and config.sub from
  autotools-dev.

[ Seth Heeren ]
* debian/zfs-fuse.man.xml:
  Added notes on the precedence, zfsrc, commandline, initscript vs.
  /etc/default/zfs-fuse on some systems.
* debian/zfs-fuse.init, debian/zfs-fuse.default: Deprecating DAEMON_OPTS.
* debian/zfs-fuse.init:
  - Removing import -a -f.
  - Removing the now unnecessary 'sleep 2'.
  - Extended shutdown wait to allow for zfs-fuse daemon's own shutdown
    timeouts.
  - Re-ordered dubious PATH setting.
* debian/zfs-fuse.init: Move existing zpool.cache to new location if
  possible.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
 * the names are stored null-terminated.
30
30
 */
31
31
 
 
32
#include <sys/zio.h>
32
33
#include <sys/spa.h>
33
34
#include <sys/dmu.h>
34
35
#include <sys/zfs_context.h>
126
127
                        le = &lc->l_entry;
127
128
 
128
129
                        le->le_type =           BSWAP_8(le->le_type);
129
 
                        le->le_int_size =       BSWAP_8(le->le_int_size);
 
130
                        le->le_value_intlen =   BSWAP_8(le->le_value_intlen);
130
131
                        le->le_next =           BSWAP_16(le->le_next);
131
132
                        le->le_name_chunk =     BSWAP_16(le->le_name_chunk);
132
 
                        le->le_name_length =    BSWAP_16(le->le_name_length);
 
133
                        le->le_name_numints =   BSWAP_16(le->le_name_numints);
133
134
                        le->le_value_chunk =    BSWAP_16(le->le_value_chunk);
134
 
                        le->le_value_length =   BSWAP_16(le->le_value_length);
 
135
                        le->le_value_numints =  BSWAP_16(le->le_value_numints);
135
136
                        le->le_cd =             BSWAP_32(le->le_cd);
136
137
                        le->le_hash =           BSWAP_64(le->le_hash);
137
138
                        break;
214
215
 
215
216
static uint16_t
216
217
zap_leaf_array_create(zap_leaf_t *l, const char *buf,
217
 
        int integer_size, int num_integers)
 
218
    int integer_size, int num_integers)
218
219
{
219
220
        uint16_t chunk_head;
220
221
        uint16_t *chunkp = &chunk_head;
272
273
static void
273
274
zap_leaf_array_read(zap_leaf_t *l, uint16_t chunk,
274
275
    int array_int_len, int array_len, int buf_int_len, uint64_t buf_len,
275
 
    char *buf)
 
276
    void *buf)
276
277
{
277
278
        int len = MIN(array_len, buf_len);
278
279
        int byten = 0;
279
280
        uint64_t value = 0;
 
281
        char *p = buf;
280
282
 
281
283
        ASSERT3U(array_int_len, <=, buf_int_len);
282
284
 
284
286
        if (array_int_len == 8 && buf_int_len == 8 && len == 1) {
285
287
                struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array;
286
288
                uint8_t *ip = la->la_array;
287
 
                uint64_t *buf64 = (uint64_t *)buf;
 
289
                uint64_t *buf64 = buf;
288
290
 
289
291
                *buf64 = (uint64_t)ip[0] << 56 | (uint64_t)ip[1] << 48 |
290
292
                    (uint64_t)ip[2] << 40 | (uint64_t)ip[3] << 32 |
299
301
                while (chunk != CHAIN_END) {
300
302
                        struct zap_leaf_array *la =
301
303
                            &ZAP_LEAF_CHUNK(l, chunk).l_array;
302
 
                        bcopy(la->la_array, buf, ZAP_LEAF_ARRAY_BYTES);
303
 
                        buf += ZAP_LEAF_ARRAY_BYTES;
 
304
                        bcopy(la->la_array, p, ZAP_LEAF_ARRAY_BYTES);
 
305
                        p += ZAP_LEAF_ARRAY_BYTES;
304
306
                        chunk = la->la_next;
305
307
                }
306
308
                return;
315
317
                        value = (value << 8) | la->la_array[i];
316
318
                        byten++;
317
319
                        if (byten == array_int_len) {
318
 
                                stv(buf_int_len, buf, value);
 
320
                                stv(buf_int_len, p, value);
319
321
                                byten = 0;
320
322
                                len--;
321
323
                                if (len == 0)
322
324
                                        return;
323
 
                                buf += buf_int_len;
 
325
                                p += buf_int_len;
324
326
                        }
325
327
                }
326
328
                chunk = la->la_next;
327
329
        }
328
330
}
329
331
 
330
 
/*
331
 
 * Only to be used on 8-bit arrays.
332
 
 * array_len is actual len in bytes (not encoded le_value_length).
333
 
 * namenorm is null-terminated.
334
 
 */
335
332
static boolean_t
336
 
zap_leaf_array_match(zap_leaf_t *l, zap_name_t *zn, int chunk, int array_len)
 
333
zap_leaf_array_match(zap_leaf_t *l, zap_name_t *zn,
 
334
    int chunk, int array_numints)
337
335
{
338
336
        int bseen = 0;
339
337
 
 
338
        if (zap_getflags(zn->zn_zap) & ZAP_FLAG_UINT64_KEY) {
 
339
                uint64_t *thiskey;
 
340
                boolean_t match;
 
341
 
 
342
                ASSERT(zn->zn_key_intlen == sizeof (*thiskey));
 
343
                thiskey = kmem_alloc(array_numints * sizeof (*thiskey),
 
344
                    KM_SLEEP);
 
345
 
 
346
                zap_leaf_array_read(l, chunk, sizeof (*thiskey), array_numints,
 
347
                    sizeof (*thiskey), array_numints, thiskey);
 
348
                match = bcmp(thiskey, zn->zn_key_orig,
 
349
                    array_numints * sizeof (*thiskey)) == 0;
 
350
                kmem_free(thiskey, array_numints * sizeof (*thiskey));
 
351
                return (match);
 
352
        }
 
353
 
 
354
        ASSERT(zn->zn_key_intlen == 1);
340
355
        if (zn->zn_matchtype == MT_FIRST) {
341
 
                char *thisname = kmem_alloc(array_len, KM_SLEEP);
 
356
                char *thisname = kmem_alloc(array_numints, KM_SLEEP);
342
357
                boolean_t match;
343
358
 
344
 
                zap_leaf_array_read(l, chunk, 1, array_len, 1,
345
 
                    array_len, thisname);
 
359
                zap_leaf_array_read(l, chunk, sizeof (char), array_numints,
 
360
                    sizeof (char), array_numints, thisname);
346
361
                match = zap_match(zn, thisname);
347
 
                kmem_free(thisname, array_len);
 
362
                kmem_free(thisname, array_numints);
348
363
                return (match);
349
364
        }
350
365
 
351
 
        /* Fast path for exact matching */
352
 
        while (bseen < array_len) {
 
366
        /*
 
367
         * Fast path for exact matching.
 
368
         * First check that the lengths match, so that we don't read
 
369
         * past the end of the zn_key_orig array.
 
370
         */
 
371
        if (array_numints != zn->zn_key_orig_numints)
 
372
                return (B_FALSE);
 
373
        while (bseen < array_numints) {
353
374
                struct zap_leaf_array *la = &ZAP_LEAF_CHUNK(l, chunk).l_array;
354
 
                int toread = MIN(array_len - bseen, ZAP_LEAF_ARRAY_BYTES);
 
375
                int toread = MIN(array_numints - bseen, ZAP_LEAF_ARRAY_BYTES);
355
376
                ASSERT3U(chunk, <, ZAP_LEAF_NUMCHUNKS(l));
356
 
                if (bcmp(la->la_array, zn->zn_name_orij + bseen, toread))
 
377
                if (bcmp(la->la_array, (char *)zn->zn_key_orig + bseen, toread))
357
378
                        break;
358
379
                chunk = la->la_next;
359
380
                bseen += toread;
360
381
        }
361
 
        return (bseen == array_len);
 
382
        return (bseen == array_numints);
362
383
}
363
384
 
364
385
/*
393
414
                ASSERT(zn->zn_matchtype == MT_EXACT ||
394
415
                    (l->l_phys->l_hdr.lh_flags & ZLF_ENTRIES_CDSORTED));
395
416
                if (zap_leaf_array_match(l, zn, le->le_name_chunk,
396
 
                    le->le_name_length)) {
397
 
                        zeh->zeh_num_integers = le->le_value_length;
398
 
                        zeh->zeh_integer_size = le->le_int_size;
 
417
                    le->le_name_numints)) {
 
418
                        zeh->zeh_num_integers = le->le_value_numints;
 
419
                        zeh->zeh_integer_size = le->le_value_intlen;
399
420
                        zeh->zeh_cd = le->le_cd;
400
421
                        zeh->zeh_hash = le->le_hash;
401
422
                        zeh->zeh_chunkp = chunkp;
426
447
{
427
448
        uint16_t chunk;
428
449
        uint64_t besth = -1ULL;
429
 
        uint32_t bestcd = ZAP_MAXCD;
 
450
        uint32_t bestcd = -1U;
430
451
        uint16_t bestlh = ZAP_LEAF_HASH_NUMENTRIES(l)-1;
431
452
        uint16_t lh;
432
453
        struct zap_leaf_entry *le;
448
469
                                besth = le->le_hash;
449
470
                                bestcd = le->le_cd;
450
471
 
451
 
                                zeh->zeh_num_integers = le->le_value_length;
452
 
                                zeh->zeh_integer_size = le->le_int_size;
 
472
                                zeh->zeh_num_integers = le->le_value_numints;
 
473
                                zeh->zeh_integer_size = le->le_value_intlen;
453
474
                                zeh->zeh_cd = le->le_cd;
454
475
                                zeh->zeh_hash = le->le_hash;
455
476
                                zeh->zeh_fakechunk = chunk;
459
480
                }
460
481
        }
461
482
 
462
 
        return (bestcd == ZAP_MAXCD ? ENOENT : 0);
 
483
        return (bestcd == -1U ? ENOENT : 0);
463
484
}
464
485
 
465
486
int
470
491
            ZAP_LEAF_ENTRY(zeh->zeh_leaf, *zeh->zeh_chunkp);
471
492
        ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY);
472
493
 
473
 
        if (le->le_int_size > integer_size)
 
494
        if (le->le_value_intlen > integer_size)
474
495
                return (EINVAL);
475
496
 
476
 
        zap_leaf_array_read(zeh->zeh_leaf, le->le_value_chunk, le->le_int_size,
477
 
            le->le_value_length, integer_size, num_integers, buf);
 
497
        zap_leaf_array_read(zeh->zeh_leaf, le->le_value_chunk,
 
498
            le->le_value_intlen, le->le_value_numints,
 
499
            integer_size, num_integers, buf);
478
500
 
479
501
        if (zeh->zeh_num_integers > num_integers)
480
502
                return (EOVERFLOW);
483
505
}
484
506
 
485
507
int
486
 
zap_entry_read_name(const zap_entry_handle_t *zeh, uint16_t buflen, char *buf)
 
508
zap_entry_read_name(zap_t *zap, const zap_entry_handle_t *zeh, uint16_t buflen,
 
509
    char *buf)
487
510
{
488
511
        struct zap_leaf_entry *le =
489
512
            ZAP_LEAF_ENTRY(zeh->zeh_leaf, *zeh->zeh_chunkp);
490
513
        ASSERT3U(le->le_type, ==, ZAP_CHUNK_ENTRY);
491
514
 
492
 
        zap_leaf_array_read(zeh->zeh_leaf, le->le_name_chunk, 1,
493
 
            le->le_name_length, 1, buflen, buf);
494
 
        if (le->le_name_length > buflen)
 
515
        if (zap_getflags(zap) & ZAP_FLAG_UINT64_KEY) {
 
516
                zap_leaf_array_read(zeh->zeh_leaf, le->le_name_chunk, 8,
 
517
                    le->le_name_numints, 8, buflen / 8, buf);
 
518
        } else {
 
519
                zap_leaf_array_read(zeh->zeh_leaf, le->le_name_chunk, 1,
 
520
                    le->le_name_numints, 1, buflen, buf);
 
521
        }
 
522
        if (le->le_name_numints > buflen)
495
523
                return (EOVERFLOW);
496
524
        return (0);
497
525
}
505
533
        struct zap_leaf_entry *le = ZAP_LEAF_ENTRY(l, *zeh->zeh_chunkp);
506
534
 
507
535
        delta_chunks = ZAP_LEAF_ARRAY_NCHUNKS(num_integers * integer_size) -
508
 
            ZAP_LEAF_ARRAY_NCHUNKS(le->le_value_length * le->le_int_size);
 
536
            ZAP_LEAF_ARRAY_NCHUNKS(le->le_value_numints * le->le_value_intlen);
509
537
 
510
538
        if ((int)l->l_phys->l_hdr.lh_nfree < delta_chunks)
511
539
                return (EAGAIN);
521
549
        zap_leaf_array_free(l, &le->le_value_chunk);
522
550
        le->le_value_chunk =
523
551
            zap_leaf_array_create(l, buf, integer_size, num_integers);
524
 
        le->le_value_length = num_integers;
525
 
        le->le_int_size = integer_size;
 
552
        le->le_value_numints = num_integers;
 
553
        le->le_value_intlen = integer_size;
526
554
        return (0);
527
555
}
528
556
 
549
577
}
550
578
 
551
579
int
552
 
zap_entry_create(zap_leaf_t *l, const char *name, uint64_t h, uint32_t cd,
 
580
zap_entry_create(zap_leaf_t *l, zap_name_t *zn, uint32_t cd,
553
581
    uint8_t integer_size, uint64_t num_integers, const void *buf,
554
582
    zap_entry_handle_t *zeh)
555
583
{
556
584
        uint16_t chunk;
557
585
        uint16_t *chunkp;
558
586
        struct zap_leaf_entry *le;
559
 
        uint64_t namelen, valuelen;
 
587
        uint64_t valuelen;
560
588
        int numchunks;
 
589
        uint64_t h = zn->zn_hash;
561
590
 
562
591
        valuelen = integer_size * num_integers;
563
 
        namelen = strlen(name) + 1;
564
 
        ASSERT(namelen >= 2);
565
592
 
566
 
        numchunks = 1 + ZAP_LEAF_ARRAY_NCHUNKS(namelen) +
567
 
            ZAP_LEAF_ARRAY_NCHUNKS(valuelen);
 
593
        numchunks = 1 + ZAP_LEAF_ARRAY_NCHUNKS(zn->zn_key_orig_numints *
 
594
            zn->zn_key_intlen) + ZAP_LEAF_ARRAY_NCHUNKS(valuelen);
568
595
        if (numchunks > ZAP_LEAF_NUMCHUNKS(l))
569
596
                return (E2BIG);
570
597
 
571
 
        if (cd == ZAP_MAXCD) {
 
598
        if (cd == ZAP_NEED_CD) {
572
599
                /* find the lowest unused cd */
573
600
                if (l->l_phys->l_hdr.lh_flags & ZLF_ENTRIES_CDSORTED) {
574
601
                        cd = 0;
585
612
                        }
586
613
                } else {
587
614
                        /* old unsorted format; do it the O(n^2) way */
588
 
                        for (cd = 0; cd < ZAP_MAXCD; cd++) {
 
615
                        for (cd = 0; ; cd++) {
589
616
                                for (chunk = *LEAF_HASH_ENTPTR(l, h);
590
617
                                    chunk != CHAIN_END; chunk = le->le_next) {
591
618
                                        le = ZAP_LEAF_ENTRY(l, chunk);
600
627
                        }
601
628
                }
602
629
                /*
603
 
                 * we would run out of space in a block before we could
604
 
                 * have ZAP_MAXCD entries
 
630
                 * We would run out of space in a block before we could
 
631
                 * store enough entries to run out of CD values.
605
632
                 */
606
 
                ASSERT3U(cd, <, ZAP_MAXCD);
 
633
                ASSERT3U(cd, <, zap_maxcd(zn->zn_zap));
607
634
        }
608
635
 
609
636
        if (l->l_phys->l_hdr.lh_nfree < numchunks)
613
640
        chunk = zap_leaf_chunk_alloc(l);
614
641
        le = ZAP_LEAF_ENTRY(l, chunk);
615
642
        le->le_type = ZAP_CHUNK_ENTRY;
616
 
        le->le_name_chunk = zap_leaf_array_create(l, name, 1, namelen);
617
 
        le->le_name_length = namelen;
 
643
        le->le_name_chunk = zap_leaf_array_create(l, zn->zn_key_orig,
 
644
            zn->zn_key_intlen, zn->zn_key_orig_numints);
 
645
        le->le_name_numints = zn->zn_key_orig_numints;
618
646
        le->le_value_chunk =
619
647
            zap_leaf_array_create(l, buf, integer_size, num_integers);
620
 
        le->le_value_length = num_integers;
621
 
        le->le_int_size = integer_size;
 
648
        le->le_value_numints = num_integers;
 
649
        le->le_value_intlen = integer_size;
622
650
        le->le_hash = h;
623
651
        le->le_cd = cd;
624
652
 
630
658
 
631
659
        zeh->zeh_leaf = l;
632
660
        zeh->zeh_num_integers = num_integers;
633
 
        zeh->zeh_integer_size = le->le_int_size;
 
661
        zeh->zeh_integer_size = le->le_value_intlen;
634
662
        zeh->zeh_cd = le->le_cd;
635
663
        zeh->zeh_hash = le->le_hash;
636
664
        zeh->zeh_chunkp = chunkp;
672
700
                        allocdzn = B_TRUE;
673
701
                }
674
702
                if (zap_leaf_array_match(zeh->zeh_leaf, zn,
675
 
                    le->le_name_chunk, le->le_name_length)) {
 
703
                    le->le_name_chunk, le->le_name_numints)) {
676
704
                        if (allocdzn)
677
705
                                zap_name_free(zn);
678
706
                        return (B_TRUE);
835
863
                        struct zap_leaf_entry *le =
836
864
                            ZAP_LEAF_ENTRY(l, chunk);
837
865
 
838
 
                        n = 1 + ZAP_LEAF_ARRAY_NCHUNKS(le->le_name_length) +
839
 
                            ZAP_LEAF_ARRAY_NCHUNKS(le->le_value_length *
840
 
                            le->le_int_size);
 
866
                        n = 1 + ZAP_LEAF_ARRAY_NCHUNKS(le->le_name_numints) +
 
867
                            ZAP_LEAF_ARRAY_NCHUNKS(le->le_value_numints *
 
868
                            le->le_value_intlen);
841
869
                        n = MIN(n, ZAP_HISTOGRAM_SIZE-1);
842
870
                        zs->zs_entries_using_n_chunks[n]++;
843
871