mtab: support moving mount points
Also fix canonical_path function; it fails to parse some paths
This commit is contained in:
parent
9f7fb97000
commit
179261a9b6
4 changed files with 71 additions and 4 deletions
|
@ -92,6 +92,7 @@ int do_getsysinfo()
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case SI_VMNT_TAB:
|
case SI_VMNT_TAB:
|
||||||
|
fetch_vmnt_paths();
|
||||||
src_addr = (vir_bytes) vmnt;
|
src_addr = (vir_bytes) vmnt;
|
||||||
len = sizeof(struct vmnt) * NR_MNTS;
|
len = sizeof(struct vmnt) * NR_MNTS;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -656,7 +656,8 @@ struct fproc *rfp;
|
||||||
char temp_path[PATH_MAX];
|
char temp_path[PATH_MAX];
|
||||||
struct lookup resolve;
|
struct lookup resolve;
|
||||||
|
|
||||||
dir_vp = NULL;
|
parent_dir = dir_vp = NULL;
|
||||||
|
parent_vmp = dir_vmp = NULL;
|
||||||
strlcpy(temp_path, orig_path, PATH_MAX);
|
strlcpy(temp_path, orig_path, PATH_MAX);
|
||||||
temp_path[PATH_MAX - 1] = '\0';
|
temp_path[PATH_MAX - 1] = '\0';
|
||||||
|
|
||||||
|
@ -678,6 +679,9 @@ struct fproc *rfp;
|
||||||
*/
|
*/
|
||||||
strlcpy(orig_path, temp_path, NAME_MAX+1); /* Store file name */
|
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 */
|
/* check if the file is a symlink, if so resolve it */
|
||||||
r = rdlink_direct(orig_path, temp_path, rfp);
|
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 */
|
/* 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_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_vnode(dir_vp);
|
||||||
unlock_vmnt(dir_vmp);
|
unlock_vmnt(dir_vmp);
|
||||||
put_vnode(dir_vp);
|
put_vnode(dir_vp);
|
||||||
|
@ -769,18 +777,23 @@ struct fproc *rfp;
|
||||||
unlock_vmnt(dir_vmp);
|
unlock_vmnt(dir_vmp);
|
||||||
put_vnode(dir_vp);
|
put_vnode(dir_vp);
|
||||||
dir_vp = parent_dir;
|
dir_vp = parent_dir;
|
||||||
|
dir_vmp = parent_vmp;
|
||||||
|
parent_vmp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unlock_vmnt(dir_vmp);
|
||||||
unlock_vnode(dir_vp);
|
unlock_vnode(dir_vp);
|
||||||
unlock_vmnt(parent_vmp);
|
|
||||||
|
|
||||||
put_vnode(dir_vp);
|
put_vnode(dir_vp);
|
||||||
|
|
||||||
/* add the leading slash */
|
/* add the leading slash */
|
||||||
|
len = strlen(orig_path);
|
||||||
if (strlen(orig_path) >= PATH_MAX) return(ENAMETOOLONG);
|
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] = '/';
|
orig_path[0] = '/';
|
||||||
|
|
||||||
|
/* remove trailing slash if there is any */
|
||||||
|
if (len > 1 && orig_path[len] == '/') orig_path[len] = '\0';
|
||||||
|
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -315,6 +315,7 @@ void init_vmnts(void);
|
||||||
int lock_vmnt(struct vmnt *vp, tll_access_t locktype);
|
int lock_vmnt(struct vmnt *vp, tll_access_t locktype);
|
||||||
void unlock_vmnt(struct vmnt *vp);
|
void unlock_vmnt(struct vmnt *vp);
|
||||||
void vmnt_unmap_by_endpt(endpoint_t proc_e);
|
void vmnt_unmap_by_endpt(endpoint_t proc_e);
|
||||||
|
void fetch_vmnt_paths(void);
|
||||||
|
|
||||||
/* vnode.c */
|
/* vnode.c */
|
||||||
void check_vnode_locks(void);
|
void check_vnode_locks(void);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "threads.h"
|
#include "threads.h"
|
||||||
#include "vmnt.h"
|
#include "vmnt.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
#include "fproc.h"
|
#include "fproc.h"
|
||||||
|
|
||||||
static int is_vmnt_locked(struct vmnt *vmp);
|
static int is_vmnt_locked(struct vmnt *vmp);
|
||||||
|
@ -214,3 +215,54 @@ void unlock_vmnt(struct vmnt *vmp)
|
||||||
#endif
|
#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 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue