#ifdef CONFIG_COMPAT
.compat_ioctl = ext2_compat_ioctl,
#endif
- .fsync = ext2_fsync,
+ .fsync = simple_fsync,
.setlease = generic_setlease,
};
/* inode.c */
extern struct inode *ext2_iget (struct super_block *, unsigned long);
extern int ext2_write_inode (struct inode *, struct writeback_control *);
+extern int ext2_sync_inode_metadata(struct inode *, struct writeback_control *);
extern void ext2_evict_inode(struct inode *);
void ext2_write_failed(struct address_space *mapping, loff_t to);
extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int);
extern const struct file_operations ext2_dir_operations;
/* file.c */
-extern int ext2_fsync(struct file *file, loff_t start, loff_t end,
- int datasync);
extern const struct inode_operations ext2_file_inode_operations;
extern const struct file_operations ext2_file_operations;
return 0;
}
-int ext2_fsync(struct file *file, loff_t start, loff_t end, int datasync)
-{
- int ret;
- struct inode *inode = file->f_mapping->host;
- struct super_block *sb = inode->i_sb;
-
- ret = mmb_fsync(file, &EXT2_I(inode)->i_metadata_bhs,
- start, end, datasync);
- if (ret == -EIO)
- /* We don't really know where the IO error happened... */
- ext2_error(sb, __func__,
- "detected IO error when writing metadata buffers");
- return ret;
-}
-
static ssize_t ext2_dio_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
struct file *file = iocb->ki_filp;
.mmap_prepare = generic_file_mmap_prepare,
.open = ext2_file_open,
.release = ext2_release_file,
- .fsync = ext2_fsync,
+ .fsync = simple_fsync,
.get_unmapped_area = thp_get_unmapped_area,
.splice_read = filemap_splice_read,
.splice_write = iter_file_splice_write,
truncate_inode_pages_final(&inode->i_data);
if (want_delete) {
- struct writeback_control wbc = {
- .sync_mode = inode_needs_sync(inode) ? WB_SYNC_ALL :
- WB_SYNC_NONE,
- };
-
sb_start_intwrite(inode->i_sb);
/* set dtime */
EXT2_I(inode)->i_dtime = ktime_get_real_seconds();
mark_inode_dirty(inode);
- ext2_write_inode(inode, &wbc);
+ sync_inode_metadata(inode, inode_needs_sync(inode));
/* truncate to 0 */
inode->i_size = 0;
if (inode->i_blocks)
} else for (n = 0; n < EXT2_N_BLOCKS; n++)
raw_inode->i_block[n] = ei->i_data[n];
mark_buffer_dirty(bh);
- /*
- * For sync(2) the generic code will call sync_blockdev() to write
- * all metadata more efficiently.
- */
- if (wbc->sync_mode == WB_SYNC_ALL && !wbc->for_sync) {
- sync_dirty_buffer(bh);
- if (buffer_req(bh) && !buffer_uptodate(bh)) {
- printk ("IO error syncing ext2 inode [%s:%08lx]\n",
- sb->s_id, (unsigned long) ino);
- err = -EIO;
- }
- }
ei->i_state &= ~EXT2_STATE_NEW;
brelse (bh);
+ set_inode_metadata_writeback(inode);
+ return err;
+}
+
+int ext2_sync_inode_metadata(struct inode *inode, struct writeback_control *wbc)
+{
+ struct buffer_head *bh;
+ struct ext2_inode *raw_inode = ext2_get_inode(inode->i_sb, inode->i_ino,
+ &bh);
+ int err = 0;
+
+ if (IS_ERR(raw_inode))
+ return -EIO;
+ err = mmb_sync(&EXT2_I(inode)->i_metadata_bhs);
+ if (err) {
+ ext2_error(inode->i_sb, __func__,
+ "Error syncing inode metadata ino=%lu\n",
+ (unsigned long)inode->i_ino);
+ goto out;
+ }
+ sync_dirty_buffer(bh);
+ if (buffer_write_io_error(bh)) {
+ ext2_error(inode->i_sb, __func__,
+ "IO error syncing inode %lu\n",
+ (unsigned long)inode->i_ino);
+ err = -EIO;
+ }
+out:
+ brelse(bh);
return err;
}
.alloc_inode = ext2_alloc_inode,
.free_inode = ext2_free_in_core_inode,
.write_inode = ext2_write_inode,
+ .sync_inode_metadata = ext2_sync_inode_metadata,
.evict_inode = ext2_evict_inode,
.put_super = ext2_put_super,
.sync_fs = ext2_sync_fs,