mtab: support moving mount points

Also fix canonical_path function; it fails to parse some paths
This commit is contained in:
Thomas Veerman 2012-11-27 17:33:59 +00:00
parent 9f7fb97000
commit 179261a9b6
4 changed files with 71 additions and 4 deletions

View file

@ -92,6 +92,7 @@ int do_getsysinfo()
break;
#endif
case SI_VMNT_TAB:
fetch_vmnt_paths();
src_addr = (vir_bytes) vmnt;
len = sizeof(struct vmnt) * NR_MNTS;
break;

View file

@ -656,7 +656,8 @@ struct fproc *rfp;
char temp_path[PATH_MAX];
struct lookup resolve;
dir_vp = NULL;
parent_dir = dir_vp = NULL;
parent_vmp = dir_vmp = NULL;
strlcpy(temp_path, orig_path, PATH_MAX);
temp_path[PATH_MAX - 1] = '\0';
@ -678,6 +679,9 @@ struct fproc *rfp;
*/
strlcpy(orig_path, temp_path, NAME_MAX+1); /* Store file name */
/* If we're just crossing a mount point, our name has changed to '.' */
if (!strcmp(orig_path, ".")) orig_path[0] = '\0';
/* check if the file is a symlink, if so resolve it */
r = rdlink_direct(orig_path, temp_path, rfp);
@ -706,6 +710,10 @@ struct fproc *rfp;
/* check if we're at the root node of the file system */
if (dir_vp->v_vmnt->m_root_node == dir_vp) {
if (dir_vp->v_vmnt->m_mounted_on == NULL) {
/* Bail out, we can't go any higher */
break;
}
unlock_vnode(dir_vp);
unlock_vmnt(dir_vmp);
put_vnode(dir_vp);
@ -769,18 +777,23 @@ struct fproc *rfp;
unlock_vmnt(dir_vmp);
put_vnode(dir_vp);
dir_vp = parent_dir;
dir_vmp = parent_vmp;
parent_vmp = NULL;
}
unlock_vmnt(dir_vmp);
unlock_vnode(dir_vp);
unlock_vmnt(parent_vmp);
put_vnode(dir_vp);
/* add the leading slash */
len = strlen(orig_path);
if (strlen(orig_path) >= PATH_MAX) return(ENAMETOOLONG);
memmove(orig_path+1, orig_path, strlen(orig_path));
memmove(orig_path+1, orig_path, len);
orig_path[0] = '/';
/* remove trailing slash if there is any */
if (len > 1 && orig_path[len] == '/') orig_path[len] = '\0';
return(OK);
}

View file

@ -315,6 +315,7 @@ void init_vmnts(void);
int lock_vmnt(struct vmnt *vp, tll_access_t locktype);
void unlock_vmnt(struct vmnt *vp);
void vmnt_unmap_by_endpt(endpoint_t proc_e);
void fetch_vmnt_paths(void);
/* vnode.c */
void check_vnode_locks(void);

View file

@ -6,6 +6,7 @@
#include "threads.h"
#include "vmnt.h"
#include <assert.h>
#include <string.h>
#include "fproc.h"
static int is_vmnt_locked(struct vmnt *vmp);
@ -214,3 +215,54 @@ void unlock_vmnt(struct vmnt *vmp)
#endif
}
/*===========================================================================*
* fetch_vmnt_paths *
*===========================================================================*/
void fetch_vmnt_paths(void)
{
struct vmnt *vmp;
struct vnode *cur_wd;
char orig_path[PATH_MAX];
cur_wd = fp->fp_wd;
for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; vmp++) {
if (vmp->m_dev == NO_DEV)
continue;
if (vmp->m_fs_e == PFS_PROC_NR)
continue;
strlcpy(orig_path, vmp->m_mount_path, PATH_MAX);
/* Find canonical path */
if (canonical_path(vmp->m_mount_path, fp) != OK) {
/* We failed to find it (moved somewhere else?). Let's try
* again by starting at the node on which we are mounted:
* pretend that node is our working directory and look for the
* canonical path of the relative path to the mount point
* (which should be in our 'working directory').
*/
char *mp;
int len;
fp->fp_wd = vmp->m_mounted_on; /* Change our working dir */
/* Isolate the mount point name of the full path */
len = strlen(vmp->m_mount_path);
if (vmp->m_mount_path[len - 1] == '/') {
vmp->m_mount_path[len - 1] = '\0';
}
mp = strrchr(vmp->m_mount_path, '/');
strlcpy(vmp->m_mount_path, mp+1, NAME_MAX+1);
if (canonical_path(vmp->m_mount_path, fp) != OK) {
/* Our second try failed too. Maybe an FS has crashed
* and we're missing part of the tree. Revert path.
*/
strlcpy(vmp->m_mount_path, orig_path, PATH_MAX);
}
fp->fp_wd = cur_wd; /* Revert working dir */
}
}
}