lkml.org 
[lkml]   [2019]   [Jan]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 067/101] ext4: force inode writes when nfsd calls commit_metadata()
    Date
    4.14-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Theodore Ts'o <tytso@mit.edu>

    commit fde872682e175743e0c3ef939c89e3c6008a1529 upstream.

    Some time back, nfsd switched from calling vfs_fsync() to using a new
    commit_metadata() hook in export_operations(). If the file system did
    not provide a commit_metadata() hook, it fell back to using
    sync_inode_metadata(). Unfortunately doesn't work on all file
    systems. In particular, it doesn't work on ext4 due to how the inode
    gets journalled --- the VFS writeback code will not always call
    ext4_write_inode().

    So we need to provide our own ext4_nfs_commit_metdata() method which
    calls ext4_write_inode() directly.

    Google-Bug-Id: 121195940
    Signed-off-by: Theodore Ts'o <tytso@mit.edu>
    Cc: stable@kernel.org
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/ext4/super.c | 11 +++++++++++
    include/trace/events/ext4.h | 20 ++++++++++++++++++++
    2 files changed, 31 insertions(+)

    --- a/fs/ext4/super.c
    +++ b/fs/ext4/super.c
    @@ -1153,6 +1153,16 @@ static struct dentry *ext4_fh_to_parent(
    ext4_nfs_get_inode);
    }

    +static int ext4_nfs_commit_metadata(struct inode *inode)
    +{
    + struct writeback_control wbc = {
    + .sync_mode = WB_SYNC_ALL
    + };
    +
    + trace_ext4_nfs_commit_metadata(inode);
    + return ext4_write_inode(inode, &wbc);
    +}
    +
    /*
    * Try to release metadata pages (indirect blocks, directories) which are
    * mapped via the block device. Since these pages could have journal heads
    @@ -1361,6 +1371,7 @@ static const struct export_operations ex
    .fh_to_dentry = ext4_fh_to_dentry,
    .fh_to_parent = ext4_fh_to_parent,
    .get_parent = ext4_get_parent,
    + .commit_metadata = ext4_nfs_commit_metadata,
    };

    enum {
    --- a/include/trace/events/ext4.h
    +++ b/include/trace/events/ext4.h
    @@ -225,6 +225,26 @@ TRACE_EVENT(ext4_drop_inode,
    (unsigned long) __entry->ino, __entry->drop)
    );

    +TRACE_EVENT(ext4_nfs_commit_metadata,
    + TP_PROTO(struct inode *inode),
    +
    + TP_ARGS(inode),
    +
    + TP_STRUCT__entry(
    + __field( dev_t, dev )
    + __field( ino_t, ino )
    + ),
    +
    + TP_fast_assign(
    + __entry->dev = inode->i_sb->s_dev;
    + __entry->ino = inode->i_ino;
    + ),
    +
    + TP_printk("dev %d,%d ino %lu",
    + MAJOR(__entry->dev), MINOR(__entry->dev),
    + (unsigned long) __entry->ino)
    +);
    +
    TRACE_EVENT(ext4_mark_inode_dirty,
    TP_PROTO(struct inode *inode, unsigned long IP),


    \
     
     \ /
      Last update: 2019-01-07 18:25    [W:4.095 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site