- Timestamp:
- 2011-07-29T14:47:52Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 00c2de63, 1814ee4d, ffff746
- Parents:
- 9350bfdd (diff), f5d51de (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- uspace
- Files:
-
- 13 added
- 3 deleted
- 51 edited
- 2 moved
-
app/bdsh/cmds/modules/cp/cp.c (modified) (2 diffs)
-
app/bdsh/cmds/modules/ls/ls.c (modified) (1 diff)
-
app/bdsh/compl.c (modified) (1 diff)
-
app/bdsh/exec.c (modified) (1 diff)
-
app/bdsh/input.c (modified) (1 diff)
-
app/init/init.c (modified) (1 diff)
-
app/taskdump/elf_core.c (modified) (14 diffs)
-
app/taskdump/include/elf.h (deleted)
-
app/taskdump/include/elf_core.h (modified) (1 diff)
-
app/taskdump/include/symtab.h (modified) (1 diff)
-
app/taskdump/symtab.c (modified) (8 diffs)
-
app/taskdump/taskdump.c (modified) (4 diffs)
-
drv/bus/usb/usbmast/bo_trans.c (modified) (7 diffs)
-
drv/bus/usb/usbmast/bo_trans.h (modified) (1 diff)
-
drv/bus/usb/usbmast/cmdw.h (modified) (1 diff)
-
drv/bus/usb/usbmast/scsi_ms.c (modified) (11 diffs)
-
lib/block/libblock.c (modified) (11 diffs)
-
lib/c/Makefile (modified) (3 diffs)
-
lib/c/arch/abs32le/include/elf_linux.h (added)
-
lib/c/arch/amd64/include/elf_linux.h (added)
-
lib/c/arch/arm32/include/elf_linux.h (added)
-
lib/c/arch/ia32/include/elf_linux.h (added)
-
lib/c/arch/ia64/include/elf_linux.h (added)
-
lib/c/arch/mips32/include/elf_linux.h (added)
-
lib/c/arch/mips32eb/include/elf_linux.h (added)
-
lib/c/arch/mips64/include/elf_linux.h (added)
-
lib/c/arch/ppc32/include/elf_linux.h (added)
-
lib/c/arch/sparc64/include/elf_linux.h (added)
-
lib/c/generic/elf/elf_load.c (moved) (moved from uspace/srv/loader/elf_load.c ) (9 diffs)
-
lib/c/generic/io/io.c (modified) (2 diffs)
-
lib/c/generic/rtld/elf_load.c (deleted)
-
lib/c/generic/rtld/module.c (modified) (7 diffs)
-
lib/c/generic/rtld/rtld.c (modified) (1 diff)
-
lib/c/generic/rtld/symbol.c (modified) (6 diffs)
-
lib/c/generic/vfs/vfs.c (modified) (1 diff)
-
lib/c/include/elf/elf.h (added)
-
lib/c/include/elf/elf_linux.h (added)
-
lib/c/include/elf/elf_load.h (moved) (moved from uspace/srv/loader/include/elf_load.h ) (3 diffs)
-
lib/c/include/rtld/elf_dyn.h (modified) (1 diff)
-
lib/c/include/rtld/rtld.h (modified) (1 diff)
-
lib/c/include/rtld/symbol.h (modified) (1 diff)
-
lib/c/include/typedefs.h (added)
-
lib/c/include/unistd.h (modified) (1 diff)
-
lib/fs/libfs.c (modified) (19 diffs)
-
lib/fs/libfs.h (modified) (3 diffs)
-
lib/scsi/include/scsi/sbc.h (modified) (2 diffs)
-
lib/scsi/include/scsi/spc.h (modified) (2 diffs)
-
lib/scsi/src/spc.c (modified) (2 diffs)
-
srv/devman/devman.c (modified) (2 diffs)
-
srv/devman/util.c (modified) (2 diffs)
-
srv/devman/util.h (modified) (1 diff)
-
srv/fs/devfs/devfs.c (modified) (3 diffs)
-
srv/fs/devfs/devfs.h (modified) (1 diff)
-
srv/fs/devfs/devfs_ops.c (modified) (25 diffs)
-
srv/fs/devfs/devfs_ops.h (modified) (1 diff)
-
srv/fs/ext2fs/ext2fs.c (modified) (3 diffs)
-
srv/fs/ext2fs/ext2fs.h (modified) (2 diffs)
-
srv/fs/ext2fs/ext2fs_ops.c (modified) (30 diffs)
-
srv/fs/fat/fat.c (modified) (2 diffs)
-
srv/fs/fat/fat.h (modified) (1 diff)
-
srv/fs/fat/fat_ops.c (modified) (39 diffs)
-
srv/fs/tmpfs/tmpfs.c (modified) (2 diffs)
-
srv/fs/tmpfs/tmpfs.h (modified) (1 diff)
-
srv/fs/tmpfs/tmpfs_ops.c (modified) (17 diffs)
-
srv/hw/irc/apic/apic.c (modified) (2 diffs)
-
srv/loader/Makefile (modified) (2 diffs)
-
srv/loader/include/elf.h (deleted)
-
srv/loader/main.c (modified) (2 diffs)
-
srv/vfs/vfs_ops.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/cmds/modules/cp/cp.c
r9350bfdd r7ae249d 71 71 size_t blen, int vb) 72 72 { 73 int fd1, fd2, bytes = 0;74 off64_t total = 0;73 int fd1, fd2, bytes; 74 off64_t total; 75 75 int64_t copied = 0; 76 76 char *buff = NULL; … … 104 104 } 105 105 106 for (;;) { 107 ssize_t res; 108 size_t written = 0; 109 110 bytes = read(fd1, buff, blen); 111 if (bytes <= 0) 106 while ((bytes = read_all(fd1, buff, blen)) > 0) { 107 if ((bytes = write_all(fd2, buff, bytes)) < 0) 112 108 break; 113 109 copied += bytes; 114 res = bytes;115 do {116 /*117 * Theoretically, it may not be enough to call write()118 * only once. Also the previous read() may have119 * returned less data than requested.120 */121 bytes = write(fd2, buff + written, res);122 if (bytes < 0)123 goto err;124 written += bytes;125 res -= bytes;126 } while (res > 0);127 128 /* TODO: re-insert assert() once this is stand alone,129 * removed as abort() exits the entire shell130 */131 if (res != 0) {132 printf("\n%zd more bytes than actually exist were copied\n", res);133 goto err;134 }135 110 } 136 111 137 112 if (bytes < 0) { 138 err:139 113 printf("\nError copying %s, (%d)\n", src, bytes); 140 114 copied = bytes; -
uspace/app/bdsh/cmds/modules/ls/ls.c
r9350bfdd r7ae249d 169 169 170 170 /* fill the name field */ 171 tosort[nbdirs].name = (char *) malloc(str_ length(dp->d_name) + 1);171 tosort[nbdirs].name = (char *) malloc(str_size(dp->d_name) + 1); 172 172 if (!tosort[nbdirs].name) { 173 173 cli_error(CL_ENOMEM, "ls: failed to scan %s", d); 174 174 goto out; 175 175 } 176 177 str_cpy(tosort[nbdirs].name, str_ length(dp->d_name) + 1, dp->d_name);176 177 str_cpy(tosort[nbdirs].name, str_size(dp->d_name) + 1, dp->d_name); 178 178 len = snprintf(buff, PATH_MAX - 1, "%s/%s", d, tosort[nbdirs].name); 179 179 buff[len] = '\0'; -
uspace/app/bdsh/compl.c
r9350bfdd r7ae249d 280 280 281 281 cs->dir = opendir(*cs->path); 282 283 /* Skip directories that we fail to open. */ 284 if (cs->dir == NULL) 285 cs->path++; 282 286 } 283 287 -
uspace/app/bdsh/exec.c
r9350bfdd r7ae249d 52 52 static int try_access(const char *); 53 53 54 const char *search_dir[] = { " app", "srv", NULL };54 const char *search_dir[] = { "/app", "/srv", NULL }; 55 55 56 56 /* work-around for access() */ -
uspace/app/bdsh/input.c
r9350bfdd r7ae249d 170 170 } 171 171 172 rc = run_command( cmd, usr, &new_iostate);172 rc = run_command(actual_cmd, usr, &new_iostate); 173 173 174 174 finit_with_files: -
uspace/app/init/init.c
r9350bfdd r7ae249d 294 294 295 295 #ifdef CONFIG_MOUNT_DATA 296 /* Make sure fat is running. */ 297 if (str_cmp(STRING(RDFMT), "fat") != 0) { 298 srv_start("/srv/fat"); 299 } 296 300 mount_data(); 297 301 #else -
uspace/app/taskdump/elf_core.c
r9350bfdd r7ae249d 1 1 /* 2 * Copyright (c) 201 0Jiri Svoboda2 * Copyright (c) 2011 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 38 38 * Looking at core files produced by Linux, these don't have section headers, 39 39 * only program headers, although objdump shows them as having sections. 40 * Basically at the beginning there should be a note segment (which we 41 * do not write) and one loadable segment per memory area (which we do write). 42 * 43 * The note segment probably contains register state, etc. -- we don't 44 * deal with these yet. Nevertheless you can use these core files with 45 * objdump or gdb. 46 */ 47 40 * Basically at the beginning there should be a note segment followed 41 * by one loadable segment per memory area. 42 * 43 * The note segment contains a series of records with register state, 44 * process info etc. We only write one record NT_PRSTATUS which contains 45 * process/register state (anything which is not register state we fill 46 * with zeroes). 47 */ 48 49 #include <align.h> 50 #include <elf/elf.h> 51 #include <elf/elf_linux.h> 48 52 #include <stdio.h> 49 53 #include <stdlib.h> … … 58 62 #include <udebug.h> 59 63 #include <macros.h> 60 61 #include <elf.h> 62 #include " include/elf_core.h"64 #include <libarch/istate.h> 65 66 #include "elf_core.h" 63 67 64 68 static off64_t align_foff_up(off64_t, uintptr_t, size_t); 65 static int write_all(int, void *, size_t);69 static int align_pos(int, size_t); 66 70 static int write_mem_area(int, as_area_info_t *, async_sess_t *); 67 71 … … 83 87 */ 84 88 int elf_core_save(const char *file_name, as_area_info_t *ainfo, unsigned int n, 85 async_sess_t *sess )89 async_sess_t *sess, istate_t *istate) 86 90 { 87 91 elf_header_t elf_hdr; … … 90 94 elf_word flags; 91 95 elf_segment_header_t *p_hdr; 96 elf_prstatus_t pr_status; 97 elf_note_t note; 98 size_t word_size; 92 99 93 100 int fd; 94 int rc;101 ssize_t rc; 95 102 unsigned int i; 96 103 97 n_ph = n; 98 99 p_hdr = malloc(sizeof(elf_segment_header_t) * n); 104 #ifdef __32_BITS__ 105 word_size = 4; 106 #endif 107 #ifdef __64_BITS__ 108 word_size = 8; 109 #endif 110 memset(&pr_status, 0, sizeof(pr_status)); 111 istate_to_elf_regs(istate, &pr_status.regs); 112 113 n_ph = n + 1; 114 115 p_hdr = malloc(sizeof(elf_segment_header_t) * n_ph); 100 116 if (p_hdr == NULL) { 101 117 printf("Failed allocating memory.\n"); … … 115 131 * ELF header 116 132 * program headers 133 * note segment 117 134 * repeat: 118 135 * (pad for alignment) 119 * segment data136 * core segment 120 137 * end repeat 121 138 */ … … 147 164 foff = elf_hdr.e_phoff + n_ph * sizeof(elf_segment_header_t); 148 165 149 for (i = 1; i <= n; ++i) { 150 foff = align_foff_up(foff, ainfo[i - 1].start_addr, PAGE_SIZE); 166 memset(&p_hdr[0], 0, sizeof(p_hdr[0])); 167 p_hdr[0].p_type = PT_NOTE; 168 p_hdr[0].p_offset = foff; 169 p_hdr[0].p_vaddr = 0; 170 p_hdr[0].p_paddr = 0; 171 p_hdr[0].p_filesz = sizeof(elf_note_t) 172 + ALIGN_UP((str_size("CORE") + 1), word_size) 173 + ALIGN_UP(sizeof(elf_prstatus_t), word_size); 174 p_hdr[0].p_memsz = 0; 175 p_hdr[0].p_flags = 0; 176 p_hdr[0].p_align = 1; 177 178 foff += p_hdr[0].p_filesz; 179 180 for (i = 0; i < n; ++i) { 181 foff = align_foff_up(foff, ainfo[i].start_addr, PAGE_SIZE); 151 182 152 183 flags = 0; 153 if (ainfo[i - 1].flags & AS_AREA_READ)184 if (ainfo[i].flags & AS_AREA_READ) 154 185 flags |= PF_R; 155 if (ainfo[i - 1].flags & AS_AREA_WRITE)186 if (ainfo[i].flags & AS_AREA_WRITE) 156 187 flags |= PF_W; 157 if (ainfo[i - 1].flags & AS_AREA_EXEC)188 if (ainfo[i].flags & AS_AREA_EXEC) 158 189 flags |= PF_X; 159 190 160 memset(&p_hdr[i - 1], 0, sizeof(p_hdr[i -1]));161 p_hdr[i -1].p_type = PT_LOAD;162 p_hdr[i -1].p_offset = foff;163 p_hdr[i - 1].p_vaddr = ainfo[i - 1].start_addr;164 p_hdr[i -1].p_paddr = 0;165 p_hdr[i - 1].p_filesz = ainfo[i - 1].size;166 p_hdr[i - 1].p_memsz = ainfo[i - 1].size;167 p_hdr[i -1].p_flags = flags;168 p_hdr[i -1].p_align = PAGE_SIZE;169 170 foff += ainfo[i - 1].size;191 memset(&p_hdr[i + 1], 0, sizeof(p_hdr[i + 1])); 192 p_hdr[i + 1].p_type = PT_LOAD; 193 p_hdr[i + 1].p_offset = foff; 194 p_hdr[i + 1].p_vaddr = ainfo[i].start_addr; 195 p_hdr[i + 1].p_paddr = 0; 196 p_hdr[i + 1].p_filesz = ainfo[i].size; 197 p_hdr[i + 1].p_memsz = ainfo[i].size; 198 p_hdr[i + 1].p_flags = flags; 199 p_hdr[i + 1].p_align = PAGE_SIZE; 200 201 foff += ainfo[i].size; 171 202 } 172 203 173 204 rc = write_all(fd, &elf_hdr, sizeof(elf_hdr)); 174 if (rc != EOK) {205 if (rc != sizeof(elf_hdr)) { 175 206 printf("Failed writing ELF header.\n"); 176 207 free(p_hdr); … … 180 211 for (i = 0; i < n_ph; ++i) { 181 212 rc = write_all(fd, &p_hdr[i], sizeof(p_hdr[i])); 182 if (rc != EOK) {213 if (rc != sizeof(p_hdr[i])) { 183 214 printf("Failed writing program header.\n"); 184 215 free(p_hdr); … … 187 218 } 188 219 189 for (i = 0; i < n_ph; ++i) { 220 if (lseek(fd, p_hdr[0].p_offset, SEEK_SET) == (off64_t) -1) { 221 printf("Failed writing memory data.\n"); 222 free(p_hdr); 223 return EIO; 224 } 225 226 /* 227 * Write note header 228 */ 229 note.namesz = str_size("CORE") + 1; 230 note.descsz = sizeof(elf_prstatus_t); 231 note.type = NT_PRSTATUS; 232 233 rc = write_all(fd, ¬e, sizeof(elf_note_t)); 234 if (rc != sizeof(elf_note_t)) { 235 printf("Failed writing note header.\n"); 236 free(p_hdr); 237 return EIO; 238 } 239 240 rc = write_all(fd, "CORE", note.namesz); 241 if (rc != (ssize_t) note.namesz) { 242 printf("Failed writing note header.\n"); 243 free(p_hdr); 244 return EIO; 245 } 246 247 rc = align_pos(fd, word_size); 248 if (rc != EOK) { 249 printf("Failed writing note header.\n"); 250 free(p_hdr); 251 return EIO; 252 } 253 254 rc = write_all(fd, &pr_status, sizeof(elf_prstatus_t)); 255 if (rc != sizeof(elf_prstatus_t)) { 256 printf("Failed writing register data.\n"); 257 free(p_hdr); 258 return EIO; 259 } 260 261 for (i = 1; i < n_ph; ++i) { 190 262 if (lseek(fd, p_hdr[i].p_offset, SEEK_SET) == (off64_t) -1) { 191 263 printf("Failed writing memory data.\n"); … … 193 265 return EIO; 194 266 } 195 if (write_mem_area(fd, &ainfo[i ], sess) != EOK) {267 if (write_mem_area(fd, &ainfo[i - 1], sess) != EOK) { 196 268 printf("Failed writing memory data.\n"); 197 269 free(p_hdr); … … 210 282 off64_t rva = vaddr % page_size; 211 283 off64_t rfo = foff % page_size; 212 284 213 285 if (rva >= rfo) 214 286 return (foff + (rva - rfo)); 215 287 216 288 return (foff + (page_size + (rva - rfo))); 217 289 } … … 231 303 size_t total; 232 304 uintptr_t addr; 233 int rc;305 ssize_t rc; 234 306 235 307 addr = area->start_addr; … … 245 317 246 318 rc = write_all(fd, buffer, to_copy); 247 if (rc != EOK) {319 if (rc != (ssize_t) to_copy) { 248 320 printf("Failed writing memory contents.\n"); 249 321 return EIO; … … 257 329 } 258 330 259 /** Write until the buffer is written in its entirety. 260 * 261 * This function fails if it cannot write exactly @a len bytes to the file. 262 * 263 * @param fd The file to write to. 264 * @param buf Data, @a len bytes long. 265 * @param len Number of bytes to write. 266 * 267 * @return EOK on error, return value from write() if writing 268 * failed. 269 */ 270 static int write_all(int fd, void *data, size_t len) 331 static int align_pos(int fd, size_t align) 271 332 { 272 int cnt = 0;273 274 do { 275 data += cnt;276 len -= cnt;277 cnt = write(fd, data, len);278 } while (cnt > 0 && (len - cnt) > 0); 279 280 if (cnt < 0)281 return cnt; 282 283 if ( len - cnt >0)284 return EIO;333 off64_t cur_pos; 334 size_t rem, adv; 335 336 cur_pos = lseek(fd, 0, SEEK_CUR); 337 if (cur_pos < 0) 338 return -1; 339 340 rem = cur_pos % align; 341 adv = align - rem; 342 343 cur_pos = lseek(fd, adv, SEEK_CUR); 344 if (cur_pos < 0) 345 return -1; 285 346 286 347 return EOK; 287 348 } 288 349 289 290 350 /** @} 291 351 */ -
uspace/app/taskdump/include/elf_core.h
r9350bfdd r7ae249d 37 37 38 38 #include <async.h> 39 #include <elf/elf_linux.h> 40 #include <libarch/istate.h> 39 41 40 42 extern int elf_core_save(const char *, as_area_info_t *, unsigned int, 41 async_sess_t * );43 async_sess_t *, istate_t *); 42 44 43 45 #endif -
uspace/app/taskdump/include/symtab.h
r9350bfdd r7ae249d 36 36 #define SYMTAB_H_ 37 37 38 #include <elf/elf.h> 38 39 #include <sys/types.h> 39 #include <elf.h>40 40 41 41 typedef struct { -
uspace/app/taskdump/symtab.c
r9350bfdd r7ae249d 36 36 */ 37 37 38 #include <elf/elf.h> 38 39 #include <stdio.h> 39 40 #include <stdlib.h> … … 43 44 #include <fcntl.h> 44 45 45 #include <elf.h>46 46 #include "include/symtab.h" 47 47 … … 50 50 elf_section_header_t *shdr); 51 51 static int chunk_load(int fd, off64_t start, size_t size, void **ptr); 52 static int read_all(int fd, void *buf, size_t len);53 52 54 53 /** Load symbol table from an ELF file. … … 90 89 91 90 rc = read_all(fd, &elf_hdr, sizeof(elf_header_t)); 92 if (rc != EOK) {91 if (rc != sizeof(elf_header_t)) { 93 92 printf("failed reading elf header\n"); 94 93 free(stab); … … 312 311 313 312 rc = read_all(fd, sec_hdr, sizeof(elf_section_header_t)); 314 if (rc != EOK)313 if (rc != sizeof(elf_section_header_t)) 315 314 return EIO; 316 315 … … 331 330 static int chunk_load(int fd, off64_t start, size_t size, void **ptr) 332 331 { 333 int rc; 334 335 rc = lseek(fd, start, SEEK_SET); 336 if (rc == (off64_t) -1) { 332 ssize_t rc; 333 off64_t offs; 334 335 offs = lseek(fd, start, SEEK_SET); 336 if (offs == (off64_t) -1) { 337 337 printf("failed seeking chunk\n"); 338 338 *ptr = NULL; … … 347 347 348 348 rc = read_all(fd, *ptr, size); 349 if (rc != EOK) {349 if (rc != (ssize_t) size) { 350 350 printf("failed reading chunk\n"); 351 351 free(*ptr); … … 357 357 } 358 358 359 /** Read until the buffer is read in its entirety.360 *361 * This function fails if it cannot read exactly @a len bytes from the file.362 *363 * @param fd The file to read from.364 * @param buf Buffer for storing data, @a len bytes long.365 * @param len Number of bytes to read.366 *367 * @return EOK on error, EIO if file is short or return value368 * from read() if reading failed.369 */370 static int read_all(int fd, void *buf, size_t len)371 {372 int cnt = 0;373 374 do {375 buf += cnt;376 len -= cnt;377 cnt = read(fd, buf, len);378 } while (cnt > 0 && (len - cnt) > 0);379 380 if (cnt < 0)381 return cnt;382 383 if (len - cnt > 0)384 return EIO;385 386 return EOK;387 }388 389 359 /** @} 390 360 */ -
uspace/app/taskdump/taskdump.c
r9350bfdd r7ae249d 34 34 35 35 #include <async.h> 36 #include <elf/elf_linux.h> 36 37 #include <stdio.h> 37 38 #include <stdlib.h> … … 72 73 static char *get_app_task_name(void); 73 74 static char *fmt_sym_address(uintptr_t addr); 75 76 static istate_t reg_state; 74 77 75 78 int main(int argc, char *argv[]) … … 293 296 if (write_core_file) { 294 297 printf("Writing core file '%s'\n", core_file_name); 295 rc = elf_core_save(core_file_name, ainfo_buf, n_areas, sess); 298 299 rc = elf_core_save(core_file_name, ainfo_buf, n_areas, sess, 300 ®_state); 301 296 302 if (rc != EOK) { 297 303 printf("Failed writing core file.\n"); … … 321 327 pc = istate_get_pc(&istate); 322 328 fp = istate_get_fp(&istate); 329 330 /* Save register state for dumping to core file later. */ 331 reg_state = istate; 323 332 324 333 sym_pc = fmt_sym_address(pc); -
uspace/drv/bus/usb/usbmast/bo_trans.c
r9350bfdd r7ae249d 58 58 * @param tag Command block wrapper tag (automatically compared 59 59 * with answer) 60 * @param cmd Command block 61 * @param cmd_size Command block size in bytes 62 * @param ddir Direction in which data will be transferred 63 * @param dbuf Data send/receive buffer 64 * @param dbuf_size Size of the data buffer 65 * @param xferred_size Number of bytes actually transferred 60 * @param cmd SCSI command 66 61 * 67 62 * @return Error code 68 63 */ 69 static int usb_massstor_cmd(usbmast_fun_t *mfun, uint32_t tag, const void *cmd, 70 size_t cmd_size, usb_direction_t ddir, void *dbuf, size_t dbuf_size, 71 size_t *xferred_size) 64 int usb_massstor_cmd(usbmast_fun_t *mfun, uint32_t tag, scsi_cmd_t *cmd) 72 65 { 73 66 int rc; 67 int retval = EOK; 74 68 size_t act_size; 75 69 usb_pipe_t *bulk_in_pipe = mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe; 76 70 usb_pipe_t *bulk_out_pipe = mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe; 71 usb_direction_t ddir; 72 void *dbuf; 73 size_t dbuf_size; 74 75 if (cmd->data_out != NULL && cmd->data_in == NULL) { 76 ddir = USB_DIRECTION_OUT; 77 dbuf = (void *)cmd->data_out; 78 dbuf_size = cmd->data_out_size; 79 } else if (cmd->data_out == NULL && cmd->data_in != NULL) { 80 ddir = USB_DIRECTION_IN; 81 dbuf = cmd->data_in; 82 dbuf_size = cmd->data_in_size; 83 } else { 84 assert(false); 85 } 77 86 78 87 /* Prepare CBW - command block wrapper */ 79 88 usb_massstor_cbw_t cbw; 80 89 usb_massstor_cbw_prepare(&cbw, tag, dbuf_size, ddir, mfun->lun, 81 cmd _size, cmd);90 cmd->cdb_size, cmd->cdb); 82 91 83 92 /* Send the CBW. */ 93 MASTLOG("Sending CBW.\n"); 84 94 rc = usb_pipe_write(bulk_out_pipe, &cbw, sizeof(cbw)); 85 95 MASTLOG("CBW '%s' sent: %s.\n", 86 96 usb_debug_str_buffer((uint8_t *) &cbw, sizeof(cbw), 0), 87 97 str_error(rc)); 88 if (rc != EOK) {89 return rc;90 } 91 98 if (rc != EOK) 99 return EIO; 100 101 MASTLOG("Transferring data.\n"); 92 102 if (ddir == USB_DIRECTION_IN) { 93 103 /* Recieve data from the device. */ … … 104 114 } 105 115 106 if (rc != EOK) { 107 /* 108 * XXX If the pipe is stalled, we should clear it 109 * and read CSW. 110 */ 111 return rc; 116 if (rc == ESTALL) { 117 /* Clear stall condition and continue below to read CSW. */ 118 if (ddir == USB_DIRECTION_IN) { 119 usb_pipe_clear_halt(&mfun->mdev->usb_dev->ctrl_pipe, 120 mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe); 121 } else { 122 usb_pipe_clear_halt(&mfun->mdev->usb_dev->ctrl_pipe, 123 mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe); 124 } 125 } else if (rc != EOK) { 126 return EIO; 112 127 } 113 128 … … 115 130 usb_massstor_csw_t csw; 116 131 size_t csw_size; 132 MASTLOG("Reading CSW.\n"); 117 133 rc = usb_pipe_read(bulk_in_pipe, &csw, sizeof(csw), &csw_size); 118 134 MASTLOG("CSW '%s' received (%zu bytes): %s.\n", … … 121 137 if (rc != EOK) { 122 138 MASTLOG("rc != EOK\n"); 123 return rc;139 return EIO; 124 140 } 125 141 126 142 if (csw_size != sizeof(csw)) { 127 143 MASTLOG("csw_size != sizeof(csw)\n"); 128 return E RANGE;144 return EIO; 129 145 } 130 146 131 147 if (csw.dCSWTag != tag) { 132 148 MASTLOG("csw.dCSWTag != tag\n"); 133 return E BADCHECKSUM;149 return EIO; 134 150 } 135 151 … … 137 153 * Determine the actual return value from the CSW. 138 154 */ 139 if (csw.dCSWStatus != 0) { 140 MASTLOG("csw.dCSWStatus != 0\n"); 141 // FIXME: better error code 142 // FIXME: distinguish 0x01 and 0x02 143 return EXDEV; 155 switch (csw.dCSWStatus) { 156 case cbs_passed: 157 cmd->status = CMDS_GOOD; 158 break; 159 case cbs_failed: 160 MASTLOG("Command failed\n"); 161 cmd->status = CMDS_FAILED; 162 break; 163 case cbs_phase_error: 164 MASTLOG("Phase error\n"); 165 retval = EIO; 166 break; 167 default: 168 retval = EIO; 169 break; 144 170 } 145 171 … … 147 173 if (residue > dbuf_size) { 148 174 MASTLOG("residue > dbuf_size\n"); 149 return E RANGE;175 return EIO; 150 176 } 151 177 … … 158 184 */ 159 185 160 if (xferred_size != NULL) 161 *xferred_size = dbuf_size - residue; 162 163 return EOK; 164 } 165 166 /** Perform data-in command. 167 * 168 * @param mfun Mass storage function 169 * @param tag Command block wrapper tag (automatically compared with 170 * answer) 171 * @param cmd CDB (Command Descriptor) 172 * @param cmd_size CDB length in bytes 173 * @param dbuf Data receive buffer 174 * @param dbuf_size Data receive buffer size in bytes 175 * @param proc_size Number of bytes actually processed by device 176 * 177 * @return Error code 178 */ 179 int usb_massstor_data_in(usbmast_fun_t *mfun, uint32_t tag, const void *cmd, 180 size_t cmd_size, void *dbuf, size_t dbuf_size, size_t *proc_size) 181 { 182 return usb_massstor_cmd(mfun, tag, cmd, cmd_size, USB_DIRECTION_IN, 183 dbuf, dbuf_size, proc_size); 184 } 185 186 /** Perform data-out command. 187 * 188 * @param mfun Mass storage function 189 * @param tag Command block wrapper tag (automatically compared with 190 * answer) 191 * @param cmd CDB (Command Descriptor) 192 * @param cmd_size CDB length in bytes 193 * @param data Command data 194 * @param data_size Size of @a data in bytes 195 * @param proc_size Number of bytes actually processed by device 196 * 197 * @return Error code 198 */ 199 int usb_massstor_data_out(usbmast_fun_t *mfun, uint32_t tag, const void *cmd, 200 size_t cmd_size, const void *data, size_t data_size, size_t *proc_size) 201 { 202 return usb_massstor_cmd(mfun, tag, cmd, cmd_size, USB_DIRECTION_OUT, 203 (void *) data, data_size, proc_size); 186 if (ddir == USB_DIRECTION_IN) 187 cmd->rcvd_size = dbuf_size - residue; 188 189 return retval; 204 190 } 205 191 -
uspace/drv/bus/usb/usbmast/bo_trans.h
r9350bfdd r7ae249d 47 47 #define BULK_OUT_EP 1 48 48 49 extern int usb_massstor_data_in(usbmast_fun_t *, uint32_t, const void *, 50 size_t, void *, size_t, size_t *); 51 extern int usb_massstor_data_out(usbmast_fun_t *, uint32_t, const void *, 52 size_t, const void *, size_t, size_t *); 49 typedef enum cmd_status { 50 CMDS_GOOD, 51 CMDS_FAILED 52 } cmd_status_t; 53 54 /** SCSI command. 55 * 56 * Contains (a subset of) the input and output arguments of SCSI 57 * Execute Command procedure call (see SAM-4 chapter 5.1) 58 */ 59 typedef struct { 60 /* 61 * Related to IN fields 62 */ 63 64 /** Command Descriptor Block */ 65 void *cdb; 66 /** CDB size in bytes */ 67 size_t cdb_size; 68 69 /** Outgoing data */ 70 const void *data_out; 71 /** Size of outgoing data in bytes */ 72 size_t data_out_size; 73 74 /* 75 * Related to OUT fields 76 */ 77 78 /** Buffer for incoming data */ 79 void *data_in; 80 /** Size of input buffer in bytes */ 81 size_t data_in_size; 82 83 /** Number of bytes actually received */ 84 size_t rcvd_size; 85 86 /** Status */ 87 cmd_status_t status; 88 } scsi_cmd_t; 89 90 extern int usb_massstor_cmd(usbmast_fun_t *, uint32_t, scsi_cmd_t *); 53 91 extern int usb_massstor_reset(usbmast_dev_t *); 54 92 extern void usb_massstor_reset_recovery(usbmast_dev_t *); -
uspace/drv/bus/usb/usbmast/cmdw.h
r9350bfdd r7ae249d 57 57 } __attribute__((packed)) usb_massstor_csw_t; 58 58 59 enum cmd_block_status { 60 cbs_passed = 0x00, 61 cbs_failed = 0x01, 62 cbs_phase_error = 0x02 63 }; 64 59 65 extern void usb_massstor_cbw_prepare(usb_massstor_cbw_t *, uint32_t, uint32_t, 60 66 usb_direction_t, uint8_t, uint8_t, const uint8_t *); -
uspace/drv/bus/usb/usbmast/scsi_ms.c
r9350bfdd r7ae249d 61 61 } 62 62 63 static void usbmast_dump_sense(scsi_sense_data_t *sense_buf) 64 { 65 unsigned sense_key; 66 67 sense_key = sense_buf->flags_key & 0x0f; 68 printf("Got sense data. Sense key: 0x%x (%s), ASC 0x%02x, " 69 "ASCQ 0x%02x.\n", sense_key, 70 scsi_get_sense_key_str(sense_key), 71 sense_buf->additional_code, 72 sense_buf->additional_cqual); 73 } 74 75 /** Run SCSI command. 76 * 77 * Run command and repeat in case of unit attention. 78 * XXX This is too simplified. 79 */ 80 static int usbmast_run_cmd(usbmast_fun_t *mfun, scsi_cmd_t *cmd) 81 { 82 uint8_t sense_key; 83 scsi_sense_data_t sense_buf; 84 int rc; 85 86 do { 87 rc = usb_massstor_cmd(mfun, 0xDEADBEEF, cmd); 88 if (rc != EOK) { 89 usb_log_error("Inquiry transport failed, device %s: %s.\n", 90 mfun->mdev->ddf_dev->name, str_error(rc)); 91 return rc; 92 } 93 94 if (cmd->status == CMDS_GOOD) 95 return EOK; 96 97 usb_log_error("SCSI command failed, device %s.\n", 98 mfun->mdev->ddf_dev->name); 99 100 rc = usbmast_request_sense(mfun, &sense_buf, sizeof(sense_buf)); 101 if (rc != EOK) { 102 usb_log_error("Failed to read sense data.\n"); 103 return EIO; 104 } 105 106 /* Dump sense data to log */ 107 usbmast_dump_sense(&sense_buf); 108 109 /* Get sense key */ 110 sense_key = sense_buf.flags_key & 0x0f; 111 112 if (sense_key == SCSI_SK_UNIT_ATTENTION) { 113 printf("Got unit attention. Re-trying command.\n"); 114 } 115 116 } while (sense_key == SCSI_SK_UNIT_ATTENTION); 117 118 /* Command status is not good, nevertheless transport succeeded. */ 119 return EOK; 120 } 121 63 122 /** Perform SCSI Inquiry command on USB mass storage device. 64 123 * … … 70 129 { 71 130 scsi_std_inquiry_data_t inq_data; 72 s ize_t response_len;131 scsi_cmd_t cmd; 73 132 scsi_cdb_inquiry_t cdb; 74 133 int rc; … … 78 137 cdb.alloc_len = host2uint16_t_be(sizeof(inq_data)); 79 138 80 rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb, 81 sizeof(cdb), &inq_data, sizeof(inq_data), &response_len); 139 memset(&cmd, 0, sizeof(cmd)); 140 cmd.cdb = &cdb; 141 cmd.cdb_size = sizeof(cdb); 142 cmd.data_in = &inq_data; 143 cmd.data_in_size = sizeof(inq_data); 144 145 rc = usb_massstor_cmd(mfun, 0xDEADBEEF, &cmd); 82 146 83 147 if (rc != EOK) { 84 usb_log_error("Inquiry failed, device %s: %s.\n", 85 mfun->mdev->ddf_dev->name, str_error(rc)); 86 return rc; 87 } 88 89 if (response_len < SCSI_STD_INQUIRY_DATA_MIN_SIZE) { 148 usb_log_error("Inquiry transport failed, device %s: %s.\n", 149 mfun->mdev->ddf_dev->name, str_error(rc)); 150 return rc; 151 } 152 153 if (cmd.status != CMDS_GOOD) { 154 usb_log_error("Inquiry command failed, device %s.\n", 155 mfun->mdev->ddf_dev->name); 156 return EIO; 157 } 158 159 if (cmd.rcvd_size < SCSI_STD_INQUIRY_DATA_MIN_SIZE) { 90 160 usb_log_error("SCSI Inquiry response too short (%zu).\n", 91 response_len);161 cmd.rcvd_size); 92 162 return EIO; 93 163 } … … 127 197 int usbmast_request_sense(usbmast_fun_t *mfun, void *buf, size_t size) 128 198 { 199 scsi_cmd_t cmd; 129 200 scsi_cdb_request_sense_t cdb; 130 size_t data_len;131 201 int rc; 132 202 … … 135 205 cdb.alloc_len = min(size, SCSI_SENSE_DATA_MAX_SIZE); 136 206 137 rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb, 138 sizeof(cdb), buf, size, &data_len); 139 140 if (rc != EOK) { 207 memset(&cmd, 0, sizeof(cmd)); 208 cmd.cdb = &cdb; 209 cmd.cdb_size = sizeof(cdb); 210 cmd.data_in = buf; 211 cmd.data_in_size = size; 212 213 rc = usb_massstor_cmd(mfun, 0xDEADBEEF, &cmd); 214 215 if (rc != EOK || cmd.status != CMDS_GOOD) { 141 216 usb_log_error("Request Sense failed, device %s: %s.\n", 142 217 mfun->mdev->ddf_dev->name, str_error(rc)); … … 144 219 } 145 220 146 if ( data_len< SCSI_SENSE_DATA_MIN_SIZE) {221 if (cmd.rcvd_size < SCSI_SENSE_DATA_MIN_SIZE) { 147 222 /* The missing bytes should be considered to be zeroes. */ 148 memset((uint8_t *)buf + data_len, 0,149 SCSI_SENSE_DATA_MIN_SIZE - data_len);223 memset((uint8_t *)buf + cmd.rcvd_size, 0, 224 SCSI_SENSE_DATA_MIN_SIZE - cmd.rcvd_size); 150 225 } 151 226 … … 164 239 uint32_t *block_size) 165 240 { 241 scsi_cmd_t cmd; 166 242 scsi_cdb_read_capacity_10_t cdb; 167 243 scsi_read_capacity_10_data_t data; 168 size_t data_len;169 244 int rc; 170 245 … … 172 247 cdb.op_code = SCSI_CMD_READ_CAPACITY_10; 173 248 174 rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb, 175 sizeof(cdb), &data, sizeof(data), &data_len); 249 memset(&cmd, 0, sizeof(cmd)); 250 cmd.cdb = &cdb; 251 cmd.cdb_size = sizeof(cdb); 252 cmd.data_in = &data; 253 cmd.data_in_size = sizeof(data); 254 255 rc = usbmast_run_cmd(mfun, &cmd); 176 256 177 257 if (rc != EOK) { 178 usb_log_error("Read Capacity (10) failed, device %s: %s.\n", 179 mfun->mdev->ddf_dev->name, str_error(rc)); 180 return rc; 181 } 182 183 if (data_len < sizeof(data)) { 258 usb_log_error("Read Capacity (10) transport failed, device %s: %s.\n", 259 mfun->mdev->ddf_dev->name, str_error(rc)); 260 return rc; 261 } 262 263 if (cmd.status != CMDS_GOOD) { 264 usb_log_error("Read Capacity (10) command failed, device %s.\n", 265 mfun->mdev->ddf_dev->name); 266 return EIO; 267 } 268 269 if (cmd.rcvd_size < sizeof(data)) { 184 270 usb_log_error("SCSI Read Capacity response too short (%zu).\n", 185 data_len);271 cmd.rcvd_size); 186 272 return EIO; 187 273 } … … 203 289 int usbmast_read(usbmast_fun_t *mfun, uint64_t ba, size_t nblocks, void *buf) 204 290 { 205 scsi_cdb_read_12_t cdb; 206 size_t data_len; 207 int rc; 208 209 /* XXX Need softstate to store block size. */ 291 scsi_cmd_t cmd; 292 scsi_cdb_read_10_t cdb; 293 int rc; 210 294 211 295 if (ba > UINT32_MAX) 212 296 return ELIMIT; 213 297 214 if ( (uint64_t)nblocks * mfun->block_size > UINT32_MAX)298 if (nblocks > UINT16_MAX) 215 299 return ELIMIT; 216 300 217 301 memset(&cdb, 0, sizeof(cdb)); 218 cdb.op_code = SCSI_CMD_READ_1 2;302 cdb.op_code = SCSI_CMD_READ_10; 219 303 cdb.lba = host2uint32_t_be(ba); 220 cdb.xfer_len = host2uint32_t_be(nblocks); 221 222 rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb, 223 sizeof(cdb), buf, nblocks * mfun->block_size, &data_len); 304 cdb.xfer_len = host2uint16_t_be(nblocks); 305 306 memset(&cmd, 0, sizeof(cmd)); 307 cmd.cdb = &cdb; 308 cmd.cdb_size = sizeof(cdb); 309 cmd.data_in = buf; 310 cmd.data_in_size = nblocks * mfun->block_size; 311 312 rc = usbmast_run_cmd(mfun, &cmd); 224 313 225 314 if (rc != EOK) { 226 usb_log_error("Read (12) failed, device %s: %s.\n", 227 mfun->mdev->ddf_dev->name, str_error(rc)); 228 return rc; 229 } 230 231 if (data_len < nblocks * mfun->block_size) { 315 usb_log_error("Read (10) transport failed, device %s: %s.\n", 316 mfun->mdev->ddf_dev->name, str_error(rc)); 317 return rc; 318 } 319 320 if (cmd.status != CMDS_GOOD) { 321 usb_log_error("Read (10) command failed, device %s.\n", 322 mfun->mdev->ddf_dev->name); 323 return EIO; 324 } 325 326 if (cmd.rcvd_size < nblocks * mfun->block_size) { 232 327 usb_log_error("SCSI Read response too short (%zu).\n", 233 data_len);328 cmd.rcvd_size); 234 329 return EIO; 235 330 } … … 250 345 const void *data) 251 346 { 252 scsi_c db_write_12_t cdb;253 s ize_t sent_len;347 scsi_cmd_t cmd; 348 scsi_cdb_write_10_t cdb; 254 349 int rc; 255 350 … … 257 352 return ELIMIT; 258 353 259 if ( (uint64_t)nblocks * mfun->block_size > UINT32_MAX)354 if (nblocks > UINT16_MAX) 260 355 return ELIMIT; 261 356 262 357 memset(&cdb, 0, sizeof(cdb)); 263 cdb.op_code = SCSI_CMD_WRITE_1 2;358 cdb.op_code = SCSI_CMD_WRITE_10; 264 359 cdb.lba = host2uint32_t_be(ba); 265 cdb.xfer_len = host2uint32_t_be(nblocks); 266 267 rc = usb_massstor_data_out(mfun, 0xDEADBEEF, (uint8_t *) &cdb, 268 sizeof(cdb), data, nblocks * mfun->block_size, &sent_len); 360 cdb.xfer_len = host2uint16_t_be(nblocks); 361 362 memset(&cmd, 0, sizeof(cmd)); 363 cmd.cdb = &cdb; 364 cmd.cdb_size = sizeof(cdb); 365 cmd.data_out = data; 366 cmd.data_out_size = nblocks * mfun->block_size; 367 368 rc = usbmast_run_cmd(mfun, &cmd); 269 369 270 370 if (rc != EOK) { 271 usb_log_error("Write (1 2)failed, device %s: %s.\n",272 mfun->mdev->ddf_dev->name, str_error(rc)); 273 return rc; 274 } 275 276 if ( sent_len < nblocks * mfun->block_size) {277 usb_log_error(" SCSI Write not all bytes transferred (%zu).\n",278 sent_len);371 usb_log_error("Write (10) transport failed, device %s: %s.\n", 372 mfun->mdev->ddf_dev->name, str_error(rc)); 373 return rc; 374 } 375 376 if (cmd.status != CMDS_GOOD) { 377 usb_log_error("Write (10) command failed, device %s.\n", 378 mfun->mdev->ddf_dev->name); 279 379 return EIO; 280 380 } -
uspace/lib/block/libblock.c
r9350bfdd r7ae249d 258 258 static hash_index_t cache_hash(unsigned long *key) 259 259 { 260 return *key& (CACHE_BUCKETS - 1);260 return MERGE_LOUP32(key[0], key[1]) & (CACHE_BUCKETS - 1); 261 261 } 262 262 … … 264 264 { 265 265 block_t *b = hash_table_get_instance(item, block_t, hash_link); 266 return b->lba == *key;266 return b->lba == MERGE_LOUP32(key[0], key[1]); 267 267 } 268 268 … … 305 305 cache->blocks_cluster = cache->lblock_size / devcon->pblock_size; 306 306 307 if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,307 if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 2, 308 308 &cache_ops)) { 309 309 free(cache); … … 344 344 } 345 345 346 unsigned long key = b->lba; 347 hash_table_remove(&cache->block_hash, &key, 1); 346 unsigned long key[2] = { 347 LOWER32(b->lba), 348 UPPER32(b->lba) 349 }; 350 hash_table_remove(&cache->block_hash, key, 2); 348 351 349 352 free(b->data); … … 398 401 block_t *b; 399 402 link_t *l; 400 unsigned long key = ba; 403 unsigned long key[2] = { 404 LOWER32(ba), 405 UPPER32(ba) 406 }; 407 401 408 int rc; 402 409 … … 413 420 414 421 fibril_mutex_lock(&cache->lock); 415 l = hash_table_find(&cache->block_hash, &key);422 l = hash_table_find(&cache->block_hash, key); 416 423 if (l) { 417 424 found: … … 451 458 * Try to recycle a block from the free list. 452 459 */ 453 unsigned long temp_key;454 460 recycle: 455 461 if (list_empty(&cache->free_list)) { … … 499 505 goto retry; 500 506 } 501 l = hash_table_find(&cache->block_hash, &key);507 l = hash_table_find(&cache->block_hash, key); 502 508 if (l) { 503 509 /* … … 522 528 */ 523 529 list_remove(&b->free_link); 524 temp_key = b->lba; 525 hash_table_remove(&cache->block_hash, &temp_key, 1); 530 unsigned long temp_key[2] = { 531 LOWER32(b->lba), 532 UPPER32(b->lba) 533 }; 534 hash_table_remove(&cache->block_hash, temp_key, 2); 526 535 } 527 536 … … 531 540 b->lba = ba; 532 541 b->pba = ba_ltop(devcon, b->lba); 533 hash_table_insert(&cache->block_hash, &key, &b->hash_link);542 hash_table_insert(&cache->block_hash, key, &b->hash_link); 534 543 535 544 /* … … 643 652 * Take the block out of the cache and free it. 644 653 */ 645 unsigned long key = block->lba; 646 hash_table_remove(&cache->block_hash, &key, 1); 654 unsigned long key[2] = { 655 LOWER32(block->lba), 656 UPPER32(block->lba) 657 }; 658 hash_table_remove(&cache->block_hash, key, 2); 647 659 fibril_mutex_unlock(&block->lock); 648 660 free(block->data); -
uspace/lib/c/Makefile
r9350bfdd r7ae249d 59 59 -include arch/$(UARCH)/Makefile.inc 60 60 61 EXTRA_CFLAGS += -I../../srv/loader/include62 63 61 GENERIC_SOURCES = \ 64 62 generic/libc.c \ … … 71 69 generic/device/hw_res.c \ 72 70 generic/device/char_dev.c \ 71 generic/elf/elf_load.c \ 73 72 generic/event.c \ 74 73 generic/errno.c \ … … 134 133 generic/dlfcn.c \ 135 134 generic/rtld/rtld.c \ 136 generic/rtld/elf_load.c \137 135 generic/rtld/dynamic.c \ 138 136 generic/rtld/module.c \ -
uspace/lib/c/generic/elf/elf_load.c
r9350bfdd r7ae249d 29 29 */ 30 30 31 /** @addtogroup generic 31 /** @addtogroup generic 32 32 * @{ 33 33 */ … … 49 49 #include <assert.h> 50 50 #include <as.h> 51 #include <elf/elf.h> 51 52 #include <unistd.h> 52 53 #include <fcntl.h> … … 55 56 #include <entry_point.h> 56 57 57 #include "elf.h" 58 #include "elf_load.h" 58 #include <elf/elf_load.h> 59 59 60 60 #define DPRINTF(...) … … 74 74 static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry); 75 75 76 /** Read until the buffer is read in its entirety. */77 static int my_read(int fd, void *buf, size_t len)78 {79 int cnt = 0;80 do {81 buf += cnt;82 len -= cnt;83 cnt = read(fd, buf, len);84 } while ((cnt > 0) && ((len - cnt) > 0));85 86 return cnt;87 }88 89 76 /** Load ELF binary from a file. 90 77 * … … 160 147 int i, rc; 161 148 162 rc = my_read(elf->fd, header, sizeof(elf_header_t));163 if (rc < 0) {149 rc = read_all(elf->fd, header, sizeof(elf_header_t)); 150 if (rc != sizeof(elf_header_t)) { 164 151 DPRINTF("Read error.\n"); 165 152 return EE_INVALID; … … 222 209 + i * sizeof(elf_segment_header_t), SEEK_SET); 223 210 224 rc = my_read(elf->fd, &segment_hdr,211 rc = read_all(elf->fd, &segment_hdr, 225 212 sizeof(elf_segment_header_t)); 226 if (rc < 0) {213 if (rc != sizeof(elf_segment_header_t)) { 227 214 DPRINTF("Read error.\n"); 228 215 return EE_INVALID; … … 244 231 + i * sizeof(elf_section_header_t), SEEK_SET); 245 232 246 rc = my_read(elf->fd, §ion_hdr,233 rc = read_all(elf->fd, §ion_hdr, 247 234 sizeof(elf_section_header_t)); 248 if (rc < 0) {235 if (rc != sizeof(elf_section_header_t)) { 249 236 DPRINTF("Read error.\n"); 250 237 return EE_INVALID; … … 334 321 uintptr_t seg_addr; 335 322 size_t mem_sz; 336 int rc;323 ssize_t rc; 337 324 338 325 bias = elf->bias; … … 412 399 if (now > left) now = left; 413 400 414 rc = my_read(elf->fd, dp, now);415 416 if (rc < 0) {401 rc = read_all(elf->fd, dp, now); 402 403 if (rc != (ssize_t) now) { 417 404 DPRINTF("Read error.\n"); 418 405 return EE_INVALID; -
uspace/lib/c/generic/io/io.c
r9350bfdd r7ae249d 594 594 } 595 595 596 buf+= now;596 data += now; 597 597 stream->buf_head += now; 598 598 buf_free -= now; 599 599 bytes_left -= now; 600 600 total_written += now; 601 stream->buf_state = _bs_write; 601 602 602 603 if (buf_free == 0) { … … 606 607 } 607 608 } 608 609 if (total_written > 0)610 stream->buf_state = _bs_write;611 609 612 610 if (need_flush) -
uspace/lib/c/generic/rtld/module.c
r9350bfdd r7ae249d 35 35 */ 36 36 37 #include <adt/list.h> 38 #include <elf/elf_load.h> 39 #include <fcntl.h> 40 #include <loader/pcb.h> 37 41 #include <stdio.h> 38 42 #include <stdlib.h> 39 43 #include <unistd.h> 40 #include <fcntl.h>41 #include <adt/list.h>42 #include <loader/pcb.h>43 44 44 45 #include <rtld/rtld.h> … … 47 48 #include <rtld/rtld_arch.h> 48 49 #include <rtld/module.h> 49 #include <elf_load.h>50 50 51 51 /** (Eagerly) process all relocation tables in a module. … … 93 93 module_t *module_find(const char *name) 94 94 { 95 link_t *head = &runtime_env->modules_head;96 97 link_t *cur;98 95 module_t *m; 99 96 const char *p, *soname; … … 110 107 111 108 /* Traverse list of all modules. Not extremely fast, but simple */ 112 DPRINTF("head = %p\n", head); 113 for (cur = head->next; cur != head; cur = cur->next) { 109 list_foreach(runtime_env->modules, cur) { 114 110 DPRINTF("cur = %p\n", cur); 115 111 m = list_get_instance(cur, module_t, modules_link); … … 177 173 178 174 /* Insert into the list of loaded modules */ 179 list_append(&m->modules_link, &runtime_env->modules _head);175 list_append(&m->modules_link, &runtime_env->modules); 180 176 181 177 return m; … … 249 245 void modules_process_relocs(module_t *start) 250 246 { 251 link_t *head = &runtime_env->modules_head; 252 253 link_t *cur; 254 module_t *m; 255 256 for (cur = head->next; cur != head; cur = cur->next) { 247 module_t *m; 248 249 list_foreach(runtime_env->modules, cur) { 257 250 m = list_get_instance(cur, module_t, modules_link); 258 251 … … 268 261 void modules_untag(void) 269 262 { 270 link_t *head = &runtime_env->modules_head; 271 272 link_t *cur; 273 module_t *m; 274 275 for (cur = head->next; cur != head; cur = cur->next) { 263 module_t *m; 264 265 list_foreach(runtime_env->modules, cur) { 276 266 m = list_get_instance(cur, module_t, modules_link); 277 267 m->bfs_tag = false; -
uspace/lib/c/generic/rtld/rtld.c
r9350bfdd r7ae249d 44 44 { 45 45 runtime_env = &rt_env_static; 46 list_initialize(&runtime_env->modules _head);46 list_initialize(&runtime_env->modules); 47 47 runtime_env->next_bias = 0x2000000; 48 48 runtime_env->program = NULL; -
uspace/lib/c/generic/rtld/symbol.c
r9350bfdd r7ae249d 38 38 #include <stdlib.h> 39 39 40 #include <elf/elf.h> 40 41 #include <rtld/rtld.h> 41 42 #include <rtld/rtld_debug.h> 42 43 #include <rtld/symbol.h> 43 #include <elf.h>44 44 45 45 /* … … 118 118 module_t *m, *dm; 119 119 elf_symbol_t *sym, *s; 120 li nk_t queue_head;120 list_t queue; 121 121 size_t i; 122 122 … … 132 132 133 133 /* Insert root (the program) into the queue and tag it */ 134 list_initialize(&queue _head);134 list_initialize(&queue); 135 135 start->bfs_tag = true; 136 list_append(&start->queue_link, &queue _head);136 list_append(&start->queue_link, &queue); 137 137 138 138 /* If the symbol is found, it will be stored in 'sym' */ … … 140 140 141 141 /* While queue is not empty */ 142 while (!list_empty(&queue _head)) {142 while (!list_empty(&queue)) { 143 143 /* Pop first element from the queue */ 144 m = list_get_instance( queue_head.next, module_t, queue_link);144 m = list_get_instance(list_first(&queue), module_t, queue_link); 145 145 list_remove(&m->queue_link); 146 146 … … 162 162 if (dm->bfs_tag == false) { 163 163 dm->bfs_tag = true; 164 list_append(&dm->queue_link, &queue _head);164 list_append(&dm->queue_link, &queue); 165 165 } 166 166 } … … 168 168 169 169 /* Empty the queue so that we leave it in a clean state */ 170 while (!list_empty(&queue _head))171 list_remove( queue_head.next);170 while (!list_empty(&queue)) 171 list_remove(list_first(&queue)); 172 172 173 173 if (!sym) { -
uspace/lib/c/generic/vfs/vfs.c
r9350bfdd r7ae249d 417 417 } 418 418 419 /** Read entire buffer. 420 * 421 * In face of short reads this function continues reading until either 422 * the entire buffer is read or no more data is available (at end of file). 423 * 424 * @param fildes File descriptor 425 * @param buf Buffer, @a nbytes bytes long 426 * @param nbytes Number of bytes to read 427 * 428 * @return On success, positive number of bytes read. 429 * On failure, negative error code from read(). 430 */ 431 ssize_t read_all(int fildes, void *buf, size_t nbyte) 432 { 433 ssize_t cnt = 0; 434 size_t nread = 0; 435 uint8_t *bp = (uint8_t *) buf; 436 437 do { 438 bp += cnt; 439 nread += cnt; 440 cnt = read(fildes, bp, nbyte - nread); 441 } while (cnt > 0 && (nbyte - nread - cnt) > 0); 442 443 if (cnt < 0) 444 return cnt; 445 446 return nread + cnt; 447 } 448 449 /** Write entire buffer. 450 * 451 * This function fails if it cannot write exactly @a len bytes to the file. 452 * 453 * @param fildes File descriptor 454 * @param buf Data, @a nbytes bytes long 455 * @param nbytes Number of bytes to write 456 * 457 * @return EOK on error, return value from write() if writing 458 * failed. 459 */ 460 ssize_t write_all(int fildes, const void *buf, size_t nbyte) 461 { 462 ssize_t cnt = 0; 463 ssize_t nwritten = 0; 464 const uint8_t *bp = (uint8_t *) buf; 465 466 do { 467 bp += cnt; 468 nwritten += cnt; 469 cnt = write(fildes, bp, nbyte - nwritten); 470 } while (cnt > 0 && ((ssize_t )nbyte - nwritten - cnt) > 0); 471 472 if (cnt < 0) 473 return cnt; 474 475 if ((ssize_t)nbyte - nwritten - cnt > 0) 476 return EIO; 477 478 return nbyte; 479 } 480 419 481 int fsync(int fildes) 420 482 { -
uspace/lib/c/include/elf/elf_load.h
r9350bfdd r7ae249d 1 1 /* 2 * Copyright (c) 2006 Sergey Bondari 2 3 * Copyright (c) 2008 Jiri Svoboda 3 4 * All rights reserved. … … 38 39 39 40 #include <arch/elf.h> 41 #include <elf/elf.h> 40 42 #include <sys/types.h> 41 43 #include <loader/pcb.h> 42 44 43 #include "elf.h" 45 /** 46 * ELF error return codes 47 */ 48 #define EE_OK 0 /* No error */ 49 #define EE_INVALID 1 /* Invalid ELF image */ 50 #define EE_MEMORY 2 /* Cannot allocate address space */ 51 #define EE_INCOMPATIBLE 3 /* ELF image is not compatible with current architecture */ 52 #define EE_UNSUPPORTED 4 /* Non-supported ELF (e.g. dynamic ELFs) */ 53 #define EE_LOADER 5 /* The image is actually a program loader. */ 54 #define EE_IRRECOVERABLE 6 44 55 45 56 typedef enum { … … 82 93 } elf_ld_t; 83 94 84 int elf_load_file(const char *file_name, size_t so_bias, eld_flags_t flags, 85 elf_info_t *info);86 void elf_create_pcb(elf_info_t *info, pcb_t *pcb);95 extern const char *elf_error(unsigned int); 96 extern int elf_load_file(const char *, size_t, eld_flags_t, elf_info_t *); 97 extern void elf_create_pcb(elf_info_t *, pcb_t *); 87 98 88 99 #endif -
uspace/lib/c/include/rtld/elf_dyn.h
r9350bfdd r7ae249d 39 39 #include <sys/types.h> 40 40 41 #include <elf .h>41 #include <elf/elf.h> 42 42 #include <libarch/rtld/elf_dyn.h> 43 43 -
uspace/lib/c/include/rtld/rtld.h
r9350bfdd r7ae249d 49 49 50 50 /** List of all loaded modules including rtld and the program */ 51 li nk_t modules_head;51 list_t modules; 52 52 53 53 /** Temporary hack to place each module at different address. */ -
uspace/lib/c/include/rtld/symbol.h
r9350bfdd r7ae249d 36 36 #define LIBC_RTLD_SYMBOL_H_ 37 37 38 #include <elf/elf.h> 38 39 #include <rtld/rtld.h> 39 #include <elf.h>40 40 41 41 elf_symbol_t *symbol_bfs_find(const char *name, module_t *start, module_t **mod); -
uspace/lib/c/include/unistd.h
r9350bfdd r7ae249d 63 63 extern ssize_t read(int, void *, size_t); 64 64 65 extern ssize_t read_all(int, void *, size_t); 66 extern ssize_t write_all(int, const void *, size_t); 67 65 68 extern off64_t lseek(int, off64_t, int); 66 69 extern int ftruncate(int, aoff64_t); -
uspace/lib/fs/libfs.c
r9350bfdd r7ae249d 45 45 #include <mem.h> 46 46 #include <sys/stat.h> 47 #include <stdlib.h> 47 48 48 49 #define on_error(rc, action) \ … … 61 62 } while (0) 62 63 64 static fs_reg_t reg; 65 66 static vfs_out_ops_t *vfs_out_ops = NULL; 67 static libfs_ops_t *libfs_ops = NULL; 68 69 static void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *); 70 static void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *); 71 static void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, 72 ipc_call_t *); 73 static void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *); 74 static void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t, 75 ipc_call_t *); 76 77 static void vfs_out_mounted(ipc_callid_t rid, ipc_call_t *req) 78 { 79 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 80 char *opts; 81 int rc; 82 83 /* Accept the mount options. */ 84 rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL); 85 if (rc != EOK) { 86 async_answer_0(rid, rc); 87 return; 88 } 89 90 fs_index_t index; 91 aoff64_t size; 92 unsigned lnkcnt; 93 rc = vfs_out_ops->mounted(devmap_handle, opts, &index, &size, &lnkcnt); 94 95 if (rc == EOK) 96 async_answer_4(rid, EOK, index, LOWER32(size), UPPER32(size), 97 lnkcnt); 98 else 99 async_answer_0(rid, rc); 100 101 free(opts); 102 } 103 104 static void vfs_out_mount(ipc_callid_t rid, ipc_call_t *req) 105 { 106 libfs_mount(libfs_ops, reg.fs_handle, rid, req); 107 } 108 109 static void vfs_out_unmounted(ipc_callid_t rid, ipc_call_t *req) 110 { 111 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 112 int rc; 113 114 rc = vfs_out_ops->unmounted(devmap_handle); 115 116 async_answer_0(rid, rc); 117 } 118 119 static void vfs_out_unmount(ipc_callid_t rid, ipc_call_t *req) 120 { 121 122 libfs_unmount(libfs_ops, rid, req); 123 } 124 125 static void vfs_out_lookup(ipc_callid_t rid, ipc_call_t *req) 126 { 127 libfs_lookup(libfs_ops, reg.fs_handle, rid, req); 128 } 129 130 static void vfs_out_read(ipc_callid_t rid, ipc_call_t *req) 131 { 132 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 133 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req); 134 aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req), 135 IPC_GET_ARG4(*req)); 136 size_t rbytes; 137 int rc; 138 139 rc = vfs_out_ops->read(devmap_handle, index, pos, &rbytes); 140 141 if (rc == EOK) 142 async_answer_1(rid, EOK, rbytes); 143 else 144 async_answer_0(rid, rc); 145 } 146 147 static void vfs_out_write(ipc_callid_t rid, ipc_call_t *req) 148 { 149 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 150 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req); 151 aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req), 152 IPC_GET_ARG4(*req)); 153 size_t wbytes; 154 aoff64_t nsize; 155 int rc; 156 157 rc = vfs_out_ops->write(devmap_handle, index, pos, &wbytes, &nsize); 158 159 if (rc == EOK) 160 async_answer_3(rid, EOK, wbytes, LOWER32(nsize), UPPER32(nsize)); 161 else 162 async_answer_0(rid, rc); 163 } 164 165 static void vfs_out_truncate(ipc_callid_t rid, ipc_call_t *req) 166 { 167 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 168 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req); 169 aoff64_t size = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req), 170 IPC_GET_ARG4(*req)); 171 int rc; 172 173 rc = vfs_out_ops->truncate(devmap_handle, index, size); 174 175 async_answer_0(rid, rc); 176 } 177 178 static void vfs_out_close(ipc_callid_t rid, ipc_call_t *req) 179 { 180 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 181 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req); 182 int rc; 183 184 rc = vfs_out_ops->close(devmap_handle, index); 185 186 async_answer_0(rid, rc); 187 } 188 189 static void vfs_out_destroy(ipc_callid_t rid, ipc_call_t *req) 190 { 191 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 192 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req); 193 int rc; 194 195 rc = vfs_out_ops->destroy(devmap_handle, index); 196 197 async_answer_0(rid, rc); 198 } 199 200 static void vfs_out_open_node(ipc_callid_t rid, ipc_call_t *req) 201 { 202 libfs_open_node(libfs_ops, reg.fs_handle, rid, req); 203 } 204 205 static void vfs_out_stat(ipc_callid_t rid, ipc_call_t *req) 206 { 207 libfs_stat(libfs_ops, reg.fs_handle, rid, req); 208 } 209 210 static void vfs_out_sync(ipc_callid_t rid, ipc_call_t *req) 211 { 212 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 213 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req); 214 int rc; 215 216 rc = vfs_out_ops->sync(devmap_handle, index); 217 218 async_answer_0(rid, rc); 219 } 220 221 static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 222 { 223 if (iid) { 224 /* 225 * This only happens for connections opened by 226 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections 227 * created by IPC_M_CONNECT_TO_ME. 228 */ 229 async_answer_0(iid, EOK); 230 } 231 232 while (true) { 233 ipc_call_t call; 234 ipc_callid_t callid = async_get_call(&call); 235 236 if (!IPC_GET_IMETHOD(call)) 237 return; 238 239 switch (IPC_GET_IMETHOD(call)) { 240 case VFS_OUT_MOUNTED: 241 vfs_out_mounted(callid, &call); 242 break; 243 case VFS_OUT_MOUNT: 244 vfs_out_mount(callid, &call); 245 break; 246 case VFS_OUT_UNMOUNTED: 247 vfs_out_unmounted(callid, &call); 248 break; 249 case VFS_OUT_UNMOUNT: 250 vfs_out_unmount(callid, &call); 251 break; 252 case VFS_OUT_LOOKUP: 253 vfs_out_lookup(callid, &call); 254 break; 255 case VFS_OUT_READ: 256 vfs_out_read(callid, &call); 257 break; 258 case VFS_OUT_WRITE: 259 vfs_out_write(callid, &call); 260 break; 261 case VFS_OUT_TRUNCATE: 262 vfs_out_truncate(callid, &call); 263 break; 264 case VFS_OUT_CLOSE: 265 vfs_out_close(callid, &call); 266 break; 267 case VFS_OUT_DESTROY: 268 vfs_out_destroy(callid, &call); 269 break; 270 case VFS_OUT_OPEN_NODE: 271 vfs_out_open_node(callid, &call); 272 break; 273 case VFS_OUT_STAT: 274 vfs_out_stat(callid, &call); 275 break; 276 case VFS_OUT_SYNC: 277 vfs_out_sync(callid, &call); 278 break; 279 default: 280 async_answer_0(callid, ENOTSUP); 281 break; 282 } 283 } 284 } 285 63 286 /** Register file system server. 64 287 * … … 68 291 * 69 292 * @param sess Session for communication with VFS. 70 * @param reg File system registration structure. It will be71 * initialized by this function.72 293 * @param info VFS info structure supplied by the file system 73 294 * implementation. 74 * @param conn Connection fibril for handling all calls originating in75 * VFS.295 * @param vops Address of the vfs_out_ops_t structure. 296 * @param lops Address of the libfs_ops_t structure. 76 297 * 77 298 * @return EOK on success or a non-zero error code on errror. 78 299 * 79 300 */ 80 int fs_register(async_sess_t *sess, fs_reg_t *reg, vfs_info_t *info,81 async_client_conn_t conn)301 int fs_register(async_sess_t *sess, vfs_info_t *info, vfs_out_ops_t *vops, 302 libfs_ops_t *lops) 82 303 { 83 304 /* … … 104 325 105 326 /* 327 * Set VFS_OUT and libfs operations. 328 */ 329 vfs_out_ops = vops; 330 libfs_ops = lops; 331 332 /* 106 333 * Ask VFS for callback connection. 107 334 */ 108 async_connect_to_me(exch, 0, 0, 0, conn, NULL);335 async_connect_to_me(exch, 0, 0, 0, vfs_connection, NULL); 109 336 110 337 /* 111 338 * Allocate piece of address space for PLB. 112 339 */ 113 reg ->plb_ro = as_get_mappable_page(PLB_SIZE);114 if (!reg ->plb_ro) {340 reg.plb_ro = as_get_mappable_page(PLB_SIZE); 341 if (!reg.plb_ro) { 115 342 async_exchange_end(exch); 116 343 async_wait_for(req, NULL); … … 121 348 * Request sharing the Path Lookup Buffer with VFS. 122 349 */ 123 rc = async_share_in_start_0_0(exch, reg ->plb_ro, PLB_SIZE);350 rc = async_share_in_start_0_0(exch, reg.plb_ro, PLB_SIZE); 124 351 125 352 async_exchange_end(exch); … … 134 361 */ 135 362 async_wait_for(req, NULL); 136 reg ->fs_handle = (int) IPC_GET_ARG1(answer);363 reg.fs_handle = (int) IPC_GET_ARG1(answer); 137 364 138 365 /* … … 140 367 * the same connection fibril as well. 141 368 */ 142 async_set_client_connection( conn);369 async_set_client_connection(vfs_connection); 143 370 144 371 return IPC_GET_RETVAL(answer); … … 151 378 152 379 void libfs_mount(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid, 153 ipc_call_t *req uest)154 { 155 devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req uest);156 fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req uest);157 fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*req uest);158 devmap_handle_t mr_devmap_handle = (devmap_handle_t) IPC_GET_ARG4(*req uest);380 ipc_call_t *req) 381 { 382 devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 383 fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req); 384 fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*req); 385 devmap_handle_t mr_devmap_handle = (devmap_handle_t) IPC_GET_ARG4(*req); 159 386 160 387 async_sess_t *mountee_sess = async_clone_receive(EXCHANGE_PARALLEL); … … 208 435 * Do not release the FS node so that it stays in memory. 209 436 */ 210 async_answer_ 3(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),211 IPC_GET_ARG3(answer) );212 } 213 214 void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *req uest)215 { 216 devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req uest);217 fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req uest);437 async_answer_4(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer), 438 IPC_GET_ARG3(answer), IPC_GET_ARG4(answer)); 439 } 440 441 void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *req) 442 { 443 devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 444 fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req); 218 445 fs_node_t *fn; 219 446 int res; … … 259 486 } 260 487 488 static char plb_get_char(unsigned pos) 489 { 490 return reg.plb_ro[pos % PLB_SIZE]; 491 } 492 261 493 /** Lookup VFS triplet by name in the file system name space. 262 494 * … … 273 505 */ 274 506 void libfs_lookup(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid, 275 ipc_call_t *req uest)276 { 277 unsigned int first = IPC_GET_ARG1(*req uest);278 unsigned int last = IPC_GET_ARG2(*req uest);507 ipc_call_t *req) 508 { 509 unsigned int first = IPC_GET_ARG1(*req); 510 unsigned int last = IPC_GET_ARG2(*req); 279 511 unsigned int next = first; 280 devmap_handle_t devmap_handle = IPC_GET_ARG3(*req uest);281 int lflag = IPC_GET_ARG4(*req uest);282 fs_index_t index = IPC_GET_ARG5(*req uest);512 devmap_handle_t devmap_handle = IPC_GET_ARG3(*req); 513 int lflag = IPC_GET_ARG4(*req); 514 fs_index_t index = IPC_GET_ARG5(*req); 283 515 char component[NAME_MAX + 1]; 284 516 int len; … … 298 530 async_exch_t *exch = async_exchange_begin(cur->mp_data.sess); 299 531 async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last, 300 cur->mp_data.devmap_handle, lflag, index, IPC_FF_ROUTE_FROM_ME); 532 cur->mp_data.devmap_handle, lflag, index, 533 IPC_FF_ROUTE_FROM_ME); 301 534 async_exchange_end(exch); 302 535 … … 306 539 307 540 /* Eat slash */ 308 if ( ops->plb_get_char(next) == '/')541 if (plb_get_char(next) == '/') 309 542 next++; 310 543 … … 319 552 /* Collect the component */ 320 553 len = 0; 321 while ((next <= last) && ( ops->plb_get_char(next) != '/')) {554 while ((next <= last) && (plb_get_char(next) != '/')) { 322 555 if (len + 1 == NAME_MAX) { 323 556 /* Component length overflow */ … … 325 558 goto out; 326 559 } 327 component[len++] = ops->plb_get_char(next);560 component[len++] = plb_get_char(next); 328 561 /* Process next character */ 329 562 next++; … … 357 590 358 591 async_exch_t *exch = async_exchange_begin(tmp->mp_data.sess); 359 async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last,360 tmp->mp_data.devmap_handle, lflag, index,592 async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, 593 last, tmp->mp_data.devmap_handle, lflag, index, 361 594 IPC_FF_ROUTE_FROM_ME); 362 595 async_exchange_end(exch); … … 451 684 len = 0; 452 685 while (next <= last) { 453 if ( ops->plb_get_char(next) == '/') {686 if (plb_get_char(next) == '/') { 454 687 /* More than one component */ 455 688 async_answer_0(rid, ENOENT); … … 463 696 } 464 697 465 component[len++] = ops->plb_get_char(next);698 component[len++] = plb_get_char(next); 466 699 /* Process next character */ 467 700 next++; … … 637 870 rc = ops->node_open(fn); 638 871 aoff64_t size = ops->size_get(fn); 639 async_answer_4(rid, rc, LOWER32(size), UPPER32(size), ops->lnkcnt_get(fn), 872 async_answer_4(rid, rc, LOWER32(size), UPPER32(size), 873 ops->lnkcnt_get(fn), 640 874 (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0)); 641 875 -
uspace/lib/fs/libfs.h
r9350bfdd r7ae249d 43 43 44 44 typedef struct { 45 int (* mounted)(devmap_handle_t, const char *, fs_index_t *, aoff64_t *, 46 unsigned *); 47 int (* unmounted)(devmap_handle_t); 48 int (* read)(devmap_handle_t, fs_index_t, aoff64_t, size_t *); 49 int (* write)(devmap_handle_t, fs_index_t, aoff64_t, size_t *, 50 aoff64_t *); 51 int (* truncate)(devmap_handle_t, fs_index_t, aoff64_t); 52 int (* close)(devmap_handle_t, fs_index_t); 53 int (* destroy)(devmap_handle_t, fs_index_t); 54 int (* sync)(devmap_handle_t, fs_index_t); 55 } vfs_out_ops_t; 56 57 typedef struct { 45 58 bool mp_active; 46 59 async_sess_t *sess; … … 71 84 int (* has_children)(bool *, fs_node_t *); 72 85 /* 73 * The second set of methods are usually mere getters that do not return74 * an integer error code.86 * The second set of methods are usually mere getters that do not 87 * return an integer error code. 75 88 */ 76 89 fs_index_t (* index_get)(fs_node_t *); 77 90 aoff64_t (* size_get)(fs_node_t *); 78 91 unsigned int (* lnkcnt_get)(fs_node_t *); 79 char (* plb_get_char)(unsigned pos);80 92 bool (* is_directory)(fs_node_t *); 81 93 bool (* is_file)(fs_node_t *); … … 88 100 } fs_reg_t; 89 101 90 extern int fs_register(async_sess_t *, fs_reg_t *, vfs_info_t *,91 async_client_conn_t);102 extern int fs_register(async_sess_t *, vfs_info_t *, vfs_out_ops_t *, 103 libfs_ops_t *); 92 104 93 105 extern void fs_node_initialize(fs_node_t *); 94 95 extern void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);96 extern void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);97 extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);98 extern void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);99 extern void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t,100 ipc_call_t *);101 106 102 107 #endif -
uspace/lib/scsi/include/scsi/sbc.h
r9350bfdd r7ae249d 56 56 }; 57 57 58 /** SCSI Read (10) command */ 59 typedef struct { 60 /** Operation code (SCSI_CMD_READ_10) */ 61 uint8_t op_code; 62 /** RdProtect, DPO, FUA, Reserved, FUA_NV, Obsolete */ 63 uint8_t flags; 64 /** Logical block address */ 65 uint32_t lba; 66 /** Reserved, Group Number */ 67 uint8_t group_no; 68 /** Transfer length */ 69 uint16_t xfer_len; 70 /** Control */ 71 uint8_t control; 72 } __attribute__((packed)) scsi_cdb_read_10_t; 73 58 74 /** SCSI Read (12) command */ 59 75 typedef struct { 60 76 /** Operation code (SCSI_CMD_READ_12) */ 61 77 uint8_t op_code; 62 /** RdProtect, DPO, FUA, Reserved, FUA_NV, Reserved*/78 /** RdProtect, DPO, FUA, Reserved, FUA_NV, Obsolete */ 63 79 uint8_t flags; 64 80 /** Logical block address */ … … 115 131 } scsi_read_capacity_10_data_t; 116 132 133 /** SCSI Write (10) command */ 134 typedef struct { 135 /** Operation code (SCSI_CMD_WRITE_10) */ 136 uint8_t op_code; 137 /** WrProtect, DPO, FUA, Reserved, FUA_NV, Obsolete */ 138 uint8_t flags; 139 /** Logical block address */ 140 uint32_t lba; 141 /** Reserved, Group Number */ 142 uint8_t group_no; 143 /** Transfer length */ 144 uint16_t xfer_len; 145 /** Control */ 146 uint8_t control; 147 } __attribute__((packed)) scsi_cdb_write_10_t; 148 117 149 /** SCSI Write (12) command */ 118 150 typedef struct { 119 151 /** Operation code (SCSI_CMD_WRITE_12) */ 120 152 uint8_t op_code; 121 /** WrProtect, DPO, FUA, Reserved, FUA_NV, Reserved*/153 /** WrProtect, DPO, FUA, Reserved, FUA_NV, Obsolete */ 122 154 uint8_t flags; 123 155 /** Logical block address */ -
uspace/lib/scsi/include/scsi/spc.h
r9350bfdd r7ae249d 179 179 uint8_t additional_len; 180 180 /** Command-specific Information */ 181 uint 8_t cmd_spec;181 uint32_t cmd_spec; 182 182 /** Additional Sense Code */ 183 183 uint8_t additional_code; … … 205 205 SCSI_SK_ABORTED_COMMAND = 0xb, 206 206 SCSI_SK_VOLUME_OVERFLOW = 0xd, 207 SCSI_SK_MISCOMPARE = 0xe 207 SCSI_SK_MISCOMPARE = 0xe, 208 209 SCSI_SK_LIMIT = 0x10 208 210 }; 209 211 210 212 extern const char *scsi_dev_type_str[SCSI_DEV_LIMIT]; 213 extern const char *scsi_sense_key_str[SCSI_SK_LIMIT]; 214 211 215 extern const char *scsi_get_dev_type_str(unsigned); 216 extern const char *scsi_get_sense_key_str(unsigned); 212 217 213 218 #endif -
uspace/lib/scsi/src/spc.c
r9350bfdd r7ae249d 44 44 }; 45 45 46 const char *scsi_sense_key_str[SCSI_SK_LIMIT] = { 47 [SCSI_SK_NO_SENSE] = "No Sense", 48 [SCSI_SK_RECOVERED_ERROR] = "Recovered Error", 49 [SCSI_SK_NOT_READY] = "Not Ready", 50 [SCSI_SK_MEDIUM_ERROR] = "Medium Error", 51 [SCSI_SK_HARDWARE_ERROR] = "Hardware Error", 52 [SCSI_SK_ILLEGAL_REQUEST] = "Illegal Request", 53 [SCSI_SK_UNIT_ATTENTION] = "Unit Attention", 54 [SCSI_SK_DATA_PROTECT] = "Data Protect", 55 [SCSI_SK_BLANK_CHECK] = "Blank Check", 56 [SCSI_SK_VENDOR_SPECIFIC] = "Vendor-specific", 57 [SCSI_SK_COPY_ABORTED] = "Copy Aborted", 58 [SCSI_SK_ABORTED_COMMAND] = "Aborted Command", 59 [SCSI_SK_VOLUME_OVERFLOW] = "Volume Overflow", 60 [SCSI_SK_MISCOMPARE] = "Miscompare" 61 }; 62 46 63 /** Get peripheral device type string. 47 64 * … … 53 70 { 54 71 if (dev_type >= SCSI_DEV_LIMIT || scsi_dev_type_str[dev_type] == NULL) 55 return " <unknown>";72 return "Unknown"; 56 73 57 74 return scsi_dev_type_str[dev_type]; 58 75 } 76 77 /** Get sense key string. 78 * 79 * Return string description of SCSI sense key. 80 * The returned string is valid indefinitely, the caller should 81 * not attempt to free it. 82 */ 83 const char *scsi_get_sense_key_str(unsigned sense_key) 84 { 85 if (sense_key >= SCSI_SK_LIMIT || scsi_sense_key_str[sense_key] == NULL) 86 return "Unknown"; 87 88 return scsi_sense_key_str[sense_key]; 89 } 90 -
uspace/srv/devman/devman.c
r9350bfdd r7ae249d 270 270 } 271 271 272 ssize_t read_bytes = safe_read(fd, buf, len);272 ssize_t read_bytes = read_all(fd, buf, len); 273 273 if (read_bytes <= 0) { 274 log_msg(LVL_ERROR, "Unable to read file '%s'.", conf_path); 274 log_msg(LVL_ERROR, "Unable to read file '%s' (%zd).", conf_path, 275 read_bytes); 275 276 goto cleanup; 276 277 } … … 421 422 } 422 423 423 insert_fun_node(tree, fun, clone_string(""), NULL);424 insert_fun_node(tree, fun, str_dup(""), NULL); 424 425 match_id_t *id = create_match_id(); 425 id->id = clone_string("root");426 id->id = str_dup("root"); 426 427 id->score = 100; 427 428 add_match_id(&fun->match_ids, id); -
uspace/srv/devman/util.c
r9350bfdd r7ae249d 91 91 } 92 92 93 char *clone_string(const char *s)94 {95 size_t size = str_size(s) + 1;96 char *str;97 98 str = (char *) malloc(size);99 if (str != NULL)100 str_cpy(str, size, s);101 return str;102 }103 104 93 void replace_char(char *str, char orig, char repl) 105 94 { … … 111 100 } 112 101 113 ssize_t safe_read(int fd, void *buffer, size_t size)114 {115 if (size == 0) {116 return 0;117 }118 119 uint8_t *buf_ptr = (uint8_t *) buffer;120 121 size_t total_read = 0;122 while (total_read < size) {123 ssize_t bytes_read = read(fd, buf_ptr, size - total_read);124 if (bytes_read < 0) {125 /* Error. */126 return bytes_read;127 } else if (bytes_read == 0) {128 /* Possibly end of file. */129 break;130 } else {131 /* Read at least something. */132 buf_ptr += bytes_read;133 total_read += bytes_read;134 }135 }136 137 return (ssize_t) total_read;138 }139 140 102 /** @} 141 103 */ -
uspace/srv/devman/util.h
r9350bfdd r7ae249d 44 44 extern size_t get_nonspace_len(const char *); 45 45 extern void free_not_null(const void *); 46 extern char *clone_string(const char *);47 46 extern void replace_char(char *, char, char); 48 49 extern ssize_t safe_read(int, void *, size_t);50 47 51 48 #endif -
uspace/srv/fs/devfs/devfs.c
r9350bfdd r7ae249d 57 57 }; 58 58 59 fs_reg_t devfs_reg;60 61 static void devfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)62 {63 if (iid)64 async_answer_0(iid, EOK);65 66 while (true) {67 ipc_call_t call;68 ipc_callid_t callid = async_get_call(&call);69 70 if (!IPC_GET_IMETHOD(call))71 return;72 73 switch (IPC_GET_IMETHOD(call)) {74 case VFS_OUT_MOUNTED:75 devfs_mounted(callid, &call);76 break;77 case VFS_OUT_MOUNT:78 devfs_mount(callid, &call);79 break;80 case VFS_OUT_UNMOUNTED:81 devfs_unmounted(callid, &call);82 break;83 case VFS_OUT_UNMOUNT:84 devfs_unmount(callid, &call);85 break;86 case VFS_OUT_LOOKUP:87 devfs_lookup(callid, &call);88 break;89 case VFS_OUT_OPEN_NODE:90 devfs_open_node(callid, &call);91 break;92 case VFS_OUT_STAT:93 devfs_stat(callid, &call);94 break;95 case VFS_OUT_READ:96 devfs_read(callid, &call);97 break;98 case VFS_OUT_WRITE:99 devfs_write(callid, &call);100 break;101 case VFS_OUT_TRUNCATE:102 devfs_truncate(callid, &call);103 break;104 case VFS_OUT_CLOSE:105 devfs_close(callid, &call);106 break;107 case VFS_OUT_SYNC:108 devfs_sync(callid, &call);109 break;110 case VFS_OUT_DESTROY:111 devfs_destroy(callid, &call);112 break;113 default:114 async_answer_0(callid, ENOTSUP);115 break;116 }117 }118 }119 120 59 int main(int argc, char *argv[]) 121 60 { … … 134 73 } 135 74 136 int rc = fs_register(vfs_sess, &devfs_ reg, &devfs_vfs_info,137 devfs_connection);75 int rc = fs_register(vfs_sess, &devfs_vfs_info, &devfs_ops, 76 &devfs_libfs_ops); 138 77 if (rc != EOK) { 139 78 printf("%s: Failed to register file system (%d)\n", NAME, rc); … … 152 91 * @} 153 92 */ 93 -
uspace/srv/fs/devfs/devfs.h
r9350bfdd r7ae249d 36 36 #include <libfs.h> 37 37 38 extern fs_reg_t devfs_reg; 38 extern vfs_out_ops_t devfs_ops; 39 extern libfs_ops_t devfs_libfs_ops; 39 40 40 41 #endif -
uspace/srv/fs/devfs/devfs_ops.c
r9350bfdd r7ae249d 403 403 } 404 404 405 static char devfs_plb_get_char(unsigned pos)406 {407 return devfs_reg.plb_ro[pos % PLB_SIZE];408 }409 410 405 static bool devfs_is_directory(fs_node_t *fn) 411 406 { … … 447 442 .size_get = devfs_size_get, 448 443 .lnkcnt_get = devfs_lnkcnt_get, 449 .plb_get_char = devfs_plb_get_char,450 444 .is_directory = devfs_is_directory, 451 445 .is_file = devfs_is_file, … … 462 456 } 463 457 464 void devfs_mounted(ipc_callid_t rid, ipc_call_t *request) 465 { 466 char *opts; 467 468 /* Accept the mount options */ 469 sysarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0, 470 0, NULL); 471 if (retval != EOK) { 472 async_answer_0(rid, retval); 473 return; 474 } 475 476 free(opts); 477 async_answer_3(rid, EOK, 0, 0, 0); 478 } 479 480 void devfs_mount(ipc_callid_t rid, ipc_call_t *request) 481 { 482 libfs_mount(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 483 } 484 485 void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request) 486 { 487 async_answer_0(rid, ENOTSUP); 488 } 489 490 void devfs_unmount(ipc_callid_t rid, ipc_call_t *request) 491 { 492 libfs_unmount(&devfs_libfs_ops, rid, request); 493 } 494 495 void devfs_lookup(ipc_callid_t rid, ipc_call_t *request) 496 { 497 libfs_lookup(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 498 } 499 500 void devfs_open_node(ipc_callid_t rid, ipc_call_t *request) 501 { 502 libfs_open_node(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 503 } 504 505 void devfs_stat(ipc_callid_t rid, ipc_call_t *request) 506 { 507 libfs_stat(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 508 } 509 510 void devfs_read(ipc_callid_t rid, ipc_call_t *request) 511 { 512 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 513 aoff64_t pos = 514 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 515 458 static int devfs_mounted(devmap_handle_t devmap_handle, const char *opts, 459 fs_index_t *index, aoff64_t *size, unsigned *lnkcnt) 460 { 461 *index = 0; 462 *size = 0; 463 *lnkcnt = 0; 464 return EOK; 465 } 466 467 static int devfs_unmounted(devmap_handle_t devmap_handle) 468 { 469 return ENOTSUP; 470 } 471 472 static int 473 devfs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 474 size_t *rbytes) 475 { 516 476 if (index == 0) { 517 477 ipc_callid_t callid; … … 519 479 if (!async_data_read_receive(&callid, &size)) { 520 480 async_answer_0(callid, EINVAL); 521 async_answer_0(rid, EINVAL); 522 return; 481 return EINVAL; 523 482 } 524 483 … … 540 499 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 541 500 free(desc); 542 async_answer_1(rid, EOK, 1);543 return ;501 *rbytes = 1; 502 return EOK; 544 503 } 545 504 … … 555 514 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 556 515 free(desc); 557 async_answer_1(rid, EOK, 1);558 return ;516 *rbytes = 1; 517 return EOK; 559 518 } 560 519 … … 563 522 564 523 async_answer_0(callid, ENOENT); 565 async_answer_1(rid, ENOENT, 0); 566 return; 524 return ENOENT; 567 525 } 568 526 … … 575 533 if (!async_data_read_receive(&callid, &size)) { 576 534 async_answer_0(callid, EINVAL); 577 async_answer_0(rid, EINVAL); 578 return; 535 return EINVAL; 579 536 } 580 537 … … 585 542 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 586 543 free(desc); 587 async_answer_1(rid, EOK, 1);588 return ;544 *rbytes = 1; 545 return EOK; 589 546 } 590 547 591 548 free(desc); 592 549 async_answer_0(callid, ENOENT); 593 async_answer_1(rid, ENOENT, 0); 594 return; 550 return ENOENT; 595 551 } 596 552 … … 606 562 if (lnk == NULL) { 607 563 fibril_mutex_unlock(&devices_mutex); 608 async_answer_0(rid, ENOENT); 609 return; 564 return ENOENT; 610 565 } 611 566 … … 617 572 fibril_mutex_unlock(&devices_mutex); 618 573 async_answer_0(callid, EINVAL); 619 async_answer_0(rid, EINVAL); 620 return; 574 return EINVAL; 621 575 } 622 576 … … 625 579 626 580 ipc_call_t answer; 627 aid_t msg = async_send_3(exch, IPC_GET_IMETHOD(*request), 628 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 629 IPC_GET_ARG3(*request), &answer); 581 aid_t msg = async_send_4(exch, VFS_OUT_READ, devmap_handle, 582 index, LOWER32(pos), UPPER32(pos), &answer); 630 583 631 584 /* Forward the IPC_M_DATA_READ request to the driver */ … … 639 592 sysarg_t rc; 640 593 async_wait_for(msg, &rc); 641 size_t bytes = IPC_GET_ARG1(answer); 642 643 /* Driver reply is the final result of the whole operation */ 644 async_answer_1(rid, rc, bytes); 645 return; 646 } 647 648 async_answer_0(rid, ENOENT); 649 } 650 651 void devfs_write(ipc_callid_t rid, ipc_call_t *request) 652 { 653 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 654 if (index == 0) { 655 async_answer_0(rid, ENOTSUP); 656 return; 657 } 594 595 *rbytes = IPC_GET_ARG1(answer); 596 return rc; 597 } 598 599 return ENOENT; 600 } 601 602 static int 603 devfs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 604 size_t *wbytes, aoff64_t *nsize) 605 { 606 if (index == 0) 607 return ENOTSUP; 658 608 659 609 devmap_handle_type_t type = devmap_handle_probe(index); … … 661 611 if (type == DEV_HANDLE_NAMESPACE) { 662 612 /* Namespace directory */ 663 async_answer_0(rid, ENOTSUP); 664 return; 613 return ENOTSUP; 665 614 } 666 615 … … 675 624 if (lnk == NULL) { 676 625 fibril_mutex_unlock(&devices_mutex); 677 async_answer_0(rid, ENOENT); 678 return; 626 return ENOENT; 679 627 } 680 628 … … 686 634 fibril_mutex_unlock(&devices_mutex); 687 635 async_answer_0(callid, EINVAL); 688 async_answer_0(rid, EINVAL); 689 return; 636 return EINVAL; 690 637 } 691 638 … … 694 641 695 642 ipc_call_t answer; 696 aid_t msg = async_send_3(exch, IPC_GET_IMETHOD(*request), 697 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 698 IPC_GET_ARG3(*request), &answer); 643 aid_t msg = async_send_4(exch, VFS_OUT_WRITE, devmap_handle, 644 index, LOWER32(pos), UPPER32(pos), &answer); 699 645 700 646 /* Forward the IPC_M_DATA_WRITE request to the driver */ … … 708 654 sysarg_t rc; 709 655 async_wait_for(msg, &rc); 710 size_t bytes = IPC_GET_ARG1(answer); 711 712 /* Driver reply is the final result of the whole operation */ 713 async_answer_1(rid, rc, bytes); 714 return; 715 } 716 717 async_answer_0(rid, ENOENT); 718 } 719 720 void devfs_truncate(ipc_callid_t rid, ipc_call_t *request) 721 { 722 async_answer_0(rid, ENOTSUP); 723 } 724 725 void devfs_close(ipc_callid_t rid, ipc_call_t *request) 726 { 727 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 728 729 if (index == 0) { 730 async_answer_0(rid, EOK); 731 return; 732 } 656 657 *wbytes = IPC_GET_ARG1(answer); 658 *nsize = 0; 659 return rc; 660 } 661 662 return ENOENT; 663 } 664 665 static int 666 devfs_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size) 667 { 668 return ENOTSUP; 669 } 670 671 static int devfs_close(devmap_handle_t devmap_handle, fs_index_t index) 672 { 673 if (index == 0) 674 return EOK; 733 675 734 676 devmap_handle_type_t type = devmap_handle_probe(index); … … 736 678 if (type == DEV_HANDLE_NAMESPACE) { 737 679 /* Namespace directory */ 738 async_answer_0(rid, EOK); 739 return; 680 return EOK; 740 681 } 741 682 … … 749 690 if (lnk == NULL) { 750 691 fibril_mutex_unlock(&devices_mutex); 751 async_answer_0(rid, ENOENT); 752 return; 692 return ENOENT; 753 693 } 754 694 … … 764 704 fibril_mutex_unlock(&devices_mutex); 765 705 766 async_answer_0(rid, EOK); 767 return; 768 } 769 770 async_answer_0(rid, ENOENT); 771 } 772 773 void devfs_sync(ipc_callid_t rid, ipc_call_t *request) 774 { 775 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 776 777 if (index == 0) { 778 async_answer_0(rid, EOK); 779 return; 780 } 706 return EOK; 707 } 708 709 return ENOENT; 710 } 711 712 static int devfs_sync(devmap_handle_t devmap_handle, fs_index_t index) 713 { 714 if (index == 0) 715 return EOK; 781 716 782 717 devmap_handle_type_t type = devmap_handle_probe(index); … … 784 719 if (type == DEV_HANDLE_NAMESPACE) { 785 720 /* Namespace directory */ 786 async_answer_0(rid, EOK); 787 return; 721 return EOK; 788 722 } 789 723 … … 797 731 if (lnk == NULL) { 798 732 fibril_mutex_unlock(&devices_mutex); 799 async_answer_0(rid, ENOENT); 800 return; 733 return ENOENT; 801 734 } 802 735 … … 808 741 809 742 ipc_call_t answer; 810 aid_t msg = async_send_2(exch, IPC_GET_IMETHOD(*request),811 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer);743 aid_t msg = async_send_2(exch, VFS_OUT_SYNC, devmap_handle, 744 index, &answer); 812 745 813 746 async_exchange_end(exch); … … 819 752 async_wait_for(msg, &rc); 820 753 821 /* Driver reply is the final result of the whole operation */ 822 async_answer_0(rid, rc); 823 return; 824 } 825 826 async_answer_0(rid, ENOENT); 827 } 828 829 void devfs_destroy(ipc_callid_t rid, ipc_call_t *request) 830 { 831 async_answer_0(rid, ENOTSUP); 832 } 754 return rc; 755 } 756 757 return ENOENT; 758 } 759 760 static int devfs_destroy(devmap_handle_t devmap_handle, fs_index_t index) 761 { 762 return ENOTSUP; 763 } 764 765 vfs_out_ops_t devfs_ops = { 766 .mounted = devfs_mounted, 767 .unmounted = devfs_unmounted, 768 .read = devfs_read, 769 .write = devfs_write, 770 .truncate = devfs_truncate, 771 .close = devfs_close, 772 .destroy = devfs_destroy, 773 .sync = devfs_sync, 774 }; 833 775 834 776 /** -
uspace/srv/fs/devfs/devfs_ops.h
r9350bfdd r7ae249d 34 34 #define DEVFS_DEVFS_OPS_H_ 35 35 36 #include <ipc/common.h>37 36 #include <bool.h> 38 37 39 38 extern bool devfs_init(void); 40 41 extern void devfs_mounted(ipc_callid_t, ipc_call_t *);42 extern void devfs_mount(ipc_callid_t, ipc_call_t *);43 extern void devfs_unmounted(ipc_callid_t, ipc_call_t *);44 extern void devfs_unmount(ipc_callid_t, ipc_call_t *);45 extern void devfs_lookup(ipc_callid_t, ipc_call_t *);46 extern void devfs_open_node(ipc_callid_t, ipc_call_t *);47 extern void devfs_stat(ipc_callid_t, ipc_call_t *);48 extern void devfs_sync(ipc_callid_t, ipc_call_t *);49 extern void devfs_read(ipc_callid_t, ipc_call_t *);50 extern void devfs_write(ipc_callid_t, ipc_call_t *);51 extern void devfs_truncate(ipc_callid_t, ipc_call_t *);52 extern void devfs_close(ipc_callid_t, ipc_call_t *);53 extern void devfs_destroy(ipc_callid_t, ipc_call_t *);54 39 55 40 #endif -
uspace/srv/fs/ext2fs/ext2fs.c
r9350bfdd r7ae249d 1 1 /* 2 2 * Copyright (c) 2006 Martin Decky 3 * Copyright (c) 2008 Jakub Jermar4 3 * Copyright (c) 2011 Martin Sucha 5 4 * All rights reserved. … … 55 54 }; 56 55 57 fs_reg_t ext2fs_reg;58 59 /**60 * This connection fibril processes VFS requests from VFS.61 *62 * In order to support simultaneous VFS requests, our design is as follows.63 * The connection fibril accepts VFS requests from VFS. If there is only one64 * instance of the fibril, VFS will need to serialize all VFS requests it sends65 * to EXT2FS. To overcome this bottleneck, VFS can send EXT2FS the IPC_M_CONNECT_ME_TO66 * call. In that case, a new connection fibril will be created, which in turn67 * will accept the call. Thus, a new phone will be opened for VFS.68 *69 * There are few issues with this arrangement. First, VFS can run out of70 * available phones. In that case, VFS can close some other phones or use one71 * phone for more serialized requests. Similarily, EXT2FS can refuse to duplicate72 * the connection. VFS should then just make use of already existing phones and73 * route its requests through them. To avoid paying the fibril creation price74 * upon each request, EXT2FS might want to keep the connections open after the75 * request has been completed.76 */77 static void ext2fs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)78 {79 if (iid) {80 /*81 * This only happens for connections opened by82 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections83 * created by IPC_M_CONNECT_TO_ME.84 */85 async_answer_0(iid, EOK);86 }87 88 dprintf(NAME ": connection opened\n");89 while (true) {90 ipc_call_t call;91 ipc_callid_t callid = async_get_call(&call);92 93 if (!IPC_GET_IMETHOD(call))94 return;95 96 switch (IPC_GET_IMETHOD(call)) {97 case VFS_OUT_MOUNTED:98 ext2fs_mounted(callid, &call);99 break;100 case VFS_OUT_MOUNT:101 ext2fs_mount(callid, &call);102 break;103 case VFS_OUT_UNMOUNTED:104 ext2fs_unmounted(callid, &call);105 break;106 case VFS_OUT_UNMOUNT:107 ext2fs_unmount(callid, &call);108 break;109 case VFS_OUT_LOOKUP:110 ext2fs_lookup(callid, &call);111 break;112 case VFS_OUT_READ:113 ext2fs_read(callid, &call);114 break;115 case VFS_OUT_WRITE:116 ext2fs_write(callid, &call);117 break;118 case VFS_OUT_TRUNCATE:119 ext2fs_truncate(callid, &call);120 break;121 case VFS_OUT_STAT:122 ext2fs_stat(callid, &call);123 break;124 case VFS_OUT_CLOSE:125 ext2fs_close(callid, &call);126 break;127 case VFS_OUT_DESTROY:128 ext2fs_destroy(callid, &call);129 break;130 case VFS_OUT_OPEN_NODE:131 ext2fs_open_node(callid, &call);132 break;133 case VFS_OUT_SYNC:134 ext2fs_sync(callid, &call);135 break;136 default:137 async_answer_0(callid, ENOTSUP);138 break;139 }140 }141 }142 143 56 int main(int argc, char **argv) 144 57 { … … 158 71 } 159 72 160 rc = fs_register(vfs_sess, &ext2fs_reg, &ext2fs_vfs_info, ext2fs_connection); 73 rc = fs_register(vfs_sess, &ext2fs_vfs_info, &ext2fs_ops, 74 &ext2fs_libfs_ops); 161 75 if (rc != EOK) { 162 76 fprintf(stdout, NAME ": Failed to register fs (%d)\n", rc); -
uspace/srv/fs/ext2fs/ext2fs.h
r9350bfdd r7ae249d 1 1 /* 2 * Copyright (c) 2008 Jakub Jermar3 2 * Copyright (c) 2011 Martin Sucha 4 3 * All rights reserved. … … 36 35 37 36 #include <libext2.h> 38 #include <fibril_synch.h>39 37 #include <libfs.h> 40 #include <atomic.h>41 38 #include <sys/types.h> 42 #include <bool.h>43 #include "../../vfs/vfs.h"44 45 #ifndef dprintf46 #define dprintf(...) printf(__VA_ARGS__)47 #endif48 39 49 40 #define min(a, b) ((a) < (b) ? (a) : (b)) 50 41 51 extern fs_reg_t ext2fs_reg; 42 extern vfs_out_ops_t ext2fs_ops; 43 extern libfs_ops_t ext2fs_libfs_ops; 52 44 53 45 extern int ext2fs_global_init(void); 54 46 extern int ext2fs_global_fini(void); 55 extern void ext2fs_mounted(ipc_callid_t, ipc_call_t *);56 extern void ext2fs_mount(ipc_callid_t, ipc_call_t *);57 extern void ext2fs_unmounted(ipc_callid_t, ipc_call_t *);58 extern void ext2fs_unmount(ipc_callid_t, ipc_call_t *);59 extern void ext2fs_lookup(ipc_callid_t, ipc_call_t *);60 extern void ext2fs_read(ipc_callid_t, ipc_call_t *);61 extern void ext2fs_write(ipc_callid_t, ipc_call_t *);62 extern void ext2fs_truncate(ipc_callid_t, ipc_call_t *);63 extern void ext2fs_stat(ipc_callid_t, ipc_call_t *);64 extern void ext2fs_close(ipc_callid_t, ipc_call_t *);65 extern void ext2fs_destroy(ipc_callid_t, ipc_call_t *);66 extern void ext2fs_open_node(ipc_callid_t, ipc_call_t *);67 extern void ext2fs_stat(ipc_callid_t, ipc_call_t *);68 extern void ext2fs_sync(ipc_callid_t, ipc_call_t *);69 47 70 48 #endif -
uspace/srv/fs/ext2fs/ext2fs_ops.c
r9350bfdd r7ae249d 1 1 /* 2 * Copyright (c) 2008 Jakub Jermar3 2 * Copyright (c) 2011 Martin Sucha 4 3 * All rights reserved. … … 87 86 */ 88 87 static int ext2fs_instance_get(devmap_handle_t, ext2fs_instance_t **); 89 static void ext2fs_read_directory(ipc_callid_t, ipc_callid_t, aoff64_t,90 size_t, ext2fs_instance_t *, ext2_inode_ref_t *);91 static void ext2fs_read_file(ipc_callid_t, ipc_callid_t, aoff64_t,92 size_t, ext2fs_instance_t *, ext2_inode_ref_t *);88 static int ext2fs_read_directory(ipc_callid_t, aoff64_t, size_t, 89 ext2fs_instance_t *, ext2_inode_ref_t *, size_t *); 90 static int ext2fs_read_file(ipc_callid_t, aoff64_t, size_t, ext2fs_instance_t *, 91 ext2_inode_ref_t *, size_t *); 93 92 static bool ext2fs_is_dots(const uint8_t *, size_t); 94 93 static int ext2fs_node_get_core(fs_node_t **, ext2fs_instance_t *, fs_index_t); … … 111 110 static aoff64_t ext2fs_size_get(fs_node_t *); 112 111 static unsigned ext2fs_lnkcnt_get(fs_node_t *); 113 static char ext2fs_plb_get_char(unsigned);114 112 static bool ext2fs_is_directory(fs_node_t *); 115 113 static bool ext2fs_is_file(fs_node_t *node); … … 538 536 EXT2FS_DBG("%u", count); 539 537 return count; 540 }541 542 char ext2fs_plb_get_char(unsigned pos)543 {544 return ext2fs_reg.plb_ro[pos % PLB_SIZE];545 538 } 546 539 … … 586 579 .size_get = ext2fs_size_get, 587 580 .lnkcnt_get = ext2fs_lnkcnt_get, 588 .plb_get_char = ext2fs_plb_get_char,589 581 .is_directory = ext2fs_is_directory, 590 582 .is_file = ext2fs_is_file, … … 596 588 */ 597 589 598 void ext2fs_mounted(ipc_callid_t rid, ipc_call_t *request) 599 { 600 EXT2FS_DBG(""); 601 int rc;602 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);590 static int ext2fs_mounted(devmap_handle_t devmap_handle, const char *opts, 591 fs_index_t *index, aoff64_t *size, unsigned *lnkcnt) 592 { 593 EXT2FS_DBG(""); 594 int rc; 603 595 ext2_filesystem_t *fs; 604 596 ext2fs_instance_t *inst; 605 597 bool read_only; 606 598 607 /* Accept the mount options */608 char *opts;609 rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);610 611 if (rc != EOK) {612 async_answer_0(rid, rc);613 return;614 }615 616 free(opts);617 618 599 /* Allocate libext2 filesystem structure */ 619 600 fs = (ext2_filesystem_t *) malloc(sizeof(ext2_filesystem_t)); 620 if (fs == NULL) { 621 async_answer_0(rid, ENOMEM); 622 return; 623 } 601 if (fs == NULL) 602 return ENOMEM; 624 603 625 604 /* Allocate instance structure */ … … 627 606 if (inst == NULL) { 628 607 free(fs); 629 async_answer_0(rid, ENOMEM); 630 return; 608 return ENOMEM; 631 609 } 632 610 … … 636 614 free(fs); 637 615 free(inst); 638 async_answer_0(rid, rc); 639 return; 616 return rc; 640 617 } 641 618 … … 646 623 free(fs); 647 624 free(inst); 648 async_answer_0(rid, rc); 649 return; 625 return rc; 650 626 } 651 627 … … 656 632 free(fs); 657 633 free(inst); 658 async_answer_0(rid, rc); 659 return; 634 return rc; 660 635 } 661 636 … … 673 648 free(fs); 674 649 free(inst); 675 async_answer_0(rid, rc); 676 return; 650 return rc; 677 651 } 678 652 ext2fs_node_t *enode = EXT2FS_NODE(root_node); … … 683 657 fibril_mutex_unlock(&instance_list_mutex); 684 658 685 async_answer_3(rid, EOK, 686 EXT2_INODE_ROOT_INDEX, 687 0, 688 ext2_inode_get_usage_count(enode->inode_ref->inode)); 659 *index = EXT2_INODE_ROOT_INDEX; 660 *size = 0; 661 *lnkcnt = ext2_inode_get_usage_count(enode->inode_ref->inode); 689 662 690 663 ext2fs_node_put(root_node); 691 } 692 693 void ext2fs_mount(ipc_callid_t rid, ipc_call_t *request) 694 { 695 EXT2FS_DBG(""); 696 libfs_mount(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request); 697 } 698 699 void ext2fs_unmounted(ipc_callid_t rid, ipc_call_t *request) 700 { 701 EXT2FS_DBG(""); 702 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 664 665 return EOK; 666 } 667 668 static int ext2fs_unmounted(devmap_handle_t devmap_handle) 669 { 670 EXT2FS_DBG(""); 703 671 ext2fs_instance_t *inst; 704 672 int rc; … … 706 674 rc = ext2fs_instance_get(devmap_handle, &inst); 707 675 708 if (rc != EOK) { 709 async_answer_0(rid, rc); 710 return; 711 } 676 if (rc != EOK) 677 return rc; 712 678 713 679 fibril_mutex_lock(&open_nodes_lock); … … 716 682 if (inst->open_nodes_count != 0) { 717 683 fibril_mutex_unlock(&open_nodes_lock); 718 async_answer_0(rid, EBUSY); 719 return; 684 return EBUSY; 720 685 } 721 686 … … 729 694 ext2_filesystem_fini(inst->filesystem); 730 695 731 async_answer_0(rid, EOK); 732 } 733 734 void ext2fs_unmount(ipc_callid_t rid, ipc_call_t *request) 735 { 736 EXT2FS_DBG(""); 737 libfs_unmount(&ext2fs_libfs_ops, rid, request); 738 } 739 740 void ext2fs_lookup(ipc_callid_t rid, ipc_call_t *request) 741 { 742 EXT2FS_DBG(""); 743 libfs_lookup(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request); 744 } 745 746 void ext2fs_read(ipc_callid_t rid, ipc_call_t *request) 747 { 748 EXT2FS_DBG(""); 749 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 750 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 751 aoff64_t pos = 752 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 696 return EOK; 697 } 698 699 static int 700 ext2fs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 701 size_t *rbytes) 702 { 703 EXT2FS_DBG(""); 753 704 754 705 ext2fs_instance_t *inst; … … 763 714 if (!async_data_read_receive(&callid, &size)) { 764 715 async_answer_0(callid, EINVAL); 765 async_answer_0(rid, EINVAL); 766 return; 716 return EINVAL; 767 717 } 768 718 … … 770 720 if (rc != EOK) { 771 721 async_answer_0(callid, rc); 772 async_answer_0(rid, rc); 773 return; 722 return rc; 774 723 } 775 724 … … 777 726 if (rc != EOK) { 778 727 async_answer_0(callid, rc); 779 async_answer_0(rid, rc); 780 return; 728 return rc; 781 729 } 782 730 783 731 if (ext2_inode_is_type(inst->filesystem->superblock, inode_ref->inode, 784 EXT2_INODE_MODE_FILE)) {785 ext2fs_read_file(rid, callid, pos, size, inst, inode_ref);786 }787 else if (ext2_inode_is_type(inst->filesystem->superblock, inode_ref->inode,788 EXT2_INODE_MODE_DIRECTORY)) {789 ext2fs_read_directory(rid, callid, pos, size, inst, inode_ref);790 }791 else {732 EXT2_INODE_MODE_FILE)) { 733 rc = ext2fs_read_file(callid, pos, size, inst, inode_ref, 734 rbytes); 735 } else if (ext2_inode_is_type(inst->filesystem->superblock, 736 inode_ref->inode, EXT2_INODE_MODE_DIRECTORY)) { 737 rc = ext2fs_read_directory(callid, pos, size, inst, inode_ref, 738 rbytes); 739 } else { 792 740 /* Other inode types not supported */ 793 741 async_answer_0(callid, ENOTSUP); 794 async_answer_0(rid, ENOTSUP);742 rc = ENOTSUP; 795 743 } 796 744 797 745 ext2_filesystem_put_inode_ref(inode_ref); 798 746 747 return rc; 799 748 } 800 749 … … 814 763 } 815 764 816 void ext2fs_read_directory(ipc_callid_t rid, ipc_callid_t callid, aoff64_t pos,817 size_t size, ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref)765 int ext2fs_read_directory(ipc_callid_t callid, aoff64_t pos, size_t size, 766 ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref, size_t *rbytes) 818 767 { 819 768 ext2_directory_iterator_t it; … … 827 776 if (rc != EOK) { 828 777 async_answer_0(callid, rc); 829 async_answer_0(rid, rc); 830 return; 778 return rc; 831 779 } 832 780 … … 841 789 842 790 name_size = ext2_directory_entry_ll_get_name_length( 843 inst->filesystem->superblock, it.current);791 inst->filesystem->superblock, it.current); 844 792 845 793 /* skip . and .. */ … … 849 797 850 798 /* The on-disk entry does not contain \0 at the end 851 * end of entry name, so we copy it to new buffer852 * and add the \0 at the end853 */799 * end of entry name, so we copy it to new buffer 800 * and add the \0 at the end 801 */ 854 802 buf = malloc(name_size+1); 855 803 if (buf == NULL) { 856 804 ext2_directory_iterator_fini(&it); 857 805 async_answer_0(callid, ENOMEM); 858 async_answer_0(rid, ENOMEM); 859 return; 806 return ENOMEM; 860 807 } 861 808 memcpy(buf, &it.current->name, name_size); 862 *(buf +name_size) = 0;809 *(buf + name_size) = 0; 863 810 found = true; 864 (void) async_data_read_finalize(callid, buf, name_size +1);811 (void) async_data_read_finalize(callid, buf, name_size + 1); 865 812 free(buf); 866 813 break; … … 871 818 ext2_directory_iterator_fini(&it); 872 819 async_answer_0(callid, rc); 873 async_answer_0(rid, rc); 874 return; 820 return rc; 875 821 } 876 822 } … … 878 824 if (found) { 879 825 rc = ext2_directory_iterator_next(&it); 880 if (rc != EOK) { 881 async_answer_0(rid, rc); 882 return; 883 } 826 if (rc != EOK) 827 return rc; 884 828 next = it.current_offset; 885 829 } 886 830 887 831 rc = ext2_directory_iterator_fini(&it); 888 if (rc != EOK) { 889 async_answer_0(rid, rc); 890 return; 891 } 832 if (rc != EOK) 833 return rc; 892 834 893 835 if (found) { 894 async_answer_1(rid, EOK, next-pos);895 }896 else {836 *rbytes = next - pos; 837 return EOK; 838 } else { 897 839 async_answer_0(callid, ENOENT); 898 async_answer_0(rid, ENOENT);899 } 900 } 901 902 void ext2fs_read_file(ipc_callid_t rid, ipc_callid_t callid, aoff64_t pos,903 size_t size, ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref)840 return ENOENT; 841 } 842 } 843 844 int ext2fs_read_file(ipc_callid_t callid, aoff64_t pos, size_t size, 845 ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref, size_t *rbytes) 904 846 { 905 847 int rc; … … 919 861 /* Read 0 bytes successfully */ 920 862 async_data_read_finalize(callid, NULL, 0); 921 async_answer_1(rid, EOK, 0);922 return ;863 *rbytes = 0; 864 return EOK; 923 865 } 924 866 … … 939 881 if (rc != EOK) { 940 882 async_answer_0(callid, rc); 941 async_answer_0(rid, rc); 942 return; 883 return rc; 943 884 } 944 885 … … 952 893 if (buffer == NULL) { 953 894 async_answer_0(callid, ENOMEM); 954 async_answer_0(rid, ENOMEM); 955 return; 895 return ENOMEM; 956 896 } 957 897 … … 959 899 960 900 async_data_read_finalize(callid, buffer, bytes); 961 async_answer_1(rid, EOK, bytes);901 *rbytes = bytes; 962 902 963 903 free(buffer); 964 904 965 return ;905 return EOK; 966 906 } 967 907 … … 970 910 if (rc != EOK) { 971 911 async_answer_0(callid, rc); 972 async_answer_0(rid, rc); 973 return; 912 return rc; 974 913 } 975 914 … … 978 917 979 918 rc = block_put(block); 980 if (rc != EOK) { 981 async_answer_0(rid, rc); 982 return; 983 } 984 985 async_answer_1(rid, EOK, bytes); 986 } 987 988 void ext2fs_write(ipc_callid_t rid, ipc_call_t *request) 989 { 990 EXT2FS_DBG(""); 991 // devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 992 // fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 993 // aoff64_t pos = 994 // (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 995 996 // TODO 997 async_answer_0(rid, ENOTSUP); 998 } 999 1000 void ext2fs_truncate(ipc_callid_t rid, ipc_call_t *request) 1001 { 1002 EXT2FS_DBG(""); 1003 // devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1004 // fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1005 // aoff64_t size = 1006 // (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 1007 1008 // TODO 1009 async_answer_0(rid, ENOTSUP); 1010 } 1011 1012 void ext2fs_close(ipc_callid_t rid, ipc_call_t *request) 1013 { 1014 EXT2FS_DBG(""); 1015 async_answer_0(rid, EOK); 1016 } 1017 1018 void ext2fs_destroy(ipc_callid_t rid, ipc_call_t *request) 1019 { 1020 EXT2FS_DBG(""); 1021 // devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request); 1022 // fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 1023 1024 // TODO 1025 async_answer_0(rid, ENOTSUP); 1026 } 1027 1028 void ext2fs_open_node(ipc_callid_t rid, ipc_call_t *request) 1029 { 1030 EXT2FS_DBG(""); 1031 libfs_open_node(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request); 1032 } 1033 1034 void ext2fs_stat(ipc_callid_t rid, ipc_call_t *request) 1035 { 1036 EXT2FS_DBG(""); 1037 libfs_stat(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request); 1038 } 1039 1040 void ext2fs_sync(ipc_callid_t rid, ipc_call_t *request) 1041 { 1042 EXT2FS_DBG(""); 1043 // devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1044 // fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1045 1046 // TODO 1047 async_answer_0(rid, ENOTSUP); 1048 } 919 if (rc != EOK) 920 return rc; 921 922 *rbytes = bytes; 923 return EOK; 924 } 925 926 static int 927 ext2fs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 928 size_t *wbytes, aoff64_t *nsize) 929 { 930 EXT2FS_DBG(""); 931 return ENOTSUP; 932 } 933 934 static int 935 ext2fs_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size) 936 { 937 EXT2FS_DBG(""); 938 return ENOTSUP; 939 } 940 941 static int ext2fs_close(devmap_handle_t devmap_handle, fs_index_t index) 942 { 943 EXT2FS_DBG(""); 944 return EOK; 945 } 946 947 static int ext2fs_destroy(devmap_handle_t devmap_handle, fs_index_t index) 948 { 949 EXT2FS_DBG(""); 950 return ENOTSUP; 951 } 952 953 static int ext2fs_sync(devmap_handle_t devmap_handle, fs_index_t index) 954 { 955 EXT2FS_DBG(""); 956 return ENOTSUP; 957 } 958 959 vfs_out_ops_t ext2fs_ops = { 960 .mounted = ext2fs_mounted, 961 .unmounted = ext2fs_unmounted, 962 .read = ext2fs_read, 963 .write = ext2fs_write, 964 .truncate = ext2fs_truncate, 965 .close = ext2fs_close, 966 .destroy = ext2fs_destroy, 967 .sync = ext2fs_sync, 968 }; 1049 969 1050 970 /** 1051 971 * @} 1052 972 */ 973 -
uspace/srv/fs/fat/fat.c
r9350bfdd r7ae249d 56 56 }; 57 57 58 fs_reg_t fat_reg;59 60 /**61 * This connection fibril processes VFS requests from VFS.62 *63 * In order to support simultaneous VFS requests, our design is as follows.64 * The connection fibril accepts VFS requests from VFS. If there is only one65 * instance of the fibril, VFS will need to serialize all VFS requests it sends66 * to FAT. To overcome this bottleneck, VFS can send FAT the IPC_M_CONNECT_ME_TO67 * call. In that case, a new connection fibril will be created, which in turn68 * will accept the call. Thus, a new phone will be opened for VFS.69 *70 * There are few issues with this arrangement. First, VFS can run out of71 * available phones. In that case, VFS can close some other phones or use one72 * phone for more serialized requests. Similarily, FAT can refuse to duplicate73 * the connection. VFS should then just make use of already existing phones and74 * route its requests through them. To avoid paying the fibril creation price75 * upon each request, FAT might want to keep the connections open after the76 * request has been completed.77 */78 static void fat_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)79 {80 if (iid) {81 /*82 * This only happens for connections opened by83 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections84 * created by IPC_M_CONNECT_TO_ME.85 */86 async_answer_0(iid, EOK);87 }88 89 dprintf(NAME ": connection opened\n");90 91 while (true) {92 ipc_call_t call;93 ipc_callid_t callid = async_get_call(&call);94 95 if (!IPC_GET_IMETHOD(call))96 return;97 98 switch (IPC_GET_IMETHOD(call)) {99 case VFS_OUT_MOUNTED:100 fat_mounted(callid, &call);101 break;102 case VFS_OUT_MOUNT:103 fat_mount(callid, &call);104 break;105 case VFS_OUT_UNMOUNTED:106 fat_unmounted(callid, &call);107 break;108 case VFS_OUT_UNMOUNT:109 fat_unmount(callid, &call);110 break;111 case VFS_OUT_LOOKUP:112 fat_lookup(callid, &call);113 break;114 case VFS_OUT_READ:115 fat_read(callid, &call);116 break;117 case VFS_OUT_WRITE:118 fat_write(callid, &call);119 break;120 case VFS_OUT_TRUNCATE:121 fat_truncate(callid, &call);122 break;123 case VFS_OUT_STAT:124 fat_stat(callid, &call);125 break;126 case VFS_OUT_CLOSE:127 fat_close(callid, &call);128 break;129 case VFS_OUT_DESTROY:130 fat_destroy(callid, &call);131 break;132 case VFS_OUT_OPEN_NODE:133 fat_open_node(callid, &call);134 break;135 case VFS_OUT_SYNC:136 fat_sync(callid, &call);137 break;138 default:139 async_answer_0(callid, ENOTSUP);140 break;141 }142 }143 }144 145 58 int main(int argc, char **argv) 146 59 { … … 158 71 } 159 72 160 rc = fs_register(vfs_sess, &fat_ reg, &fat_vfs_info, fat_connection);73 rc = fs_register(vfs_sess, &fat_vfs_info, &fat_ops, &fat_libfs_ops); 161 74 if (rc != EOK) { 162 75 fat_idx_fini(); -
uspace/srv/fs/fat/fat.h
r9350bfdd r7ae249d 224 224 } fat_node_t; 225 225 226 extern fs_reg_t fat_reg; 227 228 extern void fat_mounted(ipc_callid_t, ipc_call_t *); 229 extern void fat_mount(ipc_callid_t, ipc_call_t *); 230 extern void fat_unmounted(ipc_callid_t, ipc_call_t *); 231 extern void fat_unmount(ipc_callid_t, ipc_call_t *); 232 extern void fat_lookup(ipc_callid_t, ipc_call_t *); 233 extern void fat_read(ipc_callid_t, ipc_call_t *); 234 extern void fat_write(ipc_callid_t, ipc_call_t *); 235 extern void fat_truncate(ipc_callid_t, ipc_call_t *); 236 extern void fat_stat(ipc_callid_t, ipc_call_t *); 237 extern void fat_close(ipc_callid_t, ipc_call_t *); 238 extern void fat_destroy(ipc_callid_t, ipc_call_t *); 239 extern void fat_open_node(ipc_callid_t, ipc_call_t *); 240 extern void fat_stat(ipc_callid_t, ipc_call_t *); 241 extern void fat_sync(ipc_callid_t, ipc_call_t *); 226 extern vfs_out_ops_t fat_ops; 227 extern libfs_ops_t fat_libfs_ops; 242 228 243 229 extern int fat_idx_get_new(fat_idx_t **, devmap_handle_t); -
uspace/srv/fs/fat/fat_ops.c
r9350bfdd r7ae249d 85 85 static aoff64_t fat_size_get(fs_node_t *); 86 86 static unsigned fat_lnkcnt_get(fs_node_t *); 87 static char fat_plb_get_char(unsigned);88 87 static bool fat_is_directory(fs_node_t *); 89 88 static bool fat_is_file(fs_node_t *node); … … 901 900 } 902 901 903 char fat_plb_get_char(unsigned pos)904 {905 return fat_reg.plb_ro[pos % PLB_SIZE];906 }907 908 902 bool fat_is_directory(fs_node_t *fn) 909 903 { … … 936 930 .size_get = fat_size_get, 937 931 .lnkcnt_get = fat_lnkcnt_get, 938 .plb_get_char = fat_plb_get_char,939 932 .is_directory = fat_is_directory, 940 933 .is_file = fat_is_file, … … 943 936 944 937 /* 945 * VFSoperations.938 * FAT VFS_OUT operations. 946 939 */ 947 940 948 void fat_mounted(ipc_callid_t rid, ipc_call_t *request) 949 { 950 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 941 static int 942 fat_mounted(devmap_handle_t devmap_handle, const char *opts, fs_index_t *index, 943 aoff64_t *size, unsigned *linkcnt) 944 { 951 945 enum cache_mode cmode; 952 946 fat_bs_t *bs; 953 954 /* Accept the mount options */ 955 char *opts; 956 int rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL); 957 958 if (rc != EOK) { 959 async_answer_0(rid, rc); 960 return; 961 } 962 947 int rc; 948 963 949 /* Check for option enabling write through. */ 964 950 if (str_cmp(opts, "wtcache") == 0) … … 967 953 cmode = CACHE_MODE_WB; 968 954 969 free(opts);970 971 955 /* initialize libblock */ 972 956 rc = block_init(EXCHANGE_SERIALIZE, devmap_handle, BS_SIZE); 973 if (rc != EOK) { 974 async_answer_0(rid, rc); 975 return; 976 } 957 if (rc != EOK) 958 return rc; 977 959 978 960 /* prepare the boot block */ … … 980 962 if (rc != EOK) { 981 963 block_fini(devmap_handle); 982 async_answer_0(rid, rc); 983 return; 964 return rc; 984 965 } 985 966 … … 989 970 if (BPS(bs) != BS_SIZE) { 990 971 block_fini(devmap_handle); 991 async_answer_0(rid, ENOTSUP); 992 return; 972 return ENOTSUP; 993 973 } 994 974 … … 997 977 if (rc != EOK) { 998 978 block_fini(devmap_handle); 999 async_answer_0(rid, rc); 1000 return; 979 return rc; 1001 980 } 1002 981 … … 1006 985 (void) block_cache_fini(devmap_handle); 1007 986 block_fini(devmap_handle); 1008 async_answer_0(rid, rc); 1009 return; 987 return rc; 1010 988 } 1011 989 … … 1014 992 (void) block_cache_fini(devmap_handle); 1015 993 block_fini(devmap_handle); 1016 async_answer_0(rid, rc); 1017 return; 994 return rc; 1018 995 } 1019 996 … … 1024 1001 block_fini(devmap_handle); 1025 1002 fat_idx_fini_by_devmap_handle(devmap_handle); 1026 async_answer_0(rid, ENOMEM); 1027 return; 1003 return ENOMEM; 1028 1004 } 1029 1005 fs_node_initialize(rfn); … … 1034 1010 block_fini(devmap_handle); 1035 1011 fat_idx_fini_by_devmap_handle(devmap_handle); 1036 async_answer_0(rid, ENOMEM); 1037 return; 1012 return ENOMEM; 1038 1013 } 1039 1014 fat_node_initialize(rootp); … … 1046 1021 block_fini(devmap_handle); 1047 1022 fat_idx_fini_by_devmap_handle(devmap_handle); 1048 async_answer_0(rid, ENOMEM); 1049 return; 1023 return ENOMEM; 1050 1024 } 1051 1025 assert(ridxp->index == 0); … … 1064 1038 fibril_mutex_unlock(&ridxp->lock); 1065 1039 1066 async_answer_3(rid, EOK, ridxp->index, rootp->size, rootp->lnkcnt); 1067 } 1068 1069 void fat_mount(ipc_callid_t rid, ipc_call_t *request) 1070 { 1071 libfs_mount(&fat_libfs_ops, fat_reg.fs_handle, rid, request); 1072 } 1073 1074 void fat_unmounted(ipc_callid_t rid, ipc_call_t *request) 1075 { 1076 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1040 *index = ridxp->index; 1041 *size = rootp->size; 1042 *linkcnt = rootp->lnkcnt; 1043 1044 return EOK; 1045 } 1046 1047 static int fat_unmounted(devmap_handle_t devmap_handle) 1048 { 1077 1049 fs_node_t *fn; 1078 1050 fat_node_t *nodep; … … 1080 1052 1081 1053 rc = fat_root_get(&fn, devmap_handle); 1082 if (rc != EOK) { 1083 async_answer_0(rid, rc); 1084 return; 1085 } 1054 if (rc != EOK) 1055 return rc; 1086 1056 nodep = FAT_NODE(fn); 1087 1057 … … 1092 1062 if (nodep->refcnt != 2) { 1093 1063 (void) fat_node_put(fn); 1094 async_answer_0(rid, EBUSY); 1095 return; 1064 return EBUSY; 1096 1065 } 1097 1066 … … 1112 1081 block_fini(devmap_handle); 1113 1082 1114 async_answer_0(rid, EOK); 1115 } 1116 1117 void fat_unmount(ipc_callid_t rid, ipc_call_t *request) 1118 { 1119 libfs_unmount(&fat_libfs_ops, rid, request); 1120 } 1121 1122 void fat_lookup(ipc_callid_t rid, ipc_call_t *request) 1123 { 1124 libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request); 1125 } 1126 1127 void fat_read(ipc_callid_t rid, ipc_call_t *request) 1128 { 1129 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1130 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1131 aoff64_t pos = 1132 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 1083 return EOK; 1084 } 1085 1086 static int 1087 fat_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 1088 size_t *rbytes) 1089 { 1133 1090 fs_node_t *fn; 1134 1091 fat_node_t *nodep; … … 1139 1096 1140 1097 rc = fat_node_get(&fn, devmap_handle, index); 1141 if (rc != EOK) { 1142 async_answer_0(rid, rc); 1143 return; 1144 } 1145 if (!fn) { 1146 async_answer_0(rid, ENOENT); 1147 return; 1148 } 1098 if (rc != EOK) 1099 return rc; 1100 if (!fn) 1101 return ENOENT; 1149 1102 nodep = FAT_NODE(fn); 1150 1103 … … 1154 1107 fat_node_put(fn); 1155 1108 async_answer_0(callid, EINVAL); 1156 async_answer_0(rid, EINVAL); 1157 return; 1109 return EINVAL; 1158 1110 } 1159 1111 … … 1178 1130 fat_node_put(fn); 1179 1131 async_answer_0(callid, rc); 1180 async_answer_0(rid, rc); 1181 return; 1132 return rc; 1182 1133 } 1183 1134 (void) async_data_read_finalize(callid, … … 1186 1137 if (rc != EOK) { 1187 1138 fat_node_put(fn); 1188 async_answer_0(rid, rc); 1189 return; 1139 return rc; 1190 1140 } 1191 1141 } … … 1244 1194 rc = fat_node_put(fn); 1245 1195 async_answer_0(callid, rc != EOK ? rc : ENOENT); 1246 async_answer_1(rid, rc != EOK ? rc : ENOENT, 0);1247 return ;1196 *rbytes = 0; 1197 return rc != EOK ? rc : ENOENT; 1248 1198 1249 1199 err: 1250 1200 (void) fat_node_put(fn); 1251 1201 async_answer_0(callid, rc); 1252 async_answer_0(rid, rc); 1253 return; 1202 return rc; 1254 1203 1255 1204 hit: … … 1259 1208 1260 1209 rc = fat_node_put(fn); 1261 async_answer_1(rid, rc, (sysarg_t)bytes); 1262 } 1263 1264 void fat_write(ipc_callid_t rid, ipc_call_t *request) 1265 { 1266 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1267 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1268 aoff64_t pos = 1269 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 1210 *rbytes = bytes; 1211 return rc; 1212 } 1213 1214 static int 1215 fat_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 1216 size_t *wbytes, aoff64_t *nsize) 1217 { 1270 1218 fs_node_t *fn; 1271 1219 fat_node_t *nodep; 1272 1220 fat_bs_t *bs; 1273 size_t bytes , size;1221 size_t bytes; 1274 1222 block_t *b; 1275 1223 aoff64_t boundary; … … 1278 1226 1279 1227 rc = fat_node_get(&fn, devmap_handle, index); 1280 if (rc != EOK) { 1281 async_answer_0(rid, rc); 1282 return; 1283 } 1284 if (!fn) { 1285 async_answer_0(rid, ENOENT); 1286 return; 1287 } 1228 if (rc != EOK) 1229 return rc; 1230 if (!fn) 1231 return ENOENT; 1288 1232 nodep = FAT_NODE(fn); 1289 1233 … … 1293 1237 (void) fat_node_put(fn); 1294 1238 async_answer_0(callid, EINVAL); 1295 async_answer_0(rid, EINVAL); 1296 return; 1239 return EINVAL; 1297 1240 } 1298 1241 … … 1322 1265 (void) fat_node_put(fn); 1323 1266 async_answer_0(callid, rc); 1324 async_answer_0(rid, rc); 1325 return; 1267 return rc; 1326 1268 } 1327 1269 rc = fat_block_get(&b, bs, nodep, pos / BPS(bs), flags); … … 1329 1271 (void) fat_node_put(fn); 1330 1272 async_answer_0(callid, rc); 1331 async_answer_0(rid, rc); 1332 return; 1273 return rc; 1333 1274 } 1334 1275 (void) async_data_write_finalize(callid, … … 1338 1279 if (rc != EOK) { 1339 1280 (void) fat_node_put(fn); 1340 async_answer_0(rid, rc); 1341 return; 1281 return rc; 1342 1282 } 1343 1283 if (pos + bytes > nodep->size) { … … 1345 1285 nodep->dirty = true; /* need to sync node */ 1346 1286 } 1347 size = nodep->size; 1287 *wbytes = bytes; 1288 *nsize = nodep->size; 1348 1289 rc = fat_node_put(fn); 1349 async_answer_2(rid, rc, bytes, nodep->size); 1350 return; 1290 return rc; 1351 1291 } else { 1352 1292 /* … … 1364 1304 (void) fat_node_put(fn); 1365 1305 async_answer_0(callid, rc); 1366 async_answer_0(rid, rc); 1367 return; 1306 return rc; 1368 1307 } 1369 1308 /* zero fill any gaps */ … … 1373 1312 (void) fat_node_put(fn); 1374 1313 async_answer_0(callid, rc); 1375 async_answer_0(rid, rc); 1376 return; 1314 return rc; 1377 1315 } 1378 1316 rc = _fat_block_get(&b, bs, devmap_handle, lcl, NULL, … … 1382 1320 (void) fat_node_put(fn); 1383 1321 async_answer_0(callid, rc); 1384 async_answer_0(rid, rc); 1385 return; 1322 return rc; 1386 1323 } 1387 1324 (void) async_data_write_finalize(callid, … … 1392 1329 (void) fat_free_clusters(bs, devmap_handle, mcl); 1393 1330 (void) fat_node_put(fn); 1394 async_answer_0(rid, rc); 1395 return; 1331 return rc; 1396 1332 } 1397 1333 /* … … 1403 1339 (void) fat_free_clusters(bs, devmap_handle, mcl); 1404 1340 (void) fat_node_put(fn); 1405 async_answer_0(rid, rc);1406 return;1407 }1408 nodep->size = size = pos + bytes;1341 return rc; 1342 } 1343 *nsize = nodep->size = pos + bytes; 1344 rc = fat_node_put(fn); 1409 1345 nodep->dirty = true; /* need to sync node */ 1410 rc = fat_node_put(fn); 1411 async_answer_2(rid, rc, bytes, size); 1412 return; 1413 } 1414 } 1415 1416 void fat_truncate(ipc_callid_t rid, ipc_call_t *request) 1417 { 1418 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1419 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1420 aoff64_t size = 1421 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 1346 *wbytes = bytes; 1347 return rc; 1348 } 1349 } 1350 1351 static int 1352 fat_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size) 1353 { 1422 1354 fs_node_t *fn; 1423 1355 fat_node_t *nodep; … … 1426 1358 1427 1359 rc = fat_node_get(&fn, devmap_handle, index); 1428 if (rc != EOK) { 1429 async_answer_0(rid, rc); 1430 return; 1431 } 1432 if (!fn) { 1433 async_answer_0(rid, ENOENT); 1434 return; 1435 } 1360 if (rc != EOK) 1361 return rc; 1362 if (!fn) 1363 return ENOENT; 1436 1364 nodep = FAT_NODE(fn); 1437 1365 … … 1477 1405 out: 1478 1406 fat_node_put(fn); 1479 async_answer_0(rid, rc); 1480 return; 1481 } 1482 1483 void fat_close(ipc_callid_t rid, ipc_call_t *request) 1484 { 1485 async_answer_0(rid, EOK); 1486 } 1487 1488 void fat_destroy(ipc_callid_t rid, ipc_call_t *request) 1489 { 1490 devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request); 1491 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 1407 return rc; 1408 } 1409 1410 static int fat_close(devmap_handle_t devmap_handle, fs_index_t index) 1411 { 1412 return EOK; 1413 } 1414 1415 static int fat_destroy(devmap_handle_t devmap_handle, fs_index_t index) 1416 { 1492 1417 fs_node_t *fn; 1493 1418 fat_node_t *nodep; … … 1495 1420 1496 1421 rc = fat_node_get(&fn, devmap_handle, index); 1497 if (rc != EOK) { 1498 async_answer_0(rid, rc); 1499 return; 1500 } 1501 if (!fn) { 1502 async_answer_0(rid, ENOENT); 1503 return; 1504 } 1422 if (rc != EOK) 1423 return rc; 1424 if (!fn) 1425 return ENOENT; 1505 1426 1506 1427 nodep = FAT_NODE(fn); … … 1512 1433 1513 1434 rc = fat_destroy_node(fn); 1514 async_answer_0(rid, rc); 1515 } 1516 1517 void fat_open_node(ipc_callid_t rid, ipc_call_t *request) 1518 { 1519 libfs_open_node(&fat_libfs_ops, fat_reg.fs_handle, rid, request); 1520 } 1521 1522 void fat_stat(ipc_callid_t rid, ipc_call_t *request) 1523 { 1524 libfs_stat(&fat_libfs_ops, fat_reg.fs_handle, rid, request); 1525 } 1526 1527 void fat_sync(ipc_callid_t rid, ipc_call_t *request) 1528 { 1529 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1530 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1531 1435 return rc; 1436 } 1437 1438 static int fat_sync(devmap_handle_t devmap_handle, fs_index_t index) 1439 { 1532 1440 fs_node_t *fn; 1533 1441 int rc = fat_node_get(&fn, devmap_handle, index); 1534 if (rc != EOK) { 1535 async_answer_0(rid, rc); 1536 return; 1537 } 1538 if (!fn) { 1539 async_answer_0(rid, ENOENT); 1540 return; 1541 } 1442 if (rc != EOK) 1443 return rc; 1444 if (!fn) 1445 return ENOENT; 1542 1446 1543 1447 fat_node_t *nodep = FAT_NODE(fn); … … 1547 1451 1548 1452 fat_node_put(fn); 1549 async_answer_0(rid, rc); 1550 } 1453 return rc; 1454 } 1455 1456 vfs_out_ops_t fat_ops = { 1457 .mounted = fat_mounted, 1458 .unmounted = fat_unmounted, 1459 .read = fat_read, 1460 .write = fat_write, 1461 .truncate = fat_truncate, 1462 .close = fat_close, 1463 .destroy = fat_destroy, 1464 .sync = fat_sync, 1465 }; 1551 1466 1552 1467 /** -
uspace/srv/fs/tmpfs/tmpfs.c
r9350bfdd r7ae249d 61 61 }; 62 62 63 fs_reg_t tmpfs_reg;64 65 /**66 * This connection fibril processes VFS requests from VFS.67 *68 * In order to support simultaneous VFS requests, our design is as follows.69 * The connection fibril accepts VFS requests from VFS. If there is only one70 * instance of the fibril, VFS will need to serialize all VFS requests it sends71 * to FAT. To overcome this bottleneck, VFS can send TMPFS the72 * IPC_M_CONNECT_ME_TO call. In that case, a new connection fibril will be73 * created, which in turn will accept the call. Thus, a new phone will be74 * opened for VFS.75 *76 * There are few issues with this arrangement. First, VFS can run out of77 * available phones. In that case, VFS can close some other phones or use one78 * phone for more serialized requests. Similarily, TMPFS can refuse to duplicate79 * the connection. VFS should then just make use of already existing phones and80 * route its requests through them. To avoid paying the fibril creation price81 * upon each request, TMPFS might want to keep the connections open after the82 * request has been completed.83 */84 static void tmpfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)85 {86 if (iid) {87 /*88 * This only happens for connections opened by89 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections90 * created by IPC_M_CONNECT_TO_ME.91 */92 async_answer_0(iid, EOK);93 }94 95 dprintf(NAME ": connection opened\n");96 97 while (true) {98 ipc_call_t call;99 ipc_callid_t callid = async_get_call(&call);100 101 if (!IPC_GET_IMETHOD(call))102 return;103 104 switch (IPC_GET_IMETHOD(call)) {105 case VFS_OUT_MOUNTED:106 tmpfs_mounted(callid, &call);107 break;108 case VFS_OUT_MOUNT:109 tmpfs_mount(callid, &call);110 break;111 case VFS_OUT_UNMOUNTED:112 tmpfs_unmounted(callid, &call);113 break;114 case VFS_OUT_UNMOUNT:115 tmpfs_unmount(callid, &call);116 break;117 case VFS_OUT_LOOKUP:118 tmpfs_lookup(callid, &call);119 break;120 case VFS_OUT_READ:121 tmpfs_read(callid, &call);122 break;123 case VFS_OUT_WRITE:124 tmpfs_write(callid, &call);125 break;126 case VFS_OUT_TRUNCATE:127 tmpfs_truncate(callid, &call);128 break;129 case VFS_OUT_CLOSE:130 tmpfs_close(callid, &call);131 break;132 case VFS_OUT_DESTROY:133 tmpfs_destroy(callid, &call);134 break;135 case VFS_OUT_OPEN_NODE:136 tmpfs_open_node(callid, &call);137 break;138 case VFS_OUT_STAT:139 tmpfs_stat(callid, &call);140 break;141 case VFS_OUT_SYNC:142 tmpfs_sync(callid, &call);143 break;144 default:145 async_answer_0(callid, ENOTSUP);146 break;147 }148 }149 }150 151 63 int main(int argc, char **argv) 152 64 { … … 165 77 } 166 78 167 int rc = fs_register(vfs_sess, &tmpfs_ reg, &tmpfs_vfs_info,168 tmpfs_connection);79 int rc = fs_register(vfs_sess, &tmpfs_vfs_info, &tmpfs_ops, 80 &tmpfs_libfs_ops); 169 81 if (rc != EOK) { 170 82 printf(NAME ": Failed to register file system (%d)\n", rc); -
uspace/srv/fs/tmpfs/tmpfs.h
r9350bfdd r7ae249d 70 70 } tmpfs_node_t; 71 71 72 extern fs_reg_t tmpfs_reg; 73 72 extern vfs_out_ops_t tmpfs_ops; 74 73 extern libfs_ops_t tmpfs_libfs_ops; 75 74 76 75 extern bool tmpfs_init(void); 77 78 extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *);79 extern void tmpfs_mount(ipc_callid_t, ipc_call_t *);80 extern void tmpfs_unmounted(ipc_callid_t, ipc_call_t *);81 extern void tmpfs_unmount(ipc_callid_t, ipc_call_t *);82 extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *);83 extern void tmpfs_read(ipc_callid_t, ipc_call_t *);84 extern void tmpfs_write(ipc_callid_t, ipc_call_t *);85 extern void tmpfs_truncate(ipc_callid_t, ipc_call_t *);86 extern void tmpfs_stat(ipc_callid_t, ipc_call_t *);87 extern void tmpfs_close(ipc_callid_t, ipc_call_t *);88 extern void tmpfs_destroy(ipc_callid_t, ipc_call_t *);89 extern void tmpfs_open_node(ipc_callid_t, ipc_call_t *);90 extern void tmpfs_sync(ipc_callid_t, ipc_call_t *);91 92 76 extern bool tmpfs_restore(devmap_handle_t); 93 77 -
uspace/srv/fs/tmpfs/tmpfs_ops.c
r9350bfdd r7ae249d 104 104 } 105 105 106 static char tmpfs_plb_get_char(unsigned pos)107 {108 return tmpfs_reg.plb_ro[pos % PLB_SIZE];109 }110 111 106 static bool tmpfs_is_directory(fs_node_t *fn) 112 107 { … … 139 134 .size_get = tmpfs_size_get, 140 135 .lnkcnt_get = tmpfs_lnkcnt_get, 141 .plb_get_char = tmpfs_plb_get_char,142 136 .is_directory = tmpfs_is_directory, 143 137 .is_file = tmpfs_is_file, … … 433 427 } 434 428 435 void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request) 436 { 437 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 429 /* 430 * Implementation of the VFS_OUT interface. 431 */ 432 433 static int 434 tmpfs_mounted(devmap_handle_t devmap_handle, const char *opts, 435 fs_index_t *index, aoff64_t *size, unsigned *lnkcnt) 436 { 438 437 fs_node_t *rootfn; 439 438 int rc; 440 439 441 /* Accept the mount options. */442 char *opts;443 rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);444 if (rc != EOK) {445 async_answer_0(rid, rc);446 return;447 }448 449 440 /* Check if this device is not already mounted. */ 450 441 rc = tmpfs_root_get(&rootfn, devmap_handle); 451 442 if ((rc == EOK) && (rootfn)) { 452 443 (void) tmpfs_node_put(rootfn); 453 free(opts); 454 async_answer_0(rid, EEXIST); 455 return; 444 return EEXIST; 456 445 } 457 446 458 447 /* Initialize TMPFS instance. */ 459 if (!tmpfs_instance_init(devmap_handle)) { 460 free(opts); 461 async_answer_0(rid, ENOMEM); 462 return; 463 } 448 if (!tmpfs_instance_init(devmap_handle)) 449 return ENOMEM; 464 450 465 451 rc = tmpfs_root_get(&rootfn, devmap_handle); … … 467 453 tmpfs_node_t *rootp = TMPFS_NODE(rootfn); 468 454 if (str_cmp(opts, "restore") == 0) { 469 if (tmpfs_restore(devmap_handle)) 470 async_answer_3(rid, EOK, rootp->index, rootp->size, 471 rootp->lnkcnt); 472 else 473 async_answer_0(rid, ELIMIT); 474 } else { 475 async_answer_3(rid, EOK, rootp->index, rootp->size, 476 rootp->lnkcnt); 477 } 478 free(opts); 479 } 480 481 void tmpfs_mount(ipc_callid_t rid, ipc_call_t *request) 482 { 483 libfs_mount(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 484 } 485 486 void tmpfs_unmounted(ipc_callid_t rid, ipc_call_t *request) 487 { 488 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 489 455 if (!tmpfs_restore(devmap_handle)) 456 return ELIMIT; 457 } 458 459 *index = rootp->index; 460 *size = rootp->size; 461 *lnkcnt = rootp->lnkcnt; 462 463 return EOK; 464 } 465 466 static int tmpfs_unmounted(devmap_handle_t devmap_handle) 467 { 490 468 tmpfs_instance_done(devmap_handle); 491 async_answer_0(rid, EOK); 492 } 493 494 void tmpfs_unmount(ipc_callid_t rid, ipc_call_t *request) 495 { 496 libfs_unmount(&tmpfs_libfs_ops, rid, request); 497 } 498 499 void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request) 500 { 501 libfs_lookup(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 502 } 503 504 void tmpfs_read(ipc_callid_t rid, ipc_call_t *request) 505 { 506 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 507 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 508 aoff64_t pos = 509 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 510 469 return EOK; 470 } 471 472 static int tmpfs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 473 size_t *rbytes) 474 { 511 475 /* 512 476 * Lookup the respective TMPFS node. … … 518 482 }; 519 483 hlp = hash_table_find(&nodes, key); 520 if (!hlp) { 521 async_answer_0(rid, ENOENT); 522 return; 523 } 484 if (!hlp) 485 return ENOENT; 524 486 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 525 487 nh_link); … … 532 494 if (!async_data_read_receive(&callid, &size)) { 533 495 async_answer_0(callid, EINVAL); 534 async_answer_0(rid, EINVAL); 535 return; 496 return EINVAL; 536 497 } 537 498 … … 556 517 if (lnk == NULL) { 557 518 async_answer_0(callid, ENOENT); 558 async_answer_1(rid, ENOENT, 0); 559 return; 519 return ENOENT; 560 520 } 561 521 … … 567 527 } 568 528 569 /* 570 * Answer the VFS_READ call. 571 */ 572 async_answer_1(rid, EOK, bytes); 573 } 574 575 void tmpfs_write(ipc_callid_t rid, ipc_call_t *request) 576 { 577 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 578 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 579 aoff64_t pos = 580 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 581 529 *rbytes = bytes; 530 return EOK; 531 } 532 533 static int 534 tmpfs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 535 size_t *wbytes, aoff64_t *nsize) 536 { 582 537 /* 583 538 * Lookup the respective TMPFS node. … … 589 544 }; 590 545 hlp = hash_table_find(&nodes, key); 591 if (!hlp) { 592 async_answer_0(rid, ENOENT); 593 return; 594 } 546 if (!hlp) 547 return ENOENT; 595 548 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 596 549 nh_link); … … 603 556 if (!async_data_write_receive(&callid, &size)) { 604 557 async_answer_0(callid, EINVAL); 605 async_answer_0(rid, EINVAL); 606 return; 558 return EINVAL; 607 559 } 608 560 … … 612 564 if (pos + size <= nodep->size) { 613 565 /* The file size is not changing. */ 614 (void) async_data_write_finalize(callid, nodep->data + pos, size);615 async_answer_2(rid, EOK, size, nodep->size);616 return;566 (void) async_data_write_finalize(callid, nodep->data + pos, 567 size); 568 goto out; 617 569 } 618 570 size_t delta = (pos + size) - nodep->size; … … 627 579 if (!newdata) { 628 580 async_answer_0(callid, ENOMEM); 629 async_answer_2(rid, EOK, 0, nodep->size);630 return;581 size = 0; 582 goto out; 631 583 } 632 584 /* Clear any newly allocated memory in order to emulate gaps. */ … … 635 587 nodep->data = newdata; 636 588 (void) async_data_write_finalize(callid, nodep->data + pos, size); 637 async_answer_2(rid, EOK, size, nodep->size); 638 } 639 640 void tmpfs_truncate(ipc_callid_t rid, ipc_call_t *request) 641 { 642 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 643 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 644 aoff64_t size = 645 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 646 589 590 out: 591 *wbytes = size; 592 *nsize = nodep->size; 593 return EOK; 594 } 595 596 static int tmpfs_truncate(devmap_handle_t devmap_handle, fs_index_t index, 597 aoff64_t size) 598 { 647 599 /* 648 600 * Lookup the respective TMPFS node. … … 653 605 }; 654 606 link_t *hlp = hash_table_find(&nodes, key); 655 if (!hlp) { 656 async_answer_0(rid, ENOENT); 657 return; 658 } 659 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 660 nh_link); 661 662 if (size == nodep->size) { 663 async_answer_0(rid, EOK); 664 return; 665 } 666 667 if (size > SIZE_MAX) { 668 async_answer_0(rid, ENOMEM); 669 return; 670 } 607 if (!hlp) 608 return ENOENT; 609 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, nh_link); 610 611 if (size == nodep->size) 612 return EOK; 613 614 if (size > SIZE_MAX) 615 return ENOMEM; 671 616 672 617 void *newdata = realloc(nodep->data, size); 673 if (!newdata) { 674 async_answer_0(rid, ENOMEM); 675 return; 676 } 618 if (!newdata) 619 return ENOMEM; 677 620 678 621 if (size > nodep->size) { … … 683 626 nodep->size = size; 684 627 nodep->data = newdata; 685 async_answer_0(rid, EOK); 686 } 687 688 void tmpfs_close(ipc_callid_t rid, ipc_call_t *request) 689 { 690 async_answer_0(rid, EOK); 691 } 692 693 void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request) 694 { 695 devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request); 696 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 697 int rc; 698 628 return EOK; 629 } 630 631 static int tmpfs_close(devmap_handle_t devmap_handle, fs_index_t index) 632 { 633 return EOK; 634 } 635 636 static int tmpfs_destroy(devmap_handle_t devmap_handle, fs_index_t index) 637 { 699 638 link_t *hlp; 700 639 unsigned long key[] = { … … 703 642 }; 704 643 hlp = hash_table_find(&nodes, key); 705 if (!hlp) { 706 async_answer_0(rid, ENOENT); 707 return; 708 } 644 if (!hlp) 645 return ENOENT; 709 646 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 710 647 nh_link); 711 rc = tmpfs_destroy_node(FS_NODE(nodep)); 712 async_answer_0(rid, rc); 713 } 714 715 void tmpfs_open_node(ipc_callid_t rid, ipc_call_t *request) 716 { 717 libfs_open_node(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 718 } 719 720 void tmpfs_stat(ipc_callid_t rid, ipc_call_t *request) 721 { 722 libfs_stat(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 723 } 724 725 void tmpfs_sync(ipc_callid_t rid, ipc_call_t *request) 648 return tmpfs_destroy_node(FS_NODE(nodep)); 649 } 650 651 static int tmpfs_sync(devmap_handle_t devmap_handle, fs_index_t index) 726 652 { 727 653 /* … … 729 655 * thus the sync operation is a no-op. 730 656 */ 731 async_answer_0(rid, EOK); 732 } 657 return EOK; 658 } 659 660 vfs_out_ops_t tmpfs_ops = { 661 .mounted = tmpfs_mounted, 662 .unmounted = tmpfs_unmounted, 663 .read = tmpfs_read, 664 .write = tmpfs_write, 665 .truncate = tmpfs_truncate, 666 .close = tmpfs_close, 667 .destroy = tmpfs_destroy, 668 .sync = tmpfs_sync, 669 }; 733 670 734 671 /** 735 672 * @} 736 673 */ 674 -
uspace/srv/hw/irc/apic/apic.c
r9350bfdd r7ae249d 42 42 #include <as.h> 43 43 #include <ddi.h> 44 #include <libarch/ddi.h>45 #include <align.h>46 44 #include <bool.h> 47 45 #include <errno.h> 48 46 #include <async.h> 49 #include <align.h>50 #include <async.h>51 #include <stdio.h>52 #include <ipc/devmap.h>53 47 54 48 #define NAME "apic" 55 49 50 #define APIC_MAX_IRQ 15 51 52 #define IOREGSEL (0x00U / sizeof(uint32_t)) 53 #define IOWIN (0x10U / sizeof(uint32_t)) 54 55 #define IOREDTBL 0x10U 56 57 /** I/O Register Select Register. */ 58 typedef union { 59 uint32_t value; 60 struct { 61 uint8_t reg_addr; /**< APIC Register Address. */ 62 unsigned int : 24; /**< Reserved. */ 63 } __attribute__ ((packed)); 64 } io_regsel_t; 65 66 /** I/O Redirection Register. */ 67 typedef struct io_redirection_reg { 68 union { 69 uint32_t lo; 70 struct { 71 uint8_t intvec; /**< Interrupt Vector. */ 72 unsigned int delmod : 3; /**< Delivery Mode. */ 73 unsigned int destmod : 1; /**< Destination mode. */ 74 unsigned int delivs : 1; /**< Delivery status (RO). */ 75 unsigned int intpol : 1; /**< Interrupt Input Pin Polarity. */ 76 unsigned int irr : 1; /**< Remote IRR (RO). */ 77 unsigned int trigger_mode : 1; /**< Trigger Mode. */ 78 unsigned int masked : 1; /**< Interrupt Mask. */ 79 unsigned int : 15; /**< Reserved. */ 80 } __attribute__ ((packed)); 81 }; 82 union { 83 uint32_t hi; 84 struct { 85 unsigned int : 24; /**< Reserved. */ 86 uint8_t dest : 8; /**< Destination Field. */ 87 } __attribute__ ((packed)); 88 }; 89 } __attribute__ ((packed)) io_redirection_reg_t; 90 91 // FIXME: get the address from the kernel 92 #define IO_APIC_BASE 0xfec00000UL 93 #define IO_APIC_SIZE 20 94 95 ioport32_t *io_apic = NULL; 96 97 /** Read from IO APIC register. 98 * 99 * @param address IO APIC register address. 100 * 101 * @return Content of the addressed IO APIC register. 102 * 103 */ 104 static uint32_t io_apic_read(uint8_t address) 105 { 106 io_regsel_t regsel; 107 108 regsel.value = io_apic[IOREGSEL]; 109 regsel.reg_addr = address; 110 io_apic[IOREGSEL] = regsel.value; 111 return io_apic[IOWIN]; 112 } 113 114 /** Write to IO APIC register. 115 * 116 * @param address IO APIC register address. 117 * @param val Content to be written to the addressed IO APIC register. 118 * 119 */ 120 static void io_apic_write(uint8_t address, uint32_t val) 121 { 122 io_regsel_t regsel; 123 124 regsel.value = io_apic[IOREGSEL]; 125 regsel.reg_addr = address; 126 io_apic[IOREGSEL] = regsel.value; 127 io_apic[IOWIN] = val; 128 } 129 130 static int irq_to_pin(int irq) 131 { 132 // FIXME: get the map from the kernel, even though this may work 133 // for simple cases 134 return irq; 135 } 136 56 137 static int apic_enable_irq(sysarg_t irq) 57 138 { 58 // FIXME: TODO 59 return ENOTSUP; 139 io_redirection_reg_t reg; 140 141 if (irq > APIC_MAX_IRQ) 142 return ELIMIT; 143 144 int pin = irq_to_pin(irq); 145 if (pin == -1) 146 return ENOENT; 147 148 reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2)); 149 reg.masked = false; 150 io_apic_write((uint8_t) (IOREDTBL + pin * 2), reg.lo); 151 152 return EOK; 60 153 } 61 154 … … 111 204 return false; 112 205 } 206 207 if (pio_enable((void *) IO_APIC_BASE, IO_APIC_SIZE, 208 (void **) &io_apic) != EOK) 209 return false; 113 210 114 211 async_set_client_connection(apic_connection); -
uspace/srv/loader/Makefile
r9350bfdd r7ae249d 39 39 LINKER_SCRIPT = $(LIBC_PREFIX)/arch/$(UARCH)/_link-loader.ld 40 40 41 EXTRA_CFLAGS = -Iinclude42 43 41 BINARY = loader 44 42 STATIC_ONLY = y … … 46 44 GENERIC_SOURCES = \ 47 45 main.c \ 48 elf_load.c \49 46 interp.s 50 47 -
uspace/srv/loader/main.c
r9350bfdd r7ae249d 59 59 #include <str.h> 60 60 #include <as.h> 61 #include <elf .h>62 #include <elf _load.h>61 #include <elf/elf.h> 62 #include <elf/elf_load.h> 63 63 64 64 #ifdef CONFIG_RTLD … … 348 348 349 349 /* Initialize list of loaded modules */ 350 list_initialize(&runtime_env->modules _head);351 list_append(&prog_mod.modules_link, &runtime_env->modules _head);350 list_initialize(&runtime_env->modules); 351 list_append(&prog_mod.modules_link, &runtime_env->modules); 352 352 353 353 /* Pointer to program module. Used as root of the module graph. */ -
uspace/srv/vfs/vfs_ops.c
r9350bfdd r7ae249d 76 76 vfs_node_t *mr_node; 77 77 fs_index_t rindex; 78 size_t rsize;78 aoff64_t rsize; 79 79 unsigned rlnkcnt; 80 80 async_exch_t *exch; … … 146 146 147 147 rindex = (fs_index_t) IPC_GET_ARG1(answer); 148 rsize = ( size_t) IPC_GET_ARG2(answer);149 rlnkcnt = (unsigned) IPC_GET_ARG 3(answer);148 rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer), IPC_GET_ARG3(answer)); 149 rlnkcnt = (unsigned) IPC_GET_ARG4(answer); 150 150 151 151 mr_res.triplet.fs_handle = fs_handle; … … 229 229 if (rc == EOK) { 230 230 rindex = (fs_index_t) IPC_GET_ARG1(answer); 231 rsize = (size_t) IPC_GET_ARG2(answer); 232 rlnkcnt = (unsigned) IPC_GET_ARG3(answer); 231 rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer), 232 IPC_GET_ARG3(answer)); 233 rlnkcnt = (unsigned) IPC_GET_ARG4(answer); 233 234 234 235 mr_res.triplet.fs_handle = fs_handle; … … 795 796 ipc_call_t answer; 796 797 if (read) { 797 rc = async_data_read_forward_ 3_1(fs_exch, VFS_OUT_READ,798 file->node->devmap_handle, file->node->index, file->pos,799 &answer);798 rc = async_data_read_forward_4_1(fs_exch, VFS_OUT_READ, 799 file->node->devmap_handle, file->node->index, 800 LOWER32(file->pos), UPPER32(file->pos), &answer); 800 801 } else { 801 802 if (file->append) 802 803 file->pos = file->node->size; 803 804 804 rc = async_data_write_forward_ 3_1(fs_exch, VFS_OUT_WRITE,805 file->node->devmap_handle, file->node->index, file->pos,806 &answer);805 rc = async_data_write_forward_4_1(fs_exch, VFS_OUT_WRITE, 806 file->node->devmap_handle, file->node->index, 807 LOWER32(file->pos), UPPER32(file->pos), &answer); 807 808 } 808 809 … … 821 822 /* Update the cached version of node's size. */ 822 823 if (rc == EOK) 823 file->node->size = IPC_GET_ARG2(answer); 824 file->node->size = MERGE_LOUP32(IPC_GET_ARG2(answer), 825 IPC_GET_ARG3(answer)); 824 826 fibril_rwlock_write_unlock(&file->node->contents_rwlock); 825 827 }
Note:
See TracChangeset
for help on using the changeset viewer.
