update name of code to labcodes
This commit is contained in:
126
labcodes/lab8/kern/fs/vfs/vfspath.c
Normal file
126
labcodes/lab8/kern/fs/vfs/vfspath.c
Normal file
@@ -0,0 +1,126 @@
|
||||
#include <defs.h>
|
||||
#include <string.h>
|
||||
#include <vfs.h>
|
||||
#include <inode.h>
|
||||
#include <iobuf.h>
|
||||
#include <stat.h>
|
||||
#include <proc.h>
|
||||
#include <error.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* get_cwd_nolock - retrieve current process's working directory. without lock protect
|
||||
*/
|
||||
static struct inode *
|
||||
get_cwd_nolock(void) {
|
||||
return current->filesp->pwd;
|
||||
}
|
||||
/*
|
||||
* set_cwd_nolock - set current working directory.
|
||||
*/
|
||||
static void
|
||||
set_cwd_nolock(struct inode *pwd) {
|
||||
current->filesp->pwd = pwd;
|
||||
}
|
||||
|
||||
/*
|
||||
* lock_cfs - lock the fs related process on current process
|
||||
*/
|
||||
static void
|
||||
lock_cfs(void) {
|
||||
lock_files(current->filesp);
|
||||
}
|
||||
/*
|
||||
* unlock_cfs - unlock the fs related process on current process
|
||||
*/
|
||||
static void
|
||||
unlock_cfs(void) {
|
||||
unlock_files(current->filesp);
|
||||
}
|
||||
|
||||
/*
|
||||
* vfs_get_curdir - Get current directory as a inode.
|
||||
*/
|
||||
int
|
||||
vfs_get_curdir(struct inode **dir_store) {
|
||||
struct inode *node;
|
||||
if ((node = get_cwd_nolock()) != NULL) {
|
||||
vop_ref_inc(node);
|
||||
*dir_store = node;
|
||||
return 0;
|
||||
}
|
||||
return -E_NOENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* vfs_set_curdir - Set current directory as a inode.
|
||||
* The passed inode must in fact be a directory.
|
||||
*/
|
||||
int
|
||||
vfs_set_curdir(struct inode *dir) {
|
||||
int ret = 0;
|
||||
lock_cfs();
|
||||
struct inode *old_dir;
|
||||
if ((old_dir = get_cwd_nolock()) != dir) {
|
||||
if (dir != NULL) {
|
||||
uint32_t type;
|
||||
if ((ret = vop_gettype(dir, &type)) != 0) {
|
||||
goto out;
|
||||
}
|
||||
if (!S_ISDIR(type)) {
|
||||
ret = -E_NOTDIR;
|
||||
goto out;
|
||||
}
|
||||
vop_ref_inc(dir);
|
||||
}
|
||||
set_cwd_nolock(dir);
|
||||
if (old_dir != NULL) {
|
||||
vop_ref_dec(old_dir);
|
||||
}
|
||||
}
|
||||
out:
|
||||
unlock_cfs();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* vfs_chdir - Set current directory, as a pathname. Use vfs_lookup to translate
|
||||
* it to a inode.
|
||||
*/
|
||||
int
|
||||
vfs_chdir(char *path) {
|
||||
int ret;
|
||||
struct inode *node;
|
||||
if ((ret = vfs_lookup(path, &node)) == 0) {
|
||||
ret = vfs_set_curdir(node);
|
||||
vop_ref_dec(node);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* vfs_getcwd - retrieve current working directory(cwd).
|
||||
*/
|
||||
int
|
||||
vfs_getcwd(struct iobuf *iob) {
|
||||
int ret;
|
||||
struct inode *node;
|
||||
if ((ret = vfs_get_curdir(&node)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
assert(node->in_fs != NULL);
|
||||
|
||||
const char *devname = vfs_get_devname(node->in_fs);
|
||||
if ((ret = iobuf_move(iob, (char *)devname, strlen(devname), 1, NULL)) != 0) {
|
||||
goto out;
|
||||
}
|
||||
char colon = ':';
|
||||
if ((ret = iobuf_move(iob, &colon, sizeof(colon), 1, NULL)) != 0) {
|
||||
goto out;
|
||||
}
|
||||
ret = vop_namefile(node, iob);
|
||||
|
||||
out:
|
||||
vop_ref_dec(node);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user