The path resolving functions can now also fill in the ID of the parent directory.
This is currently only used for the file cache module API. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13862 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -222,10 +222,10 @@ static status_t common_read_stat(struct file_descriptor *, struct stat *);
|
|||||||
static status_t common_write_stat(struct file_descriptor *, const struct stat *, int statMask);
|
static status_t common_write_stat(struct file_descriptor *, const struct stat *, int statMask);
|
||||||
|
|
||||||
static status_t vnode_path_to_vnode(struct vnode *vnode, char *path,
|
static status_t vnode_path_to_vnode(struct vnode *vnode, char *path,
|
||||||
bool traverseLeafLink, int count, struct vnode **_vnode, int *_type);
|
bool traverseLeafLink, int count, struct vnode **_vnode, vnode_id *_parentID, int *_type);
|
||||||
static status_t dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize);
|
static status_t dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize);
|
||||||
static status_t fd_and_path_to_vnode(int fd, char *path, bool traverseLeafLink,
|
static status_t fd_and_path_to_vnode(int fd, char *path, bool traverseLeafLink,
|
||||||
struct vnode **_vnode, bool kernel);
|
struct vnode **_vnode, vnode_id *_parentID, bool kernel);
|
||||||
static void inc_vnode_ref_count(struct vnode *vnode);
|
static void inc_vnode_ref_count(struct vnode *vnode);
|
||||||
static status_t dec_vnode_ref_count(struct vnode *vnode, bool reenter);
|
static status_t dec_vnode_ref_count(struct vnode *vnode, bool reenter);
|
||||||
static inline void put_vnode(struct vnode *vnode);
|
static inline void put_vnode(struct vnode *vnode);
|
||||||
@@ -1316,7 +1316,7 @@ entry_ref_to_vnode(mount_id mountID, vnode_id directoryID, const char *name, str
|
|||||||
if (status < 0)
|
if (status < 0)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
return vnode_path_to_vnode(directory, clonedName, false, 0, _vnode, NULL);
|
return vnode_path_to_vnode(directory, clonedName, false, 0, _vnode, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1328,9 +1328,10 @@ entry_ref_to_vnode(mount_id mountID, vnode_id directoryID, const char *name, str
|
|||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
vnode_path_to_vnode(struct vnode *vnode, char *path, bool traverseLeafLink,
|
vnode_path_to_vnode(struct vnode *vnode, char *path, bool traverseLeafLink,
|
||||||
int count, struct vnode **_vnode, int *_type)
|
int count, struct vnode **_vnode, vnode_id *_parentID, int *_type)
|
||||||
{
|
{
|
||||||
status_t status = 0;
|
status_t status = 0;
|
||||||
|
vnode_id lastParentID = -1;
|
||||||
int type = 0;
|
int type = 0;
|
||||||
|
|
||||||
FUNCTION(("vnode_path_to_vnode(vnode = %p, path = %s)\n", vnode, path));
|
FUNCTION(("vnode_path_to_vnode(vnode = %p, path = %s)\n", vnode, path));
|
||||||
@@ -1397,7 +1398,8 @@ vnode_path_to_vnode(struct vnode *vnode, char *path, bool traverseLeafLink,
|
|||||||
if (!nextVnode) {
|
if (!nextVnode) {
|
||||||
// pretty screwed up here - the file system found the vnode, but the hash
|
// pretty screwed up here - the file system found the vnode, but the hash
|
||||||
// lookup failed, so our internal structures are messed up
|
// lookup failed, so our internal structures are messed up
|
||||||
panic("path_to_vnode: could not lookup vnode (mountid 0x%lx vnid 0x%Lx)\n", vnode->device, vnodeID);
|
panic("vnode_path_to_vnode: could not lookup vnode (mountid 0x%lx vnid 0x%Lx)\n",
|
||||||
|
vnode->device, vnodeID);
|
||||||
put_vnode(vnode);
|
put_vnode(vnode);
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
@@ -1451,7 +1453,8 @@ vnode_path_to_vnode(struct vnode *vnode, char *path, bool traverseLeafLink,
|
|||||||
// balance the next recursion - we will decrement the ref_count
|
// balance the next recursion - we will decrement the ref_count
|
||||||
// of the vnode, no matter if we succeeded or not
|
// of the vnode, no matter if we succeeded or not
|
||||||
|
|
||||||
status = vnode_path_to_vnode(vnode, path, traverseLeafLink, count + 1, &nextVnode, _type);
|
status = vnode_path_to_vnode(vnode, path, traverseLeafLink, count + 1,
|
||||||
|
&nextVnode, &lastParentID, _type);
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
|
||||||
@@ -1459,7 +1462,8 @@ vnode_path_to_vnode(struct vnode *vnode, char *path, bool traverseLeafLink,
|
|||||||
put_vnode(vnode);
|
put_vnode(vnode);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
|
lastParentID = vnode->id;
|
||||||
|
|
||||||
// decrease the ref count on the old dir we just looked up into
|
// decrease the ref count on the old dir we just looked up into
|
||||||
put_vnode(vnode);
|
put_vnode(vnode);
|
||||||
@@ -1478,13 +1482,16 @@ vnode_path_to_vnode(struct vnode *vnode, char *path, bool traverseLeafLink,
|
|||||||
*_vnode = vnode;
|
*_vnode = vnode;
|
||||||
if (_type)
|
if (_type)
|
||||||
*_type = type;
|
*_type = type;
|
||||||
|
if (_parentID)
|
||||||
|
*_parentID = lastParentID;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
path_to_vnode(char *path, bool traverseLink, struct vnode **_vnode, bool kernel)
|
path_to_vnode(char *path, bool traverseLink, struct vnode **_vnode,
|
||||||
|
vnode_id *_parentID, bool kernel)
|
||||||
{
|
{
|
||||||
struct vnode *start;
|
struct vnode *start;
|
||||||
|
|
||||||
@@ -1513,7 +1520,7 @@ path_to_vnode(char *path, bool traverseLink, struct vnode **_vnode, bool kernel)
|
|||||||
mutex_unlock(&context->io_mutex);
|
mutex_unlock(&context->io_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return vnode_path_to_vnode(start, path, traverseLink, 0, _vnode, NULL);
|
return vnode_path_to_vnode(start, path, traverseLink, 0, _vnode, _parentID, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1529,7 +1536,7 @@ path_to_dir_vnode(char *path, struct vnode **_vnode, char *filename, bool kernel
|
|||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
return path_to_vnode(path, true, _vnode, kernel);
|
return path_to_vnode(path, true, _vnode, NULL, kernel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1571,7 +1578,7 @@ fd_and_path_to_dir_vnode(int fd, char *path, struct vnode **_vnode,
|
|||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
return fd_and_path_to_vnode(fd, path, true, _vnode, kernel);
|
return fd_and_path_to_vnode(fd, path, true, _vnode, NULL, kernel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1883,32 +1890,34 @@ get_vnode_from_fd(int fd, bool kernel)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
fd_and_path_to_vnode(int fd, char *path, bool traverseLeafLink, struct vnode **_vnode, bool kernel)
|
fd_and_path_to_vnode(int fd, char *path, bool traverseLeafLink,
|
||||||
|
struct vnode **_vnode, vnode_id *_parentID, bool kernel)
|
||||||
{
|
{
|
||||||
if (fd < 0 && !path)
|
if (fd < 0 && !path)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
status_t status;
|
|
||||||
struct vnode *vnode = NULL;
|
|
||||||
if (fd < 0 || (path != NULL && path[0] == '/')) {
|
if (fd < 0 || (path != NULL && path[0] == '/')) {
|
||||||
// no FD or absolute path
|
// no FD or absolute path
|
||||||
status = path_to_vnode(path, traverseLeafLink, &vnode, kernel);
|
return path_to_vnode(path, traverseLeafLink, _vnode, _parentID, kernel);
|
||||||
} else {
|
|
||||||
// FD only, or FD + relative path
|
|
||||||
vnode = get_vnode_from_fd(fd, kernel);
|
|
||||||
if (!vnode)
|
|
||||||
return B_FILE_ERROR;
|
|
||||||
|
|
||||||
if (path != NULL) {
|
|
||||||
status = vnode_path_to_vnode(vnode, path, traverseLeafLink, 0,
|
|
||||||
&vnode, NULL);
|
|
||||||
} else
|
|
||||||
status = B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == B_OK)
|
// FD only, or FD + relative path
|
||||||
*_vnode = vnode;
|
struct vnode *vnode = get_vnode_from_fd(fd, kernel);
|
||||||
return status;
|
if (!vnode)
|
||||||
|
return B_FILE_ERROR;
|
||||||
|
|
||||||
|
if (path != NULL) {
|
||||||
|
return vnode_path_to_vnode(vnode, path, traverseLeafLink, 0,
|
||||||
|
_vnode, _parentID, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// there is no relative path to take into account
|
||||||
|
|
||||||
|
*_vnode = vnode;
|
||||||
|
if (_parentID)
|
||||||
|
*_parentID = -1;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2164,7 +2173,7 @@ vfs_get_vnode_from_path(const char *path, bool kernel, void **_vnode)
|
|||||||
|
|
||||||
strlcpy(buffer, path, sizeof(buffer));
|
strlcpy(buffer, path, sizeof(buffer));
|
||||||
|
|
||||||
status = path_to_vnode(buffer, true, &vnode, kernel);
|
status = path_to_vnode(buffer, true, &vnode, NULL, kernel);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -2214,7 +2223,7 @@ vfs_get_fs_node_from_path(mount_id mountID, const char *path, bool kernel, void
|
|||||||
PRINT(("vfs_get_fs_node_from_path(mountID = %ld, path = \"%s\", kernel %d)\n", mountID, path, kernel));
|
PRINT(("vfs_get_fs_node_from_path(mountID = %ld, path = \"%s\", kernel %d)\n", mountID, path, kernel));
|
||||||
|
|
||||||
strlcpy(buffer, path, sizeof(buffer));
|
strlcpy(buffer, path, sizeof(buffer));
|
||||||
status = path_to_vnode(buffer, true, &vnode, kernel);
|
status = path_to_vnode(buffer, true, &vnode, NULL, kernel);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -2249,7 +2258,7 @@ vfs_get_module_path(const char *basePath, const char *moduleName, char *pathBuff
|
|||||||
if (bufferSize == 0 || strlcpy(pathBuffer, basePath, bufferSize) >= bufferSize)
|
if (bufferSize == 0 || strlcpy(pathBuffer, basePath, bufferSize) >= bufferSize)
|
||||||
return B_BUFFER_OVERFLOW;
|
return B_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
status = path_to_vnode(pathBuffer, true, &dir, true);
|
status = path_to_vnode(pathBuffer, true, &dir, NULL, true);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -2281,7 +2290,7 @@ vfs_get_module_path(const char *basePath, const char *moduleName, char *pathBuff
|
|||||||
path[length] = '\0';
|
path[length] = '\0';
|
||||||
moduleName = nextPath;
|
moduleName = nextPath;
|
||||||
|
|
||||||
status = vnode_path_to_vnode(dir, path, true, 0, &file, &type);
|
status = vnode_path_to_vnode(dir, path, true, 0, &file, NULL, &type);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@@ -2367,7 +2376,7 @@ vfs_normalize_path(const char *path, char *buffer, size_t bufferSize,
|
|||||||
// vnode and ignore the leaf later
|
// vnode and ignore the leaf later
|
||||||
bool isDir = (strcmp(leaf, ".") == 0 || strcmp(leaf, "..") == 0);
|
bool isDir = (strcmp(leaf, ".") == 0 || strcmp(leaf, "..") == 0);
|
||||||
if (isDir)
|
if (isDir)
|
||||||
error = vnode_path_to_vnode(dirNode, leaf, false, 0, &dirNode, NULL);
|
error = vnode_path_to_vnode(dirNode, leaf, false, 0, &dirNode, NULL, NULL);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
PRINT(("vfs_normalize_path(): failed to get dir vnode for \".\" or \"..\": %s\n", strerror(error)));
|
PRINT(("vfs_normalize_path(): failed to get dir vnode for \".\" or \"..\": %s\n", strerror(error)));
|
||||||
return error;
|
return error;
|
||||||
@@ -3097,7 +3106,8 @@ file_open(int fd, char *path, int openMode, bool kernel)
|
|||||||
|
|
||||||
// get the vnode matching the vnode + path combination
|
// get the vnode matching the vnode + path combination
|
||||||
struct vnode *vnode = NULL;
|
struct vnode *vnode = NULL;
|
||||||
status = fd_and_path_to_vnode(fd, path, traverse, &vnode, kernel);
|
vnode_id parentID;
|
||||||
|
status = fd_and_path_to_vnode(fd, path, traverse, &vnode, &parentID, kernel);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -3107,7 +3117,9 @@ file_open(int fd, char *path, int openMode, bool kernel)
|
|||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
put_vnode(vnode);
|
put_vnode(vnode);
|
||||||
|
|
||||||
cache_node_opened(vnode, FDTYPE_FILE, vnode->cache, vnode->device, -1, vnode->id, NULL);
|
cache_node_opened(vnode, FDTYPE_FILE, vnode->cache,
|
||||||
|
vnode->device, parentID, vnode->id, NULL);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3329,7 +3341,8 @@ dir_open(int fd, char *path, bool kernel)
|
|||||||
|
|
||||||
// get the vnode matching the vnode + path combination
|
// get the vnode matching the vnode + path combination
|
||||||
struct vnode *vnode = NULL;
|
struct vnode *vnode = NULL;
|
||||||
status = fd_and_path_to_vnode(fd, path, true, &vnode, kernel);
|
vnode_id parentID;
|
||||||
|
status = fd_and_path_to_vnode(fd, path, true, &vnode, &parentID, kernel);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -3338,7 +3351,7 @@ dir_open(int fd, char *path, bool kernel)
|
|||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
put_vnode(vnode);
|
put_vnode(vnode);
|
||||||
|
|
||||||
cache_node_opened(vnode, FDTYPE_DIR, vnode->cache, vnode->device, -1, vnode->id, NULL);
|
cache_node_opened(vnode, FDTYPE_DIR, vnode->cache, vnode->device, parentID, vnode->id, NULL);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3394,7 +3407,7 @@ fix_dirent(struct vnode *parent, struct dirent *entry)
|
|||||||
|
|
||||||
struct vnode *vnode;
|
struct vnode *vnode;
|
||||||
status_t status = vnode_path_to_vnode(parent, "..", false, 0, &vnode,
|
status_t status = vnode_path_to_vnode(parent, "..", false, 0, &vnode,
|
||||||
NULL);
|
NULL, NULL);
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
entry->d_dev = vnode->device;
|
entry->d_dev = vnode->device;
|
||||||
@@ -3635,7 +3648,7 @@ common_read_link(int fd, char *path, char *buffer, size_t *_bufferSize,
|
|||||||
struct vnode *vnode;
|
struct vnode *vnode;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
status = fd_and_path_to_vnode(fd, path, false, &vnode, kernel);
|
status = fd_and_path_to_vnode(fd, path, false, &vnode, NULL, kernel);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -3656,7 +3669,7 @@ common_write_link(char *path, char *toPath, bool kernel)
|
|||||||
struct vnode *vnode;
|
struct vnode *vnode;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
status = path_to_vnode(path, false, &vnode, kernel);
|
status = path_to_vnode(path, false, &vnode, NULL, kernel);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -3711,7 +3724,7 @@ common_create_link(char *path, char *toPath, bool kernel)
|
|||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
status = path_to_vnode(toPath, true, &vnode, kernel);
|
status = path_to_vnode(toPath, true, &vnode, NULL, kernel);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@@ -3764,7 +3777,7 @@ common_access(char *path, int mode, bool kernel)
|
|||||||
struct vnode *vnode;
|
struct vnode *vnode;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
status = path_to_vnode(path, true, &vnode, kernel);
|
status = path_to_vnode(path, true, &vnode, NULL, kernel);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -3858,7 +3871,7 @@ common_path_read_stat(int fd, char *path, bool traverseLeafLink,
|
|||||||
|
|
||||||
FUNCTION(("common_path_read_stat: fd: %d, path '%s', stat %p,\n", fd, path, stat));
|
FUNCTION(("common_path_read_stat: fd: %d, path '%s', stat %p,\n", fd, path, stat));
|
||||||
|
|
||||||
status = fd_and_path_to_vnode(fd, path, traverseLeafLink, &vnode, kernel);
|
status = fd_and_path_to_vnode(fd, path, traverseLeafLink, &vnode, NULL, kernel);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -3884,7 +3897,7 @@ common_path_write_stat(int fd, char *path, bool traverseLeafLink,
|
|||||||
|
|
||||||
FUNCTION(("common_write_stat: fd: %d, path '%s', stat %p, stat_mask %d, kernel %d\n", fd, path, stat, statMask, kernel));
|
FUNCTION(("common_write_stat: fd: %d, path '%s', stat %p, stat_mask %d, kernel %d\n", fd, path, stat, statMask, kernel));
|
||||||
|
|
||||||
status = fd_and_path_to_vnode(fd, path, traverseLeafLink, &vnode, kernel);
|
status = fd_and_path_to_vnode(fd, path, traverseLeafLink, &vnode, NULL, kernel);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -3907,7 +3920,7 @@ attr_dir_open(int fd, char *path, bool kernel)
|
|||||||
|
|
||||||
FUNCTION(("attr_dir_open(fd = %d, path = '%s', kernel = %d)\n", fd, path, kernel));
|
FUNCTION(("attr_dir_open(fd = %d, path = '%s', kernel = %d)\n", fd, path, kernel));
|
||||||
|
|
||||||
status = fd_and_path_to_vnode(fd, path, true, &vnode, kernel);
|
status = fd_and_path_to_vnode(fd, path, true, &vnode, NULL, kernel);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -4701,7 +4714,7 @@ fs_mount(char *path, const char *device, const char *fsName, uint32 flags,
|
|||||||
|
|
||||||
mount->covers_vnode = NULL; // this is the root mount
|
mount->covers_vnode = NULL; // this is the root mount
|
||||||
} else {
|
} else {
|
||||||
err = path_to_vnode(path, true, &covered_vnode, kernel);
|
err = path_to_vnode(path, true, &covered_vnode, NULL, kernel);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err5;
|
goto err5;
|
||||||
|
|
||||||
@@ -4793,7 +4806,7 @@ fs_unmount(char *path, uint32 flags, bool kernel)
|
|||||||
|
|
||||||
FUNCTION(("vfs_unmount: entry. path = '%s', kernel %d\n", path, kernel));
|
FUNCTION(("vfs_unmount: entry. path = '%s', kernel %d\n", path, kernel));
|
||||||
|
|
||||||
err = path_to_vnode(path, true, &vnode, kernel);
|
err = path_to_vnode(path, true, &vnode, NULL, kernel);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
@@ -5049,7 +5062,7 @@ set_cwd(int fd, char *path, bool kernel)
|
|||||||
FUNCTION(("set_cwd: path = \'%s\'\n", path));
|
FUNCTION(("set_cwd: path = \'%s\'\n", path));
|
||||||
|
|
||||||
// Get vnode for passed path, and bail if it failed
|
// Get vnode for passed path, and bail if it failed
|
||||||
rc = fd_and_path_to_vnode(fd, path, true, &vnode, kernel);
|
rc = fd_and_path_to_vnode(fd, path, true, &vnode, NULL, kernel);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user