FreeBSD Bugzilla – Attachment 165400 Details for
Bug 205816
[ext2fs] [patch] EXT4 sparse blocks unsupported, contain garbage when read
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
support for EXT4 sparse files, cleaned up
ext4-sparse.diff (text/plain), 5.31 KB, created by
Pedro F. Giffuni
on 2016-01-11 16:08:58 UTC
(
hide
)
Description:
support for EXT4 sparse files, cleaned up
Filename:
MIME Type:
Creator:
Pedro F. Giffuni
Created:
2016-01-11 16:08:58 UTC
Size:
5.31 KB
patch
obsolete
>Index: sys/fs/ext2fs/ext2_bmap.c >=================================================================== >--- sys/fs/ext2fs/ext2_bmap.c (revision 293646) >+++ sys/fs/ext2fs/ext2_bmap.c (working copy) >@@ -102,9 +102,6 @@ > fs = ip->i_e2fs; > lbn = bn; > >- /* >- * TODO: need to implement read ahead to improve the performance. >- */ > if (runp != NULL) > *runp = 0; > >@@ -112,15 +109,25 @@ > *runb = 0; > > ext4_ext_find_extent(fs, ip, lbn, &path); >- ep = path.ep_ext; >- if (ep == NULL) >- ret = EIO; >- else { >- *bnp = fsbtodb(fs, lbn - ep->e_blk + >- (ep->e_start_lo | (daddr_t)ep->e_start_hi << 32)); >+ if (path.ep_is_sparse) { >+ *bnp = -1; >+ if (runp != NULL) >+ *runp = path.ep_sparse_ext.e_len - >+ (lbn - path.ep_sparse_ext.e_blk) - 1; >+ } else { >+ ep = path.ep_ext; >+ if (ep == NULL) >+ ret = EIO; >+ else { >+ *bnp = fsbtodb(fs, lbn - ep->e_blk + >+ (ep->e_start_lo | (daddr_t)ep->e_start_hi << 32)); > >- if (*bnp == 0) >- *bnp = -1; >+ if (*bnp == 0) >+ *bnp = -1; >+ >+ if (runp != NULL) >+ *runp = ep->e_len - (lbn - ep->e_blk) - 1; >+ } > } > > if (path.ep_bp != NULL) { >Index: sys/fs/ext2fs/ext2_extents.c >=================================================================== >--- sys/fs/ext2fs/ext2_extents.c (revision 293645) >+++ sys/fs/ext2fs/ext2_extents.c (working copy) >@@ -66,13 +66,14 @@ > ext4_ext_binsearch(struct inode *ip, struct ext4_extent_path *path, daddr_t lbn) > { > struct ext4_extent_header *ehp = path->ep_header; >- struct ext4_extent *l, *r, *m; >+ struct ext4_extent *first, *l, *r, *m; > > if (ehp->eh_ecount == 0) > return; > >- l = (struct ext4_extent *)(char *)(ehp + 1); >- r = (struct ext4_extent *)(char *)(ehp + 1) + ehp->eh_ecount - 1; >+ first = (struct ext4_extent *)(char *)(ehp + 1); >+ l = first; >+ r = first + ehp->eh_ecount - 1; > while (l <= r) { > m = l + (r - l) / 2; > if (lbn < m->e_blk) >@@ -81,7 +82,25 @@ > l = m + 1; > } > >+ if (l == first) { >+ path->ep_sparse_ext.e_blk = lbn; >+ path->ep_sparse_ext.e_len = first->e_blk - lbn; >+ path->ep_sparse_ext.e_start_hi = 0; >+ path->ep_sparse_ext.e_start_lo = 0; >+ path->ep_is_sparse = 1; >+ return; >+ } > path->ep_ext = l - 1; >+ if (path->ep_ext->e_blk + path->ep_ext->e_len <= lbn) { >+ path->ep_sparse_ext.e_blk = lbn; >+ if (l <= (first + ehp->eh_ecount - 1)) >+ path->ep_sparse_ext.e_len = l->e_blk - lbn; >+ else // XXX: where does it end? >+ path->ep_sparse_ext.e_len = 1; >+ path->ep_sparse_ext.e_start_hi = 0; >+ path->ep_sparse_ext.e_start_lo = 0; >+ path->ep_is_sparse = 1; >+ } > } > > /* >@@ -169,6 +188,7 @@ > path->ep_depth = i; > path->ep_ext = NULL; > path->ep_index = NULL; >+ path->ep_is_sparse = 0; > > ext4_ext_binsearch(ip, path, lbn); > return (path); >Index: sys/fs/ext2fs/ext2_extents.h >=================================================================== >--- sys/fs/ext2fs/ext2_extents.h (revision 293645) >+++ sys/fs/ext2fs/ext2_extents.h (working copy) >@@ -84,7 +84,11 @@ > struct ext4_extent_path { > uint16_t ep_depth; > struct buf *ep_bp; >- struct ext4_extent *ep_ext; >+ int ep_is_sparse; >+ union { >+ struct ext4_extent ep_sparse_ext; >+ struct ext4_extent *ep_ext; >+ }; > struct ext4_extent_index *ep_index; > struct ext4_extent_header *ep_header; > }; >Index: sys/fs/ext2fs/ext2_vnops.c >=================================================================== >--- sys/fs/ext2fs/ext2_vnops.c (revision 293645) >+++ sys/fs/ext2fs/ext2_vnops.c (working copy) >@@ -1787,6 +1787,7 @@ > static int > ext4_ext_read(struct vop_read_args *ap) > { >+ static unsigned char zeroes[EXT2_MAX_BLOCK_SIZE]; > struct vnode *vp; > struct inode *ip; > struct uio *uio; >@@ -1831,11 +1832,15 @@ > switch (cache_type) { > case EXT4_EXT_CACHE_NO: > ext4_ext_find_extent(fs, ip, lbn, &path); >- ep = path.ep_ext; >+ if (path.ep_is_sparse) >+ ep = &path.ep_sparse_ext; >+ else >+ ep = path.ep_ext; > if (ep == NULL) > return (EIO); > >- ext4_ext_put_cache(ip, ep, EXT4_EXT_CACHE_IN); >+ ext4_ext_put_cache(ip, ep, >+ path.ep_is_sparse ? EXT4_EXT_CACHE_GAP : EXT4_EXT_CACHE_IN); > > newblk = lbn - ep->e_blk + (ep->e_start_lo | > (daddr_t)ep->e_start_hi << 32); >@@ -1848,7 +1853,7 @@ > > case EXT4_EXT_CACHE_GAP: > /* block has not been allocated yet */ >- return (0); >+ break; > > case EXT4_EXT_CACHE_IN: > newblk = lbn - nex.e_blk + (nex.e_start_lo | >@@ -1859,24 +1864,34 @@ > panic("%s: invalid cache type", __func__); > } > >- error = bread(ip->i_devvp, fsbtodb(fs, newblk), size, NOCRED, &bp); >- if (error) { >- brelse(bp); >- return (error); >- } >+ if (cache_type == EXT4_EXT_CACHE_GAP || >+ (cache_type == EXT4_EXT_CACHE_NO && path.ep_is_sparse)) { >+ if (xfersize > sizeof(zeroes)) >+ xfersize = sizeof(zeroes); >+ error = uiomove(zeroes, xfersize, uio); >+ if (error) >+ return (error); >+ } else { >+ error = bread(ip->i_devvp, fsbtodb(fs, newblk), size, >+ NOCRED, &bp); >+ if (error) { >+ brelse(bp); >+ return (error); >+ } > >- size -= bp->b_resid; >- if (size < xfersize) { >- if (size == 0) { >- bqrelse(bp); >- break; >+ size -= bp->b_resid; >+ if (size < xfersize) { >+ if (size == 0) { >+ bqrelse(bp); >+ break; >+ } >+ xfersize = size; > } >- xfersize = size; >+ error = uiomove(bp->b_data + blkoffset, xfersize, uio); >+ bqrelse(bp); >+ if (error) >+ return (error); > } >- error = uiomove(bp->b_data + blkoffset, (int)xfersize, uio); >- bqrelse(bp); >- if (error) >- return (error); > } > > return (0);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 205816
:
164979
|
165234
|
165366
| 165400 |
165814