mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
IN_RENAME should only be cleared by the routine that set it. This fixes
a rename/rmdir race that has been shown to cause a panic. Bug reported by: Yevgeniy Aleynikov <eugenea@infospace.com> MFC after: 3 days
This commit is contained in:
parent
4a5470eebd
commit
be2a975a9f
1 changed files with 8 additions and 3 deletions
|
|
@ -936,6 +936,7 @@ ufs_rename(ap)
|
|||
struct direct newdir;
|
||||
int doingdirectory = 0, oldparent = 0, newparent = 0;
|
||||
int error = 0, ioflag;
|
||||
int in_rename_flag = 0;
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if ((tcnp->cn_flags & HASBUF) == 0 ||
|
||||
|
|
@ -1049,6 +1050,8 @@ abortit:
|
|||
goto abortit;
|
||||
}
|
||||
ip->i_flag |= IN_RENAME;
|
||||
/* note: only the routine that sets IN_RENAME can clear it */
|
||||
in_rename_flag = 1;
|
||||
oldparent = dp->i_number;
|
||||
doingdirectory = 1;
|
||||
}
|
||||
|
|
@ -1293,7 +1296,8 @@ abortit:
|
|||
cache_purge(fdvp);
|
||||
}
|
||||
error = ufs_dirremove(fdvp, xp, fcnp->cn_flags, 0);
|
||||
xp->i_flag &= ~IN_RENAME;
|
||||
if (in_rename_flag)
|
||||
xp->i_flag &= ~IN_RENAME;
|
||||
}
|
||||
VN_KNOTE(fvp, NOTE_RENAME);
|
||||
if (dp)
|
||||
|
|
@ -1308,13 +1312,14 @@ bad:
|
|||
vput(ITOV(xp));
|
||||
vput(ITOV(dp));
|
||||
out:
|
||||
if (doingdirectory)
|
||||
if (doingdirectory && in_rename_flag)
|
||||
ip->i_flag &= ~IN_RENAME;
|
||||
if (vn_lock(fvp, LK_EXCLUSIVE, td) == 0) {
|
||||
ip->i_effnlink--;
|
||||
ip->i_nlink--;
|
||||
ip->i_flag |= IN_CHANGE;
|
||||
ip->i_flag &= ~IN_RENAME;
|
||||
if (in_rename_flag)
|
||||
ip->i_flag &= ~IN_RENAME; /* XXX huh? Why again? */
|
||||
if (DOINGSOFTDEP(fvp))
|
||||
softdep_change_linkcnt(ip);
|
||||
vput(fvp);
|
||||
|
|
|
|||
Loading…
Reference in a new issue