2
* Copyright (c) 2007 Jakub Jermar
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
9
* - Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
* - The name of the author may not be used to endorse or promote products
15
* derived from this software without specific prior written permission.
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
* @brief Various operations on files have their home in this file.
44
#include <fibril_sync.h>
48
* This is a per-connection table of open files.
49
* Our assumption is that each client opens only one connection and therefore
50
* there is one table of open files per task. However, this may not be the case
51
* and the client can open more connections to VFS. In that case, there will be
52
* several tables and several file handle name spaces per task. Besides of this,
53
* the functionality will stay unchanged. So unless the client knows what it is
54
* doing, it should open one connection to VFS only.
56
* Allocation of the open files table is deferred until the client makes the
57
* first VFS_OPEN operation.
59
* This resource being per-connection and, in the first place, per-fibril, we
60
* don't need to protect it by a mutex.
62
fibril_local vfs_file_t **files = NULL;
64
/** Initialize the table of open files. */
65
bool vfs_files_init(void)
68
files = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *));
71
memset(files, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));
76
/** Allocate a file descriptor.
78
* @return First available file descriptor or a negative error
81
int vfs_fd_alloc(void)
83
if (!vfs_files_init())
87
for (i = 0; i < MAX_OPEN_FILES; i++) {
89
files[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));
93
memset(files[i], 0, sizeof(vfs_file_t));
94
fibril_mutex_initialize(&files[i]->lock);
95
vfs_file_addref(files[i]);
103
/** Release file descriptor.
105
* @param fd File descriptor being released.
107
* @return EOK on success or EBADF if fd is an invalid file
110
int vfs_fd_free(int fd)
112
if (!vfs_files_init())
115
if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (files[fd] == NULL))
118
vfs_file_delref(files[fd]);
124
/** Increment reference count of VFS file structure.
126
* @param file File structure that will have reference count
129
void vfs_file_addref(vfs_file_t *file)
132
* File structures are per-connection, so no-one, except the current
133
* fibril, should have a reference to them. This is the reason we don't
134
* do any synchronization here.
139
/** Decrement reference count of VFS file structure.
141
* @param file File structure that will have reference count
144
void vfs_file_delref(vfs_file_t *file)
146
if (file->refcnt-- == 1) {
148
* Lost the last reference to a file, need to drop our reference
149
* to the underlying VFS node.
151
vfs_node_delref(file->node);
156
/** Find VFS file structure for a given file descriptor.
158
* @param fd File descriptor.
160
* @return VFS file structure corresponding to fd.
162
vfs_file_t *vfs_file_get(int fd)
164
if (!vfs_files_init())
167
if ((fd >= 0) && (fd < MAX_OPEN_FILES))