* Eliminated fs_mount::mount_point. It wasn't really used anyway, only
in dir_vnode_to_path() which does now continue until hitting "/". * Refactored common volume root to mount point resolution code into a separate function. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9210 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+63
-29
@@ -88,7 +88,6 @@ struct fs_mount {
|
|||||||
file_system_info *fs;
|
file_system_info *fs;
|
||||||
mount_id id;
|
mount_id id;
|
||||||
void *cookie;
|
void *cookie;
|
||||||
char *mount_point;
|
|
||||||
char *device_name;
|
char *device_name;
|
||||||
char *fs_name;
|
char *fs_name;
|
||||||
recursive_lock rlock; // guards the vnodes list
|
recursive_lock rlock; // guards the vnodes list
|
||||||
@@ -732,6 +731,36 @@ put_vnode(struct vnode *vnode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Resolves a volume root vnode to the underlying mount point vnode.
|
||||||
|
|
||||||
|
Given an arbitrary vnode, the function checks, whether the node is the
|
||||||
|
root of a volume. If it is (and if it is not "/"), the function obtains
|
||||||
|
a reference to the underlying mount point node and returns it.
|
||||||
|
|
||||||
|
\param vnode The vnode in question.
|
||||||
|
\return The mount point vnode the vnode covers, if it is indeed a volume
|
||||||
|
root and not "/", or \c NULL otherwise.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
struct vnode*
|
||||||
|
resolve_volume_root_to_mount_point(struct vnode *vnode)
|
||||||
|
{
|
||||||
|
if (!vnode)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
struct vnode *mountPoint = NULL;
|
||||||
|
|
||||||
|
recursive_lock_lock(&sMountOpLock);
|
||||||
|
if (vnode->covered_by) {
|
||||||
|
mountPoint = vnode->covered_by;
|
||||||
|
inc_vnode_ref_count(mountPoint);
|
||||||
|
}
|
||||||
|
recursive_lock_unlock(&sMountOpLock);
|
||||||
|
|
||||||
|
return mountPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** \brief Gets the directory path and leaf name for a given path.
|
/** \brief Gets the directory path and leaf name for a given path.
|
||||||
|
|
||||||
The supplied \a path is transformed to refer to the directory part of
|
The supplied \a path is transformed to refer to the directory part of
|
||||||
@@ -933,14 +962,11 @@ vnode_path_to_vnode(struct vnode *vnode, char *path, bool traverseLeafLink,
|
|||||||
vnode = nextVnode;
|
vnode = nextVnode;
|
||||||
|
|
||||||
// see if we hit a mount point
|
// see if we hit a mount point
|
||||||
recursive_lock_lock(&sMountOpLock);
|
struct vnode *mountPoint = resolve_volume_root_to_mount_point(vnode);
|
||||||
if (vnode->covered_by) {
|
if (mountPoint) {
|
||||||
nextVnode = vnode->covered_by;
|
|
||||||
inc_vnode_ref_count(nextVnode);
|
|
||||||
put_vnode(vnode);
|
put_vnode(vnode);
|
||||||
vnode = nextVnode;
|
vnode = mountPoint;
|
||||||
}
|
}
|
||||||
recursive_lock_unlock(&sMountOpLock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*_vnode = vnode;
|
*_vnode = vnode;
|
||||||
@@ -1098,10 +1124,11 @@ get_vnode_name(struct vnode *vnode, struct vnode *parent,
|
|||||||
* It might be a good idea, though, to check if the returned path exists
|
* It might be a good idea, though, to check if the returned path exists
|
||||||
* in the calling function (it's not done here because of efficiency)
|
* in the calling function (it's not done here because of efficiency)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize)
|
dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize)
|
||||||
{
|
{
|
||||||
|
FUNCTION(("dir_vnode_to_path(%p, %p, %lu\n)", vnode, buffer, bufferSize));
|
||||||
|
|
||||||
/* this implementation is currently bound to SYS_MAX_PATH_LEN */
|
/* this implementation is currently bound to SYS_MAX_PATH_LEN */
|
||||||
char path[SYS_MAX_PATH_LEN];
|
char path[SYS_MAX_PATH_LEN];
|
||||||
int32 insert = sizeof(path);
|
int32 insert = sizeof(path);
|
||||||
@@ -1116,6 +1143,13 @@ dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize)
|
|||||||
// efficient and does all we need from get_vnode()
|
// efficient and does all we need from get_vnode()
|
||||||
inc_vnode_ref_count(vnode);
|
inc_vnode_ref_count(vnode);
|
||||||
|
|
||||||
|
// resolve a volume root to its mount point
|
||||||
|
struct vnode *mountPoint = resolve_volume_root_to_mount_point(vnode);
|
||||||
|
if (mountPoint) {
|
||||||
|
put_vnode(vnode);
|
||||||
|
vnode = mountPoint;
|
||||||
|
}
|
||||||
|
|
||||||
path[--insert] = '\0';
|
path[--insert] = '\0';
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -1141,6 +1175,13 @@ dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resolve a volume root to its mount point
|
||||||
|
mountPoint = resolve_volume_root_to_mount_point(parentVnode);
|
||||||
|
if (mountPoint) {
|
||||||
|
put_vnode(parentVnode);
|
||||||
|
parentVnode = mountPoint;
|
||||||
|
}
|
||||||
|
|
||||||
// Does the file system support getting the name of a vnode?
|
// Does the file system support getting the name of a vnode?
|
||||||
// If so, get it here...
|
// If so, get it here...
|
||||||
if (status == B_OK && FS_CALL(vnode, get_vnode_name))
|
if (status == B_OK && FS_CALL(vnode, get_vnode_name))
|
||||||
@@ -1167,8 +1208,8 @@ dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (parentID == id) {
|
if (parentID == id) {
|
||||||
// we have reached the root level directory of this file system
|
// we have reached "/", which means we have constructed the full
|
||||||
// which means we have constructed the full path
|
// path
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1211,16 +1252,18 @@ dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize)
|
|||||||
path[--insert] = '/';
|
path[--insert] = '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the mountpoint
|
// the root dir will result in an empty path: fix it
|
||||||
length = strlen(vnode->mount->mount_point);
|
if (path[insert] == '\0')
|
||||||
if (bufferSize - (sizeof(path) - insert) < (uint32)length + 1) {
|
path[--insert] = '/';
|
||||||
status = ENOBUFS;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(buffer, vnode->mount->mount_point, length);
|
PRINT((" path is: %s\n", path + insert));
|
||||||
if (insert != sizeof(path))
|
|
||||||
memcpy(buffer + length, path + insert, sizeof(path) - insert);
|
// copy the path to the output buffer
|
||||||
|
length = sizeof(path) - insert;
|
||||||
|
if (length <= (int)bufferSize)
|
||||||
|
memcpy(buffer, path + insert, length);
|
||||||
|
else
|
||||||
|
status = ENOBUFS;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
put_vnode(vnode);
|
put_vnode(vnode);
|
||||||
@@ -3541,16 +3584,10 @@ fs_mount(char *path, const char *device, const char *fsName, void *args, bool ke
|
|||||||
|
|
||||||
list_init_etc(&mount->vnodes, offsetof(struct vnode, mount_link));
|
list_init_etc(&mount->vnodes, offsetof(struct vnode, mount_link));
|
||||||
|
|
||||||
mount->mount_point = strdup(path);
|
|
||||||
if (mount->mount_point == NULL) {
|
|
||||||
err = B_NO_MEMORY;
|
|
||||||
goto err1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mount->fs_name = strdup(fsName);
|
mount->fs_name = strdup(fsName);
|
||||||
if (mount->fs_name == NULL) {
|
if (mount->fs_name == NULL) {
|
||||||
err = B_NO_MEMORY;
|
err = B_NO_MEMORY;
|
||||||
goto err2;
|
goto err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mount->device_name = strdup(device);
|
mount->device_name = strdup(device);
|
||||||
@@ -3658,8 +3695,6 @@ err4:
|
|||||||
free(mount->device_name);
|
free(mount->device_name);
|
||||||
err3:
|
err3:
|
||||||
free(mount->fs_name);
|
free(mount->fs_name);
|
||||||
err2:
|
|
||||||
free(mount->mount_point);
|
|
||||||
err1:
|
err1:
|
||||||
free(mount);
|
free(mount);
|
||||||
err:
|
err:
|
||||||
@@ -3755,7 +3790,6 @@ fs_unmount(char *path, bool kernel)
|
|||||||
|
|
||||||
free(mount->device_name);
|
free(mount->device_name);
|
||||||
free(mount->fs_name);
|
free(mount->fs_name);
|
||||||
free(mount->mount_point);
|
|
||||||
free(mount);
|
free(mount);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user