VFS: fix last_dir not returning last directory
If the provided path was only a single component (i.e., without slashes), then last_dir would return early and skip the symlink detection (i.e., check whether the path ends in a symlink and resolve that first before returning). This bug triggered an assert in open which expects that an advance after an last_dir (with VMNT_WRITE lock) does not yield another vmnt lock.
This commit is contained in:
parent
d25ded6d3d
commit
0c1cd8720a
|
@ -206,30 +206,13 @@ struct fproc *rfp;
|
|||
|
||||
cp = strrchr(resolve->l_path, '/');
|
||||
if (cp == NULL) {
|
||||
/* Just an entry in the current working directory */
|
||||
struct vmnt *vmp;
|
||||
|
||||
vmp = find_vmnt(start_dir->v_fs_e);
|
||||
if (vmp == NULL) {
|
||||
r = EIO;
|
||||
res_vp = NULL;
|
||||
break;
|
||||
}
|
||||
r = lock_vmnt(vmp, resolve->l_vmnt_lock);
|
||||
if (r == EDEADLK) {
|
||||
res_vp = NULL;
|
||||
break;
|
||||
} else if (r == OK)
|
||||
*resolve->l_vmp = vmp;
|
||||
|
||||
lock_vnode(start_dir, resolve->l_vnode_lock);
|
||||
*resolve->l_vnode = start_dir;
|
||||
dup_vnode(start_dir);
|
||||
if (loop_start != NULL) {
|
||||
unlock_vnode(loop_start);
|
||||
put_vnode(loop_start);
|
||||
}
|
||||
return(start_dir);
|
||||
/* Just an entry in the current working directory. Prepend
|
||||
* "./" in front of the path and resolve it.
|
||||
*/
|
||||
strncpy(dir_entry, resolve->l_path, NAME_MAX);
|
||||
dir_entry[NAME_MAX] = '\0';
|
||||
resolve->l_path[0] = '.';
|
||||
resolve->l_path[1] = '\0';
|
||||
} else if (cp[1] == '\0') {
|
||||
/* Path ends in a slash. The directory entry is '.' */
|
||||
strcpy(dir_entry, ".");
|
||||
|
@ -341,6 +324,10 @@ struct fproc *rfp;
|
|||
|
||||
/* Copy the directory entry back to user_fullpath */
|
||||
strncpy(resolve->l_path, dir_entry, NAME_MAX + 1);
|
||||
|
||||
/* Turn PATH_RET_SYMLINK flag back on if it was on */
|
||||
if (ret_on_symlink) resolve->l_flags |= PATH_RET_SYMLINK;
|
||||
|
||||
return(res_vp);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue