* relookup - lookup a path name component * Used by lookup to re-acquire things. */
| 1316 | * Used by lookup to re-acquire things. |
| 1317 | */ |
| 1318 | int |
| 1319 | relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp) |
| 1320 | { |
| 1321 | struct vnode *dp = NULL; /* the directory we are searching */ |
| 1322 | int rdonly; /* lookup read-only flag bit */ |
| 1323 | int error = 0; |
| 1324 | |
| 1325 | KASSERT(cnp->cn_flags & ISLASTCN, |
| 1326 | ("relookup: Not given last component.")); |
| 1327 | /* |
| 1328 | * Setup: break out flag bits into variables. |
| 1329 | */ |
| 1330 | KASSERT((cnp->cn_flags & (LOCKPARENT | WANTPARENT)) != 0, |
| 1331 | ("relookup: parent not wanted")); |
| 1332 | rdonly = cnp->cn_flags & RDONLY; |
| 1333 | cnp->cn_flags &= ~ISSYMLINK; |
| 1334 | dp = dvp; |
| 1335 | cnp->cn_lkflags = LK_EXCLUSIVE; |
| 1336 | vn_lock(dp, LK_EXCLUSIVE | LK_RETRY); |
| 1337 | |
| 1338 | /* |
| 1339 | * Search a new directory. |
| 1340 | * |
| 1341 | * The last component of the filename is left accessible via |
| 1342 | * cnp->cn_nameptr for callers that need the name. Callers needing |
| 1343 | * the name set the SAVENAME flag. When done, they assume |
| 1344 | * responsibility for freeing the pathname buffer. |
| 1345 | */ |
| 1346 | #ifdef NAMEI_DIAGNOSTIC |
| 1347 | printf("{%s}: ", cnp->cn_nameptr); |
| 1348 | #endif |
| 1349 | |
| 1350 | /* |
| 1351 | * Check for "" which represents the root directory after slash |
| 1352 | * removal. |
| 1353 | */ |
| 1354 | if (cnp->cn_nameptr[0] == '\0') { |
| 1355 | /* |
| 1356 | * Support only LOOKUP for "/" because lookup() |
| 1357 | * can't succeed for CREATE, DELETE and RENAME. |
| 1358 | */ |
| 1359 | KASSERT(cnp->cn_nameiop == LOOKUP, ("nameiop must be LOOKUP")); |
| 1360 | KASSERT(dp->v_type == VDIR, ("dp is not a directory")); |
| 1361 | |
| 1362 | if (!(cnp->cn_flags & LOCKLEAF)) |
| 1363 | VOP_UNLOCK(dp); |
| 1364 | *vpp = dp; |
| 1365 | /* XXX This should probably move to the top of function. */ |
| 1366 | if (cnp->cn_flags & SAVESTART) |
| 1367 | panic("lookup: SAVESTART"); |
| 1368 | return (0); |
| 1369 | } |
| 1370 | |
| 1371 | if (cnp->cn_flags & ISDOTDOT) |
| 1372 | panic ("relookup: lookup on dot-dot"); |
| 1373 | |
| 1374 | /* |
| 1375 | * We now have a segment name to search for, and a directory to search. |