提交 c3765016 编写于 作者: C Christoph Hellwig 提交者: Al Viro

fs: add sync_inode_metadata

Add a new helper to write out the inode using the writeback code,
that is including the correct dirty bit and list manipulation.  A few
of filesystems already opencode this, and a lot of others should be
using it instead of using write_inode_now which also writes out the
data.
Signed-off-by: NChristoph Hellwig <hch@lst.de>
Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
上级 81fca444
...@@ -882,12 +882,8 @@ static struct inode *pohmelfs_alloc_inode(struct super_block *sb) ...@@ -882,12 +882,8 @@ static struct inode *pohmelfs_alloc_inode(struct super_block *sb)
static int pohmelfs_fsync(struct file *file, int datasync) static int pohmelfs_fsync(struct file *file, int datasync)
{ {
struct inode *inode = file->f_mapping->host; struct inode *inode = file->f_mapping->host;
struct writeback_control wbc = {
.sync_mode = WB_SYNC_ALL,
.nr_to_write = 0, /* sys_fsync did this */
};
return sync_inode(inode, &wbc); return sync_inode_metadata(inode, 1);
} }
ssize_t pohmelfs_write(struct file *file, const char __user *buf, ssize_t pohmelfs_write(struct file *file, const char __user *buf,
......
...@@ -46,10 +46,6 @@ static int exofs_file_fsync(struct file *filp, int datasync) ...@@ -46,10 +46,6 @@ static int exofs_file_fsync(struct file *filp, int datasync)
{ {
int ret; int ret;
struct inode *inode = filp->f_mapping->host; struct inode *inode = filp->f_mapping->host;
struct writeback_control wbc = {
.sync_mode = WB_SYNC_ALL,
.nr_to_write = 0, /* metadata-only; caller takes care of data */
};
struct super_block *sb; struct super_block *sb;
if (!(inode->i_state & I_DIRTY)) if (!(inode->i_state & I_DIRTY))
...@@ -57,7 +53,7 @@ static int exofs_file_fsync(struct file *filp, int datasync) ...@@ -57,7 +53,7 @@ static int exofs_file_fsync(struct file *filp, int datasync)
if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
return 0; return 0;
ret = sync_inode(inode, &wbc); ret = sync_inode_metadata(inode, 1);
/* This is a good place to write the sb */ /* This is a good place to write the sb */
/* TODO: Sechedule an sb-sync on create */ /* TODO: Sechedule an sb-sync on create */
......
...@@ -98,7 +98,7 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len) ...@@ -98,7 +98,7 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
if (IS_DIRSYNC(dir)) { if (IS_DIRSYNC(dir)) {
err = write_one_page(page, 1); err = write_one_page(page, 1);
if (!err) if (!err)
err = ext2_sync_inode(dir); err = sync_inode_metadata(dir, 1);
} else { } else {
unlock_page(page); unlock_page(page);
} }
......
...@@ -120,7 +120,6 @@ extern unsigned long ext2_count_free (struct buffer_head *, unsigned); ...@@ -120,7 +120,6 @@ extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
extern struct inode *ext2_iget (struct super_block *, unsigned long); extern struct inode *ext2_iget (struct super_block *, unsigned long);
extern int ext2_write_inode (struct inode *, struct writeback_control *); extern int ext2_write_inode (struct inode *, struct writeback_control *);
extern void ext2_evict_inode(struct inode *); extern void ext2_evict_inode(struct inode *);
extern int ext2_sync_inode (struct inode *);
extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int); extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int);
extern int ext2_setattr (struct dentry *, struct iattr *); extern int ext2_setattr (struct dentry *, struct iattr *);
extern void ext2_set_inode_flags(struct inode *inode); extern void ext2_set_inode_flags(struct inode *inode);
......
...@@ -1203,7 +1203,7 @@ static int ext2_setsize(struct inode *inode, loff_t newsize) ...@@ -1203,7 +1203,7 @@ static int ext2_setsize(struct inode *inode, loff_t newsize)
inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
if (inode_needs_sync(inode)) { if (inode_needs_sync(inode)) {
sync_mapping_buffers(inode->i_mapping); sync_mapping_buffers(inode->i_mapping);
ext2_sync_inode (inode); sync_inode_metadata(inode, 1);
} else { } else {
mark_inode_dirty(inode); mark_inode_dirty(inode);
} }
...@@ -1523,15 +1523,6 @@ int ext2_write_inode(struct inode *inode, struct writeback_control *wbc) ...@@ -1523,15 +1523,6 @@ int ext2_write_inode(struct inode *inode, struct writeback_control *wbc)
return __ext2_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); return __ext2_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
} }
int ext2_sync_inode(struct inode *inode)
{
struct writeback_control wbc = {
.sync_mode = WB_SYNC_ALL,
.nr_to_write = 0, /* sys_fsync did this */
};
return sync_inode(inode, &wbc);
}
int ext2_setattr(struct dentry *dentry, struct iattr *iattr) int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
{ {
struct inode *inode = dentry->d_inode; struct inode *inode = dentry->d_inode;
......
...@@ -699,7 +699,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh, ...@@ -699,7 +699,7 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0; EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
inode->i_ctime = CURRENT_TIME_SEC; inode->i_ctime = CURRENT_TIME_SEC;
if (IS_SYNC(inode)) { if (IS_SYNC(inode)) {
error = ext2_sync_inode (inode); error = sync_inode_metadata(inode, 1);
/* In case sync failed due to ENOSPC the inode was actually /* In case sync failed due to ENOSPC the inode was actually
* written (only some dirty data were not) so we just proceed * written (only some dirty data were not) so we just proceed
* as if nothing happened and cleanup the unused block */ * as if nothing happened and cleanup the unused block */
......
...@@ -1198,3 +1198,23 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc) ...@@ -1198,3 +1198,23 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc)
return ret; return ret;
} }
EXPORT_SYMBOL(sync_inode); EXPORT_SYMBOL(sync_inode);
/**
* sync_inode - write an inode to disk
* @inode: the inode to sync
* @wait: wait for I/O to complete.
*
* Write an inode to disk and adjust it's dirty state after completion.
*
* Note: only writes the actual inode, no associated data or other metadata.
*/
int sync_inode_metadata(struct inode *inode, int wait)
{
struct writeback_control wbc = {
.sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_NONE,
.nr_to_write = 0, /* metadata-only */
};
return sync_inode(inode, &wbc);
}
EXPORT_SYMBOL(sync_inode_metadata);
...@@ -892,10 +892,6 @@ EXPORT_SYMBOL_GPL(generic_fh_to_parent); ...@@ -892,10 +892,6 @@ EXPORT_SYMBOL_GPL(generic_fh_to_parent);
*/ */
int generic_file_fsync(struct file *file, int datasync) int generic_file_fsync(struct file *file, int datasync)
{ {
struct writeback_control wbc = {
.sync_mode = WB_SYNC_ALL,
.nr_to_write = 0, /* metadata-only; caller takes care of data */
};
struct inode *inode = file->f_mapping->host; struct inode *inode = file->f_mapping->host;
int err; int err;
int ret; int ret;
...@@ -906,7 +902,7 @@ int generic_file_fsync(struct file *file, int datasync) ...@@ -906,7 +902,7 @@ int generic_file_fsync(struct file *file, int datasync)
if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
return ret; return ret;
err = sync_inode(inode, &wbc); err = sync_inode_metadata(inode, 1);
if (ret == 0) if (ret == 0)
ret = err; ret = err;
return ret; return ret;
......
...@@ -281,23 +281,13 @@ commit_metadata(struct svc_fh *fhp) ...@@ -281,23 +281,13 @@ commit_metadata(struct svc_fh *fhp)
{ {
struct inode *inode = fhp->fh_dentry->d_inode; struct inode *inode = fhp->fh_dentry->d_inode;
const struct export_operations *export_ops = inode->i_sb->s_export_op; const struct export_operations *export_ops = inode->i_sb->s_export_op;
int error = 0;
if (!EX_ISSYNC(fhp->fh_export)) if (!EX_ISSYNC(fhp->fh_export))
return 0; return 0;
if (export_ops->commit_metadata) { if (export_ops->commit_metadata)
error = export_ops->commit_metadata(inode); return export_ops->commit_metadata(inode);
} else { return sync_inode_metadata(inode, 1);
struct writeback_control wbc = {
.sync_mode = WB_SYNC_ALL,
.nr_to_write = 0, /* metadata only */
};
error = sync_inode(inode, &wbc);
}
return error;
} }
/* /*
......
...@@ -1734,6 +1734,7 @@ static inline void file_accessed(struct file *file) ...@@ -1734,6 +1734,7 @@ static inline void file_accessed(struct file *file)
} }
int sync_inode(struct inode *inode, struct writeback_control *wbc); int sync_inode(struct inode *inode, struct writeback_control *wbc);
int sync_inode_metadata(struct inode *inode, int wait);
struct file_system_type { struct file_system_type {
const char *name; const char *name;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册