diff --git a/kmod/src/filerw.c b/kmod/src/filerw.c index 40429532..6f9a322d 100644 --- a/kmod/src/filerw.c +++ b/kmod/src/filerw.c @@ -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); diff --git a/kmod/src/inode.c b/kmod/src/inode.c index da3e150f..98a005ca 100644 --- a/kmod/src/inode.c +++ b/kmod/src/inode.c @@ -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. */ diff --git a/kmod/src/inode.h b/kmod/src/inode.h index f303ba97..52ad52a6 100644 --- a/kmod/src/inode.h +++ b/kmod/src/inode.h @@ -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); diff --git a/kmod/src/super.c b/kmod/src/super.c index f7f0c81f..a668f8a2 100644 --- a/kmod/src/super.c +++ b/kmod/src/super.c @@ -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,