Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4584 → Rev 4585

/trunk/uspace/lib/libc/include/ipc/vfs.h
63,6 → 63,7
VFS_IN_WRITE,
VFS_IN_SEEK,
VFS_IN_TRUNCATE,
VFS_IN_FSTAT,
VFS_IN_CLOSE,
VFS_IN_MOUNT,
VFS_IN_UNMOUNT,
72,6 → 73,7
VFS_IN_MKDIR,
VFS_IN_UNLINK,
VFS_IN_RENAME,
VFS_IN_STAT,
VFS_IN_NODE
} vfs_in_request_t;
 
86,6 → 88,7
VFS_OUT_UNMOUNT,
VFS_OUT_DEVICE,
VFS_OUT_SYNC,
VFS_OUT_STAT,
VFS_OUT_LOOKUP,
VFS_OUT_DESTROY,
VFS_OUT_LAST
/trunk/uspace/lib/libc/include/sys/stat.h
36,7 → 36,25
#define LIBC_SYS_STAT_H_
 
#include <sys/types.h>
#include <bool.h>
#include <ipc/vfs.h>
#include <ipc/devmap.h>
 
struct stat {
fs_handle_t fs_handle;
dev_handle_t dev_handle;
fs_index_t index;
unsigned lnkcnt;
bool is_file;
off_t size;
union {
struct {
dev_handle_t device;
} devfs_stat;
};
};
 
extern int fstat(int, struct stat *);
extern int mkdir(const char *, mode_t);
 
#endif
/trunk/uspace/lib/libc/generic/vfs/vfs.c
38,8 → 38,8
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <stdio.h>
#include <sys/types.h>
#include <ipc/ipc.h>
#include <ipc/services.h>
314,48 → 314,6
return -1;
}
 
int fd_phone(int fildes)
{
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
ipcarg_t device;
ipcarg_t rc = async_req_1_1(vfs_phone, VFS_IN_DEVICE, fildes, &device);
async_serialize_end();
futex_up(&vfs_phone_futex);
if (rc != EOK)
return -1;
return devmap_device_connect((dev_handle_t) device, 0);
}
 
int fd_node(int fildes, fdi_node_t *node)
{
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
ipcarg_t fs_handle;
ipcarg_t dev_handle;
ipcarg_t index;
ipcarg_t rc = async_req_1_3(vfs_phone, VFS_IN_NODE, fildes, &fs_handle,
&dev_handle, &index);
async_serialize_end();
futex_up(&vfs_phone_futex);
if (rc == EOK) {
node->fs_handle = (fs_handle_t) fs_handle;
node->dev_handle = (dev_handle_t) dev_handle;
node->index = (fs_index_t) index;
}
return rc;
}
 
int fsync(int fildes)
{
futex_down(&vfs_phone_futex);
405,6 → 363,31
return (int) rc;
}
 
int fstat(int fildes, struct stat *stat)
{
ipcarg_t rc;
ipc_call_t answer;
aid_t req;
 
futex_down(&vfs_phone_futex);
async_serialize_start();
vfs_connect();
req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
rc = ipc_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat));
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
futex_up(&vfs_phone_futex);
return (ssize_t) rc;
}
async_wait_for(req, &rc);
async_serialize_end();
futex_up(&vfs_phone_futex);
 
return rc;
}
 
DIR *opendir(const char *dirname)
{
DIR *dirp = malloc(sizeof(DIR));
598,5 → 581,34
return buf;
}
 
int fd_phone(int fildes)
{
struct stat stat;
int rc;
 
rc = fstat(fildes, &stat);
 
if (!stat.devfs_stat.device)
return -1;
return devmap_device_connect(stat.devfs_stat.device, 0);
}
 
int fd_node(int fildes, fdi_node_t *node)
{
struct stat stat;
int rc;
 
rc = fstat(fildes, &stat);
if (rc == EOK) {
node->fs_handle = stat.fs_handle;
node->dev_handle = stat.dev_handle;
node->index = stat.index;
}
return rc;
}
 
/** @}
*/
/trunk/uspace/srv/fs/devfs/devfs.c
79,8 → 79,8
case VFS_OUT_OPEN_NODE:
devfs_open_node(callid, &call);
break;
case VFS_OUT_DEVICE:
devfs_device(callid, &call);
case VFS_OUT_STAT:
devfs_stat(callid, &call);
break;
case VFS_OUT_READ:
devfs_read(callid, &call);
/trunk/uspace/srv/fs/devfs/devfs_ops.c
43,6 → 43,7
#include <libfs.h>
#include <fibril_sync.h>
#include <adt/hash_table.h>
#include <sys/stat.h>
#include "devfs.h"
#include "devfs_ops.h"
 
277,10 → 278,35
ipc_answer_3(rid, EOK, 0, 1, L_FILE);
}
 
void devfs_device(ipc_callid_t rid, ipc_call_t *request)
void devfs_stat(ipc_callid_t rid, ipc_call_t *request)
{
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
ipc_callid_t callid;
size_t size;
if (!ipc_data_read_receive(&callid, &size) ||
size < sizeof(struct stat)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
struct stat *stat = malloc(sizeof(struct stat));
if (!stat) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
memset(stat, 0, sizeof(struct stat));
 
stat->fs_handle = devfs_reg.fs_handle;
stat->dev_handle = dev_handle;
stat->index = index;
stat->lnkcnt = 1;
stat->is_file = (index != 0);
stat->size = 0;
if (index != 0) {
unsigned long key[] = {
[DEVICES_KEY_HANDLE] = (unsigned long) index
288,16 → 314,15
fibril_mutex_lock(&devices_mutex);
link_t *lnk = hash_table_find(&devices, key);
if (lnk == NULL) {
fibril_mutex_unlock(&devices_mutex);
ipc_answer_0(rid, ENOENT);
return;
}
if (lnk != NULL)
stat->devfs_stat.device = (dev_handle_t)index;
fibril_mutex_unlock(&devices_mutex);
ipc_answer_1(rid, EOK, (ipcarg_t) index);
} else
ipc_answer_0(rid, ENOTSUP);
}
 
ipc_data_read_finalize(callid, stat, sizeof(struct stat));
ipc_answer_0(rid, EOK);
 
free(stat);
}
 
void devfs_read(ipc_callid_t rid, ipc_call_t *request)
/trunk/uspace/srv/fs/devfs/devfs_ops.h
42,7 → 42,7
extern void devfs_mount(ipc_callid_t, ipc_call_t *);
extern void devfs_lookup(ipc_callid_t, ipc_call_t *);
extern void devfs_open_node(ipc_callid_t, ipc_call_t *);
extern void devfs_device(ipc_callid_t, ipc_call_t *);
extern void devfs_stat(ipc_callid_t, ipc_call_t *);
extern void devfs_sync(ipc_callid_t, ipc_call_t *);
extern void devfs_read(ipc_callid_t, ipc_call_t *);
extern void devfs_write(ipc_callid_t, ipc_call_t *);
/trunk/uspace/srv/fs/tmpfs/tmpfs.h
86,10 → 86,10
extern void tmpfs_read(ipc_callid_t, ipc_call_t *);
extern void tmpfs_write(ipc_callid_t, ipc_call_t *);
extern void tmpfs_truncate(ipc_callid_t, ipc_call_t *);
extern void tmpfs_stat(ipc_callid_t, ipc_call_t *);
extern void tmpfs_close(ipc_callid_t, ipc_call_t *);
extern void tmpfs_destroy(ipc_callid_t, ipc_call_t *);
extern void tmpfs_open_node(ipc_callid_t, ipc_call_t *);
extern void tmpfs_device(ipc_callid_t, ipc_call_t *);
extern void tmpfs_sync(ipc_callid_t, ipc_call_t *);
 
extern bool tmpfs_restore(dev_handle_t);
/trunk/uspace/srv/fs/tmpfs/tmpfs.c
125,8 → 125,8
case VFS_OUT_OPEN_NODE:
tmpfs_open_node(callid, &call);
break;
case VFS_OUT_DEVICE:
tmpfs_device(callid, &call);
case VFS_OUT_STAT:
tmpfs_stat(callid, &call);
break;
case VFS_OUT_SYNC:
tmpfs_sync(callid, &call);
/trunk/uspace/srv/fs/tmpfs/tmpfs_ops.c
628,7 → 628,7
libfs_open_node(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
}
 
void tmpfs_device(ipc_callid_t rid, ipc_call_t *request)
void tmpfs_stat(ipc_callid_t rid, ipc_call_t *request)
{
ipc_answer_0(rid, ENOTSUP);
}
/trunk/uspace/srv/fs/fat/fat.h
207,10 → 207,11
extern void fat_read(ipc_callid_t, ipc_call_t *);
extern void fat_write(ipc_callid_t, ipc_call_t *);
extern void fat_truncate(ipc_callid_t, ipc_call_t *);
extern void fat_stat(ipc_callid_t, ipc_call_t *);
extern void fat_close(ipc_callid_t, ipc_call_t *);
extern void fat_destroy(ipc_callid_t, ipc_call_t *);
extern void fat_open_node(ipc_callid_t, ipc_call_t *);
extern void fat_device(ipc_callid_t, ipc_call_t *);
extern void fat_stat(ipc_callid_t, ipc_call_t *);
extern void fat_sync(ipc_callid_t, ipc_call_t *);
 
extern fat_idx_t *fat_idx_get_new(dev_handle_t);
/trunk/uspace/srv/fs/fat/fat.c
109,6 → 109,9
case VFS_OUT_TRUNCATE:
fat_truncate(callid, &call);
break;
case VFS_OUT_STAT:
fat_stat(callid, &call);
break;
case VFS_OUT_CLOSE:
fat_close(callid, &call);
break;
118,9 → 121,6
case VFS_OUT_OPEN_NODE:
fat_open_node(callid, &call);
break;
case VFS_OUT_DEVICE:
fat_device(callid, &call);
break;
case VFS_OUT_SYNC:
fat_sync(callid, &call);
break;
/trunk/uspace/srv/fs/fat/fat_ops.c
1202,7 → 1202,7
libfs_open_node(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
}
 
void fat_device(ipc_callid_t rid, ipc_call_t *request)
void fat_stat(ipc_callid_t rid, ipc_call_t *request)
{
ipc_answer_0(rid, ENOTSUP);
}
/trunk/uspace/srv/vfs/vfs.c
107,6 → 107,12
case VFS_IN_TRUNCATE:
vfs_truncate(callid, &call);
break;
case VFS_IN_FSTAT:
vfs_fstat(callid, &call);
break;
case VFS_IN_STAT:
vfs_stat(callid, &call);
break;
case VFS_IN_MKDIR:
vfs_mkdir(callid, &call);
break;
116,15 → 122,9
case VFS_IN_RENAME:
vfs_rename(callid, &call);
break;
case VFS_IN_DEVICE:
vfs_device(callid, &call);
break;
case VFS_IN_SYNC:
vfs_sync(callid, &call);
break;
case VFS_IN_NODE:
vfs_node(callid, &call);
break;
default:
ipc_answer_0(callid, ENOTSUP);
break;
/trunk/uspace/srv/vfs/vfs_ops.c
641,55 → 641,6
ipc_answer_1(rid, EOK, fd);
}
 
void vfs_node(ipc_callid_t rid, ipc_call_t *request)
{
int fd = IPC_GET_ARG1(*request);
/* Lookup the file structure corresponding to the file descriptor. */
vfs_file_t *file = vfs_file_get(fd);
if (!file) {
ipc_answer_0(rid, ENOENT);
return;
}
ipc_answer_3(rid, EOK, file->node->fs_handle, file->node->dev_handle,
file->node->index);
}
 
void vfs_device(ipc_callid_t rid, ipc_call_t *request)
{
int fd = IPC_GET_ARG1(*request);
/* Lookup the file structure corresponding to the file descriptor. */
vfs_file_t *file = vfs_file_get(fd);
if (!file) {
ipc_answer_0(rid, ENOENT);
return;
}
/*
* Lock the open file structure so that no other thread can manipulate
* the same open file at a time.
*/
fibril_mutex_lock(&file->lock);
int fs_phone = vfs_grab_phone(file->node->fs_handle);
/* Make a VFS_OUT_DEVICE request at the destination FS server. */
aid_t msg;
ipc_call_t answer;
msg = async_send_2(fs_phone, VFS_OUT_DEVICE, file->node->dev_handle,
file->node->index, &answer);
 
/* Wait for reply from the FS server. */
ipcarg_t rc;
async_wait_for(msg, &rc);
 
vfs_release_phone(fs_phone);
fibril_mutex_unlock(&file->lock);
ipc_answer_1(rid, EOK, IPC_GET_ARG1(answer));
}
 
void vfs_sync(ipc_callid_t rid, ipc_call_t *request)
{
int fd = IPC_GET_ARG1(*request);
976,6 → 927,44
ipc_answer_0(rid, (ipcarg_t)rc);
}
 
void vfs_fstat(ipc_callid_t rid, ipc_call_t *request)
{
int fd = IPC_GET_ARG1(*request);
size_t size = IPC_GET_ARG2(*request);
ipcarg_t rc;
 
vfs_file_t *file = vfs_file_get(fd);
if (!file) {
ipc_answer_0(rid, ENOENT);
return;
}
 
ipc_callid_t callid;
if (!ipc_data_read_receive(&callid, NULL)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
fibril_mutex_lock(&file->lock);
 
int fs_phone = vfs_grab_phone(file->node->fs_handle);
aid_t msg;
msg = async_send_3(fs_phone, VFS_OUT_STAT, file->node->dev_handle,
file->node->index, true, NULL);
ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
async_wait_for(msg, &rc);
vfs_release_phone(fs_phone);
 
fibril_mutex_unlock(&file->lock);
ipc_answer_0(rid, rc);
}
 
void vfs_stat(ipc_callid_t rid, ipc_call_t *request)
{
}
 
void vfs_mkdir(ipc_callid_t rid, ipc_call_t *request)
{
int mode = IPC_GET_ARG1(*request);
/trunk/uspace/srv/vfs/vfs.h
198,14 → 198,15
extern void vfs_mount(ipc_callid_t, ipc_call_t *);
extern void vfs_open(ipc_callid_t, ipc_call_t *);
extern void vfs_open_node(ipc_callid_t, ipc_call_t *);
extern void vfs_device(ipc_callid_t, ipc_call_t *);
extern void vfs_sync(ipc_callid_t, ipc_call_t *);
extern void vfs_node(ipc_callid_t, ipc_call_t *);
extern void vfs_close(ipc_callid_t, ipc_call_t *);
extern void vfs_read(ipc_callid_t, ipc_call_t *);
extern void vfs_write(ipc_callid_t, ipc_call_t *);
extern void vfs_seek(ipc_callid_t, ipc_call_t *);
extern void vfs_truncate(ipc_callid_t, ipc_call_t *);
extern void vfs_fstat(ipc_callid_t, ipc_call_t *);
extern void vfs_fstat(ipc_callid_t, ipc_call_t *);
extern void vfs_stat(ipc_callid_t, ipc_call_t *);
extern void vfs_mkdir(ipc_callid_t, ipc_call_t *);
extern void vfs_unlink(ipc_callid_t, ipc_call_t *);
extern void vfs_rename(ipc_callid_t, ipc_call_t *);