if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
goto retry;
- bch2_fs_fatal_err_on(ret == -ENOENT, c,
+ bch2_fs_fatal_err_on(bch2_err_matches(ret, ENOENT), c,
"inode %u:%llu not found when updating",
inode_inum(inode).subvol,
inode_inum(inode).inum);
cur.k->k.p.offset += cur.k->k.size;
if (have_extent) {
+ bch2_trans_unlock(&trans);
ret = bch2_fill_extent(c, info,
bkey_i_to_s_c(prev.k), 0);
if (ret)
if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
goto retry;
- if (!ret && have_extent)
+ if (!ret && have_extent) {
+ bch2_trans_unlock(&trans);
ret = bch2_fill_extent(c, info, bkey_i_to_s_c(prev.k),
FIEMAP_EXTENT_LAST);
+ }
bch2_trans_exit(&trans);
bch2_bkey_buf_exit(&cur, c);
.mmap = bch2_mmap,
.open = generic_file_open,
.fsync = bch2_fsync,
- .splice_read = generic_file_splice_read,
+ .splice_read = filemap_splice_read,
.splice_write = iter_file_splice_write,
.fallocate = bch2_fallocate_dispatch,
.unlocked_ioctl = bch2_fs_file_ioctl,
goto err;
if (k.k->type != KEY_TYPE_dirent) {
- ret = -ENOENT;
+ ret = -BCH_ERR_ENOENT_dirent_doesnt_match_inode;
goto err;
}
d = bkey_s_c_to_dirent(k);
ret = bch2_dirent_read_target(&trans, inode_inum(dir), d, &target);
if (ret > 0)
- ret = -ENOENT;
+ ret = -BCH_ERR_ENOENT_dirent_doesnt_match_inode;
if (ret)
goto err;
continue;
if (!(inode->v.i_state & I_DONTCACHE) &&
- !(inode->v.i_state & I_FREEING)) {
+ !(inode->v.i_state & I_FREEING) &&
+ igrab(&inode->v)) {
this_pass_clean = false;
- d_mark_dontcache(&inode->v);
- d_prune_aliases(&inode->v);
-
- /*
- * If i_count was zero, we have to take and release a
- * ref in order for I_DONTCACHE to be noticed and the
- * inode to be dropped;
- */
-
- if (!atomic_read(&inode->v.i_count) &&
- igrab(&inode->v) &&
- darray_push_gfp(&grabbed, inode, GFP_ATOMIC|__GFP_NOWARN))
+ if (darray_push_gfp(&grabbed, inode, GFP_ATOMIC|__GFP_NOWARN)) {
+ iput(&inode->v);
break;
+ }
} else if (clean_pass && this_pass_clean) {
wait_queue_head_t *wq = bit_waitqueue(&inode->v.i_state, __I_NEW);
DEFINE_WAIT_BIT(wait, &inode->v.i_state, __I_NEW);
}
mutex_unlock(&c->vfs_inodes_lock);
- darray_for_each(grabbed, i)
- iput(&(*i)->v);
+ darray_for_each(grabbed, i) {
+ inode = *i;
+ d_mark_dontcache(&inode->v);
+ d_prune_aliases(&inode->v);
+ iput(&inode->v);
+ }
grabbed.nr = 0;
if (!clean_pass || !this_pass_clean) {