* [PATCH] fs: add sync_inode_metadata
@ 2010-10-06 8:48 Christoph Hellwig
2010-10-20 10:02 ` Jan Kara
0 siblings, 1 reply; 2+ messages in thread
From: Christoph Hellwig @ 2010-10-06 8:48 UTC (permalink / raw)
To: viro; +Cc: linux-fsdevel
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: Christoph Hellwig <hch@lst.de>
Index: linux-2.6/drivers/staging/pohmelfs/inode.c
===================================================================
--- linux-2.6.orig/drivers/staging/pohmelfs/inode.c 2010-10-05 10:51:24.565005008 +0200
+++ linux-2.6/drivers/staging/pohmelfs/inode.c 2010-10-05 10:52:12.866254065 +0200
@@ -882,12 +882,8 @@ static struct inode *pohmelfs_alloc_inod
static int pohmelfs_fsync(struct file *file, int datasync)
{
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,
Index: linux-2.6/fs/ext2/dir.c
===================================================================
--- linux-2.6.orig/fs/ext2/dir.c 2010-10-05 10:51:24.574004450 +0200
+++ linux-2.6/fs/ext2/dir.c 2010-10-05 10:52:12.867253925 +0200
@@ -98,7 +98,7 @@ static int ext2_commit_chunk(struct page
if (IS_DIRSYNC(dir)) {
err = write_one_page(page, 1);
if (!err)
- err = ext2_sync_inode(dir);
+ err = sync_inode_metadata(dir, 1);
} else {
unlock_page(page);
}
Index: linux-2.6/fs/ext2/ext2.h
===================================================================
--- linux-2.6.orig/fs/ext2/ext2.h 2010-10-05 10:51:24.581003472 +0200
+++ linux-2.6/fs/ext2/ext2.h 2010-10-05 10:52:12.871253995 +0200
@@ -120,7 +120,6 @@ extern unsigned long ext2_count_free (st
extern struct inode *ext2_iget (struct super_block *, unsigned long);
extern int ext2_write_inode (struct inode *, struct writeback_control *);
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_setattr (struct dentry *, struct iattr *);
extern void ext2_set_inode_flags(struct inode *inode);
Index: linux-2.6/fs/ext2/inode.c
===================================================================
--- linux-2.6.orig/fs/ext2/inode.c 2010-10-05 10:51:24.588253716 +0200
+++ linux-2.6/fs/ext2/inode.c 2010-10-05 10:52:12.874253996 +0200
@@ -1203,7 +1203,7 @@ static int ext2_setsize(struct inode *in
inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
if (inode_needs_sync(inode)) {
sync_mapping_buffers(inode->i_mapping);
- ext2_sync_inode (inode);
+ sync_inode_metadata(inode, 1);
} else {
mark_inode_dirty(inode);
}
@@ -1523,15 +1523,6 @@ int ext2_write_inode(struct inode *inode
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)
{
struct inode *inode = dentry->d_inode;
Index: linux-2.6/fs/ext2/xattr.c
===================================================================
--- linux-2.6.orig/fs/ext2/xattr.c 2010-10-05 10:51:24.595254275 +0200
+++ linux-2.6/fs/ext2/xattr.c 2010-10-05 10:52:12.878253995 +0200
@@ -699,7 +699,7 @@ ext2_xattr_set2(struct inode *inode, str
EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
inode->i_ctime = CURRENT_TIME_SEC;
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
* written (only some dirty data were not) so we just proceed
* as if nothing happened and cleanup the unused block */
Index: linux-2.6/fs/fs-writeback.c
===================================================================
--- linux-2.6.orig/fs/fs-writeback.c 2010-10-05 10:51:24.611023726 +0200
+++ linux-2.6/fs/fs-writeback.c 2010-10-05 10:53:24.684255876 +0200
@@ -1209,3 +1209,23 @@ int sync_inode(struct inode *inode, stru
return ret;
}
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);
Index: linux-2.6/fs/libfs.c
===================================================================
--- linux-2.6.orig/fs/libfs.c 2010-10-05 10:51:24.618004031 +0200
+++ linux-2.6/fs/libfs.c 2010-10-05 10:52:12.887255532 +0200
@@ -892,10 +892,6 @@ EXPORT_SYMBOL_GPL(generic_fh_to_parent);
*/
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;
int err;
int ret;
@@ -906,7 +902,7 @@ int generic_file_fsync(struct file *file
if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
return ret;
- err = sync_inode(inode, &wbc);
+ err = sync_inode_metadata(inode, 1);
if (ret == 0)
ret = err;
return ret;
Index: linux-2.6/fs/nfsd/vfs.c
===================================================================
--- linux-2.6.orig/fs/nfsd/vfs.c 2010-10-05 10:51:24.625004031 +0200
+++ linux-2.6/fs/nfsd/vfs.c 2010-10-05 10:52:12.892255391 +0200
@@ -286,18 +286,9 @@ commit_metadata(struct svc_fh *fhp)
if (!EX_ISSYNC(fhp->fh_export))
return 0;
- if (export_ops->commit_metadata) {
- error = export_ops->commit_metadata(inode);
- } else {
- struct writeback_control wbc = {
- .sync_mode = WB_SYNC_ALL,
- .nr_to_write = 0, /* metadata only */
- };
-
- error = sync_inode(inode, &wbc);
- }
-
- return error;
+ if (export_ops->commit_metadata)
+ return export_ops->commit_metadata(inode);
+ return sync_inode_metadata(inode, 1);
}
/*
Index: linux-2.6/include/linux/fs.h
===================================================================
--- linux-2.6.orig/include/linux/fs.h 2010-10-05 10:51:24.641010386 +0200
+++ linux-2.6/include/linux/fs.h 2010-10-05 10:52:12.897255881 +0200
@@ -1732,6 +1732,7 @@ static inline void file_accessed(struct
}
int sync_inode(struct inode *inode, struct writeback_control *wbc);
+int sync_inode_metadata(struct inode *inode, int wait);
struct file_system_type {
const char *name;
Index: linux-2.6/fs/exofs/file.c
===================================================================
--- linux-2.6.orig/fs/exofs/file.c 2010-10-05 10:51:24.633010177 +0200
+++ linux-2.6/fs/exofs/file.c 2010-10-05 10:52:12.899255253 +0200
@@ -46,10 +46,6 @@ static int exofs_file_fsync(struct file
{
int ret;
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;
if (!(inode->i_state & I_DIRTY))
@@ -57,7 +53,7 @@ static int exofs_file_fsync(struct file
if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
return 0;
- ret = sync_inode(inode, &wbc);
+ ret = sync_inode_metadata(inode, 1);
/* This is a good place to write the sb */
/* TODO: Sechedule an sb-sync on create */
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] fs: add sync_inode_metadata
2010-10-06 8:48 [PATCH] fs: add sync_inode_metadata Christoph Hellwig
@ 2010-10-20 10:02 ` Jan Kara
0 siblings, 0 replies; 2+ messages in thread
From: Jan Kara @ 2010-10-20 10:02 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: viro, linux-fsdevel
On Wed 06-10-10 10:48:20, Christoph Hellwig wrote:
> 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.
I'm reacting late but anyways:
> Index: linux-2.6/fs/fs-writeback.c
> ===================================================================
> --- linux-2.6.orig/fs/fs-writeback.c 2010-10-05 10:51:24.611023726 +0200
> +++ linux-2.6/fs/fs-writeback.c 2010-10-05 10:53:24.684255876 +0200
> @@ -1209,3 +1209,23 @@ int sync_inode(struct inode *inode, stru
> return ret;
> }
> 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 */
This is a catch in write_cache_pages() code. If you call it in
WB_SYNC_ALL mode, they will just ignore the .nr_to_write argument. So what
actually ensures that we do not write data is that .range_start and
.range_end are implicitely set to 0. In fact, write_cache_pages() will
write page with index 0 in that case. So setting .range_start to 1 would be
even better.
Otherwise the patch looks OK.
Honza
--
Jan Kara <jack@suse.cz>
SUSE Labs, CR
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-10-20 10:03 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-06 8:48 [PATCH] fs: add sync_inode_metadata Christoph Hellwig
2010-10-20 10:02 ` Jan Kara
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).