-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
diff_cb() does not handle large dnodes
Trying to 'zfs diff' a snapshot with large dnodes will incorrectly try to access its interior slots when dnodesize > sizeof(dnode_phys_t). This is normally not an issue because the interior slots are zero-filled, which report_dnode() handles calling report_free_dnode_range(). However this is not the case for encrypted large dnodes or filesystem using many SA based xattrs where the extra data past the legacy dnode size boundary is interpreted as a dnode_phys_t. Signed-off-by: loli10K <[email protected]>
- Loading branch information
Showing
2 changed files
with
15 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ | |
/* | ||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | ||
* Copyright (c) 2012, 2018 by Delphix. All rights reserved. | ||
* Copyright (c) 2010, loli10K <[email protected]>. All rights reserved. | ||
*/ | ||
|
||
#include <sys/dmu.h> | ||
|
@@ -131,7 +132,7 @@ diff_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, | |
dnode_phys_t *blk; | ||
arc_buf_t *abuf; | ||
arc_flags_t aflags = ARC_FLAG_WAIT; | ||
int blksz = BP_GET_LSIZE(bp); | ||
int epb = BP_GET_LSIZE(bp) >> DNODE_SHIFT; | ||
int zio_flags = ZIO_FLAG_CANFAIL; | ||
int i; | ||
|
||
|
@@ -143,7 +144,7 @@ diff_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, | |
return (SET_ERROR(EIO)); | ||
|
||
blk = abuf->b_data; | ||
for (i = 0; i < blksz >> DNODE_SHIFT; i++) { | ||
for (i = 0; i < epb; i += blk[i].dn_extra_slots + 1) { | ||
uint64_t dnobj = (zb->zb_blkid << | ||
(DNODE_BLOCK_SHIFT - DNODE_SHIFT)) + i; | ||
err = report_dnode(da, dnobj, blk+i); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters