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:
@@ -115,6 +115,9 @@ status_t vfs_unmount(dev_t mountID, uint32 flags);
|
|||||||
status_t vfs_disconnect_vnode(dev_t mountID, ino_t vnodeID);
|
status_t vfs_disconnect_vnode(dev_t mountID, ino_t vnodeID);
|
||||||
void vfs_free_unused_vnodes(int32 level);
|
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 */
|
/* special module convenience call */
|
||||||
status_t vfs_get_module_path(const char *basePath, const char *moduleName,
|
status_t vfs_get_module_path(const char *basePath, const char *moduleName,
|
||||||
char *pathBuffer, size_t bufferSize);
|
char *pathBuffer, size_t bufferSize);
|
||||||
|
|||||||
@@ -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_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_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,
|
static status_t vnode_path_to_vnode(struct vnode *vnode, char *path,
|
||||||
bool traverseLeafLink, int count, struct vnode **_vnode, ino_t *_parentID, int *_type);
|
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);
|
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,
|
/*! Finds the full path to the file that contains the module \a moduleName,
|
||||||
puts it into \a pathBuffer, and returns B_OK for success.
|
puts it into \a pathBuffer, and returns B_OK for success.
|
||||||
If \a pathBuffer was too small, it returns \c B_BUFFER_OVERFLOW,
|
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;
|
stat = &completeStat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path) {
|
status = vfs_read_stat(fd, path, traverseLeafLink, stat, true);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status == B_OK && originalStat != NULL)
|
if (status == B_OK && originalStat != NULL)
|
||||||
memcpy(originalStat, stat, statSize);
|
memcpy(originalStat, stat, statSize);
|
||||||
|
|||||||
Reference in New Issue
Block a user