mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-05-13 23:19:24 +08:00
rtemsbsd/open: Correctly open a mount directory
- If the open is for a directory and it is the root of the mounted file system open from the pseudo's root node.
This commit is contained in:
parent
715e29f2a0
commit
d9dd59d9ef
@ -61,6 +61,8 @@
|
|||||||
|
|
||||||
static int rtems_bsd_sysgen_open_error(
|
static int rtems_bsd_sysgen_open_error(
|
||||||
rtems_libio_t *iop, const char *path, int oflag, mode_t mode);
|
rtems_libio_t *iop, const char *path, int oflag, mode_t mode);
|
||||||
|
static int rtems_bsd_sysgen_opendir(
|
||||||
|
rtems_libio_t *iop, const char *path, int oflag, mode_t mode);
|
||||||
static int rtems_bsd_sysgen_open(
|
static int rtems_bsd_sysgen_open(
|
||||||
rtems_libio_t *iop, const char *path, int oflag, mode_t mode);
|
rtems_libio_t *iop, const char *path, int oflag, mode_t mode);
|
||||||
static int rtems_bsd_sysgen_close(rtems_libio_t *iop);
|
static int rtems_bsd_sysgen_close(rtems_libio_t *iop);
|
||||||
@ -90,7 +92,7 @@ static int rtems_bsd_sysgen_poll(rtems_libio_t *iop, int events);
|
|||||||
static int rtems_bsd_sysgen_kqfilter(rtems_libio_t *iop, struct knote *kn);
|
static int rtems_bsd_sysgen_kqfilter(rtems_libio_t *iop, struct knote *kn);
|
||||||
|
|
||||||
const rtems_filesystem_file_handlers_r rtems_bsd_sysgen_dirops = {
|
const rtems_filesystem_file_handlers_r rtems_bsd_sysgen_dirops = {
|
||||||
.open_h = rtems_bsd_sysgen_open,
|
.open_h = rtems_bsd_sysgen_opendir,
|
||||||
.close_h = rtems_bsd_sysgen_close,
|
.close_h = rtems_bsd_sysgen_close,
|
||||||
.read_h = rtems_bsd_sysgen_read,
|
.read_h = rtems_bsd_sysgen_read,
|
||||||
.write_h = rtems_filesystem_default_write,
|
.write_h = rtems_filesystem_default_write,
|
||||||
@ -928,9 +930,9 @@ rtems_bsd_sysgen_open_error(
|
|||||||
return rtems_bsd_error_to_status_and_errno(ENXIO);
|
return rtems_bsd_error_to_status_and_errno(ENXIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int
|
||||||
rtems_bsd_sysgen_open(
|
rtems_bsd_sysgen_open_node(
|
||||||
rtems_libio_t *iop, const char *path, int oflag, mode_t mode)
|
rtems_libio_t *iop, const char *path, int oflag, mode_t mode, bool isdir)
|
||||||
{
|
{
|
||||||
struct thread *td = rtems_bsd_get_curthread_or_null();
|
struct thread *td = rtems_bsd_get_curthread_or_null();
|
||||||
struct filedesc *fdp;
|
struct filedesc *fdp;
|
||||||
@ -954,13 +956,13 @@ rtems_bsd_sysgen_open(
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* There is no easy or clean means to open a vnode and follow the
|
* There is no easy or clean means to open a vnode and follow the
|
||||||
* POSIX open semantics. You can open a vnode but the extra
|
* POSIX open semantics. See `kern_openat`. You can open a vnode but
|
||||||
* functionality such as create and truncate are not part of the
|
* the extra functionality such as the file pointer, descriptor,
|
||||||
* basic vnode open. All the calls that provide that functionality
|
* create and truncate are not part of the basic vnode open. All the
|
||||||
* take a path as the argument. As a result find the last token in
|
* calls that provide that functionality take a path as the
|
||||||
* the path and use the parent directory vnode to position ourselves
|
* argument. As a result find the last token in the path and use the
|
||||||
* in the parent directory. The pathloc vnode points to the '.' or
|
* parent directory vnode to position ourselves in the parent
|
||||||
* '..' directory.
|
* directory. The pathloc vnode points to the '.' or '..' directory.
|
||||||
*/
|
*/
|
||||||
opath = path + strlen(path);
|
opath = path + strlen(path);
|
||||||
opathlen = 0;
|
opathlen = 0;
|
||||||
@ -982,10 +984,20 @@ rtems_bsd_sysgen_open(
|
|||||||
rtems_filesystem_location_info_t *rootloc =
|
rtems_filesystem_location_info_t *rootloc =
|
||||||
&iop->pathinfo.mt_entry->mt_fs_root->location;
|
&iop->pathinfo.mt_entry->mt_fs_root->location;
|
||||||
cdir = rtems_bsd_libio_loc_to_vnode_dir(&iop->pathinfo);
|
cdir = rtems_bsd_libio_loc_to_vnode_dir(&iop->pathinfo);
|
||||||
if (fdp->fd_cdir == NULL ||
|
if (fdp->fd_cdir == NULL) {
|
||||||
rtems_bsd_libio_loc_to_vnode(&iop->pathinfo) ==
|
|
||||||
rtems_bsd_libio_loc_to_vnode(rootloc)) {
|
|
||||||
cdir = rtems_bsd_libio_loc_to_vnode(rootloc);
|
cdir = rtems_bsd_libio_loc_to_vnode(rootloc);
|
||||||
|
} else if (rtems_bsd_libio_loc_to_vnode(&iop->pathinfo) ==
|
||||||
|
rtems_bsd_libio_loc_to_vnode(rootloc)) {
|
||||||
|
/*
|
||||||
|
* If this is a directory and this is the root node of
|
||||||
|
* the mounted file system we need to move up the
|
||||||
|
* hidden pseudo file system node.
|
||||||
|
*/
|
||||||
|
if (isdir) {
|
||||||
|
cdir = rootvnode;
|
||||||
|
} else {
|
||||||
|
cdir = rtems_bsd_libio_loc_to_vnode(rootloc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -999,10 +1011,10 @@ rtems_bsd_sysgen_open(
|
|||||||
|
|
||||||
if (RTEMS_BSD_SYSCALL_TRACE) {
|
if (RTEMS_BSD_SYSCALL_TRACE) {
|
||||||
printf("bsd: sys: open: path=%s opath=%s vn=%p cwd=%p"
|
printf("bsd: sys: open: path=%s opath=%s vn=%p cwd=%p"
|
||||||
" flags=%08x mode=%08x\n",
|
" flags=%08x mode=%08x isdir=%s\n",
|
||||||
path, opath,
|
path, opath,
|
||||||
creat ? NULL : rtems_bsd_libio_loc_to_vnode(&iop->pathinfo),
|
creat ? NULL : rtems_bsd_libio_loc_to_vnode(&iop->pathinfo),
|
||||||
fdp->fd_cdir, oflag, mode);
|
fdp->fd_cdir, oflag, mode, isdir ? "yes" : "no");
|
||||||
}
|
}
|
||||||
|
|
||||||
VREF(fdp->fd_cdir);
|
VREF(fdp->fd_cdir);
|
||||||
@ -1047,6 +1059,20 @@ rtems_bsd_sysgen_open(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rtems_bsd_sysgen_opendir(
|
||||||
|
rtems_libio_t *iop, const char *path, int oflag, mode_t mode)
|
||||||
|
{
|
||||||
|
return rtems_bsd_sysgen_open_node(iop, path, oflag, mode, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rtems_bsd_sysgen_open(
|
||||||
|
rtems_libio_t *iop, const char *path, int oflag, mode_t mode)
|
||||||
|
{
|
||||||
|
return rtems_bsd_sysgen_open_node(iop, path, oflag, mode, false);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
rtems_bsd_sysgen_close(rtems_libio_t *iop)
|
rtems_bsd_sysgen_close(rtems_libio_t *iop)
|
||||||
{
|
{
|
||||||
@ -1084,8 +1110,8 @@ rtems_bsd_sysgen_read(rtems_libio_t *iop, void *buffer, size_t count)
|
|||||||
ssize_t size = 0;
|
ssize_t size = 0;
|
||||||
|
|
||||||
if (RTEMS_BSD_SYSCALL_TRACE) {
|
if (RTEMS_BSD_SYSCALL_TRACE) {
|
||||||
printf("bsd: sys: read: %d -> %d: vn=%p len=%d\n",
|
printf("bsd: sys: read: %d -> %d: vn=%p vn-type=%d len=%d\n",
|
||||||
rtems_libio_iop_to_descriptor(iop), fd, vp, count);
|
rtems_libio_iop_to_descriptor(iop), fd, vp, vp->v_type, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (td == NULL) {
|
if (td == NULL) {
|
||||||
|
@ -335,6 +335,9 @@ rtems_bsd_vfs_eval_token(rtems_filesystem_eval_path_context_t *ctx, void *arg,
|
|||||||
|
|
||||||
if (*vpp != NULL) {
|
if (*vpp != NULL) {
|
||||||
rtems_filesystem_eval_path_clear_token(ctx);
|
rtems_filesystem_eval_path_clear_token(ctx);
|
||||||
|
if ((*vpp)->v_type != VDIR) {
|
||||||
|
currentloc->handlers = &rtems_bsd_sysgen_fileops;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return no_more_path ? RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE :
|
return no_more_path ? RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE :
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -279,7 +280,11 @@ test_walk_tree_unlink(walk_tree_dir state,
|
|||||||
static void
|
static void
|
||||||
test_setup(const char *base)
|
test_setup(const char *base)
|
||||||
{
|
{
|
||||||
|
struct DIR *ddir;
|
||||||
printf("test: nfs: setup\n");
|
printf("test: nfs: setup\n");
|
||||||
|
printf("test: nfs: opendir: %s\n", base);
|
||||||
|
rtems_test_errno_assert((ddir = opendir(base)) != NULL);
|
||||||
|
rtems_test_errno_assert(closedir(ddir) == 0);
|
||||||
printf("test: nfs: chdir: %s\n", base);
|
printf("test: nfs: chdir: %s\n", base);
|
||||||
rtems_test_errno_assert(chdir(base) == 0);
|
rtems_test_errno_assert(chdir(base) == 0);
|
||||||
printf("test: nfs: mkdir: %s\n", test_top);
|
printf("test: nfs: mkdir: %s\n", test_top);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user