version 1.207, 2017/06/01 02:45:13 |
version 1.207.2.2, 2021/06/21 14:55:15 |
Line 673 namei_start(struct namei_state *state, i |
|
Line 673 namei_start(struct namei_state *state, i |
|
} |
} |
|
|
/* NDAT may feed us with a non directory namei_getstartdir */ |
/* NDAT may feed us with a non directory namei_getstartdir */ |
if (startdir->v_type != VDIR) |
if (startdir->v_type != VDIR) { |
|
vrele(startdir); |
return ENOTDIR; |
return ENOTDIR; |
|
} |
|
|
vn_lock(startdir, LK_EXCLUSIVE | LK_RETRY); |
vn_lock(startdir, LK_EXCLUSIVE | LK_RETRY); |
|
|
Line 1400 namei_oneroot(struct namei_state *state, |
|
Line 1402 namei_oneroot(struct namei_state *state, |
|
* a CREATE, DELETE, or RENAME), and we don't have one |
* a CREATE, DELETE, or RENAME), and we don't have one |
* (because this is the root directory, or we crossed |
* (because this is the root directory, or we crossed |
* a mount point), then we must fail. |
* a mount point), then we must fail. |
|
* |
|
* 20210604 dholland when NONEXCLHACK is set (open |
|
* with O_CREAT but not O_EXCL) skip this logic. Since |
|
* we have a foundobj, open will not be creating, so |
|
* it doesn't actually need or use the searchdir, so |
|
* it's ok to return it even if it's on a different |
|
* volume, and it's also ok to return NULL; by setting |
|
* NONEXCLHACK the open code promises to cope with |
|
* those cases correctly. (That is, it should do what |
|
* it would do anyway, that is, just release the |
|
* searchdir, except not crash if it's null.) This is |
|
* needed because otherwise opening mountpoints with |
|
* O_CREAT but not O_EXCL fails... which is a silly |
|
* thing to do but ought to work. (This whole issue |
|
* came to light because 3rd party code wanted to open |
|
* certain procfs nodes with O_CREAT for some 3rd |
|
* party reason, and it failed.) |
|
* |
|
* Note that NONEXCLHACK is properly a different |
|
* nameiop (it is partway between LOOKUP and CREATE) |
|
* but it was stuffed in as a flag instead to make the |
|
* resulting patch less invasive for pullup. Blah. |
*/ |
*/ |
if (cnp->cn_nameiop != LOOKUP && |
if (cnp->cn_nameiop != LOOKUP && |
(searchdir == NULL || |
(searchdir == NULL || |
searchdir->v_mount != foundobj->v_mount)) { |
searchdir->v_mount != foundobj->v_mount) && |
|
(cnp->cn_flags & NONEXCLHACK) == 0) { |
if (searchdir) { |
if (searchdir) { |
vput(searchdir); |
vput(searchdir); |
} |
} |