Changeset 8f9ede5 in mainline
- Timestamp:
- 2007-09-20T17:01:52Z (17 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a4627c4
- Parents:
- 6675c70
- Location:
- uspace/srv/vfs
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/Makefile
r6675c70 r8f9ede5 42 42 OUTPUT = vfs 43 43 SOURCES = \ 44 vfs.c 44 vfs.c \ 45 vfs_register.c 45 46 46 47 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) -
uspace/srv/vfs/vfs.c
r6675c70 r8f9ede5 41 41 #include <errno.h> 42 42 #include <stdio.h> 43 #include <stdlib.h>44 #include <string.h>45 #include <ctype.h>46 43 #include <bool.h> 47 #include <futex.h>48 44 #include <libadt/list.h> 49 45 #include "vfs.h" 50 46 51 52 47 #define dprintf(...) printf(__VA_ARGS__) 53 54 atomic_t fs_head_futex = FUTEX_INITIALIZER;55 link_t fs_head;56 57 /** Verify the VFS info structure.58 *59 * @param info Info structure to be verified.60 *61 * @return Non-zero if the info structure is sane, zero otherwise.62 */63 static bool vfs_info_sane(vfs_info_t *info)64 {65 int i;66 67 /*68 * Check if the name is non-empty and is composed solely of ASCII69 * characters [a-z]+[a-z0-9_-]*.70 */71 if (!islower(info->name[0])) {72 dprintf("The name doesn't start with a lowercase character.\n");73 return false;74 }75 for (i = 1; i < FS_NAME_MAXLEN; i++) {76 if (!(islower(info->name[i]) || isdigit(info->name[i])) &&77 (info->name[i] != '-') && (info->name[i] != '_')) {78 if (info->name[i] == '\0') {79 break;80 } else {81 dprintf("The name contains illegal "82 "characters.\n");83 return false;84 }85 }86 }87 88 89 /*90 * Check if the FS implements mandatory VFS operations.91 */92 if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_REGISTER)] != VFS_OP_DEFINED) {93 dprintf("Operation VFS_REGISTER not defined by the client.\n");94 return false;95 }96 if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_MOUNT)] != VFS_OP_DEFINED) {97 dprintf("Operation VFS_MOUNT not defined by the client.\n");98 return false;99 }100 if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_UNMOUNT)] != VFS_OP_DEFINED) {101 dprintf("Operation VFS_UNMOUNT not defined by the client.\n");102 return false;103 }104 if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_LOOKUP)] != VFS_OP_DEFINED) {105 dprintf("Operation VFS_LOOKUP not defined by the client.\n");106 return false;107 }108 if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_OPEN)] != VFS_OP_DEFINED) {109 dprintf("Operation VFS_OPEN not defined by the client.\n");110 return false;111 }112 if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_CLOSE)] != VFS_OP_DEFINED) {113 dprintf("Operation VFS_CLOSE not defined by the client.\n");114 return false;115 }116 if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_READ)] != VFS_OP_DEFINED) {117 dprintf("Operation VFS_READ not defined by the client.\n");118 return false;119 }120 121 /*122 * Check if each operation is either not defined, defined or default.123 */124 for (i = VFS_FIRST; i < VFS_LAST; i++) {125 if ((info->ops[IPC_METHOD_TO_VFS_OP(i)] != VFS_OP_NULL) &&126 (info->ops[IPC_METHOD_TO_VFS_OP(i)] != VFS_OP_DEFAULT) &&127 (info->ops[IPC_METHOD_TO_VFS_OP(i)] != VFS_OP_DEFINED)) {128 dprintf("Operation info not understood.\n");129 return false;130 }131 }132 return true;133 }134 135 /** VFS_REGISTER protocol function.136 *137 * @param rid Hash of the call with the request.138 * @param request Call structure with the request.139 */140 static void vfs_register(ipc_callid_t rid, ipc_call_t *request)141 {142 ipc_callid_t callid;143 ipc_call_t call;144 int rc;145 size_t size;146 147 dprintf("Processing VFS_REGISTER request received from %p.\n",148 request->in_phone_hash);149 150 /*151 * The first call has to be IPC_M_DATA_SEND in which we receive the152 * VFS info structure from the client FS.153 */154 if (!ipc_data_receive(&callid, &call, NULL, &size)) {155 /*156 * The client doesn't obey the same protocol as we do.157 */158 dprintf("Receiving of VFS info failed.\n");159 ipc_answer_fast(callid, EINVAL, 0, 0);160 ipc_answer_fast(rid, EINVAL, 0, 0);161 return;162 }163 164 dprintf("VFS info received, size = %d\n", size);165 166 /*167 * We know the size of the VFS info structure. See if the client168 * understands this easy concept too.169 */170 if (size != sizeof(vfs_info_t)) {171 /*172 * The client is sending us something, which cannot be173 * the info structure.174 */175 dprintf("Received VFS info has bad size.\n");176 ipc_answer_fast(callid, EINVAL, 0, 0);177 ipc_answer_fast(rid, EINVAL, 0, 0);178 return;179 }180 fs_info_t *fs_info;181 182 /*183 * Allocate and initialize a buffer for the fs_info structure.184 */185 fs_info = (fs_info_t *) malloc(sizeof(fs_info_t));186 if (!fs_info) {187 dprintf("Could not allocate memory for FS info.\n");188 ipc_answer_fast(callid, ENOMEM, 0, 0);189 ipc_answer_fast(rid, ENOMEM, 0, 0);190 return;191 }192 link_initialize(&fs_info->fs_link);193 194 rc = ipc_data_deliver(callid, &call, &fs_info->vfs_info, size);195 if (rc != EOK) {196 dprintf("Failed to deliver the VFS info into our AS, rc=%d.\n",197 rc);198 free(fs_info);199 ipc_answer_fast(callid, rc, 0, 0);200 ipc_answer_fast(rid, rc, 0, 0);201 return;202 }203 204 dprintf("VFS info delivered.\n");205 206 if (!vfs_info_sane(&fs_info->vfs_info)) {207 free(fs_info);208 ipc_answer_fast(callid, EINVAL, 0, 0);209 ipc_answer_fast(rid, EINVAL, 0, 0);210 return;211 }212 213 futex_down(&fs_head_futex);214 215 /*216 * Check for duplicit registrations.217 */218 link_t *cur;219 for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {220 fs_info_t *fi = list_get_instance(cur, fs_info_t,221 fs_link);222 /* TODO: replace strcmp with strncmp once we have it */223 if (strcmp(fs_info->vfs_info.name, fi->vfs_info.name) == 0) {224 /*225 * We already register a fs like this.226 */227 dprintf("FS is already registered.\n");228 futex_up(&fs_head_futex);229 free(fs_info);230 ipc_answer_fast(callid, EEXISTS, 0, 0);231 ipc_answer_fast(rid, EEXISTS, 0, 0);232 return;233 }234 }235 236 /*237 * Add fs_info to the list of registered FS's.238 */239 dprintf("Adding FS into the registered list.\n");240 list_append(&fs_info->fs_link, &fs_head);241 242 /*243 * ACK receiving a properly formatted, non-duplicit vfs_info.244 */245 ipc_answer_fast(callid, EOK, 0, 0);246 247 /*248 * Now we want the client to send us the IPC_M_CONNECT_TO_ME call so249 * that a callback connection is created and we have a phone through250 * which to forward VFS requests to it.251 */252 callid = async_get_call(&call);253 if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) {254 dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call));255 list_remove(&fs_info->fs_link);256 futex_up(&fs_head_futex);257 free(fs_info);258 ipc_answer_fast(callid, EINVAL, 0, 0);259 ipc_answer_fast(rid, EINVAL, 0, 0);260 return;261 }262 fs_info->phone = IPC_GET_ARG3(call);263 ipc_answer_fast(callid, EOK, 0, 0);264 265 dprintf("Callback connection to FS created.\n");266 267 futex_up(&fs_head_futex);268 269 /*270 * That was it. The FS has been registered.271 */272 ipc_answer_fast(rid, EOK, 0, 0);273 dprintf("\"%s\" filesystem successfully registered.\n",274 fs_info->vfs_info.name);275 }276 48 277 49 static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall) -
uspace/srv/vfs/vfs.h
r6675c70 r8f9ede5 36 36 #include <ipc/ipc.h> 37 37 #include <libadt/list.h> 38 39 #define dprintf(...) printf(__VA_ARGS__) 38 40 39 41 #define VFS_FIRST FIRST_USER_METHOD … … 89 91 } fs_info_t; 90 92 93 extern link_t fs_head; 94 95 extern void vfs_register(ipc_callid_t rid, ipc_call_t *request); 96 91 97 #endif 92 98
Note:
See TracChangeset
for help on using the changeset viewer.