Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2683 → Rev 2684

/trunk/uspace/srv/vfs/vfs.c
99,10 → 99,12
case VFS_WRITE:
vfs_write(callid, &call);
break;
case VFS_SEEK:
vfs_seek(callid, &call);
break;
case VFS_UNMOUNT:
case VFS_CREATE:
case VFS_CLOSE:
case VFS_SEEK:
case VFS_UNLINK:
case VFS_RENAME:
default:
/trunk/uspace/srv/vfs/vfs.h
135,6 → 135,7
VFS_TRIPLET; /**< Identity of the node. */
unsigned refcnt; /**< Usage counter. */
link_t nh_link; /**< Node hash-table link. */
size_t size; /**< Cached size of the file. */
 
/**
* Holding this rwlock prevents modifications of the node's contents.
210,6 → 211,7
extern void vfs_open(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 *);
 
#endif
 
/trunk/uspace/srv/vfs/vfs_rdwr.c
40,6 → 40,7
#include <async.h>
#include <errno.h>
#include <rwlock.h>
#include <unistd.h>
 
static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read)
{
155,6 → 156,60
vfs_rdwr(rid, request, false);
}
 
void vfs_seek(ipc_callid_t rid, ipc_call_t *request)
{
int fd = (int) IPC_GET_ARG1(*request);
off_t off = (off_t) IPC_GET_ARG2(*request);
int whence = (int) IPC_GET_ARG3(*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;
}
 
off_t newpos;
futex_down(&file->lock);
if (whence == SEEK_SET) {
file->pos = off;
futex_up(&file->lock);
ipc_answer_1(rid, EOK, off);
return;
}
if (whence == SEEK_CUR) {
if (file->pos + off < file->pos) {
futex_up(&file->lock);
ipc_answer_0(rid, EOVERFLOW);
return;
}
file->pos += off;
newpos = file->pos;
futex_up(&file->lock);
ipc_answer_1(rid, EOK, newpos);
return;
}
if (whence == SEEK_END) {
rwlock_reader_lock(&file->node->contents_rwlock);
size_t size = file->node->size;
rwlock_reader_unlock(&file->node->contents_rwlock);
if (size + off < size) {
futex_up(&file->lock);
ipc_answer_0(rid, EOVERFLOW);
return;
}
newpos = size + off;
futex_up(&file->lock);
ipc_answer_1(rid, EOK, newpos);
return;
}
futex_up(&file->lock);
ipc_answer_0(rid, EINVAL);
}
 
/**
* @}
*/