@@ -252,19 +252,20 @@ int bch2_hash_needs_whiteout(struct btree_trans *trans,
252252}
253253
254254static __always_inline
255- int bch2_hash_set_in_snapshot (struct btree_trans * trans ,
255+ struct bkey_s_c bch2_hash_set_or_get_in_snapshot (struct btree_trans * trans ,
256+ struct btree_iter * iter ,
256257 const struct bch_hash_desc desc ,
257258 const struct bch_hash_info * info ,
258259 subvol_inum inum , u32 snapshot ,
259260 struct bkey_i * insert ,
260261 enum btree_iter_update_trigger_flags flags )
261262{
262- struct btree_iter iter , slot = { NULL };
263+ struct btree_iter slot = {};
263264 struct bkey_s_c k ;
264265 bool found = false;
265266 int ret ;
266267
267- for_each_btree_key_upto_norestart (trans , iter , desc .btree_id ,
268+ for_each_btree_key_upto_norestart (trans , * iter , desc .btree_id ,
268269 SPOS (insert -> k .p .inode ,
269270 desc .hash_bkey (info , bkey_i_to_s_c (insert )),
270271 snapshot ),
@@ -279,7 +280,7 @@ int bch2_hash_set_in_snapshot(struct btree_trans *trans,
279280 }
280281
281282 if (!slot .path && !(flags & STR_HASH_must_replace ))
282- bch2_trans_copy_iter (& slot , & iter );
283+ bch2_trans_copy_iter (& slot , iter );
283284
284285 if (k .k -> type != KEY_TYPE_hash_whiteout )
285286 goto not_found ;
@@ -289,28 +290,49 @@ int bch2_hash_set_in_snapshot(struct btree_trans *trans,
289290 ret = - BCH_ERR_ENOSPC_str_hash_create ;
290291out :
291292 bch2_trans_iter_exit (trans , & slot );
292- bch2_trans_iter_exit (trans , & iter );
293-
294- return ret ;
293+ bch2_trans_iter_exit (trans , iter );
294+ return ret ? bkey_s_c_err (ret ) : bkey_s_c_null ;
295295found :
296296 found = true;
297297not_found :
298-
299- if (!found && (flags & STR_HASH_must_replace )) {
298+ if (found && (flags & STR_HASH_must_create )) {
299+ bch2_trans_iter_exit (trans , & slot );
300+ return k ;
301+ } else if (!found && (flags & STR_HASH_must_replace )) {
300302 ret = - BCH_ERR_ENOENT_str_hash_set_must_replace ;
301- } else if (found && (flags & STR_HASH_must_create )) {
302- ret = - BCH_ERR_EEXIST_str_hash_set ;
303303 } else {
304304 if (!found && slot .path )
305- swap (iter , slot );
305+ swap (* iter , slot );
306306
307- insert -> k .p = iter . pos ;
308- ret = bch2_trans_update (trans , & iter , insert , flags );
307+ insert -> k .p = iter -> pos ;
308+ ret = bch2_trans_update (trans , iter , insert , flags );
309309 }
310310
311311 goto out ;
312312}
313313
314+ static __always_inline
315+ int bch2_hash_set_in_snapshot (struct btree_trans * trans ,
316+ const struct bch_hash_desc desc ,
317+ const struct bch_hash_info * info ,
318+ subvol_inum inum , u32 snapshot ,
319+ struct bkey_i * insert ,
320+ enum btree_iter_update_trigger_flags flags )
321+ {
322+ struct btree_iter iter ;
323+ struct bkey_s_c k = bch2_hash_set_or_get_in_snapshot (trans , & iter , desc , info , inum ,
324+ snapshot , insert , flags );
325+ int ret = bkey_err (k );
326+ if (ret )
327+ return ret ;
328+ if (k .k ) {
329+ bch2_trans_iter_exit (trans , & iter );
330+ return - BCH_ERR_EEXIST_str_hash_set ;
331+ }
332+
333+ return 0 ;
334+ }
335+
314336static __always_inline
315337int bch2_hash_set (struct btree_trans * trans ,
316338 const struct bch_hash_desc desc ,
0 commit comments