Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2706 → Rev 2707

/trunk/uspace/app/tester/vfs/vfs1.c
30,11 → 30,12
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <vfs.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "../tester.h"
 
char *test_vfs1(bool quiet)
42,6 → 43,8
if (mount("tmpfs", "/", "nulldev0") != EOK)
return "Mount failed.\n";
 
if (mkdir("/mydir", 0) != 0)
return "mkdir() failed.\n";
 
DIR *dirp;
struct dirent *dp;
/trunk/uspace/lib/libc/include/sys/stat.h
0,0 → 1,45
/*
* Copyright (c) 2008 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup libc
* @{
*/
/** @file
*/
 
#ifndef LIBC_SYS_STAT_H_
#define LIBC_SYS_STAT_H_
 
#include <sys/types.h>
 
extern int mkdir(const char *, mode_t);
 
#endif
 
/** @}
*/
/trunk/uspace/lib/libc/include/sys/types.h
40,6 → 40,7
typedef unsigned long size_t;
typedef signed long ssize_t;
typedef long off_t;
typedef int mode_t;
 
#endif
 
/trunk/uspace/lib/libc/generic/vfs.c
37,6 → 37,8
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <async.h>
131,6 → 133,11
return _open(path, L_FILE, oflag);
}
 
int close(int fildes)
{
return 0; /* TODO */
}
 
ssize_t read(int fildes, void *buf, size_t nbyte)
{
int res;
209,7 → 216,7
off_t newoffs;
rc = async_req_3_1(vfs_phone, VFS_SEEK, fildes, offset, whence,
&newoffs);
(ipcarg_t)&newoffs);
 
async_serialize_end();
futex_up(&vfs_phone_futex);
274,9 → 281,35
return 0;
}
 
int close(int fildes)
int mkdir(const char *path, mode_t mode)
{
return 0; /* TODO */
int res;
ipcarg_t rc;
ipc_call_t answer;
aid_t req;
futex_down(&vfs_phone_futex);
async_serialize_start();
if (vfs_phone < 0) {
res = vfs_connect();
if (res < 0) {
async_serialize_end();
futex_up(&vfs_phone_futex);
return res;
}
}
req = async_send_1(vfs_phone, VFS_MKDIR, mode, &answer);
rc = ipc_data_write_start(vfs_phone, path, strlen(path));
if (rc != EOK) {
async_wait_for(req, NULL);
async_serialize_end();
futex_up(&vfs_phone_futex);
return (int) rc;
}
async_wait_for(req, &rc);
async_serialize_end();
futex_up(&vfs_phone_futex);
return EOK;
}
 
/** @}
/trunk/uspace/srv/fs/tmpfs/tmpfs_ops.c
211,7 → 211,42
static unsigned long create_node(tmpfs_dentry_t *dentry,
const char *component, int lflag)
{
return 0;
assert(dentry->type == TMPFS_DIRECTORY);
assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
 
tmpfs_dentry_t *node = malloc(sizeof(tmpfs_dentry_t));
if (!node)
return 0;
size_t len = strlen(component);
char *name = malloc(len + 1);
if (!name) {
free(node);
return 0;
}
strcpy(name, component);
 
tmpfs_dentry_initialize(node);
node->index = tmpfs_next_index++;
node->name = name;
node->parent = dentry;
if (lflag & L_DIRECTORY)
node->type = TMPFS_DIRECTORY;
else
node->type = TMPFS_FILE;
 
/* Insert the new node into the namespace. */
if (dentry->child) {
tmpfs_dentry_t *tmp = dentry->child;
while (tmp->sibling)
tmp = tmp->sibling;
tmp->sibling = node;
} else {
dentry->child = node;
}
 
/* Insert the new node into the dentry hash table. */
hash_table_insert(&dentries, &node->index, &node->dh_link);
return node->index;
}
 
static int destroy_component(tmpfs_dentry_t *dentry)
256,7 → 291,7
}
component[len++] = PLB_GET_CHAR(next);
next++; /* process next character */
if (next <= last)
if (next <= last)
continue;
}
 
279,7 → 314,7
}
unsigned long index = create_node(dcur,
component, lflag);
if (index) {
if (index > 0) {
ipc_answer_4(rid, EOK,
tmpfs_reg.fs_handle, dev_handle,
index, 0);
/trunk/uspace/srv/vfs/vfs.c
105,13 → 105,9
case VFS_TRUNCATE:
vfs_truncate(callid, &call);
break;
case VFS_UNMOUNT:
case VFS_CLOSE:
case VFS_UNLINK:
case VFS_RENAME:
case VFS_OPENDIR:
case VFS_READDIR:
case VFS_CLOSEDIR:
case VFS_MKDIR:
vfs_mkdir(callid, &call);
break;
default:
ipc_answer_0(callid, ENOTSUP);
break;
/trunk/uspace/srv/vfs/vfs_ops.c
115,9 → 115,7
return;
}
 
/*
* Deliver the file system name.
*/
/* Deliver the file system name. */
char fs_name[FS_NAME_MAXLEN + 1];
(void) ipc_data_write_finalize(callid, fs_name, size);
fs_name[size] = '\0';
132,9 → 130,7
return;
}
 
/*
* Now, we want the client to send us the mount point.
*/
/* Now, we want the client to send us the mount point. */
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
141,17 → 137,13
return;
}
 
/*
* Check whether size is reasonable wrt. the mount point.
*/
/* Check whether size is reasonable wrt. the mount point. */
if (size < 1 || size > MAX_PATH_LEN) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
/*
* Allocate buffer for the mount point data being received.
*/
/* Allocate buffer for the mount point data being received. */
uint8_t *buf;
buf = malloc(size);
if (!buf) {
160,9 → 152,7
return;
}
 
/*
* Deliver the mount point.
*/
/* Deliver the mount point. */
(void) ipc_data_write_finalize(callid, buf, size);
 
/*
186,22 → 176,16
return;
}
 
/*
* Finally, we need to resolve the path to the mountpoint.
*/
/* Finally, we need to resolve the path to the mountpoint. */
vfs_lookup_res_t mp_res;
futex_down(&rootfs_futex);
if (rootfs.fs_handle) {
/*
* We already have the root FS.
*/
/* We already have the root FS. */
rwlock_write_lock(&namespace_rwlock);
rc = vfs_lookup_internal(buf, size, L_DIRECTORY, &mp_res,
NULL);
if (rc != EOK) {
/*
* The lookup failed for some reason.
*/
/* The lookup failed for some reason. */
rwlock_write_unlock(&namespace_rwlock);
futex_up(&rootfs_futex);
vfs_node_put(mr_node); /* failed -> drop reference */
225,13 → 209,9
*/
rwlock_write_unlock(&namespace_rwlock);
} else {
/*
* We still don't have the root file system mounted.
*/
/* We still don't have the root file system mounted. */
if ((size == 1) && (buf[0] == '/')) {
/*
* For this simple, but important case, we are done.
*/
/* For this simple, but important case, we are done. */
rootfs = mr_res.triplet;
futex_up(&rootfs_futex);
free(buf);
347,9 → 327,7
*/
rwlock_read_lock(&namespace_rwlock);
 
/*
* The path is now populated and we can call vfs_lookup_internal().
*/
/* The path is now populated and we can call vfs_lookup_internal(). */
vfs_lookup_res_t lr;
rc = vfs_lookup_internal(path, len, lflag, &lr, NULL);
if (rc) {
359,9 → 337,7
return;
}
 
/*
* Path is no longer needed.
*/
/** Path is no longer needed. */
free(path);
 
vfs_node_t *node = vfs_node_get(&lr);
390,9 → 366,7
vfs_node_addref(node);
vfs_node_put(node);
 
/*
* Success! Return the new file descriptor to the client.
*/
/* Success! Return the new file descriptor to the client. */
ipc_answer_1(rid, EOK, fd);
}
 
411,9 → 385,7
 
int fd = IPC_GET_ARG1(*request);
 
/*
* Lookup the file structure corresponding to the file descriptor.
*/
/* Lookup the file structure corresponding to the file descriptor. */
vfs_file_t *file = vfs_file_get(fd);
if (!file) {
ipc_answer_0(rid, ENOENT);
453,9 → 425,7
 
int fs_phone = vfs_grab_phone(file->node->fs_handle);
/*
* Make a VFS_READ/VFS_WRITE request at the destination FS server.
*/
/* Make a VFS_READ/VFS_WRITE request at the destination FS server. */
aid_t msg;
ipc_call_t answer;
msg = async_send_3(fs_phone, IPC_GET_METHOD(*request),
471,16 → 441,12
 
vfs_release_phone(fs_phone);
 
/*
* Wait for reply from the FS server.
*/
/* Wait for reply from the FS server. */
ipcarg_t rc;
async_wait_for(msg, &rc);
size_t bytes = IPC_GET_ARG1(answer);
 
/*
* Unlock the VFS node.
*/
/* Unlock the VFS node. */
if (read)
rwlock_read_unlock(&file->node->contents_rwlock);
else {
489,9 → 455,7
rwlock_write_unlock(&file->node->contents_rwlock);
}
 
/*
* Update the position pointer and unlock the open file.
*/
/* Update the position pointer and unlock the open file. */
file->pos += bytes;
futex_up(&file->lock);
 
519,9 → 483,7
int whence = (int) IPC_GET_ARG3(*request);
 
 
/*
* Lookup the file structure corresponding to the file descriptor.
*/
/* Lookup the file structure corresponding to the file descriptor. */
vfs_file_t *file = vfs_file_get(fd);
if (!file) {
ipc_answer_0(rid, ENOENT);
581,8 → 543,9
 
rwlock_write_lock(&file->node->contents_rwlock);
int fs_phone = vfs_grab_phone(file->node->fs_handle);
rc = async_req_3_0(fs_phone, VFS_TRUNCATE, (ipcarg_t)file->node->dev_handle,
(ipcarg_t)file->node->index, (ipcarg_t)size);
rc = async_req_3_0(fs_phone, VFS_TRUNCATE,
(ipcarg_t)file->node->dev_handle, (ipcarg_t)file->node->index,
(ipcarg_t)size);
vfs_release_phone(fs_phone);
if (rc == EOK)
file->node->size = size;
592,6 → 555,48
ipc_answer_0(rid, rc);
}
 
void vfs_mkdir(ipc_callid_t rid, ipc_call_t *request)
{
int mode = IPC_GET_ARG1(*request);
size_t len;
 
ipc_callid_t callid;
 
if (!ipc_data_write_receive(&callid, &len)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
return;
}
 
/*
* Now we are on the verge of accepting the path.
*
* There is one optimization we could do in the future: copy the path
* directly into the PLB using some kind of a callback.
*/
char *path = malloc(len);
if (!path) {
ipc_answer_0(callid, ENOMEM);
ipc_answer_0(rid, ENOMEM);
return;
}
 
int rc;
if ((rc = ipc_data_write_finalize(callid, path, len))) {
ipc_answer_0(rid, rc);
free(path);
return;
}
rwlock_write_lock(&namespace_rwlock);
int lflag = L_DIRECTORY | L_CREATE | L_EXCLUSIVE;
rc = vfs_lookup_internal(path, len, lflag, NULL, NULL);
rwlock_write_unlock(&namespace_rwlock);
free(path);
ipc_answer_0(rid, rc);
}
 
/**
* @}
*/
/trunk/uspace/srv/vfs/vfs.h
56,6 → 56,7
VFS_OPENDIR,
VFS_READDIR,
VFS_CLOSEDIR,
VFS_MKDIR,
VFS_UNLINK,
VFS_MOUNT,
VFS_UNMOUNT,
261,6 → 262,7
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_mkdir(ipc_callid_t, ipc_call_t *);
 
#endif
 
/trunk/uspace/srv/vfs/vfs_lookup.c
57,6 → 57,7
* @param len Number of path characters pointed by path.
* @param lflag Flags to be used during lookup.
* @param result Empty structure where the lookup result will be stored.
* Can be NULL.
* @param altroot If non-empty, will be used instead of rootfs as the root
* of the whole VFS tree.
*
162,7 → 163,7
memset(plb, 0, cnt2);
futex_up(&plb_futex);
 
if (rc == EOK) {
if ((rc == EOK) && result) {
result->triplet.fs_handle = (int) IPC_GET_ARG1(answer);
result->triplet.dev_handle = (int) IPC_GET_ARG2(answer);
result->triplet.index = (int) IPC_GET_ARG3(answer);