mirror of
https://github.com/versity/scoutfs.git
synced 2025-12-23 05:25:18 +00:00
scoutfs: wire up sop->dirty_inode
We're using the generic block buffer_head write_begin and write_end functions. They call sop->dirty_inode() to update the inode i_size. We didn't have that method wired up so updates to the inode in the write path wasn't dirtying the inode item. Lost i_size updates would trivially lose data but we first noticed this when looking at inode item sequence numbers while overwriting. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
@@ -625,6 +625,11 @@ retry:
|
||||
/* can't re-enter fs, have trans */
|
||||
flags |= AOP_FLAG_NOFS;
|
||||
|
||||
/* generic write_end updates i_size and calls dirty_inode */
|
||||
ret = scoutfs_dirty_inode_item(inode);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* make sure our get_block gets a chance to alloc */
|
||||
clear_mapped_page_buffers(page);
|
||||
|
||||
|
||||
@@ -275,6 +275,34 @@ void scoutfs_update_inode_item(struct inode *inode)
|
||||
trace_scoutfs_update_inode(inode);
|
||||
}
|
||||
|
||||
/*
|
||||
* sop->dirty_inode() can't return failure. Our use of it has to be
|
||||
* careful to pin the inode during a transaction. The generic write
|
||||
* paths pin the inode in write_begin and get called to update the inode
|
||||
* in write_end.
|
||||
*
|
||||
* The caller should have a trans but it's cheap for us to grab it
|
||||
* ourselves to make sure.
|
||||
*
|
||||
* This will holler at us if a caller didn't pin the inode and we
|
||||
* couldn't dirty the inode ourselves.
|
||||
*/
|
||||
void scoutfs_dirty_inode(struct inode *inode, int flags)
|
||||
{
|
||||
struct super_block *sb = inode->i_sb;
|
||||
int ret;
|
||||
|
||||
ret = scoutfs_hold_trans(sb);
|
||||
if (ret == 0) {
|
||||
ret = scoutfs_dirty_inode_item(inode);
|
||||
if (ret == 0)
|
||||
scoutfs_update_inode_item(inode);
|
||||
scoutfs_release_trans(sb);
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* A quick atomic sample of the last inode number that's been allocated.
|
||||
*/
|
||||
|
||||
@@ -29,6 +29,7 @@ int scoutfs_orphan_inode(struct inode *inode);
|
||||
|
||||
struct inode *scoutfs_iget(struct super_block *sb, u64 ino);
|
||||
int scoutfs_dirty_inode_item(struct inode *inode);
|
||||
void scoutfs_dirty_inode(struct inode *inode, int flags);
|
||||
void scoutfs_update_inode_item(struct inode *inode);
|
||||
struct inode *scoutfs_new_inode(struct super_block *sb, struct inode *dir,
|
||||
umode_t mode, dev_t rdev);
|
||||
|
||||
@@ -74,6 +74,7 @@ static int scoutfs_statfs(struct dentry *dentry, struct kstatfs *kst)
|
||||
|
||||
static const struct super_operations scoutfs_super_ops = {
|
||||
.alloc_inode = scoutfs_alloc_inode,
|
||||
.dirty_inode = scoutfs_dirty_inode,
|
||||
.drop_inode = scoutfs_drop_inode,
|
||||
.evict_inode = scoutfs_evict_inode,
|
||||
.destroy_inode = scoutfs_destroy_inode,
|
||||
|
||||
Reference in New Issue
Block a user