fs: add sync_inode_metadata
Christoph Hellwig [Wed, 6 Oct 2010 08:48:20 +0000 (10:48 +0200)]
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>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

drivers/staging/pohmelfs/inode.c
fs/exofs/file.c
fs/ext2/dir.c
fs/ext2/ext2.h
fs/ext2/inode.c
fs/ext2/xattr.c
fs/fs-writeback.c
fs/libfs.c
fs/nfsd/vfs.c
include/linux/fs.h

index 97dae29..c62d300 100644 (file)
@@ -882,12 +882,8 @@ static struct inode *pohmelfs_alloc_inode(struct super_block *sb)
 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 68cb23e..b905c79 100644 (file)
@@ -46,10 +46,6 @@ static int exofs_file_fsync(struct file *filp, int datasync)
 {
        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 *filp, int datasync)
        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 */
index 7641098..2709b34 100644 (file)
@@ -98,7 +98,7 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
        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 416daa6..6346a2a 100644 (file)
@@ -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 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 533699c..40ad210 100644 (file)
@@ -1203,7 +1203,7 @@ static int ext2_setsize(struct inode *inode, loff_t newsize)
        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, 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 = {
-               .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 8c29ae1..f84700b 100644 (file)
@@ -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;
        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 ab38fef..29e3f40 100644 (file)
@@ -1198,3 +1198,23 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc)
        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 62baa03..2dbf487 100644 (file)
@@ -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, int datasync)
        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 661a6cf..184938f 100644 (file)
@@ -281,23 +281,13 @@ commit_metadata(struct svc_fh *fhp)
 {
        struct inode *inode = fhp->fh_dentry->d_inode;
        const struct export_operations *export_ops = inode->i_sb->s_export_op;
-       int error = 0;
 
        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 4f34ff6..0b03f49 100644 (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_metadata(struct inode *inode, int wait);
 
 struct file_system_type {
        const char *name;