tmpfs_readdir(): unlock the locked node.
During readdir() we guarantee that the tn_dir.tn_parent does not go away, but it might be replaced by a parallel rename. Read tn_parent only once, then use the cached value. Reported and tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
175f92d15a
commit
e9ef39b7bd
@ -1147,8 +1147,9 @@ static int
|
||||
tmpfs_dir_getdotdotdent(struct tmpfs_mount *tm, struct tmpfs_node *node,
|
||||
struct uio *uio)
|
||||
{
|
||||
int error;
|
||||
struct tmpfs_node *parent;
|
||||
struct dirent dent;
|
||||
int error;
|
||||
|
||||
TMPFS_VALIDATE_DIR(node);
|
||||
MPASS(uio->uio_offset == TMPFS_DIRCOOKIE_DOTDOT);
|
||||
@ -1157,12 +1158,13 @@ tmpfs_dir_getdotdotdent(struct tmpfs_mount *tm, struct tmpfs_node *node,
|
||||
* Return ENOENT if the current node is already removed.
|
||||
*/
|
||||
TMPFS_ASSERT_LOCKED(node);
|
||||
if (node->tn_dir.tn_parent == NULL)
|
||||
parent = node->tn_dir.tn_parent;
|
||||
if (parent == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
TMPFS_NODE_LOCK(node->tn_dir.tn_parent);
|
||||
dent.d_fileno = node->tn_dir.tn_parent->tn_id;
|
||||
TMPFS_NODE_UNLOCK(node->tn_dir.tn_parent);
|
||||
TMPFS_NODE_LOCK(parent);
|
||||
dent.d_fileno = parent->tn_id;
|
||||
TMPFS_NODE_UNLOCK(parent);
|
||||
|
||||
dent.d_type = DT_DIR;
|
||||
dent.d_namlen = 2;
|
||||
|
Loading…
Reference in New Issue
Block a user