diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2021-04-29 22:39:57 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2021-07-07 10:23:58 +0000 |
commit | 9487bd8ee37e6a0394946909636267f644ee8df0 (patch) | |
tree | 6708806ff9dd8fda4fb95668e331b799ca80cd2b | |
parent | a7a074d50aecfe5717d469a81018678ce2880cf1 (diff) | |
download | src-9487bd8ee37e6a0394946909636267f644ee8df0.tar.gz src-9487bd8ee37e6a0394946909636267f644ee8df0.zip |
ufs_rename(): only do softdep_prerename() when other thread changed a vnode
(cherry picked from commit f7565466622a411a50522f23528faeb1e57d4571)
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 2154f7aa7f95..b0fb1b74b900 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -1248,6 +1248,7 @@ ufs_rename(ap) int error = 0; struct mount *mp; ino_t ino; + seqc_t fdvp_s, fvp_s, tdvp_s, tvp_s; bool want_seqc_end; want_seqc_end = false; @@ -1271,6 +1272,8 @@ ufs_rename(ap) mp = NULL; goto releout; } + + fdvp_s = fvp_s = tdvp_s = tvp_s = SEQC_MOD; relock: /* * We need to acquire 2 to 4 locks depending on whether tvp is NULL @@ -1364,10 +1367,20 @@ relock: } } - if (DOINGSUJ(fdvp)) { + if (DOINGSUJ(fdvp) && + (seqc_in_modify(fdvp_s) || !vn_seqc_consistent(fdvp, fdvp_s) || + seqc_in_modify(fvp_s) || !vn_seqc_consistent(fvp, fvp_s) || + seqc_in_modify(tdvp_s) || !vn_seqc_consistent(tdvp, tdvp_s) || + (tvp != NULL && (seqc_in_modify(tvp_s) || + !vn_seqc_consistent(tvp, tvp_s))))) { error = softdep_prerename(fdvp, fvp, tdvp, tvp); if (error != 0) { if (error == ERELOOKUP) { + fdvp_s = vn_seqc_read_any(fdvp); + fvp_s = vn_seqc_read_any(fvp); + tdvp_s = vn_seqc_read_any(tdvp); + if (tvp != NULL) + tvp_s = vn_seqc_read_any(tvp); atomic_add_int(&rename_restarts, 1); goto relock; } |