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

« back to all changes in this revision

Viewing changes to src/lib/libzpool/zio_checksum.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:
19
19
 * CDDL HEADER END
20
20
 */
21
21
/*
22
 
 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 
22
 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23
23
 * Use is subject to license terms.
24
24
 */
25
25
 
27
27
#include <sys/spa.h>
28
28
#include <sys/zio.h>
29
29
#include <sys/zio_checksum.h>
 
30
#include <sys/zil.h>
30
31
 
31
32
/*
32
33
 * Checksum vectors.
49
50
 *      we want the ability to take advantage of that hardware.
50
51
 *
51
52
 * Of course, we don't want a checksum upgrade to invalidate existing
52
 
 * data, so we store the checksum *function* in five bits of the DVA.
53
 
 * This gives us room for up to 32 different checksum functions.
 
53
 * data, so we store the checksum *function* in eight bits of the bp.
 
54
 * This gives us room for up to 256 different checksum functions.
54
55
 *
55
56
 * When writing a block, we always checksum it with the latest-and-greatest
56
57
 * checksum function of the appropriate strength.  When reading a block,
57
58
 * we compare the expected checksum against the actual checksum, which we
58
 
 * compute via the checksum function specified in the DVA encoding.
 
59
 * compute via the checksum function specified by BP_GET_CHECKSUM(bp).
59
60
 */
60
61
 
61
62
/*ARGSUSED*/
66
67
}
67
68
 
68
69
zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = {
69
 
        {{NULL,                 NULL},                  0, 0,   "inherit"},
70
 
        {{NULL,                 NULL},                  0, 0,   "on"},
71
 
        {{zio_checksum_off,     zio_checksum_off},      0, 0,   "off"},
72
 
        {{zio_checksum_SHA256,  zio_checksum_SHA256},   1, 1,   "label"},
73
 
        {{zio_checksum_SHA256,  zio_checksum_SHA256},   1, 1,   "gang_header"},
74
 
        {{fletcher_2_native,    fletcher_2_byteswap},   0, 1,   "zilog"},
75
 
        {{fletcher_2_native,    fletcher_2_byteswap},   0, 0,   "fletcher2"},
76
 
        {{fletcher_4_native,    fletcher_4_byteswap},   1, 0,   "fletcher4"},
77
 
        {{zio_checksum_SHA256,  zio_checksum_SHA256},   1, 0,   "SHA256"},
 
70
        {{NULL,                 NULL},                  0, 0, 0, "inherit"},
 
71
        {{NULL,                 NULL},                  0, 0, 0, "on"},
 
72
        {{zio_checksum_off,     zio_checksum_off},      0, 0, 0, "off"},
 
73
        {{zio_checksum_SHA256,  zio_checksum_SHA256},   1, 1, 0, "label"},
 
74
        {{zio_checksum_SHA256,  zio_checksum_SHA256},   1, 1, 0, "gang_header"},
 
75
        {{fletcher_2_native,    fletcher_2_byteswap},   0, 1, 0, "zilog"},
 
76
        {{fletcher_2_native,    fletcher_2_byteswap},   0, 0, 0, "fletcher2"},
 
77
        {{fletcher_4_native,    fletcher_4_byteswap},   1, 0, 0, "fletcher4"},
 
78
        {{zio_checksum_SHA256,  zio_checksum_SHA256},   1, 0, 1, "sha256"},
 
79
        {{fletcher_4_native,    fletcher_4_byteswap},   0, 1, 0, "zilog2"},
78
80
};
79
81
 
80
 
uint8_t
81
 
zio_checksum_select(uint8_t child, uint8_t parent)
 
82
enum zio_checksum
 
83
zio_checksum_select(enum zio_checksum child, enum zio_checksum parent)
82
84
{
83
85
        ASSERT(child < ZIO_CHECKSUM_FUNCTIONS);
84
86
        ASSERT(parent < ZIO_CHECKSUM_FUNCTIONS);
93
95
        return (child);
94
96
}
95
97
 
 
98
enum zio_checksum
 
99
zio_checksum_dedup_select(spa_t *spa, enum zio_checksum child,
 
100
    enum zio_checksum parent)
 
101
{
 
102
        ASSERT((child & ZIO_CHECKSUM_MASK) < ZIO_CHECKSUM_FUNCTIONS);
 
103
        ASSERT((parent & ZIO_CHECKSUM_MASK) < ZIO_CHECKSUM_FUNCTIONS);
 
104
        ASSERT(parent != ZIO_CHECKSUM_INHERIT && parent != ZIO_CHECKSUM_ON);
 
105
 
 
106
        if (child == ZIO_CHECKSUM_INHERIT)
 
107
                return (parent);
 
108
 
 
109
        if (child == ZIO_CHECKSUM_ON)
 
110
                return (spa_dedup_checksum(spa));
 
111
 
 
112
        if (child == (ZIO_CHECKSUM_ON | ZIO_CHECKSUM_VERIFY))
 
113
                return (spa_dedup_checksum(spa) | ZIO_CHECKSUM_VERIFY);
 
114
 
 
115
        ASSERT(zio_checksum_table[child & ZIO_CHECKSUM_MASK].ci_dedup ||
 
116
            (child & ZIO_CHECKSUM_VERIFY) || child == ZIO_CHECKSUM_OFF);
 
117
 
 
118
        return (child);
 
119
}
 
120
 
96
121
/*
97
122
 * Set the external verifier for a gang block based on <vdev, offset, txg>,
98
123
 * a tuple which is guaranteed to be unique for the life of the pool.
101
126
zio_checksum_gang_verifier(zio_cksum_t *zcp, blkptr_t *bp)
102
127
{
103
128
        dva_t *dva = BP_IDENTITY(bp);
104
 
        uint64_t txg = bp->blk_birth;
 
129
        uint64_t txg = BP_PHYSICAL_BIRTH(bp);
105
130
 
106
131
        ASSERT(BP_IS_GANG(bp));
107
132
 
128
153
{
129
154
        blkptr_t *bp = zio->io_bp;
130
155
        uint64_t offset = zio->io_offset;
131
 
        zio_block_tail_t *zbt = (zio_block_tail_t *)((char *)data + size) - 1;
132
156
        zio_checksum_info_t *ci = &zio_checksum_table[checksum];
133
 
        zio_cksum_t zbt_cksum;
 
157
        zio_cksum_t cksum;
134
158
 
135
159
        ASSERT((uint_t)checksum < ZIO_CHECKSUM_FUNCTIONS);
136
160
        ASSERT(ci->ci_func[0] != NULL);
137
161
 
138
 
        if (ci->ci_zbt) {
 
162
        if (ci->ci_eck) {
 
163
                zio_eck_t *eck;
 
164
 
 
165
                if (checksum == ZIO_CHECKSUM_ZILOG2) {
 
166
                        zil_chain_t *zilc = data;
 
167
 
 
168
                        size = P2ROUNDUP_TYPED(zilc->zc_nused, ZIL_MIN_BLKSZ,
 
169
                            uint64_t);
 
170
                        eck = &zilc->zc_eck;
 
171
                } else {
 
172
                        eck = (zio_eck_t *)((char *)data + size) - 1;
 
173
                }
139
174
                if (checksum == ZIO_CHECKSUM_GANG_HEADER)
140
 
                        zio_checksum_gang_verifier(&zbt->zbt_cksum, bp);
 
175
                        zio_checksum_gang_verifier(&eck->zec_cksum, bp);
141
176
                else if (checksum == ZIO_CHECKSUM_LABEL)
142
 
                        zio_checksum_label_verifier(&zbt->zbt_cksum, offset);
 
177
                        zio_checksum_label_verifier(&eck->zec_cksum, offset);
143
178
                else
144
 
                        bp->blk_cksum = zbt->zbt_cksum;
145
 
                zbt->zbt_magic = ZBT_MAGIC;
146
 
                ci->ci_func[0](data, size, &zbt_cksum);
147
 
                zbt->zbt_cksum = zbt_cksum;
 
179
                        bp->blk_cksum = eck->zec_cksum;
 
180
                eck->zec_magic = ZEC_MAGIC;
 
181
                ci->ci_func[0](data, size, &cksum);
 
182
                eck->zec_cksum = cksum;
148
183
        } else {
149
184
                ci->ci_func[0](data, size, &bp->blk_cksum);
150
185
        }
151
186
}
152
187
 
153
188
int
154
 
zio_checksum_error(zio_t *zio)
 
189
zio_checksum_error(zio_t *zio, zio_bad_cksum_t *info)
155
190
{
156
191
        blkptr_t *bp = zio->io_bp;
157
192
        uint_t checksum = (bp == NULL ? zio->io_prop.zp_checksum :
158
193
            (BP_IS_GANG(bp) ? ZIO_CHECKSUM_GANG_HEADER : BP_GET_CHECKSUM(bp)));
159
194
        int byteswap;
160
 
        void *data = zio->io_data;
 
195
        int error;
161
196
        uint64_t size = (bp == NULL ? zio->io_size :
162
197
            (BP_IS_GANG(bp) ? SPA_GANGBLOCKSIZE : BP_GET_PSIZE(bp)));
163
198
        uint64_t offset = zio->io_offset;
164
 
        zio_block_tail_t *zbt = (zio_block_tail_t *)((char *)data + size) - 1;
 
199
        void *data = zio->io_data;
165
200
        zio_checksum_info_t *ci = &zio_checksum_table[checksum];
166
201
        zio_cksum_t actual_cksum, expected_cksum, verifier;
167
202
 
168
203
        if (checksum >= ZIO_CHECKSUM_FUNCTIONS || ci->ci_func[0] == NULL)
169
204
                return (EINVAL);
170
205
 
171
 
        if (ci->ci_zbt) {
 
206
        if (ci->ci_eck) {
 
207
                zio_eck_t *eck;
 
208
 
 
209
                if (checksum == ZIO_CHECKSUM_ZILOG2) {
 
210
                        zil_chain_t *zilc = data;
 
211
                        uint64_t nused;
 
212
 
 
213
                        eck = &zilc->zc_eck;
 
214
                        if (eck->zec_magic == ZEC_MAGIC)
 
215
                                nused = zilc->zc_nused;
 
216
                        else if (eck->zec_magic == BSWAP_64(ZEC_MAGIC))
 
217
                                nused = BSWAP_64(zilc->zc_nused);
 
218
                        else
 
219
                                return (ECKSUM);
 
220
 
 
221
                        if (nused > size)
 
222
                                return (ECKSUM);
 
223
 
 
224
                        size = P2ROUNDUP_TYPED(nused, ZIL_MIN_BLKSZ, uint64_t);
 
225
                } else {
 
226
                        eck = (zio_eck_t *)((char *)data + size) - 1;
 
227
                }
 
228
 
172
229
                if (checksum == ZIO_CHECKSUM_GANG_HEADER)
173
230
                        zio_checksum_gang_verifier(&verifier, bp);
174
231
                else if (checksum == ZIO_CHECKSUM_LABEL)
176
233
                else
177
234
                        verifier = bp->blk_cksum;
178
235
 
179
 
                byteswap = (zbt->zbt_magic == BSWAP_64(ZBT_MAGIC));
 
236
                byteswap = (eck->zec_magic == BSWAP_64(ZEC_MAGIC));
180
237
 
181
238
                if (byteswap)
182
239
                        byteswap_uint64_array(&verifier, sizeof (zio_cksum_t));
183
240
 
184
 
                expected_cksum = zbt->zbt_cksum;
185
 
                zbt->zbt_cksum = verifier;
 
241
                expected_cksum = eck->zec_cksum;
 
242
                eck->zec_cksum = verifier;
186
243
                ci->ci_func[byteswap](data, size, &actual_cksum);
187
 
                zbt->zbt_cksum = expected_cksum;
 
244
                eck->zec_cksum = expected_cksum;
188
245
 
189
246
                if (byteswap)
190
247
                        byteswap_uint64_array(&expected_cksum,
196
253
                ci->ci_func[byteswap](data, size, &actual_cksum);
197
254
        }
198
255
 
 
256
        info->zbc_expected = expected_cksum;
 
257
        info->zbc_actual = actual_cksum;
 
258
        info->zbc_checksum_name = ci->ci_name;
 
259
        info->zbc_byteswapped = byteswap;
 
260
        info->zbc_injected = 0;
 
261
        info->zbc_has_cksum = 1;
 
262
 
199
263
        if (!ZIO_CHECKSUM_EQUAL(actual_cksum, expected_cksum))
200
264
                return (ECKSUM);
201
265
 
202
 
        if (zio_injection_enabled && !zio->io_error)
203
 
                return (zio_handle_fault_injection(zio, ECKSUM));
 
266
        if (zio_injection_enabled && !zio->io_error &&
 
267
            (error = zio_handle_fault_injection(zio, ECKSUM)) != 0) {
 
268
 
 
269
                info->zbc_injected = 1;
 
270
                return (error);
 
271
        }
204
272
 
205
273
        return (0);
206
274
}