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
This commit is contained in:
Ingo Weinhold 2008-03-29 23:57:34 +00:00
parent 3bef7d0252
commit 8c117a6d88
2 changed files with 40 additions and 22 deletions

View File

@ -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);

View File

@ -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);