diff --git a/kmod/src/data.c b/kmod/src/data.c index 68ca9345..eeb9081a 100644 --- a/kmod/src/data.c +++ b/kmod/src/data.c @@ -599,7 +599,8 @@ out: * partial progress. */ int scoutfs_data_truncate_items(struct super_block *sb, u64 ino, u64 iblock, - u64 len, bool offline) + u64 len, bool offline, + struct scoutfs_lock *lock) { struct scoutfs_key_buf last_key; struct scoutfs_key_buf key; @@ -633,7 +634,7 @@ int scoutfs_data_truncate_items(struct super_block *sb, u64 ino, u64 iblock, init_mapping_key(&key, &bmk, ino, iblock); scoutfs_kvec_init(val, map->encoded, sizeof(map->encoded)); - ret = scoutfs_item_next(sb, &key, &last_key, val, NULL); + ret = scoutfs_item_next(sb, &key, &last_key, val, lock->end); if (ret < 0) { if (ret == -ENOENT) ret = 0; @@ -669,7 +670,8 @@ int scoutfs_data_truncate_items(struct super_block *sb, u64 ino, u64 iblock, if (!dirtied) { /* dirty item with full size encoded */ - ret = scoutfs_item_update(sb, &key, val, NULL); + ret = scoutfs_item_update(sb, &key, val, + lock->end); if (ret) break; dirtied = true; diff --git a/kmod/src/data.h b/kmod/src/data.h index 04dd9050..0dcd23a6 100644 --- a/kmod/src/data.h +++ b/kmod/src/data.h @@ -5,7 +5,8 @@ extern const struct address_space_operations scoutfs_file_aops; extern const struct file_operations scoutfs_file_fops; int scoutfs_data_truncate_items(struct super_block *sb, u64 ino, u64 iblock, - u64 len, bool offline); + u64 len, bool offline, + struct scoutfs_lock *lock); int scoutfs_data_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, u64 start, u64 len); diff --git a/kmod/src/ioctl.c b/kmod/src/ioctl.c index a7b794da..17747af8 100644 --- a/kmod/src/ioctl.c +++ b/kmod/src/ioctl.c @@ -331,6 +331,7 @@ static long scoutfs_ioc_release(struct file *file, unsigned long arg) struct inode *inode = file_inode(file); struct super_block *sb = inode->i_sb; struct scoutfs_ioctl_release args; + struct scoutfs_lock *lock = NULL; loff_t start; loff_t end_inc; int ret; @@ -352,6 +353,11 @@ static long scoutfs_ioc_release(struct file *file, unsigned long arg) mutex_lock(&inode->i_mutex); + ret = scoutfs_lock_inode(sb, DLM_LOCK_EX, SCOUTFS_LKF_REFRESH_INODE, + inode, &lock); + if (ret) + goto out; + if (!S_ISREG(inode->i_mode)) { ret = -EINVAL; goto out; @@ -375,8 +381,9 @@ static long scoutfs_ioc_release(struct file *file, unsigned long arg) truncate_inode_pages_range(&inode->i_data, start, end_inc); ret = scoutfs_data_truncate_items(sb, scoutfs_ino(inode), args.block, - args.count, true); + args.count, true, lock); out: + scoutfs_unlock(sb, lock, DLM_LOCK_EX); mutex_unlock(&inode->i_mutex); mnt_drop_write_file(file);