Skip to content

Commit

Permalink
pass writeback_control to ->write_inode
Browse files Browse the repository at this point in the history
This gives the filesystem more information about the writeback that
is happening.  Trond requested this for the NFS unstable write handling,
and other filesystems might benefit from this too by beeing able to
distinguish between the different callers in more detail.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
  • Loading branch information
Christoph Hellwig authored and Al Viro committed Mar 5, 2010
1 parent 26821ed commit a9185b4
Show file tree
Hide file tree
Showing 45 changed files with 115 additions and 72 deletions.
2 changes: 1 addition & 1 deletion fs/adfs/adfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ struct adfs_discmap {

/* Inode stuff */
struct inode *adfs_iget(struct super_block *sb, struct object_info *obj);
int adfs_write_inode(struct inode *inode,int unused);
int adfs_write_inode(struct inode *inode, struct writeback_control *wbc);
int adfs_notify_change(struct dentry *dentry, struct iattr *attr);

/* map.c */
Expand Down
5 changes: 3 additions & 2 deletions fs/adfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/writeback.h>
#include "adfs.h"

/*
Expand Down Expand Up @@ -360,7 +361,7 @@ adfs_notify_change(struct dentry *dentry, struct iattr *attr)
* The adfs-specific inode data has already been updated by
* adfs_notify_change()
*/
int adfs_write_inode(struct inode *inode, int wait)
int adfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
struct super_block *sb = inode->i_sb;
struct object_info obj;
Expand All @@ -375,7 +376,7 @@ int adfs_write_inode(struct inode *inode, int wait)
obj.attr = ADFS_I(inode)->attr;
obj.size = inode->i_size;

ret = adfs_dir_update(sb, &obj, wait);
ret = adfs_dir_update(sb, &obj, wbc->sync_mode == WB_SYNC_ALL);
unlock_kernel();
return ret;
}
3 changes: 2 additions & 1 deletion fs/affs/affs.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@ extern void affs_delete_inode(struct inode *inode);
extern void affs_clear_inode(struct inode *inode);
extern struct inode *affs_iget(struct super_block *sb,
unsigned long ino);
extern int affs_write_inode(struct inode *inode, int);
extern int affs_write_inode(struct inode *inode,
struct writeback_control *wbc);
extern int affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s32 type);

/* file.c */
Expand Down
2 changes: 1 addition & 1 deletion fs/affs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino)
}

int
affs_write_inode(struct inode *inode, int unused)
affs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
struct super_block *sb = inode->i_sb;
struct buffer_head *bh;
Expand Down
5 changes: 3 additions & 2 deletions fs/bfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/vfs.h>
#include <linux/writeback.h>
#include <asm/uaccess.h>
#include "bfs.h"

Expand Down Expand Up @@ -98,7 +99,7 @@ struct inode *bfs_iget(struct super_block *sb, unsigned long ino)
return ERR_PTR(-EIO);
}

static int bfs_write_inode(struct inode *inode, int wait)
static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
struct bfs_sb_info *info = BFS_SB(inode->i_sb);
unsigned int ino = (u16)inode->i_ino;
Expand Down Expand Up @@ -147,7 +148,7 @@ static int bfs_write_inode(struct inode *inode, int wait)
di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1);

mark_buffer_dirty(bh);
if (wait) {
if (wbc->sync_mode == WB_SYNC_ALL) {
sync_dirty_buffer(bh);
if (buffer_req(bh) && !buffer_uptodate(bh))
err = -EIO;
Expand Down
2 changes: 1 addition & 1 deletion fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -2326,7 +2326,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
int btrfs_readpage(struct file *file, struct page *page);
void btrfs_delete_inode(struct inode *inode);
void btrfs_put_inode(struct inode *inode);
int btrfs_write_inode(struct inode *inode, int wait);
int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc);
void btrfs_dirty_inode(struct inode *inode);
struct inode *btrfs_alloc_inode(struct super_block *sb);
void btrfs_destroy_inode(struct inode *inode);
Expand Down
4 changes: 2 additions & 2 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -3968,7 +3968,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
return ret;
}

int btrfs_write_inode(struct inode *inode, int wait)
int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
struct btrfs_root *root = BTRFS_I(inode)->root;
struct btrfs_trans_handle *trans;
Expand All @@ -3977,7 +3977,7 @@ int btrfs_write_inode(struct inode *inode, int wait)
if (root->fs_info->btree_inode == inode)
return 0;

if (wait) {
if (wbc->sync_mode == WB_SYNC_ALL) {
trans = btrfs_join_transaction(root, 1);
btrfs_set_trans_block_group(trans, inode);
ret = btrfs_commit_transaction(trans, root);
Expand Down
2 changes: 1 addition & 1 deletion fs/exofs/exofs.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ int exofs_write_begin(struct file *file, struct address_space *mapping,
struct page **pagep, void **fsdata);
extern struct inode *exofs_iget(struct super_block *, unsigned long);
struct inode *exofs_new_inode(struct inode *, int);
extern int exofs_write_inode(struct inode *, int);
extern int exofs_write_inode(struct inode *, struct writeback_control *wbc);
extern void exofs_delete_inode(struct inode *);

/* dir.c: */
Expand Down
4 changes: 2 additions & 2 deletions fs/exofs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1280,9 +1280,9 @@ static int exofs_update_inode(struct inode *inode, int do_sync)
return ret;
}

int exofs_write_inode(struct inode *inode, int wait)
int exofs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
return exofs_update_inode(inode, wait);
return exofs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
}

/*
Expand Down
2 changes: 1 addition & 1 deletion fs/ext2/ext2.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ extern unsigned long ext2_count_free (struct buffer_head *, unsigned);

/* inode.c */
extern struct inode *ext2_iget (struct super_block *, unsigned long);
extern int ext2_write_inode (struct inode *, int);
extern int ext2_write_inode (struct inode *, struct writeback_control *);
extern void ext2_delete_inode (struct inode *);
extern int ext2_sync_inode (struct inode *);
extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int);
Expand Down
11 changes: 9 additions & 2 deletions fs/ext2/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ MODULE_AUTHOR("Remy Card and others");
MODULE_DESCRIPTION("Second Extended Filesystem");
MODULE_LICENSE("GPL");

static int __ext2_write_inode(struct inode *inode, int do_sync);

/*
* Test whether an inode is a fast symlink.
*/
Expand All @@ -64,7 +66,7 @@ void ext2_delete_inode (struct inode * inode)
goto no_delete;
EXT2_I(inode)->i_dtime = get_seconds();
mark_inode_dirty(inode);
ext2_write_inode(inode, inode_needs_sync(inode));
__ext2_write_inode(inode, inode_needs_sync(inode));

inode->i_size = 0;
if (inode->i_blocks)
Expand Down Expand Up @@ -1335,7 +1337,7 @@ struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
return ERR_PTR(ret);
}

int ext2_write_inode(struct inode *inode, int do_sync)
static int __ext2_write_inode(struct inode *inode, int do_sync)
{
struct ext2_inode_info *ei = EXT2_I(inode);
struct super_block *sb = inode->i_sb;
Expand Down Expand Up @@ -1440,6 +1442,11 @@ int ext2_write_inode(struct inode *inode, int do_sync)
return err;
}

int ext2_write_inode(struct inode *inode, struct writeback_control *wbc)
{
return __ext2_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
}

int ext2_sync_inode(struct inode *inode)
{
struct writeback_control wbc = {
Expand Down
4 changes: 2 additions & 2 deletions fs/ext3/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -3096,7 +3096,7 @@ static int ext3_do_update_inode(handle_t *handle,
* `stuff()' is running, and the new i_size will be lost. Plus the inode
* will no longer be on the superblock's dirty inode list.
*/
int ext3_write_inode(struct inode *inode, int wait)
int ext3_write_inode(struct inode *inode, struct writeback_control *wbc)
{
if (current->flags & PF_MEMALLOC)
return 0;
Expand All @@ -3107,7 +3107,7 @@ int ext3_write_inode(struct inode *inode, int wait)
return -EIO;
}

if (!wait)
if (wbc->sync_mode != WB_SYNC_ALL)
return 0;

return ext3_force_commit(inode->i_sb);
Expand Down
2 changes: 1 addition & 1 deletion fs/ext4/ext4.h
Original file line number Diff line number Diff line change
Expand Up @@ -1416,7 +1416,7 @@ int ext4_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create);

extern struct inode *ext4_iget(struct super_block *, unsigned long);
extern int ext4_write_inode(struct inode *, int);
extern int ext4_write_inode(struct inode *, struct writeback_control *);
extern int ext4_setattr(struct dentry *, struct iattr *);
extern int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat);
Expand Down
6 changes: 3 additions & 3 deletions fs/ext4/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -5177,7 +5177,7 @@ static int ext4_do_update_inode(handle_t *handle,
* `stuff()' is running, and the new i_size will be lost. Plus the inode
* will no longer be on the superblock's dirty inode list.
*/
int ext4_write_inode(struct inode *inode, int wait)
int ext4_write_inode(struct inode *inode, struct writeback_control *wbc)
{
int err;

Expand All @@ -5191,7 +5191,7 @@ int ext4_write_inode(struct inode *inode, int wait)
return -EIO;
}

if (!wait)
if (wbc->sync_mode != WB_SYNC_ALL)
return 0;

err = ext4_force_commit(inode->i_sb);
Expand All @@ -5201,7 +5201,7 @@ int ext4_write_inode(struct inode *inode, int wait)
err = ext4_get_inode_loc(inode, &iloc);
if (err)
return err;
if (wait)
if (wbc->sync_mode == WB_SYNC_ALL)
sync_dirty_buffer(iloc.bh);
if (buffer_req(iloc.bh) && !buffer_uptodate(iloc.bh)) {
ext4_error(inode->i_sb, __func__,
Expand Down
9 changes: 7 additions & 2 deletions fs/fat/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ static inline loff_t fat_i_pos_read(struct msdos_sb_info *sbi,
return i_pos;
}

static int fat_write_inode(struct inode *inode, int wait)
static int __fat_write_inode(struct inode *inode, int wait)
{
struct super_block *sb = inode->i_sb;
struct msdos_sb_info *sbi = MSDOS_SB(sb);
Expand Down Expand Up @@ -634,9 +634,14 @@ static int fat_write_inode(struct inode *inode, int wait)
return err;
}

static int fat_write_inode(struct inode *inode, struct writeback_control *wbc)
{
return __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
}

int fat_sync_inode(struct inode *inode)
{
return fat_write_inode(inode, 1);
return __fat_write_inode(inode, 1);
}

EXPORT_SYMBOL_GPL(fat_sync_inode);
Expand Down
11 changes: 5 additions & 6 deletions fs/fs-writeback.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,10 +381,10 @@ static void queue_io(struct bdi_writeback *wb, unsigned long *older_than_this)
move_expired_inodes(&wb->b_dirty, &wb->b_io, older_than_this);
}

static int write_inode(struct inode *inode, int sync)
static int write_inode(struct inode *inode, struct writeback_control *wbc)
{
if (inode->i_sb->s_op->write_inode && !is_bad_inode(inode))
return inode->i_sb->s_op->write_inode(inode, sync);
return inode->i_sb->s_op->write_inode(inode, wbc);
return 0;
}

Expand Down Expand Up @@ -421,7 +421,6 @@ static int
writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
{
struct address_space *mapping = inode->i_mapping;
int wait = wbc->sync_mode == WB_SYNC_ALL;
unsigned dirty;
int ret;

Expand All @@ -439,7 +438,7 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
* We'll have another go at writing back this inode when we
* completed a full scan of b_io.
*/
if (!wait) {
if (wbc->sync_mode != WB_SYNC_ALL) {
requeue_io(inode);
return 0;
}
Expand All @@ -466,15 +465,15 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
* This is important for filesystems that modify metadata on data
* I/O completion.
*/
if (wait) {
if (wbc->sync_mode == WB_SYNC_ALL) {
int err = filemap_fdatawait(mapping);
if (ret == 0)
ret = err;
}

/* Don't write the inode if only I_DIRTY_PAGES was set */
if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) {
int err = write_inode(inode, wait);
int err = write_inode(inode, wbc);
if (ret == 0)
ret = err;
}
Expand Down
5 changes: 3 additions & 2 deletions fs/gfs2/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <linux/crc32.h>
#include <linux/time.h>
#include <linux/wait.h>
#include <linux/writeback.h>

#include "gfs2.h"
#include "incore.h"
Expand Down Expand Up @@ -711,7 +712,7 @@ void gfs2_unfreeze_fs(struct gfs2_sbd *sdp)
* Returns: errno
*/

static int gfs2_write_inode(struct inode *inode, int sync)
static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc)
{
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode);
Expand Down Expand Up @@ -745,7 +746,7 @@ static int gfs2_write_inode(struct inode *inode, int sync)
do_unlock:
gfs2_glock_dq_uninit(&gh);
do_flush:
if (sync != 0)
if (wbc->sync_mode == WB_SYNC_ALL)
gfs2_log_flush(GFS2_SB(inode), ip->i_gl);
return ret;
}
Expand Down
2 changes: 1 addition & 1 deletion fs/hfs/hfs_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ extern const struct address_space_operations hfs_btree_aops;

extern struct inode *hfs_new_inode(struct inode *, struct qstr *, int);
extern void hfs_inode_write_fork(struct inode *, struct hfs_extent *, __be32 *, __be32 *);
extern int hfs_write_inode(struct inode *, int);
extern int hfs_write_inode(struct inode *, struct writeback_control *);
extern int hfs_inode_setattr(struct dentry *, struct iattr *);
extern void hfs_inode_read_fork(struct inode *inode, struct hfs_extent *ext,
__be32 log_size, __be32 phys_size, u32 clump_size);
Expand Down
2 changes: 1 addition & 1 deletion fs/hfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ void hfs_inode_write_fork(struct inode *inode, struct hfs_extent *ext,
HFS_SB(inode->i_sb)->alloc_blksz);
}

int hfs_write_inode(struct inode *inode, int unused)
int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
struct inode *main_inode = inode;
struct hfs_find_data fd;
Expand Down
3 changes: 2 additions & 1 deletion fs/hfsplus/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ struct inode *hfsplus_iget(struct super_block *sb, unsigned long ino)
return ERR_PTR(err);
}

static int hfsplus_write_inode(struct inode *inode, int unused)
static int hfsplus_write_inode(struct inode *inode,
struct writeback_control *wbc)
{
struct hfsplus_vh *vhdr;
int ret = 0;
Expand Down
5 changes: 4 additions & 1 deletion fs/jfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <linux/buffer_head.h>
#include <linux/pagemap.h>
#include <linux/quotaops.h>
#include <linux/writeback.h>
#include "jfs_incore.h"
#include "jfs_inode.h"
#include "jfs_filsys.h"
Expand Down Expand Up @@ -120,8 +121,10 @@ int jfs_commit_inode(struct inode *inode, int wait)
return rc;
}

int jfs_write_inode(struct inode *inode, int wait)
int jfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
int wait = wbc->sync_mode == WB_SYNC_ALL;

if (test_cflag(COMMIT_Nolink, inode))
return 0;
/*
Expand Down
2 changes: 1 addition & 1 deletion fs/jfs/jfs_inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ extern long jfs_ioctl(struct file *, unsigned int, unsigned long);
extern long jfs_compat_ioctl(struct file *, unsigned int, unsigned long);
extern struct inode *jfs_iget(struct super_block *, unsigned long);
extern int jfs_commit_inode(struct inode *, int);
extern int jfs_write_inode(struct inode*, int);
extern int jfs_write_inode(struct inode *, struct writeback_control *);
extern void jfs_delete_inode(struct inode *);
extern void jfs_dirty_inode(struct inode *);
extern void jfs_truncate(struct inode *);
Expand Down
Loading

0 comments on commit a9185b4

Please sign in to comment.