diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2021-04-29 22:39:57 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2021-06-23 20:46:15 +0000 |
commit | f7565466622a411a50522f23528faeb1e57d4571 (patch) | |
tree | 63a96a2e8e038eed30ee94dd0bfdf3ec6fef7cce | |
parent | d4d289cd51078de9e82c9d83977cfa614032cd06 (diff) | |
download | src-f7565466622a411a50522f23528faeb1e57d4571.tar.gz src-f7565466622a411a50522f23528faeb1e57d4571.zip |
ufs_rename(): only do softdep_prerename() when other thread changed a vnode
Reviewed by: mckusick
Discussed with: markj
Tested by: pho
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Differential revision: https://reviews.freebsd.org/D30041
-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; } |