05 Sep, 2018

2 commits

  • [ Upstream commit a3f94cb99a854fa381fe7fadd97c4f61633717a5 ]

    Previously in squashfs_readpage() when copying data into the page
    cache, it used the length of the datablock read from the filesystem
    (after decompression). However, if the filesystem has been corrupted
    this data block may be short, which will leave pages unfilled.

    The fix for this is to compute the expected number of bytes to copy
    from the inode size, and use this to detect if the block is short.

    Signed-off-by: Phillip Lougher
    Tested-by: Willy Tarreau
    Cc: Анатолий Тросиненко
    Signed-off-by: Linus Torvalds
    Signed-off-by: Sasha Levin
    Signed-off-by: Greg Kroah-Hartman

    Phillip Lougher
     
  • [ Upstream commit cdbb65c4c7ead680ebe54f4f0d486e2847a500ea ]

    Anatoly continues to find issues with fuzzed squashfs images.

    This time, corrupt, missing, or undersized data for the page filling
    wasn't checked for, because the squashfs_{copy,read}_cache() functions
    did the squashfs_copy_data() call without checking the resulting data
    size.

    Which could result in the page cache pages being incompletely filled in,
    and no error indication to the user space reading garbage data.

    So make a helper function for the "fill in pages" case, because the
    exact same incomplete sequence existed in two places.

    [ I should have made a squashfs branch for these things, but I didn't
    intend to start doing them in the first place.

    My historical connection through cramfs is why I got into looking at
    these issues at all, and every time I (continue to) think it's a
    one-off.

    Because _this_ time is always the last time. Right? - Linus ]

    Reported-by: Anatoly Trosinenko
    Tested-by: Willy Tarreau
    Cc: Al Viro
    Cc: Phillip Lougher
    Signed-off-by: Linus Torvalds
    Signed-off-by: Sasha Levin
    Signed-off-by: Greg Kroah-Hartman

    Linus Torvalds
     

06 Aug, 2018

2 commits

  • commit 71755ee5350b63fb1f283de8561cdb61b47f4d1d upstream.

    The squashfs fragment reading code doesn't actually verify that the
    fragment is inside the fragment table. The end result _is_ verified to
    be inside the image when actually reading the fragment data, but before
    that is done, we may end up taking a page fault because the fragment
    table itself might not even exist.

    Another report from Anatoly and his endless squashfs image fuzzing.

    Reported-by: Анатолий Тросиненко
    Acked-by:: Phillip Lougher ,
    Cc: Willy Tarreau
    Signed-off-by: Linus Torvalds
    Signed-off-by: Greg Kroah-Hartman

    Linus Torvalds
     
  • commit d512584780d3e6a7cacb2f482834849453d444a1 upstream.

    Anatoly reports another squashfs fuzzing issue, where the decompression
    parameters themselves are in a compressed block.

    This causes squashfs_read_data() to be called in order to read the
    decompression options before the decompression stream having been set
    up, making squashfs go sideways.

    Reported-by: Anatoly Trosinenko
    Acked-by: Phillip Lougher
    Cc: stable@kernel.org
    Signed-off-by: Linus Torvalds
    Signed-off-by: Greg Kroah-Hartman

    Linus Torvalds
     

03 Aug, 2018

1 commit

  • commit 01cfb7937a9af2abb1136c7e89fbf3fd92952956 upstream.

    Anatoly Trosinenko reports that a corrupted squashfs image can cause a
    kernel oops. It turns out that squashfs can end up being confused about
    negative fragment lengths.

    The regular squashfs_read_data() does check for negative lengths, but
    squashfs_read_metadata() did not, and the fragment size code just
    blindly trusted the on-disk value. Fix both the fragment parsing and
    the metadata reading code.

    Reported-by: Anatoly Trosinenko
    Cc: Al Viro
    Cc: Phillip Lougher
    Cc: stable@kernel.org
    Signed-off-by: Linus Torvalds
    Signed-off-by: Greg Kroah-Hartman

    Linus Torvalds
     

02 Nov, 2017

1 commit

  • Many source files in the tree are missing licensing information, which
    makes it harder for compliance tools to determine the correct license.

    By default all files without license information are under the default
    license of the kernel, which is GPL version 2.

    Update the files which contain no license information with the 'GPL-2.0'
    SPDX license identifier. The SPDX identifier is a legally binding
    shorthand, which can be used instead of the full boiler plate text.

    This patch is based on work done by Thomas Gleixner and Kate Stewart and
    Philippe Ombredanne.

    How this work was done:

    Patches were generated and checked against linux-4.14-rc6 for a subset of
    the use cases:
    - file had no licensing information it it.
    - file was a */uapi/* one with no licensing information in it,
    - file was a */uapi/* one with existing licensing information,

    Further patches will be generated in subsequent months to fix up cases
    where non-standard license headers were used, and references to license
    had to be inferred by heuristics based on keywords.

    The analysis to determine which SPDX License Identifier to be applied to
    a file was done in a spreadsheet of side by side results from of the
    output of two independent scanners (ScanCode & Windriver) producing SPDX
    tag:value files created by Philippe Ombredanne. Philippe prepared the
    base worksheet, and did an initial spot review of a few 1000 files.

    The 4.13 kernel was the starting point of the analysis with 60,537 files
    assessed. Kate Stewart did a file by file comparison of the scanner
    results in the spreadsheet to determine which SPDX license identifier(s)
    to be applied to the file. She confirmed any determination that was not
    immediately clear with lawyers working with the Linux Foundation.

    Criteria used to select files for SPDX license identifier tagging was:
    - Files considered eligible had to be source code files.
    - Make and config files were included as candidates if they contained >5
    lines of source
    - File already had some variant of a license header in it (even if
    Reviewed-by: Philippe Ombredanne
    Reviewed-by: Thomas Gleixner
    Signed-off-by: Greg Kroah-Hartman

    Greg Kroah-Hartman
     

09 Sep, 2017

1 commit

  • Add zstd compression and decompression support to SquashFS. zstd is a
    great fit for SquashFS because it can compress at ratios approaching xz,
    while decompressing twice as fast as zlib. For SquashFS in particular,
    it can decompress as fast as lzo and lz4. It also has the flexibility
    to turn down the compression ratio for faster compression times.

    The compression benchmark is run on the file tree from the SquashFS archive
    found in ubuntu-16.10-desktop-amd64.iso [1]. It uses `mksquashfs` with the
    default block size (128 KB) and and various compression algorithms/levels.
    xz and zstd are also benchmarked with 256 KB blocks. The decompression
    benchmark times how long it takes to `tar` the file tree into `/dev/null`.
    See the benchmark file in the upstream zstd source repository located under
    `contrib/linux-kernel/squashfs-benchmark.sh` [2] for details.

    I ran the benchmarks on a Ubuntu 14.04 VM with 2 cores and 4 GiB of RAM.
    The VM is running on a MacBook Pro with a 3.1 GHz Intel Core i7 processor,
    16 GB of RAM, and a SSD.

    | Method | Ratio | Compression MB/s | Decompression MB/s |
    |----------------|-------|------------------|--------------------|
    | gzip | 2.92 | 15 | 128 |
    | lzo | 2.64 | 9.5 | 217 |
    | lz4 | 2.12 | 94 | 218 |
    | xz | 3.43 | 5.5 | 35 |
    | xz 256 KB | 3.53 | 5.4 | 40 |
    | zstd 1 | 2.71 | 96 | 210 |
    | zstd 5 | 2.93 | 69 | 198 |
    | zstd 10 | 3.01 | 41 | 225 |
    | zstd 15 | 3.13 | 11.4 | 224 |
    | zstd 16 256 KB | 3.24 | 8.1 | 210 |

    This patch was written by Sean Purcell , but I will be
    taking over the submission process.

    [1] http://releases.ubuntu.com/16.10/
    [2] https://github.com/facebook/zstd/blob/dev/contrib/linux-kernel/squashfs-benchmark.sh

    zstd source repository: https://github.com/facebook/zstd

    Signed-off-by: Sean Purcell
    Signed-off-by: Nick Terrell
    Signed-off-by: Chris Mason
    Acked-by: Phillip Lougher

    Sean Purcell
     

25 Feb, 2017

1 commit

  • Update fs/pstore and fs/squashfs to use the updated functions from the
    new LZ4 module.

    Link: http://lkml.kernel.org/r/1486321748-19085-5-git-send-email-4sschmid@informatik.uni-hamburg.de
    Signed-off-by: Sven Schmidt
    Cc: Bongkyu Kim
    Cc: Rui Salvaterra
    Cc: Sergey Senozhatsky
    Cc: Greg Kroah-Hartman
    Cc: Herbert Xu
    Cc: David S. Miller
    Cc: Anton Vorontsov
    Cc: Colin Cross
    Cc: Kees Cook
    Cc: Tony Luck
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Sven Schmidt
     

18 Dec, 2016

1 commit

  • …/linux/kernel/git/mszeredi/vfs

    Pull partial readlink cleanups from Miklos Szeredi.

    This is the uncontroversial part of the readlink cleanup patch-set that
    simplifies the default readlink handling.

    Miklos and Al are still discussing the rest of the series.

    * git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs:
    vfs: make generic_readlink() static
    vfs: remove ".readlink = generic_readlink" assignments
    vfs: default to generic_readlink()
    vfs: replace calling i_op->readlink with vfs_readlink()
    proc/self: use generic_readlink
    ecryptfs: use vfs_get_link()
    bad_inode: add missing i_op initializers

    Linus Torvalds
     

09 Dec, 2016

1 commit


01 Nov, 2016

1 commit


08 Oct, 2016

1 commit


08 Jun, 2016

1 commit


09 May, 2016

1 commit


03 May, 2016

1 commit


11 Apr, 2016

1 commit


05 Apr, 2016

2 commits

  • Mostly direct substitution with occasional adjustment or removing
    outdated comments.

    Signed-off-by: Kirill A. Shutemov
    Acked-by: Michal Hocko
    Signed-off-by: Linus Torvalds

    Kirill A. Shutemov
     
  • PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
    ago with promise that one day it will be possible to implement page
    cache with bigger chunks than PAGE_SIZE.

    This promise never materialized. And unlikely will.

    We have many places where PAGE_CACHE_SIZE assumed to be equal to
    PAGE_SIZE. And it's constant source of confusion on whether
    PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
    especially on the border between fs and mm.

    Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
    breakage to be doable.

    Let's stop pretending that pages in page cache are special. They are
    not.

    The changes are pretty straight-forward:

    - << (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> ;

    - >> (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> ;

    - PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -> PAGE_{SIZE,SHIFT,MASK,ALIGN};

    - page_cache_get() -> get_page();

    - page_cache_release() -> put_page();

    This patch contains automated changes generated with coccinelle using
    script below. For some reason, coccinelle doesn't patch header files.
    I've called spatch for them manually.

    The only adjustment after coccinelle is revert of changes to
    PAGE_CAHCE_ALIGN definition: we are going to drop it later.

    There are few places in the code where coccinelle didn't reach. I'll
    fix them manually in a separate patch. Comments and documentation also
    will be addressed with the separate patch.

    virtual patch

    @@
    expression E;
    @@
    - E << (PAGE_CACHE_SHIFT - PAGE_SHIFT)
    + E

    @@
    expression E;
    @@
    - E >> (PAGE_CACHE_SHIFT - PAGE_SHIFT)
    + E

    @@
    @@
    - PAGE_CACHE_SHIFT
    + PAGE_SHIFT

    @@
    @@
    - PAGE_CACHE_SIZE
    + PAGE_SIZE

    @@
    @@
    - PAGE_CACHE_MASK
    + PAGE_MASK

    @@
    expression E;
    @@
    - PAGE_CACHE_ALIGN(E)
    + PAGE_ALIGN(E)

    @@
    expression E;
    @@
    - page_cache_get(E)
    + get_page(E)

    @@
    expression E;
    @@
    - page_cache_release(E)
    + put_page(E)

    Signed-off-by: Kirill A. Shutemov
    Acked-by: Michal Hocko
    Signed-off-by: Linus Torvalds

    Kirill A. Shutemov
     

15 Jan, 2016

1 commit

  • Mark those kmem allocations that are known to be easily triggered from
    userspace as __GFP_ACCOUNT/SLAB_ACCOUNT, which makes them accounted to
    memcg. For the list, see below:

    - threadinfo
    - task_struct
    - task_delay_info
    - pid
    - cred
    - mm_struct
    - vm_area_struct and vm_region (nommu)
    - anon_vma and anon_vma_chain
    - signal_struct
    - sighand_struct
    - fs_struct
    - files_struct
    - fdtable and fdtable->full_fds_bits
    - dentry and external_name
    - inode for all filesystems. This is the most tedious part, because
    most filesystems overwrite the alloc_inode method.

    The list is far from complete, so feel free to add more objects.
    Nevertheless, it should be close to "account everything" approach and
    keep most workloads within bounds. Malevolent users will be able to
    breach the limit, but this was possible even with the former "account
    everything" approach (simply because it did not account everything in
    fact).

    [akpm@linux-foundation.org: coding-style fixes]
    Signed-off-by: Vladimir Davydov
    Acked-by: Johannes Weiner
    Acked-by: Michal Hocko
    Cc: Tejun Heo
    Cc: Greg Thelen
    Cc: Christoph Lameter
    Cc: Pekka Enberg
    Cc: David Rientjes
    Cc: Joonsoo Kim
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Vladimir Davydov
     

13 Jan, 2016

1 commit

  • Pull misc vfs updates from Al Viro:
    "All kinds of stuff. That probably should've been 5 or 6 separate
    branches, but by the time I'd realized how large and mixed that bag
    had become it had been too close to -final to play with rebasing.

    Some fs/namei.c cleanups there, memdup_user_nul() introduction and
    switching open-coded instances, burying long-dead code, whack-a-mole
    of various kinds, several new helpers for ->llseek(), assorted
    cleanups and fixes from various people, etc.

    One piece probably deserves special mention - Neil's
    lookup_one_len_unlocked(). Similar to lookup_one_len(), but gets
    called without ->i_mutex and tries to avoid ever taking it. That, of
    course, means that it's not useful for any directory modifications,
    but things like getting inode attributes in nfds readdirplus are fine
    with that. I really should've asked for moratorium on lookup-related
    changes this cycle, but since I hadn't done that early enough... I
    *am* asking for that for the coming cycle, though - I'm going to try
    and get conversion of i_mutex to rwsem with ->lookup() done under lock
    taken shared.

    There will be a patch closer to the end of the window, along the lines
    of the one Linus had posted last May - mechanical conversion of
    ->i_mutex accesses to inode_lock()/inode_unlock()/inode_trylock()/
    inode_is_locked()/inode_lock_nested(). To quote Linus back then:

    -----
    | This is an automated patch using
    |
    | sed 's/mutex_lock(&\(.*\)->i_mutex)/inode_lock(\1)/'
    | sed 's/mutex_unlock(&\(.*\)->i_mutex)/inode_unlock(\1)/'
    | sed 's/mutex_lock_nested(&\(.*\)->i_mutex,[ ]*I_MUTEX_\([A-Z0-9_]*\))/inode_lock_nested(\1, I_MUTEX_\2)/'
    | sed 's/mutex_is_locked(&\(.*\)->i_mutex)/inode_is_locked(\1)/'
    | sed 's/mutex_trylock(&\(.*\)->i_mutex)/inode_trylock(\1)/'
    |
    | with a very few manual fixups
    -----

    I'm going to send that once the ->i_mutex-affecting stuff in -next
    gets mostly merged (or when Linus says he's about to stop taking
    merges)"

    * 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (63 commits)
    nfsd: don't hold i_mutex over userspace upcalls
    fs:affs:Replace time_t with time64_t
    fs/9p: use fscache mutex rather than spinlock
    proc: add a reschedule point in proc_readfd_common()
    logfs: constify logfs_block_ops structures
    fcntl: allow to set O_DIRECT flag on pipe
    fs: __generic_file_splice_read retry lookup on AOP_TRUNCATED_PAGE
    fs: xattr: Use kvfree()
    [s390] page_to_phys() always returns a multiple of PAGE_SIZE
    nbd: use ->compat_ioctl()
    fs: use block_device name vsprintf helper
    lib/vsprintf: add %*pg format specifier
    fs: use gendisk->disk_name where possible
    poll: plug an unused argument to do_poll
    amdkfd: don't open-code memdup_user()
    cdrom: don't open-code memdup_user()
    rsxx: don't open-code memdup_user()
    mtip32xx: don't open-code memdup_user()
    [um] mconsole: don't open-code memdup_user_nul()
    [um] hostaudio: don't open-code memdup_user()
    ...

    Linus Torvalds
     

12 Jan, 2016

1 commit

  • Pull vfs xattr updates from Al Viro:
    "Andreas' xattr cleanup series.

    It's a followup to his xattr work that went in last cycle; -0.5KLoC"

    * 'work.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
    xattr handlers: Simplify list operation
    ocfs2: Replace list xattr handler operations
    nfs: Move call to security_inode_listsecurity into nfs_listxattr
    xfs: Change how listxattr generates synthetic attributes
    tmpfs: listxattr should include POSIX ACL xattrs
    tmpfs: Use xattr handler infrastructure
    btrfs: Use xattr handler infrastructure
    vfs: Distinguish between full xattr names and proper prefixes
    posix acls: Remove duplicate xattr name definitions
    gfs2: Remove gfs2_xattr_acl_chmod
    vfs: Remove vfs_xattr_cmp

    Linus Torvalds
     

07 Jan, 2016

1 commit


31 Dec, 2015

1 commit


14 Dec, 2015

1 commit

  • Change the list operation to only return whether or not an attribute
    should be listed. Copying the attribute names into the buffer is moved
    to the callers.

    Since the result only depends on the dentry and not on the attribute
    name, we do not pass the attribute name to list operations.

    Signed-off-by: Andreas Gruenbacher
    Signed-off-by: Al Viro

    Andreas Gruenbacher
     

09 Dec, 2015

2 commits

  • new method: ->get_link(); replacement of ->follow_link(). The differences
    are:
    * inode and dentry are passed separately
    * might be called both in RCU and non-RCU mode;
    the former is indicated by passing it a NULL dentry.
    * when called that way it isn't allowed to block
    and should return ERR_PTR(-ECHILD) if it needs to be called
    in non-RCU mode.

    It's a flagday change - the old method is gone, all in-tree instances
    converted. Conversion isn't hard; said that, so far very few instances
    do not immediately bail out when called in RCU mode. That'll change
    in the next commits.

    Signed-off-by: Al Viro

    Al Viro
     
  • kmap() in page_follow_link_light() needed to go - allowing to hold
    an arbitrary number of kmaps for long is a great way to deadlocking
    the system.

    new helper (inode_nohighmem(inode)) needs to be used for pagecache
    symlinks inodes; done for all in-tree cases. page_follow_link_light()
    instrumented to yell about anything missed.

    Signed-off-by: Al Viro

    Al Viro
     

07 Dec, 2015

1 commit

  • Add an additional "name" field to struct xattr_handler. When the name
    is set, the handler matches attributes with exactly that name. When the
    prefix is set instead, the handler matches attributes with the given
    prefix and with a non-empty suffix.

    This patch should avoid bugs like the one fixed in commit c361016a in
    the future.

    Signed-off-by: Andreas Gruenbacher
    Reviewed-by: James Morris
    Signed-off-by: Al Viro

    Andreas Gruenbacher
     

14 Nov, 2015

2 commits

  • Now that the xattr handler is passed to the xattr handler operations, we
    have access to the attribute name prefix, so simplify the squashfs xattr
    handlers a bit.

    Signed-off-by: Andreas Gruenbacher
    Cc: Phillip Lougher
    Signed-off-by: Al Viro

    Andreas Gruenbacher
     
  • The xattr_handler operations are currently all passed a file system
    specific flags value which the operations can use to disambiguate between
    different handlers; some file systems use that to distinguish the xattr
    namespace, for example. In some oprations, it would be useful to also have
    access to the handler prefix. To allow that, pass a pointer to the handler
    to operations instead of the flags value alone.

    Signed-off-by: Andreas Gruenbacher
    Reviewed-by: Christoph Hellwig
    Signed-off-by: Al Viro

    Andreas Gruenbacher
     

24 Jun, 2015

1 commit

  • list_entry is just a wrapper for container_of, but it is arguably
    wrong (and slightly confusing) to use it when the pointed-to struct
    member is not a struct list_head. Use container_of directly instead.

    Signed-off-by: Rasmus Villemoes
    Signed-off-by: Al Viro

    Rasmus Villemoes
     

16 Apr, 2015

1 commit


28 Nov, 2014

1 commit


27 Nov, 2014

1 commit


07 Aug, 2014

2 commits


05 Jun, 2014

1 commit


13 Mar, 2014

1 commit

  • Previously, the no-op "mount -o mount /dev/xxx" operation when the
    file system is already mounted read-write causes an implied,
    unconditional syncfs(). This seems pretty stupid, and it's certainly
    documented or guaraunteed to do this, nor is it particularly useful,
    except in the case where the file system was mounted rw and is getting
    remounted read-only.

    However, it's possible that there might be some file systems that are
    actually depending on this behavior. In most file systems, it's
    probably fine to only call sync_filesystem() when transitioning from
    read-write to read-only, and there are some file systems where this is
    not needed at all (for example, for a pseudo-filesystem or something
    like romfs).

    Signed-off-by: "Theodore Ts'o"
    Cc: linux-fsdevel@vger.kernel.org
    Cc: Christoph Hellwig
    Cc: Artem Bityutskiy
    Cc: Adrian Hunter
    Cc: Evgeniy Dushistov
    Cc: Jan Kara
    Cc: OGAWA Hirofumi
    Cc: Anders Larsen
    Cc: Phillip Lougher
    Cc: Kees Cook
    Cc: Mikulas Patocka
    Cc: Petr Vandrovec
    Cc: xfs@oss.sgi.com
    Cc: linux-btrfs@vger.kernel.org
    Cc: linux-cifs@vger.kernel.org
    Cc: samba-technical@lists.samba.org
    Cc: codalist@coda.cs.cmu.edu
    Cc: linux-ext4@vger.kernel.org
    Cc: linux-f2fs-devel@lists.sourceforge.net
    Cc: fuse-devel@lists.sourceforge.net
    Cc: cluster-devel@redhat.com
    Cc: linux-mtd@lists.infradead.org
    Cc: jfs-discussion@lists.sourceforge.net
    Cc: linux-nfs@vger.kernel.org
    Cc: linux-nilfs@vger.kernel.org
    Cc: linux-ntfs-dev@lists.sourceforge.net
    Cc: ocfs2-devel@oss.oracle.com
    Cc: reiserfs-devel@vger.kernel.org

    Theodore Ts'o
     

24 Nov, 2013

1 commit


20 Nov, 2013

2 commits

  • Fix static checker complaint that stream is not checked in
    squashfs_decompressor_destroy().

    Reported-by: Dan Carpenter
    Signed-off-by: Phillip Lougher
    Reviewed-by: Minchan Kim

    Phillip Lougher
     
  • This introduces an implementation of squashfs_readpage_block()
    that directly decompresses into the page cache.

    This uses the previously added page handler abstraction to push
    down the necessary kmap_atomic/kunmap_atomic operations on the
    page cache buffers into the decompressors. This enables
    direct copying into the page cache without using the slow
    kmap/kunmap calls.

    The code detects when multiple threads are racing in
    squashfs_readpage() to decompress the same block, and avoids
    this regression by falling back to using an intermediate
    buffer.

    This patch enhances the performance of Squashfs significantly
    when multiple processes are accessing the filesystem simultaneously
    because it not only reduces memcopying, but it more importantly
    eliminates the lock contention on the intermediate buffer.

    Using single-thread decompression.

    dd if=file1 of=/dev/null bs=4096 &
    dd if=file2 of=/dev/null bs=4096 &
    dd if=file3 of=/dev/null bs=4096 &
    dd if=file4 of=/dev/null bs=4096

    Before:

    629145600 bytes (629 MB) copied, 45.8046 s, 13.7 MB/s

    After:

    629145600 bytes (629 MB) copied, 9.29414 s, 67.7 MB/s

    Signed-off-by: Phillip Lougher
    Reviewed-by: Minchan Kim

    Phillip Lougher