From 8c117a6d887caefe7aacdddb08bb6557d100f106 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sat, 29 Mar 2008 23:57:34 +0000 Subject: [PATCH] Added function vfs_read_stat() that also allows for stat()ing files in the user IO context from within the kernel. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24667 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/vfs.h | 3 ++ src/system/kernel/fs/vfs.cpp | 59 ++++++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/headers/private/kernel/vfs.h b/headers/private/kernel/vfs.h index ce3a18907a..ac7628de24 100644 --- a/headers/private/kernel/vfs.h +++ b/headers/private/kernel/vfs.h @@ -115,6 +115,9 @@ status_t vfs_unmount(dev_t mountID, uint32 flags); status_t vfs_disconnect_vnode(dev_t mountID, ino_t vnodeID); void vfs_free_unused_vnodes(int32 level); +status_t vfs_read_stat(int fd, const char *path, bool traverseLeafLink, + struct stat *stat, bool kernel); + /* special module convenience call */ status_t vfs_get_module_path(const char *basePath, const char *moduleName, char *pathBuffer, size_t bufferSize); diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 85ede2f8ac..8f8d2777ab 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -241,6 +241,9 @@ static status_t common_ioctl(struct file_descriptor *, ulong, void *buf, size_t static status_t common_read_stat(struct file_descriptor *, struct stat *); static status_t common_write_stat(struct file_descriptor *, const struct stat *, int statMask); +static status_t common_path_read_stat(int fd, char *path, bool traverseLeafLink, + struct stat *stat, bool kernel); + static status_t vnode_path_to_vnode(struct vnode *vnode, char *path, bool traverseLeafLink, int count, struct vnode **_vnode, ino_t *_parentID, int *_type); static status_t dir_vnode_to_path(struct vnode *vnode, char *buffer, size_t bufferSize); @@ -3302,6 +3305,39 @@ vfs_get_fs_node_from_path(dev_t mountID, const char *path, bool kernel, } +status_t +vfs_read_stat(int fd, const char *path, bool traverseLeafLink, + struct stat *stat, bool kernel) +{ + status_t status; + + if (path) { + // path given: get the stat of the node referred to by (fd, path) + KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1); + if (pathBuffer.InitCheck() != B_OK) + return B_NO_MEMORY; + + status = common_path_read_stat(fd, pathBuffer.LockBuffer(), + traverseLeafLink, stat, kernel); + } else { + // no path given: get the FD and use the FD operation + struct file_descriptor *descriptor + = get_fd(get_current_io_context(kernel), fd); + if (descriptor == NULL) + return B_FILE_ERROR; + + if (descriptor->ops->fd_read_stat) + status = descriptor->ops->fd_read_stat(descriptor, stat); + else + status = EOPNOTSUPP; + + put_fd(descriptor); + } + + return status; +} + + /*! Finds the full path to the file that contains the module \a moduleName, puts it into \a pathBuffer, and returns B_OK for success. If \a pathBuffer was too small, it returns \c B_BUFFER_OVERFLOW, @@ -6910,28 +6946,7 @@ _kern_read_stat(int fd, const char *path, bool traverseLeafLink, stat = &completeStat; } - if (path) { - // path given: get the stat of the node referred to by (fd, path) - KPath pathBuffer(path, false, B_PATH_NAME_LENGTH + 1); - if (pathBuffer.InitCheck() != B_OK) - return B_NO_MEMORY; - - status = common_path_read_stat(fd, pathBuffer.LockBuffer(), - traverseLeafLink, stat, true); - } else { - // no path given: get the FD and use the FD operation - struct file_descriptor *descriptor - = get_fd(get_current_io_context(true), fd); - if (descriptor == NULL) - return B_FILE_ERROR; - - if (descriptor->ops->fd_read_stat) - status = descriptor->ops->fd_read_stat(descriptor, stat); - else - status = EOPNOTSUPP; - - put_fd(descriptor); - } + status = vfs_read_stat(fd, path, traverseLeafLink, stat, true); if (status == B_OK && originalStat != NULL) memcpy(originalStat, stat, statSize);