* 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:
Ingo Weinhold 2004-10-05 16:08:31 +00:00
parent e1130011b7
commit 5741bcb5d8

View File

@ -88,7 +88,6 @@ struct fs_mount {
file_system_info *fs;
mount_id id;
void *cookie;
char *mount_point;
char *device_name;
char *fs_name;
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.
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;
// see if we hit a mount point
recursive_lock_lock(&sMountOpLock);
if (vnode->covered_by) {
nextVnode = vnode->covered_by;
inc_vnode_ref_count(nextVnode);
struct vnode *mountPoint = resolve_volume_root_to_mount_point(vnode);
if (mountPoint) {
put_vnode(vnode);
vnode = nextVnode;
vnode = mountPoint;
}
recursive_lock_unlock(&sMountOpLock);
}
*_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
* in the calling function (it's not done here because of efficiency)
*/
static status_t
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 */
char path[SYS_MAX_PATH_LEN];
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()
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';
while (true) {
@ -1141,6 +1175,13 @@ dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize)
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?
// If so, get it here...
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) {
// we have reached the root level directory of this file system
// which means we have constructed the full path
// we have reached "/", which means we have constructed the full
// path
break;
}
@ -1211,16 +1252,18 @@ dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize)
path[--insert] = '/';
}
// add the mountpoint
length = strlen(vnode->mount->mount_point);
if (bufferSize - (sizeof(path) - insert) < (uint32)length + 1) {
status = ENOBUFS;
goto out;
}
// the root dir will result in an empty path: fix it
if (path[insert] == '\0')
path[--insert] = '/';
memcpy(buffer, vnode->mount->mount_point, length);
if (insert != sizeof(path))
memcpy(buffer + length, path + insert, sizeof(path) - insert);
PRINT((" path is: %s\n", 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:
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));
mount->mount_point = strdup(path);
if (mount->mount_point == NULL) {
err = B_NO_MEMORY;
goto err1;
}
mount->fs_name = strdup(fsName);
if (mount->fs_name == NULL) {
err = B_NO_MEMORY;
goto err2;
goto err1;
}
mount->device_name = strdup(device);
@ -3658,8 +3695,6 @@ err4:
free(mount->device_name);
err3:
free(mount->fs_name);
err2:
free(mount->mount_point);
err1:
free(mount);
err:
@ -3755,7 +3790,6 @@ fs_unmount(char *path, bool kernel)
free(mount->device_name);
free(mount->fs_name);
free(mount->mount_point);
free(mount);
return 0;