24 Aug, 2020

1 commit

  • Replace the existing /* fall through */ comments and its variants with
    the new pseudo-keyword macro fallthrough[1]. Also, remove unnecessary
    fall-through markings when it is the case.

    [1] https://www.kernel.org/doc/html/v5.7/process/deprecated.html?highlight=fallthrough#implicit-switch-case-fall-through

    Signed-off-by: Gustavo A. R. Silva

    Gustavo A. R. Silva
     

13 Aug, 2020

1 commit

  • Add macros for nilfs_(sb, fmt, ...) and convert the uses of
    'nilfs_msg(sb, KERN_, ...)' to 'nilfs_(sb, ...)' so nilfs2
    uses a logging style more like the typical kernel logging style.

    Miscellanea:

    o Realign arguments for these uses

    Signed-off-by: Joe Perches
    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Link: http://lkml.kernel.org/r/1595860111-3920-4-git-send-email-konishi.ryusuke@gmail.com
    Signed-off-by: Linus Torvalds

    Joe Perches
     

11 Jun, 2020

1 commit

  • After commit c3aab9a0bd91 ("mm/filemap.c: don't initiate writeback if
    mapping has no dirty pages"), the following null pointer dereference has
    been reported on nilfs2:

    BUG: kernel NULL pointer dereference, address: 00000000000000a8
    #PF: supervisor read access in kernel mode
    #PF: error_code(0x0000) - not-present page
    PGD 0 P4D 0
    Oops: 0000 [#1] SMP PTI
    ...
    RIP: 0010:percpu_counter_add_batch+0xa/0x60
    ...
    Call Trace:
    __test_set_page_writeback+0x2d3/0x330
    nilfs_segctor_do_construct+0x10d3/0x2110 [nilfs2]
    nilfs_segctor_construct+0x168/0x260 [nilfs2]
    nilfs_segctor_thread+0x127/0x3b0 [nilfs2]
    kthread+0xf8/0x130
    ...

    This crash turned out to be caused by set_page_writeback() call for
    segment summary buffers at nilfs_segctor_prepare_write().

    set_page_writeback() can call inc_wb_stat(inode_to_wb(inode),
    WB_WRITEBACK) where inode_to_wb(inode) is NULL if the inode of
    underlying block device does not have an associated wb.

    This fixes the issue by calling inode_attach_wb() in advance to ensure
    to associate the bdev inode with its wb.

    Fixes: c3aab9a0bd91 ("mm/filemap.c: don't initiate writeback if mapping has no dirty pages")
    Reported-by: Walton Hoops
    Reported-by: Tomas Hlavaty
    Reported-by: ARAI Shun-ichi
    Reported-by: Hideki EIRAKU
    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Tested-by: Ryusuke Konishi
    Cc: [5.4+]
    Link: http://lkml.kernel.org/r/20200608.011819.1399059588922299158.konishi.ryusuke@gmail.com
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     

05 Sep, 2018

1 commit

  • Remove the verbose license text from NILFS2 files and replace them with
    SPDX tags. This does not change the license of any of the code.

    Link: http://lkml.kernel.org/r/1535624528-5982-1-git-send-email-konishi.ryusuke@lab.ntt.co.jp
    Signed-off-by: Ryusuke Konishi
    Reviewed-by: Andrew Morton
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     

07 Feb, 2018

1 commit

  • The superblock and segment timestamps are used only internally in nilfs2
    and can be read out using sysfs.

    Since we are using the old 'get_seconds()' interface and store the data
    as timestamps, the behavior differs slightly between 64-bit and 32-bit
    kernels, the latter will show incorrect timestamps after 2038 in sysfs,
    and presumably fail completely in 2106 as comparisons go wrong.

    This changes nilfs2 to use time64_t with ktime_get_real_seconds() to
    handle timestamps, making the behavior consistent and correct on both
    32-bit and 64-bit machines.

    The on-disk format already uses 64-bit timestamps, so nothing changes
    there.

    Link: http://lkml.kernel.org/r/20180122211050.1286441-1-arnd@arndb.de
    Signed-off-by: Arnd Bergmann
    Acked-by: Ryusuke Konishi
    Cc: Jens Axboe
    Cc: Ingo Molnar
    Cc: Jan Kara
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Arnd Bergmann
     

28 Nov, 2017

1 commit

  • This is a pure automated search-and-replace of the internal kernel
    superblock flags.

    The s_flags are now called SB_*, with the names and the values for the
    moment mirroring the MS_* flags that they're equivalent to.

    Note how the MS_xyz flags are the ones passed to the mount system call,
    while the SB_xyz flags are what we then use in sb->s_flags.

    The script to do this was:

    # places to look in; re security/*: it generally should *not* be
    # touched (that stuff parses mount(2) arguments directly), but
    # there are two places where we really deal with superblock flags.
    FILES="drivers/mtd drivers/staging/lustre fs ipc mm \
    include/linux/fs.h include/uapi/linux/bfs_fs.h \
    security/apparmor/apparmorfs.c security/apparmor/include/lib.h"
    # the list of MS_... constants
    SYMS="RDONLY NOSUID NODEV NOEXEC SYNCHRONOUS REMOUNT MANDLOCK \
    DIRSYNC NOATIME NODIRATIME BIND MOVE REC VERBOSE SILENT \
    POSIXACL UNBINDABLE PRIVATE SLAVE SHARED RELATIME KERNMOUNT \
    I_VERSION STRICTATIME LAZYTIME SUBMOUNT NOREMOTELOCK NOSEC BORN \
    ACTIVE NOUSER"

    SED_PROG=
    for i in $SYMS; do SED_PROG="$SED_PROG -e s/MS_$i/SB_$i/g"; done

    # we want files that contain at least one of MS_...,
    # with fs/namespace.c and fs/pnode.c excluded.
    L=$(for i in $SYMS; do git grep -w -l MS_$i $FILES; done| sort|uniq|grep -v '^fs/namespace.c'|grep -v '^fs/pnode.c')

    for f in $L; do sed -i $f $SED_PROG; done

    Requested-by: Al Viro
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

18 Nov, 2017

2 commits

  • There is a race condition between nilfs_dirty_inode() and
    nilfs_set_file_dirty().

    When a file is opened, nilfs_dirty_inode() is called to update the
    access timestamp in the inode. It calls __nilfs_mark_inode_dirty() in a
    separate transaction. __nilfs_mark_inode_dirty() caches the ifile
    buffer_head in the i_bh field of the inode info structure and marks it
    as dirty.

    After some data was written to the file in another transaction, the
    function nilfs_set_file_dirty() is called, which adds the inode to the
    ns_dirty_files list.

    Then the segment construction calls nilfs_segctor_collect_dirty_files(),
    which goes through the ns_dirty_files list and checks the i_bh field.
    If there is a cached buffer_head in i_bh it is not marked as dirty
    again.

    Since nilfs_dirty_inode() and nilfs_set_file_dirty() use separate
    transactions, it is possible that a segment construction that writes out
    the ifile occurs in-between the two. If this happens the inode is not
    on the ns_dirty_files list, but its ifile block is still marked as dirty
    and written out.

    In the next segment construction, the data for the file is written out
    and nilfs_bmap_propagate() updates the b-tree. Eventually the bmap root
    is written into the i_bh block, which is not dirty, because it was
    written out in another segment construction.

    As a result the bmap update can be lost, which leads to file system
    corruption. Either the virtual block address points to an unallocated
    DAT block, or the DAT entry will be reused for something different.

    The error can remain undetected for a long time. A typical error
    message would be one of the "bad btree" errors or a warning that a DAT
    entry could not be found.

    This bug can be reproduced reliably by a simple benchmark that creates
    and overwrites millions of 4k files.

    Link: http://lkml.kernel.org/r/1509367935-3086-2-git-send-email-konishi.ryusuke@lab.ntt.co.jp
    Signed-off-by: Andreas Rohner
    Signed-off-by: Ryusuke Konishi
    Tested-by: Andreas Rohner
    Tested-by: Ryusuke Konishi
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andreas Rohner
     
  • In preparation for unconditionally passing the struct timer_list pointer
    to all timer callbacks, switch to using the new timer_setup() and
    from_timer() to pass the timer pointer explicitly. This requires adding
    a pointer to hold the timer's target task, as the lifetime of sc_task
    doesn't appear to match the timer's task.

    Link: http://lkml.kernel.org/r/20171016235900.GA102729@beast
    Signed-off-by: Kees Cook
    Acked-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Kees Cook
     

16 Nov, 2017

3 commits

  • Every pagevec_init user claims the pages being released are hot even in
    cases where it is unlikely the pages are hot. As no one cares about the
    hotness of pages being released to the allocator, just ditch the
    parameter.

    No performance impact is expected as the overhead is marginal. The
    parameter is removed simply because it is a bit stupid to have a useless
    parameter copied everywhere.

    Link: http://lkml.kernel.org/r/20171018075952.10627-6-mgorman@techsingularity.net
    Signed-off-by: Mel Gorman
    Acked-by: Vlastimil Babka
    Cc: Andi Kleen
    Cc: Dave Chinner
    Cc: Dave Hansen
    Cc: Jan Kara
    Cc: Johannes Weiner
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Mel Gorman
     
  • All users of pagevec_lookup() and pagevec_lookup_range() now pass
    PAGEVEC_SIZE as a desired number of pages. Just drop the argument.

    Link: http://lkml.kernel.org/r/20171009151359.31984-15-jack@suse.cz
    Signed-off-by: Jan Kara
    Reviewed-by: Daniel Jordan
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Jan Kara
     
  • We want only pages from given range in nilfs_lookup_dirty_data_buffers().
    Use pagevec_lookup_range_tag() instead of pagevec_lookup_tag() and
    remove unnecessary code.

    Link: http://lkml.kernel.org/r/20171009151359.31984-10-jack@suse.cz
    Signed-off-by: Jan Kara
    Reviewed-by: Daniel Jordan
    Acked-by: Ryusuke Konishi
    Cc: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Jan Kara
     

20 Jun, 2017

2 commits

  • So I've noticed a number of instances where it was not obvious from the
    code whether ->task_list was for a wait-queue head or a wait-queue entry.

    Furthermore, there's a number of wait-queue users where the lists are
    not for 'tasks' but other entities (poll tables, etc.), in which case
    the 'task_list' name is actively confusing.

    To clear this all up, name the wait-queue head and entry list structure
    fields unambiguously:

    struct wait_queue_head::task_list => ::head
    struct wait_queue_entry::task_list => ::entry

    For example, this code:

    rqw->wait.task_list.next != &wait->task_list

    ... is was pretty unclear (to me) what it's doing, while now it's written this way:

    rqw->wait.head.next != &wait->entry

    ... which makes it pretty clear that we are iterating a list until we see the head.

    Other examples are:

    list_for_each_entry_safe(pos, next, &x->task_list, task_list) {
    list_for_each_entry(wq, &fence->wait.task_list, task_list) {

    ... where it's unclear (to me) what we are iterating, and during review it's
    hard to tell whether it's trying to walk a wait-queue entry (which would be
    a bug), while now it's written as:

    list_for_each_entry_safe(pos, next, &x->head, entry) {
    list_for_each_entry(wq, &fence->wait.head, entry) {

    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: linux-kernel@vger.kernel.org
    Signed-off-by: Ingo Molnar

    Ingo Molnar
     
  • Rename:

    wait_queue_t => wait_queue_entry_t

    'wait_queue_t' was always a slight misnomer: its name implies that it's a "queue",
    but in reality it's a queue *entry*. The 'real' queue is the wait queue head,
    which had to carry the name.

    Start sorting this out by renaming it to 'wait_queue_entry_t'.

    This also allows the real structure name 'struct __wait_queue' to
    lose its double underscore and become 'struct wait_queue_entry',
    which is the more canonical nomenclature for such data types.

    Cc: Linus Torvalds
    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: linux-kernel@vger.kernel.org
    Signed-off-by: Ingo Molnar

    Ingo Molnar
     

02 Mar, 2017

1 commit


28 Feb, 2017

1 commit

  • Replace all 1 << inode->i_blkbits and (1 << inode->i_blkbits) in fs
    branch.

    This patch also fixes multiple checkpatch warnings: WARNING: Prefer
    'unsigned int' to bare use of 'unsigned'

    Thanks to Andrew Morton for suggesting more appropriate function instead
    of macro.

    [geliangtang@gmail.com: truncate: use i_blocksize()]
    Link: http://lkml.kernel.org/r/9c8b2cd83c8f5653805d43debde9fa8817e02fc4.1484895804.git.geliangtang@gmail.com
    Link: http://lkml.kernel.org/r/1481319905-10126-1-git-send-email-fabf@skynet.be
    Signed-off-by: Fabian Frederick
    Signed-off-by: Geliang Tang
    Cc: Alexander Viro
    Cc: Ross Zwisler
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Fabian Frederick
     

03 Aug, 2016

4 commits

  • Replace bit shifts by BIT macro for clarity.

    Link: http://lkml.kernel.org/r/1465825507-3407-3-git-send-email-konishi.ryusuke@lab.ntt.co.jp
    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     
  • Use cond_resched() instead of yield() in the loop of
    nilfs_transaction_lock() since the usage corresponds to the "be nice for
    others" case that the comment of yield() says.

    This removes the following checkpatch.pl warning:

    "WARNING: Using yield() is generally wrong. See yield() kernel-doc
    (sched/core.c)"

    Link: http://lkml.kernel.org/r/1464875891-5443-8-git-send-email-konishi.ryusuke@lab.ntt.co.jp
    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     
  • Use nilfs_msg() to output warning messages and get rid of
    nilfs_warning() function. This also removes function names from the
    messages unless we embed them explicitly in format strings. Instead,
    some messages are revised to clarify the context.

    [arnd@arndb.de: avoid warning about unused variables]
    Link: http://lkml.kernel.org/r/20160615201945.3348205-1-arnd@arndb.de
    Link: http://lkml.kernel.org/r/1464875891-5443-6-git-send-email-konishi.ryusuke@lab.ntt.co.jp
    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     
  • Replace most use of printk() in nilfs2 implementation with nilfs_msg(),
    and reduce the following checkpatch.pl warning:

    "WARNING: Prefer [subsystem eg: netdev]_crit([subsystem]dev, ...
    then dev_crit(dev, ... then pr_crit(... to printk(KERN_CRIT ..."

    This patch also fixes a minor checkpatch warning "WARNING: quoted string
    split across lines" that often accompanies the prior warning, and amends
    message format as needed.

    Link: http://lkml.kernel.org/r/1464875891-5443-5-git-send-email-konishi.ryusuke@lab.ntt.co.jp
    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     

24 May, 2016

8 commits

  • This fixes block comments with proper formatting to eliminate the
    following checkpatch.pl warnings:

    "WARNING: Block comments use * on subsequent lines"
    "WARNING: Block comments use a trailing */ on a separate line"

    Link: http://lkml.kernel.org/r/1462886671-3521-8-git-send-email-konishi.ryusuke@lab.ntt.co.jp
    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     
  • This fixes the checkpatch.pl warning that suggests else is not
    generally useful after a break or return.

    Link: http://lkml.kernel.org/r/1462886671-3521-6-git-send-email-konishi.ryusuke@lab.ntt.co.jp
    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     
  • This fixes checkpatch.pl warning "WARNING: Prefer 'unsigned int' to
    bare use of 'unsigned'".

    Link: http://lkml.kernel.org/r/1462886671-3521-5-git-send-email-konishi.ryusuke@lab.ntt.co.jp
    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     
  • This updates call sites of nilfs_warning() and nilfs_error() so that they
    don't add a duplicate newline. These output functions are already
    designed to add a trailing newline to the message.

    Link: http://lkml.kernel.org/r/1462886671-3521-2-git-send-email-konishi.ryusuke@lab.ntt.co.jp
    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     
  • Clean up checkpatch.pl warnings "WARNING: Missing a blank line after
    declarations" from nilfs2.

    Link: http://lkml.kernel.org/r/1461935747-10380-11-git-send-email-konishi.ryusuke@lab.ntt.co.jp
    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     
  • E-mail addresses of osrg.net domain are no longer available. This
    removes them from authorship notices and prevents reporters from being
    confused.

    Link: http://lkml.kernel.org/r/1461935747-10380-5-git-send-email-konishi.ryusuke@lab.ntt.co.jp
    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     
  • This removes the extra paragraph which mentions FSF address in GPL
    notices from source code of nilfs2 and avoids the checkpatch.pl error
    related to it.

    Link: http://lkml.kernel.org/r/1461935747-10380-4-git-send-email-konishi.ryusuke@lab.ntt.co.jp
    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     
  • The nilfs_sc_operations structures are never modified, so declare them
    as const.

    Done with the help of Coccinelle.

    Signed-off-by: Julia Lawall
    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Julia Lawall
     

05 Apr, 2016

1 commit

  • 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
     

07 Nov, 2015

3 commits

  • Fix the following build warnings:

    $ make W=1
    [...]
    CC [M] fs/nilfs2/btree.o
    fs/nilfs2/btree.c: In function 'nilfs_btree_split':
    fs/nilfs2/btree.c:923:8: warning: variable 'newptr' set but not used [-Wunused-but-set-variable]
    __u64 newptr;
    ^
    fs/nilfs2/btree.c:922:8: warning: variable 'newkey' set but not used [-Wunused-but-set-variable]
    __u64 newkey;
    ^
    CC [M] fs/nilfs2/dat.o
    fs/nilfs2/dat.c: In function 'nilfs_dat_prepare_end':
    fs/nilfs2/dat.c:158:8: warning: variable 'start' set but not used [-Wunused-but-set-variable]
    __u64 start;
    ^
    CC [M] fs/nilfs2/segment.o
    fs/nilfs2/segment.c: In function 'nilfs_segctor_do_immediate_flush':
    fs/nilfs2/segment.c:2433:6: warning: variable 'err' set but not used [-Wunused-but-set-variable]
    int err;
    ^
    CC [M] fs/nilfs2/sufile.o
    fs/nilfs2/sufile.c: In function 'nilfs_sufile_alloc':
    fs/nilfs2/sufile.c:320:27: warning: variable 'ncleansegs' set but not used [-Wunused-but-set-variable]
    unsigned long nsegments, ncleansegs, nsus, cnt;
    ^
    CC [M] fs/nilfs2/alloc.o
    fs/nilfs2/alloc.c: In function 'nilfs_palloc_prepare_alloc_entry':
    fs/nilfs2/alloc.c:478:38: warning: variable 'groups_per_desc_block' set but not used [-Wunused-but-set-variable]
    unsigned long n, entries_per_group, groups_per_desc_block;
    ^

    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     
  • This patch adds a tracepoint for transaction events of nilfs. With the
    tracepoint, these events can be tracked: begin, abort, commit, trylock,
    lock, and unlock. Basically, these events have corresponding functions
    e.g. begin event corresponds nilfs_transaction_begin(). The unlock event
    is an exception. It corresponds to the iteration in
    nilfs_transaction_lock().

    Only one tracepoint is introcued: nilfs2_transaction_transition. The
    above events are distinguished with newly introduced enum. With this
    tracepoint, we can analyse a critical section of segment constructoin.

    Sample output by tpoint of perf-tools:
    cp-4457 [000] ...1 63.266220: nilfs2_transaction_transition: sb = ffff8802112b8800 ti = ffff8800bf5ccc58 count = 1 flags = 9 state = BEGIN
    cp-4457 [000] ...1 63.266221: nilfs2_transaction_transition: sb = ffff8802112b8800 ti = ffff8800bf5ccc58 count = 0 flags = 9 state = COMMIT
    cp-4457 [000] ...1 63.266221: nilfs2_transaction_transition: sb = ffff8802112b8800 ti = ffff8800bf5ccc58 count = 0 flags = 9 state = COMMIT
    segctord-4371 [001] ...1 68.261196: nilfs2_transaction_transition: sb = ffff8802112b8800 ti = ffff8800b889bdf8 count = 0 flags = 10 state = TRYLOCK
    segctord-4371 [001] ...1 68.261280: nilfs2_transaction_transition: sb = ffff8802112b8800 ti = ffff8800b889bdf8 count = 0 flags = 10 state = LOCK
    segctord-4371 [001] ...1 68.261877: nilfs2_transaction_transition: sb = ffff8802112b8800 ti = ffff8800b889bdf8 count = 1 flags = 10 state = BEGIN
    segctord-4371 [001] ...1 68.262116: nilfs2_transaction_transition: sb = ffff8802112b8800 ti = ffff8800b889bdf8 count = 0 flags = 18 state = COMMIT
    segctord-4371 [001] ...1 68.265032: nilfs2_transaction_transition: sb = ffff8802112b8800 ti = ffff8800b889bdf8 count = 0 flags = 18 state = UNLOCK
    segctord-4371 [001] ...1 132.376847: nilfs2_transaction_transition: sb = ffff8802112b8800 ti = ffff8800b889bdf8 count = 0 flags = 10 state = TRYLOCK

    This patch also does trivial cleaning of comma usage in collection stage
    transition event for consistent coding style.

    Signed-off-by: Hitoshi Mitake
    Signed-off-by: Ryusuke Konishi
    Cc: Steven Rostedt
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Hitoshi Mitake
     
  • This patch adds a tracepoint for tracking stage transition of block
    collection in segment construction. With the tracepoint, we can analysis
    the behavior of segment construction in depth. It would be useful for
    bottleneck detection and debugging, etc.

    The tracepoint is created with the standard trace API of linux (like ext3,
    ext4, f2fs and btrfs). So we can analysis with existing tools easily. Of
    course, more detailed analysis will be possible if we can create nilfs
    specific analysis tools.

    Below is an example of event dump with Brendan Gregg's perf-tools
    (https://github.com/brendangregg/perf-tools). Time consumption between
    each stage can be obtained.

    $ sudo bin/tpoint nilfs2:nilfs2_collection_stage_transition
    Tracing nilfs2:nilfs2_collection_stage_transition. Ctrl-C to end.
    segctord-14875 [003] ...1 28311.067794: nilfs2_collection_stage_transition: sci = ffff8800ce6de000 stage = ST_INIT
    segctord-14875 [003] ...1 28311.068139: nilfs2_collection_stage_transition: sci = ffff8800ce6de000 stage = ST_GC
    segctord-14875 [003] ...1 28311.068139: nilfs2_collection_stage_transition: sci = ffff8800ce6de000 stage = ST_FILE
    segctord-14875 [003] ...1 28311.068486: nilfs2_collection_stage_transition: sci = ffff8800ce6de000 stage = ST_IFILE
    segctord-14875 [003] ...1 28311.068540: nilfs2_collection_stage_transition: sci = ffff8800ce6de000 stage = ST_CPFILE
    segctord-14875 [003] ...1 28311.068561: nilfs2_collection_stage_transition: sci = ffff8800ce6de000 stage = ST_SUFILE
    segctord-14875 [003] ...1 28311.068565: nilfs2_collection_stage_transition: sci = ffff8800ce6de000 stage = ST_DAT
    segctord-14875 [003] ...1 28311.068573: nilfs2_collection_stage_transition: sci = ffff8800ce6de000 stage = ST_SR
    segctord-14875 [003] ...1 28311.068574: nilfs2_collection_stage_transition: sci = ffff8800ce6de000 stage = ST_DONE

    For capturing transition correctly, this patch adds wrappers for the
    member scnt of nilfs_cstage. With this change, every transition of the
    stage can produce trace event in a correct manner.

    Signed-off-by: Hitoshi Mitake
    Signed-off-by: Ryusuke Konishi
    Cc: Steven Rostedt
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Hitoshi Mitake
     

17 Apr, 2015

2 commits

  • nilfs_forget_buffer(), nilfs_clear_dirty_page(), and
    nilfs_segctor_complete_write() are using a bunch of atomic bit operations
    against buffer state bitmap.

    This reduces the number of them by utilizing set_mask_bits() macro.

    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     
  • The async write flag is introduced to nilfs2 in the commit 7f42ec394156
    ("nilfs2: fix issue with race condition of competition between segments
    for dirty blocks"), but the flag only makes sense for data buffers and
    btree node buffers. It is not needed for segment summary buffers.

    This gets rid of the latter uses as part of refactoring of atomic bit
    operations on buffer state bitmap.

    Signed-off-by: Ryusuke Konishi
    Cc: Vyacheslav Dubeyko
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     

13 Mar, 2015

1 commit

  • According to a report from Yuxuan Shui, nilfs2 in kernel 3.19 got stuck
    during recovery at mount time. The code path that caused the deadlock was
    as follows:

    nilfs_fill_super()
    load_nilfs()
    nilfs_salvage_orphan_logs()
    * Do roll-forwarding, attach segment constructor for recovery,
    and kick it.

    nilfs_segctor_thread()
    nilfs_segctor_thread_construct()
    * A lock is held with nilfs_transaction_lock()
    nilfs_segctor_do_construct()
    nilfs_segctor_drop_written_files()
    iput()
    iput_final()
    write_inode_now()
    writeback_single_inode()
    __writeback_single_inode()
    do_writepages()
    nilfs_writepage()
    nilfs_construct_dsync_segment()
    nilfs_transaction_lock() --> deadlock

    This can happen if commit 7ef3ff2fea8b ("nilfs2: fix deadlock of segment
    constructor over I_SYNC flag") is applied and roll-forward recovery was
    performed at mount time. The roll-forward recovery can happen if datasync
    write is done and the file system crashes immediately after that. For
    instance, we can reproduce the issue with the following steps:

    < nilfs2 is mounted on /nilfs (device: /dev/sdb1) >
    # dd if=/dev/zero of=/nilfs/test bs=4k count=1 && sync
    # dd if=/dev/zero of=/nilfs/test conv=notrunc oflag=dsync bs=4k
    count=1 && reboot -nfh
    < the system will immediately reboot >
    # mount -t nilfs2 /dev/sdb1 /nilfs

    The deadlock occurs because iput() can run segment constructor through
    writeback_single_inode() if MS_ACTIVE flag is not set on sb->s_flags. The
    above commit changed segment constructor so that it calls iput()
    asynchronously for inodes with i_nlink == 0, but that change was
    imperfect.

    This fixes the another deadlock by deferring iput() in segment constructor
    even for the case that mount is not finished, that is, for the case that
    MS_ACTIVE flag is not set.

    Signed-off-by: Ryusuke Konishi
    Reported-by: Yuxuan Shui
    Tested-by: Ryusuke Konishi
    Cc: Al Viro
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     

06 Feb, 2015

1 commit

  • Nilfs2 eventually hangs in a stress test with fsstress program. This
    issue was caused by the following deadlock over I_SYNC flag between
    nilfs_segctor_thread() and writeback_sb_inodes():

    nilfs_segctor_thread()
    nilfs_segctor_thread_construct()
    nilfs_segctor_unlock()
    nilfs_dispose_list()
    iput()
    iput_final()
    evict()
    inode_wait_for_writeback() * wait for I_SYNC flag

    writeback_sb_inodes()
    * set I_SYNC flag on inode->i_state
    __writeback_single_inode()
    do_writepages()
    nilfs_writepages()
    nilfs_construct_dsync_segment()
    nilfs_segctor_sync()
    * wait for completion of segment constructor
    inode_sync_complete()
    * clear I_SYNC flag after __writeback_single_inode() completed

    writeback_sb_inodes() calls do_writepages() for dirty inodes after
    setting I_SYNC flag on inode->i_state. do_writepages() in turn calls
    nilfs_writepages(), which can run segment constructor and wait for its
    completion. On the other hand, segment constructor calls iput(), which
    can call evict() and wait for the I_SYNC flag on
    inode_wait_for_writeback().

    Since segment constructor doesn't know when I_SYNC will be set, it
    cannot know whether iput() will block or not unless inode->i_nlink has a
    non-zero count. We can prevent evict() from being called in iput() by
    implementing sop->drop_inode(), but it's not preferable to leave inodes
    with i_nlink == 0 for long periods because it even defers file
    truncation and inode deallocation. So, this instead resolves the
    deadlock by calling iput() asynchronously with a workqueue for inodes
    with i_nlink == 0.

    Signed-off-by: Ryusuke Konishi
    Cc: Al Viro
    Tested-by: Ryusuke Konishi
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ryusuke Konishi
     

14 Oct, 2014

2 commits

  • Support for fdatasync() has been implemented in NILFS2 for a long time,
    but whenever the corresponding inode is dirty the implementation falls
    back to a full-flegded sync(). Since every write operation has to
    update the modification time of the file, the inode will almost always
    be dirty and fdatasync() will fall back to sync() most of the time. But
    this fallback is only necessary for a change of the file size and not
    for a change of the various timestamps.

    This patch adds a new flag NILFS_I_INODE_SYNC to differentiate between
    those two situations.

    * If it is set the file size was changed and a full sync is necessary.
    * If it is not set then only the timestamps were updated and
    fdatasync() can go ahead.

    There is already a similar flag I_DIRTY_DATASYNC on the VFS layer with
    the exact same semantics. Unfortunately it cannot be used directly,
    because NILFS2 doesn't implement write_inode() and doesn't clear the VFS
    flags when inodes are written out. So the VFS writeback thread can
    clear I_DIRTY_DATASYNC at any time without notifying NILFS2. So
    I_DIRTY_DATASYNC has to be mapped onto NILFS_I_INODE_SYNC in
    nilfs_update_inode().

    Signed-off-by: Andreas Rohner
    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andreas Rohner
     
  • Under normal circumstances nilfs_sync_fs() writes out the super block,
    which causes a flush of the underlying block device. But this depends
    on the THE_NILFS_SB_DIRTY flag, which is only set if the pointer to the
    last segment crosses a segment boundary. So if only a small amount of
    data is written before the call to nilfs_sync_fs(), no flush of the
    block device occurs.

    In the above case an additional call to blkdev_issue_flush() is needed.
    To prevent unnecessary overhead, the new flag nilfs->ns_flushed_device
    is introduced, which is cleared whenever new logs are written and set
    whenever the block device is flushed. For convenience the function
    nilfs_flush_device() is added, which contains the above logic.

    Signed-off-by: Andreas Rohner
    Signed-off-by: Ryusuke Konishi
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andreas Rohner
     

15 Jan, 2014

1 commit

  • There is a bug in the function nilfs_segctor_collect, which results in
    active data being written to a segment, that is marked as clean. It is
    possible, that this segment is selected for a later segment
    construction, whereby the old data is overwritten.

    The problem shows itself with the following kernel log message:

    nilfs_sufile_do_cancel_free: segment 6533 must be clean

    Usually a few hours later the file system gets corrupted:

    NILFS: bad btree node (blocknr=8748107): level = 0, flags = 0x0, nchildren = 0
    NILFS error (device sdc1): nilfs_bmap_last_key: broken bmap (inode number=114660)

    The issue can be reproduced with a file system that is nearly full and
    with the cleaner running, while some IO intensive task is running.
    Although it is quite hard to reproduce.

    This is what happens:

    1. The cleaner starts the segment construction
    2. nilfs_segctor_collect is called
    3. sc_stage is on NILFS_ST_SUFILE and segments are freed
    4. sc_stage is on NILFS_ST_DAT current segment is full
    5. nilfs_segctor_extend_segments is called, which
    allocates a new segment
    6. The new segment is one of the segments freed in step 3
    7. nilfs_sufile_cancel_freev is called and produces an error message
    8. Loop around and the collection starts again
    9. sc_stage is on NILFS_ST_SUFILE and segments are freed
    including the newly allocated segment, which will contain active
    data and can be allocated at a later time
    10. A few hours later another segment construction allocates the
    segment and causes file system corruption

    This can be prevented by simply reordering the statements. If
    nilfs_sufile_cancel_freev is called before nilfs_segctor_extend_segments
    the freed segments are marked as dirty and cannot be allocated any more.

    Signed-off-by: Andreas Rohner
    Reviewed-by: Ryusuke Konishi
    Tested-by: Andreas Rohner
    Signed-off-by: Ryusuke Konishi
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andreas Rohner
     

01 Oct, 2013

1 commit

  • Many NILFS2 users were reported about strange file system corruption
    (for example):

    NILFS: bad btree node (blocknr=185027): level = 0, flags = 0x0, nchildren = 768
    NILFS error (device sda4): nilfs_bmap_last_key: broken bmap (inode number=11540)

    But such error messages are consequence of file system's issue that takes
    place more earlier. Fortunately, Jerome Poulin
    and Anton Eliasson were reported about another
    issue not so recently. These reports describe the issue with segctor
    thread's crash:

    BUG: unable to handle kernel paging request at 0000000000004c83
    IP: nilfs_end_page_io+0x12/0xd0 [nilfs2]

    Call Trace:
    nilfs_segctor_do_construct+0xf25/0x1b20 [nilfs2]
    nilfs_segctor_construct+0x17b/0x290 [nilfs2]
    nilfs_segctor_thread+0x122/0x3b0 [nilfs2]
    kthread+0xc0/0xd0
    ret_from_fork+0x7c/0xb0

    These two issues have one reason. This reason can raise third issue
    too. Third issue results in hanging of segctor thread with eating of
    100% CPU.

    REPRODUCING PATH:

    One of the possible way or the issue reproducing was described by
    Jermoe me Poulin :

    1. init S to get to single user mode.
    2. sysrq+E to make sure only my shell is running
    3. start network-manager to get my wifi connection up
    4. login as root and launch "screen"
    5. cd /boot/log/nilfs which is a ext3 mount point and can log when NILFS dies.
    6. lscp | xz -9e > lscp.txt.xz
    7. mount my snapshot using mount -o cp=3360839,ro /dev/vgUbuntu/root /mnt/nilfs
    8. start a screen to dump /proc/kmsg to text file since rsyslog is killed
    9. start a screen and launch strace -f -o find-cat.log -t find
    /mnt/nilfs -type f -exec cat {} > /dev/null \;
    10. start a screen and launch strace -f -o apt-get.log -t apt-get update
    11. launch the last command again as it did not crash the first time
    12. apt-get crashes
    13. ps aux > ps-aux-crashed.log
    13. sysrq+W
    14. sysrq+E wait for everything to terminate
    15. sysrq+SUSB

    Simplified way of the issue reproducing is starting kernel compilation
    task and "apt-get update" in parallel.

    REPRODUCIBILITY:

    The issue is reproduced not stable [60% - 80%]. It is very important to
    have proper environment for the issue reproducing. The critical
    conditions for successful reproducing:

    (1) It should have big modified file by mmap() way.

    (2) This file should have the count of dirty blocks are greater that
    several segments in size (for example, two or three) from time to time
    during processing.

    (3) It should be intensive background activity of files modification
    in another thread.

    INVESTIGATION:

    First of all, it is possible to see that the reason of crash is not valid
    page address:

    NILFS [nilfs_segctor_complete_write]:2100 bh->b_count 0, bh->b_blocknr 13895680, bh->b_size 13897727, bh->b_page 0000000000001a82
    NILFS [nilfs_segctor_complete_write]:2101 segbuf->sb_segnum 6783

    Moreover, value of b_page (0x1a82) is 6786. This value looks like segment
    number. And b_blocknr with b_size values look like block numbers. So,
    buffer_head's pointer points on not proper address value.

    Detailed investigation of the issue is discovered such picture:

    [-----------------------------SEGMENT 6783-------------------------------]
    NILFS [nilfs_segctor_do_construct]:2310 nilfs_segctor_begin_construction
    NILFS [nilfs_segctor_do_construct]:2321 nilfs_segctor_collect
    NILFS [nilfs_segctor_do_construct]:2336 nilfs_segctor_assign
    NILFS [nilfs_segctor_do_construct]:2367 nilfs_segctor_update_segusage
    NILFS [nilfs_segctor_do_construct]:2371 nilfs_segctor_prepare_write
    NILFS [nilfs_segctor_do_construct]:2376 nilfs_add_checksums_on_logs
    NILFS [nilfs_segctor_do_construct]:2381 nilfs_segctor_write
    NILFS [nilfs_segbuf_submit_bio]:464 bio->bi_sector 111149024, segbuf->sb_segnum 6783

    [-----------------------------SEGMENT 6784-------------------------------]
    NILFS [nilfs_segctor_do_construct]:2310 nilfs_segctor_begin_construction
    NILFS [nilfs_segctor_do_construct]:2321 nilfs_segctor_collect
    NILFS [nilfs_lookup_dirty_data_buffers]:782 bh->b_count 1, bh->b_page ffffea000709b000, page->index 0, i_ino 1033103, i_size 25165824
    NILFS [nilfs_lookup_dirty_data_buffers]:783 bh->b_assoc_buffers.next ffff8802174a6798, bh->b_assoc_buffers.prev ffff880221cffee8
    NILFS [nilfs_segctor_do_construct]:2336 nilfs_segctor_assign
    NILFS [nilfs_segctor_do_construct]:2367 nilfs_segctor_update_segusage
    NILFS [nilfs_segctor_do_construct]:2371 nilfs_segctor_prepare_write
    NILFS [nilfs_segctor_do_construct]:2376 nilfs_add_checksums_on_logs
    NILFS [nilfs_segctor_do_construct]:2381 nilfs_segctor_write
    NILFS [nilfs_segbuf_submit_bh]:575 bh->b_count 1, bh->b_page ffffea000709b000, page->index 0, i_ino 1033103, i_size 25165824
    NILFS [nilfs_segbuf_submit_bh]:576 segbuf->sb_segnum 6784
    NILFS [nilfs_segbuf_submit_bh]:577 bh->b_assoc_buffers.next ffff880218a0d5f8, bh->b_assoc_buffers.prev ffff880218bcdf50
    NILFS [nilfs_segbuf_submit_bio]:464 bio->bi_sector 111150080, segbuf->sb_segnum 6784, segbuf->sb_nbio 0
    [----------] ditto
    NILFS [nilfs_segbuf_submit_bio]:464 bio->bi_sector 111164416, segbuf->sb_segnum 6784, segbuf->sb_nbio 15

    [-----------------------------SEGMENT 6785-------------------------------]
    NILFS [nilfs_segctor_do_construct]:2310 nilfs_segctor_begin_construction
    NILFS [nilfs_segctor_do_construct]:2321 nilfs_segctor_collect
    NILFS [nilfs_lookup_dirty_data_buffers]:782 bh->b_count 2, bh->b_page ffffea000709b000, page->index 0, i_ino 1033103, i_size 25165824
    NILFS [nilfs_lookup_dirty_data_buffers]:783 bh->b_assoc_buffers.next ffff880219277e80, bh->b_assoc_buffers.prev ffff880221cffc88
    NILFS [nilfs_segctor_do_construct]:2367 nilfs_segctor_update_segusage
    NILFS [nilfs_segctor_do_construct]:2371 nilfs_segctor_prepare_write
    NILFS [nilfs_segctor_do_construct]:2376 nilfs_add_checksums_on_logs
    NILFS [nilfs_segctor_do_construct]:2381 nilfs_segctor_write
    NILFS [nilfs_segbuf_submit_bh]:575 bh->b_count 2, bh->b_page ffffea000709b000, page->index 0, i_ino 1033103, i_size 25165824
    NILFS [nilfs_segbuf_submit_bh]:576 segbuf->sb_segnum 6785
    NILFS [nilfs_segbuf_submit_bh]:577 bh->b_assoc_buffers.next ffff880218a0d5f8, bh->b_assoc_buffers.prev ffff880222cc7ee8
    NILFS [nilfs_segbuf_submit_bio]:464 bio->bi_sector 111165440, segbuf->sb_segnum 6785, segbuf->sb_nbio 0
    [----------] ditto
    NILFS [nilfs_segbuf_submit_bio]:464 bio->bi_sector 111177728, segbuf->sb_segnum 6785, segbuf->sb_nbio 12

    NILFS [nilfs_segctor_do_construct]:2399 nilfs_segctor_wait
    NILFS [nilfs_segbuf_wait]:676 segbuf->sb_segnum 6783
    NILFS [nilfs_segbuf_wait]:676 segbuf->sb_segnum 6784
    NILFS [nilfs_segbuf_wait]:676 segbuf->sb_segnum 6785

    NILFS [nilfs_segctor_complete_write]:2100 bh->b_count 0, bh->b_blocknr 13895680, bh->b_size 13897727, bh->b_page 0000000000001a82

    BUG: unable to handle kernel paging request at 0000000000001a82
    IP: [] nilfs_end_page_io+0x12/0xd0 [nilfs2]

    Usually, for every segment we collect dirty files in list. Then, dirty
    blocks are gathered for every dirty file, prepared for write and
    submitted by means of nilfs_segbuf_submit_bh() call. Finally, it takes
    place complete write phase after calling nilfs_end_bio_write() on the
    block layer. Buffers/pages are marked as not dirty on final phase and
    processed files removed from the list of dirty files.

    It is possible to see that we had three prepare_write and submit_bio
    phases before segbuf_wait and complete_write phase. Moreover, segments
    compete between each other for dirty blocks because on every iteration
    of segments processing dirty buffer_heads are added in several lists of
    payload_buffers:

    [SEGMENT 6784]: bh->b_assoc_buffers.next ffff880218a0d5f8, bh->b_assoc_buffers.prev ffff880218bcdf50
    [SEGMENT 6785]: bh->b_assoc_buffers.next ffff880218a0d5f8, bh->b_assoc_buffers.prev ffff880222cc7ee8

    The next pointer is the same but prev pointer has changed. It means
    that buffer_head has next pointer from one list but prev pointer from
    another. Such modification can be made several times. And, finally, it
    can be resulted in various issues: (1) segctor hanging, (2) segctor
    crashing, (3) file system metadata corruption.

    FIX:
    This patch adds:

    (1) setting of BH_Async_Write flag in nilfs_segctor_prepare_write()
    for every proccessed dirty block;

    (2) checking of BH_Async_Write flag in
    nilfs_lookup_dirty_data_buffers() and
    nilfs_lookup_dirty_node_buffers();

    (3) clearing of BH_Async_Write flag in nilfs_segctor_complete_write(),
    nilfs_abort_logs(), nilfs_forget_buffer(), nilfs_clear_dirty_page().

    Reported-by: Jerome Poulin
    Reported-by: Anton Eliasson
    Cc: Paul Fertser
    Cc: ARAI Shun-ichi
    Cc: Piotr Szymaniak
    Cc: Juan Barry Manuel Canham
    Cc: Zahid Chowdhury
    Cc: Elmer Zhang
    Cc: Kenneth Langga
    Signed-off-by: Vyacheslav Dubeyko
    Acked-by: Ryusuke Konishi
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Vyacheslav Dubeyko
     

04 Jul, 2013

1 commit

  • The cp_inodes_count and cp_blocks_count are represented as __le64 type in
    on-disk structure (struct nilfs_checkpoint). But analogous fields in
    in-core structure (struct nilfs_root) are represented by atomic_t type.

    This patch replaces atomic_t on atomic64_t type in representation of
    inodes_count and blocks_count fields in struct nilfs_root.

    Signed-off-by: Vyacheslav Dubeyko
    Acked-by: Ryusuke Konishi
    Acked-by: Joern Engel
    Cc: Clemens Eisserer
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Vyacheslav Dubeyko