Changes in / [80e9e5e:c936c7f] in mainline
- Files:
-
- 2 deleted
- 40 edited
Legend:
- Unmodified
- Added
- Removed
-
HelenOS.config
r80e9e5e rc936c7f 88 88 @ "tmpfs" TMPFS image 89 89 @ "fat" FAT16 image 90 @ "ext2fs" EXT2 image91 90 ! RDFMT (choice) 92 91 -
boot/Makefile
r80e9e5e rc936c7f 50 50 $(MKFAT) 1048576 $(DIST_PATH) $@ 51 51 endif 52 ifeq ($(RDFMT),ext2fs)53 $(MKEXT2) 1048576 $(DIST_PATH) $@54 endif55 52 56 53 build_dist: clean_dist -
boot/Makefile.common
r80e9e5e rc936c7f 56 56 MKTMPFS = $(TOOLS_PATH)/mktmpfs.py 57 57 MKFAT = $(TOOLS_PATH)/mkfat.py 58 MKEXT2 = $(TOOLS_PATH)/mkext2.py59 58 MKUIMAGE = $(TOOLS_PATH)/mkuimage.py 60 59 … … 83 82 ifeq ($(RDFMT),fat) 84 83 INIT_TASKS += $(USPACE_PATH)/srv/fs/fat/fat 85 endif86 87 ifeq ($(RDFMT),ext2fs)88 INIT_TASKS += $(USPACE_PATH)/srv/fs/ext2fs/ext2fs89 84 endif 90 85 -
tools/mkfat.py
r80e9e5e rc936c7f 37 37 import xstruct 38 38 import array 39 from imgutil import * 39 40 exclude_names = set(['.svn', '.bzr']) 41 42 def align_up(size, alignment): 43 "Return size aligned up to alignment" 44 45 if (size % alignment == 0): 46 return size 47 48 return ((size // alignment) + 1) * alignment 40 49 41 50 def subtree_size(root, cluster_size, dirent_size): … … 45 54 files = 2 46 55 47 for item in listdir_items(root): 48 if item.is_file: 49 size += align_up(item.size, cluster_size) 56 for name in os.listdir(root): 57 canon = os.path.join(root, name) 58 59 if (os.path.isfile(canon) and (not name in exclude_names)): 60 size += align_up(os.path.getsize(canon), cluster_size) 50 61 files += 1 51 elif item.is_dir: 52 size += subtree_size(item.path, cluster_size, dirent_size) 62 63 if (os.path.isdir(canon) and (not name in exclude_names)): 64 size += subtree_size(canon, cluster_size, dirent_size) 53 65 files += 1 54 66 … … 60 72 return len(os.listdir(root)) 61 73 62 def write_file( item, outf, cluster_size, data_start, fat, reserved_clusters):74 def write_file(path, outf, cluster_size, data_start, fat, reserved_clusters): 63 75 "Store the contents of a file" 64 76 77 size = os.path.getsize(path) 65 78 prev = -1 66 79 first = 0 67 80 68 for data in chunks(item, cluster_size): 81 inf = open(path, "rb") 82 rd = 0; 83 while (rd < size): 69 84 empty_cluster = fat.index(0) 70 85 fat[empty_cluster] = 0xffff … … 77 92 prev = empty_cluster 78 93 94 data = bytes(inf.read(cluster_size)); 79 95 outf.seek(data_start + (empty_cluster - reserved_clusters) * cluster_size) 80 96 outf.write(data) 81 82 return first, item.size 97 rd += len(data) 98 inf.close() 99 100 return first, size 83 101 84 102 def write_directory(directory, outf, cluster_size, data_start, fat, reserved_clusters, dirent_size, empty_cluster): … … 285 303 empty_cluster = 0 286 304 287 for item in listdir_items(root): 288 if item.is_file: 289 rv = write_file(item, outf, cluster_size, data_start, fat, reserved_clusters) 290 directory.append(create_dirent(item.name, False, rv[0], rv[1])) 291 elif item.is_dir: 292 rv = recursion(False, item.path, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, empty_cluster) 293 directory.append(create_dirent(item.name, True, rv[0], rv[1])) 305 for name in os.listdir(root): 306 canon = os.path.join(root, name) 307 308 if (os.path.isfile(canon) and (not name in exclude_names)): 309 rv = write_file(canon, outf, cluster_size, data_start, fat, reserved_clusters) 310 directory.append(create_dirent(name, False, rv[0], rv[1])) 311 312 if (os.path.isdir(canon) and (not name in exclude_names)): 313 rv = recursion(False, canon, outf, cluster_size, root_start, data_start, fat, reserved_clusters, dirent_size, empty_cluster) 314 directory.append(create_dirent(name, True, rv[0], rv[1])) 294 315 295 316 if (head): -
tools/mktmpfs.py
r80e9e5e rc936c7f 35 35 import os 36 36 import xstruct 37 from imgutil import listdir_items, chunks 37 38 exclude_names = set(['.svn', '.bzr']) 38 39 39 40 HEADER = """little: … … 70 71 "Recursive directory walk" 71 72 72 for item in listdir_items(root): 73 if item.is_file: 74 dentry = xstruct.create(DENTRY_FILE % len(item.name)) 73 for name in os.listdir(root): 74 canon = os.path.join(root, name) 75 76 if (os.path.isfile(canon) and (not name in exclude_names)): 77 size = os.path.getsize(canon) 78 79 dentry = xstruct.create(DENTRY_FILE % len(name)) 75 80 dentry.kind = TMPFS_FILE 76 dentry.fname_len = len( item.name)77 dentry.fname = item.name.encode('ascii')78 dentry.flen = item.size81 dentry.fname_len = len(name) 82 dentry.fname = name.encode('ascii') 83 dentry.flen = size 79 84 80 85 outf.write(dentry.pack()) 81 86 82 for data in chunks(item, 4096): 87 inf = open(canon, "rb") 88 rd = 0; 89 while (rd < size): 90 data = inf.read(4096); 83 91 outf.write(data) 92 rd += len(data) 93 inf.close() 84 94 85 elif item.is_dir:86 dentry = xstruct.create(DENTRY_DIRECTORY % len( item.name))95 if (os.path.isdir(canon) and (not name in exclude_names)): 96 dentry = xstruct.create(DENTRY_DIRECTORY % len(name)) 87 97 dentry.kind = TMPFS_DIRECTORY 88 dentry.fname_len = len( item.name)89 dentry.fname = item.name.encode('ascii')98 dentry.fname_len = len(name) 99 dentry.fname = name.encode('ascii') 90 100 91 101 outf.write(dentry.pack()) 92 102 93 recursion( item.path, outf)103 recursion(canon, outf) 94 104 95 105 dentry = xstruct.create(DENTRY_NONE) -
tools/xstruct.py
r80e9e5e rc936c7f 1 1 # 2 2 # Copyright (c) 2008 Martin Decky 3 # Copyright (c) 2011 Martin Sucha4 3 # All rights reserved. 5 4 # … … 32 31 33 32 import struct 34 import types35 36 ranges = {37 'B': ((int, long), 0x00, 0xff),38 'H': ((int, long), 0x0000, 0xffff),39 'L': ((int, long), 0x00000000, 0xffffffff),40 'Q': ((int, long), 0x0000000000000000, 0xffffffffffffffff),41 'b': ((int, long), -0x80, 0x7f),42 'h': ((int, long), -0x8000, 0x7fff),43 'l': ((int, long), -0x80000000, 0x7fffffff) ,44 'q': ((int, long), -0x8000000000000000, 0x7fffffffffffffff),45 }46 47 def check_range(varname, fmt, value):48 if value == None:49 raise ValueError('Variable "%s" not set' % varname)50 if not fmt in ranges:51 return52 vartype, varmin, varmax = ranges[fmt]53 if not isinstance(value, vartype):54 raise ValueError('Variable "%s" is %s but should be %s' %55 (varname, str(type(value)), str(vartype)))56 if value < varmin or value > varmax:57 raise ValueError('Variable "%s" value %s out of range %s..%s' %58 (varname, repr(value), repr(varmin), repr(varmax)))59 33 60 34 class Struct: … … 64 38 def pack(self): 65 39 args = [] 66 for variable, fmt, length in self._args_: 67 value = self.__dict__[variable] 68 if isinstance(value, list): 69 if length != None and length != len(value): 70 raise ValueError('Variable "%s" length %u does not match %u' % 71 (variable, len(value), length)) 72 for index, item in enumerate(value): 73 check_range(variable + '[' + repr(index) + ']', fmt, item) 40 for variable in self._args_: 41 if (isinstance(self.__dict__[variable], list)): 42 for item in self.__dict__[variable]: 74 43 args.append(item) 75 44 else: 76 check_range(variable, fmt, value)77 args.append(value)45 args.append(self.__dict__[variable]) 46 78 47 return struct.pack(self._format_, *args) 79 80 def unpack(self, data):81 values = struct.unpack(self._format_, data)82 i = 083 for variable, fmt, length in self._args_:84 self.__dict__[variable] = values[i]85 i += 186 48 87 49 def create(definition): … … 115 77 subtokens = token.split("[") 116 78 117 length = None118 79 if (len(subtokens) > 1): 119 length = int(subtokens[1].split("]")[0]) 120 format += "%d" % length 80 format += "%d" % int(subtokens[1].split("]")[0]) 121 81 122 82 format += variable 123 83 124 84 inst.__dict__[subtokens[0]] = None 125 args.append( (subtokens[0], variable, length))85 args.append(subtokens[0]) 126 86 127 87 variable = None -
uspace/app/bdsh/cmds/modules/cp/cp.c
r80e9e5e rc936c7f 71 71 size_t blen, int vb) 72 72 { 73 int fd1, fd2, bytes ;74 off64_t total ;73 int fd1, fd2, bytes = 0; 74 off64_t total = 0; 75 75 int64_t copied = 0; 76 76 char *buff = NULL; … … 104 104 } 105 105 106 while ((bytes = read_all(fd1, buff, blen)) > 0) { 107 if ((bytes = write_all(fd2, buff, bytes)) < 0) 106 for (;;) { 107 ssize_t res; 108 size_t written = 0; 109 110 bytes = read(fd1, buff, blen); 111 if (bytes <= 0) 108 112 break; 109 113 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 have 119 * 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 shell 130 */ 131 if (res != 0) { 132 printf("\n%zd more bytes than actually exist were copied\n", res); 133 goto err; 134 } 110 135 } 111 136 112 137 if (bytes < 0) { 138 err: 113 139 printf("\nError copying %s, (%d)\n", src, bytes); 114 140 copied = bytes; -
uspace/app/bdsh/compl.c
r80e9e5e rc936c7f 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++;286 282 } 287 283 -
uspace/app/taskdump/elf_core.c
r80e9e5e rc936c7f 67 67 68 68 static off64_t align_foff_up(off64_t, uintptr_t, size_t); 69 static int write_all(int, const void *, size_t); 69 70 static int align_pos(int, size_t); 70 71 static int write_mem_area(int, as_area_info_t *, async_sess_t *); … … 99 100 100 101 int fd; 101 ssize_t rc;102 int rc; 102 103 unsigned int i; 103 104 … … 203 204 204 205 rc = write_all(fd, &elf_hdr, sizeof(elf_hdr)); 205 if (rc != sizeof(elf_hdr)) {206 if (rc != EOK) { 206 207 printf("Failed writing ELF header.\n"); 207 208 free(p_hdr); … … 211 212 for (i = 0; i < n_ph; ++i) { 212 213 rc = write_all(fd, &p_hdr[i], sizeof(p_hdr[i])); 213 if (rc != sizeof(p_hdr[i])) {214 if (rc != EOK) { 214 215 printf("Failed writing program header.\n"); 215 216 free(p_hdr); … … 232 233 233 234 rc = write_all(fd, ¬e, sizeof(elf_note_t)); 234 if (rc != sizeof(elf_note_t)) {235 if (rc != EOK) { 235 236 printf("Failed writing note header.\n"); 236 237 free(p_hdr); … … 239 240 240 241 rc = write_all(fd, "CORE", note.namesz); 241 if (rc != (ssize_t) note.namesz) {242 if (rc != EOK) { 242 243 printf("Failed writing note header.\n"); 243 244 free(p_hdr); … … 253 254 254 255 rc = write_all(fd, &pr_status, sizeof(elf_prstatus_t)); 255 if (rc != sizeof(elf_prstatus_t)) {256 if (rc != EOK) { 256 257 printf("Failed writing register data.\n"); 257 258 free(p_hdr); … … 303 304 size_t total; 304 305 uintptr_t addr; 305 ssize_t rc;306 int rc; 306 307 307 308 addr = area->start_addr; … … 317 318 318 319 rc = write_all(fd, buffer, to_copy); 319 if (rc != (ssize_t) to_copy) {320 if (rc != EOK) { 320 321 printf("Failed writing memory contents.\n"); 321 322 return EIO; … … 325 326 total += to_copy; 326 327 } 328 329 return EOK; 330 } 331 332 /** Write until the buffer is written in its entirety. 333 * 334 * This function fails if it cannot write exactly @a len bytes to the file. 335 * 336 * @param fd The file to write to. 337 * @param buf Data, @a len bytes long. 338 * @param len Number of bytes to write. 339 * 340 * @return EOK on error, return value from write() if writing 341 * failed. 342 */ 343 static int write_all(int fd, const void *data, size_t len) 344 { 345 int cnt = 0; 346 347 do { 348 data += cnt; 349 len -= cnt; 350 cnt = write(fd, data, len); 351 } while (cnt > 0 && (len - cnt) > 0); 352 353 if (cnt < 0) 354 return cnt; 355 356 if (len - cnt > 0) 357 return EIO; 327 358 328 359 return EOK; -
uspace/app/taskdump/symtab.c
r80e9e5e rc936c7f 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); 52 53 53 54 /** Load symbol table from an ELF file. … … 89 90 90 91 rc = read_all(fd, &elf_hdr, sizeof(elf_header_t)); 91 if (rc != sizeof(elf_header_t)) {92 if (rc != EOK) { 92 93 printf("failed reading elf header\n"); 93 94 free(stab); … … 311 312 312 313 rc = read_all(fd, sec_hdr, sizeof(elf_section_header_t)); 313 if (rc != sizeof(elf_section_header_t))314 if (rc != EOK) 314 315 return EIO; 315 316 … … 330 331 static int chunk_load(int fd, off64_t start, size_t size, void **ptr) 331 332 { 332 ssize_t rc; 333 off64_t offs; 334 335 offs = lseek(fd, start, SEEK_SET); 336 if (offs == (off64_t) -1) { 333 int rc; 334 335 rc = lseek(fd, start, SEEK_SET); 336 if (rc == (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 != (ssize_t) size) {349 if (rc != EOK) { 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 value 368 * 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 359 389 /** @} 360 390 */ -
uspace/drv/bus/usb/usbmast/bo_trans.c
r80e9e5e rc936c7f 58 58 * @param tag Command block wrapper tag (automatically compared 59 59 * with answer) 60 * @param cmd SCSI command 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 61 66 * 62 67 * @return Error code 63 68 */ 64 int usb_massstor_cmd(usbmast_fun_t *mfun, uint32_t tag, scsi_cmd_t *cmd) 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) 65 72 { 66 73 int rc; 67 int retval = EOK;68 74 size_t act_size; 69 75 usb_pipe_t *bulk_in_pipe = mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe; 70 76 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 }86 77 87 78 /* Prepare CBW - command block wrapper */ 88 79 usb_massstor_cbw_t cbw; 89 80 usb_massstor_cbw_prepare(&cbw, tag, dbuf_size, ddir, mfun->lun, 90 cmd ->cdb_size, cmd->cdb);81 cmd_size, cmd); 91 82 92 83 /* Send the CBW. */ 93 MASTLOG("Sending CBW.\n");94 84 rc = usb_pipe_write(bulk_out_pipe, &cbw, sizeof(cbw)); 95 85 MASTLOG("CBW '%s' sent: %s.\n", 96 86 usb_debug_str_buffer((uint8_t *) &cbw, sizeof(cbw), 0), 97 87 str_error(rc)); 98 if (rc != EOK) 99 return EIO;100 101 MASTLOG("Transferring data.\n"); 88 if (rc != EOK) { 89 return rc; 90 } 91 102 92 if (ddir == USB_DIRECTION_IN) { 103 93 /* Recieve data from the device. */ … … 114 104 } 115 105 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; 106 if (rc != EOK) { 107 /* 108 * XXX If the pipe is stalled, we should clear it 109 * and read CSW. 110 */ 111 return rc; 127 112 } 128 113 … … 130 115 usb_massstor_csw_t csw; 131 116 size_t csw_size; 132 MASTLOG("Reading CSW.\n");133 117 rc = usb_pipe_read(bulk_in_pipe, &csw, sizeof(csw), &csw_size); 134 118 MASTLOG("CSW '%s' received (%zu bytes): %s.\n", … … 137 121 if (rc != EOK) { 138 122 MASTLOG("rc != EOK\n"); 139 return EIO;123 return rc; 140 124 } 141 125 142 126 if (csw_size != sizeof(csw)) { 143 127 MASTLOG("csw_size != sizeof(csw)\n"); 144 return E IO;128 return ERANGE; 145 129 } 146 130 147 131 if (csw.dCSWTag != tag) { 148 132 MASTLOG("csw.dCSWTag != tag\n"); 149 return E IO;133 return EBADCHECKSUM; 150 134 } 151 135 … … 153 137 * Determine the actual return value from the CSW. 154 138 */ 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; 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; 170 144 } 171 145 … … 173 147 if (residue > dbuf_size) { 174 148 MASTLOG("residue > dbuf_size\n"); 175 return E IO;149 return ERANGE; 176 150 } 177 151 … … 184 158 */ 185 159 186 if (ddir == USB_DIRECTION_IN) 187 cmd->rcvd_size = dbuf_size - residue; 188 189 return retval; 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); 190 204 } 191 205 -
uspace/drv/bus/usb/usbmast/bo_trans.h
r80e9e5e rc936c7f 47 47 #define BULK_OUT_EP 1 48 48 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 *); 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 *); 91 53 extern int usb_massstor_reset(usbmast_dev_t *); 92 54 extern void usb_massstor_reset_recovery(usbmast_dev_t *); -
uspace/drv/bus/usb/usbmast/cmdw.h
r80e9e5e rc936c7f 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 = 0x0263 };64 65 59 extern void usb_massstor_cbw_prepare(usb_massstor_cbw_t *, uint32_t, uint32_t, 66 60 usb_direction_t, uint8_t, uint8_t, const uint8_t *); -
uspace/drv/bus/usb/usbmast/scsi_ms.c
r80e9e5e rc936c7f 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 122 63 /** Perform SCSI Inquiry command on USB mass storage device. 123 64 * … … 129 70 { 130 71 scsi_std_inquiry_data_t inq_data; 131 s csi_cmd_t cmd;72 size_t response_len; 132 73 scsi_cdb_inquiry_t cdb; 133 74 int rc; … … 137 78 cdb.alloc_len = host2uint16_t_be(sizeof(inq_data)); 138 79 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); 80 rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb, 81 sizeof(cdb), &inq_data, sizeof(inq_data), &response_len); 146 82 147 83 if (rc != EOK) { 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) { 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) { 160 90 usb_log_error("SCSI Inquiry response too short (%zu).\n", 161 cmd.rcvd_size);91 response_len); 162 92 return EIO; 163 93 } … … 197 127 int usbmast_request_sense(usbmast_fun_t *mfun, void *buf, size_t size) 198 128 { 199 scsi_cmd_t cmd;200 129 scsi_cdb_request_sense_t cdb; 130 size_t data_len; 201 131 int rc; 202 132 … … 205 135 cdb.alloc_len = min(size, SCSI_SENSE_DATA_MAX_SIZE); 206 136 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) { 137 rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb, 138 sizeof(cdb), buf, size, &data_len); 139 140 if (rc != EOK) { 216 141 usb_log_error("Request Sense failed, device %s: %s.\n", 217 142 mfun->mdev->ddf_dev->name, str_error(rc)); … … 219 144 } 220 145 221 if ( cmd.rcvd_size< SCSI_SENSE_DATA_MIN_SIZE) {146 if (data_len < SCSI_SENSE_DATA_MIN_SIZE) { 222 147 /* The missing bytes should be considered to be zeroes. */ 223 memset((uint8_t *)buf + cmd.rcvd_size, 0,224 SCSI_SENSE_DATA_MIN_SIZE - cmd.rcvd_size);148 memset((uint8_t *)buf + data_len, 0, 149 SCSI_SENSE_DATA_MIN_SIZE - data_len); 225 150 } 226 151 … … 239 164 uint32_t *block_size) 240 165 { 241 scsi_cmd_t cmd;242 166 scsi_cdb_read_capacity_10_t cdb; 243 167 scsi_read_capacity_10_data_t data; 168 size_t data_len; 244 169 int rc; 245 170 … … 247 172 cdb.op_code = SCSI_CMD_READ_CAPACITY_10; 248 173 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); 256 257 if (rc != EOK) { 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)) { 174 rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb, 175 sizeof(cdb), &data, sizeof(data), &data_len); 176 177 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)) { 270 184 usb_log_error("SCSI Read Capacity response too short (%zu).\n", 271 cmd.rcvd_size);185 data_len); 272 186 return EIO; 273 187 } … … 289 203 int usbmast_read(usbmast_fun_t *mfun, uint64_t ba, size_t nblocks, void *buf) 290 204 { 291 scsi_cmd_t cmd; 292 scsi_cdb_read_10_t cdb; 293 int rc; 205 scsi_cdb_read_12_t cdb; 206 size_t data_len; 207 int rc; 208 209 /* XXX Need softstate to store block size. */ 294 210 295 211 if (ba > UINT32_MAX) 296 212 return ELIMIT; 297 213 298 if ( nblocks > UINT16_MAX)299 return ELIMIT; 300 301 memset(&cdb, 0, sizeof(cdb)); 302 cdb.op_code = SCSI_CMD_READ_1 0;214 if ((uint64_t)nblocks * mfun->block_size > UINT32_MAX) 215 return ELIMIT; 216 217 memset(&cdb, 0, sizeof(cdb)); 218 cdb.op_code = SCSI_CMD_READ_12; 303 219 cdb.lba = host2uint32_t_be(ba); 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); 313 314 if (rc != EOK) { 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) { 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); 224 225 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) { 327 232 usb_log_error("SCSI Read response too short (%zu).\n", 328 cmd.rcvd_size);233 data_len); 329 234 return EIO; 330 235 } … … 345 250 const void *data) 346 251 { 347 scsi_c md_t cmd;348 s csi_cdb_write_10_t cdb;252 scsi_cdb_write_12_t cdb; 253 size_t sent_len; 349 254 int rc; 350 255 … … 352 257 return ELIMIT; 353 258 354 if ( nblocks > UINT16_MAX)355 return ELIMIT; 356 357 memset(&cdb, 0, sizeof(cdb)); 358 cdb.op_code = SCSI_CMD_WRITE_1 0;259 if ((uint64_t)nblocks * mfun->block_size > UINT32_MAX) 260 return ELIMIT; 261 262 memset(&cdb, 0, sizeof(cdb)); 263 cdb.op_code = SCSI_CMD_WRITE_12; 359 264 cdb.lba = host2uint32_t_be(ba); 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); 369 370 if (rc != EOK) { 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); 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); 269 270 if (rc != EOK) { 271 usb_log_error("Write (12) 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); 379 279 return EIO; 380 280 } -
uspace/lib/block/libblock.c
r80e9e5e rc936c7f 258 258 static hash_index_t cache_hash(unsigned long *key) 259 259 { 260 return MERGE_LOUP32(key[0], key[1])& (CACHE_BUCKETS - 1);260 return *key & (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 == MERGE_LOUP32(key[0], key[1]);266 return b->lba == *key; 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, 2,307 if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1, 308 308 &cache_ops)) { 309 309 free(cache); … … 344 344 } 345 345 346 unsigned long key[2] = { 347 LOWER32(b->lba), 348 UPPER32(b->lba) 349 }; 350 hash_table_remove(&cache->block_hash, key, 2); 346 unsigned long key = b->lba; 347 hash_table_remove(&cache->block_hash, &key, 1); 351 348 352 349 free(b->data); … … 401 398 block_t *b; 402 399 link_t *l; 403 unsigned long key[2] = { 404 LOWER32(ba), 405 UPPER32(ba) 406 }; 407 400 unsigned long key = ba; 408 401 int rc; 409 402 … … 420 413 421 414 fibril_mutex_lock(&cache->lock); 422 l = hash_table_find(&cache->block_hash, key);415 l = hash_table_find(&cache->block_hash, &key); 423 416 if (l) { 424 417 found: … … 458 451 * Try to recycle a block from the free list. 459 452 */ 453 unsigned long temp_key; 460 454 recycle: 461 455 if (list_empty(&cache->free_list)) { … … 505 499 goto retry; 506 500 } 507 l = hash_table_find(&cache->block_hash, key);501 l = hash_table_find(&cache->block_hash, &key); 508 502 if (l) { 509 503 /* … … 528 522 */ 529 523 list_remove(&b->free_link); 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); 524 temp_key = b->lba; 525 hash_table_remove(&cache->block_hash, &temp_key, 1); 535 526 } 536 527 … … 540 531 b->lba = ba; 541 532 b->pba = ba_ltop(devcon, b->lba); 542 hash_table_insert(&cache->block_hash, key, &b->hash_link);533 hash_table_insert(&cache->block_hash, &key, &b->hash_link); 543 534 544 535 /* … … 652 643 * Take the block out of the cache and free it. 653 644 */ 654 unsigned long key[2] = { 655 LOWER32(block->lba), 656 UPPER32(block->lba) 657 }; 658 hash_table_remove(&cache->block_hash, key, 2); 645 unsigned long key = block->lba; 646 hash_table_remove(&cache->block_hash, &key, 1); 659 647 fibril_mutex_unlock(&block->lock); 660 648 free(block->data); -
uspace/lib/c/generic/elf/elf_load.c
r80e9e5e rc936c7f 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 76 89 /** Load ELF binary from a file. 77 90 * … … 147 160 int i, rc; 148 161 149 rc = read_all(elf->fd, header, sizeof(elf_header_t));150 if (rc != sizeof(elf_header_t)) {162 rc = my_read(elf->fd, header, sizeof(elf_header_t)); 163 if (rc < 0) { 151 164 DPRINTF("Read error.\n"); 152 165 return EE_INVALID; … … 209 222 + i * sizeof(elf_segment_header_t), SEEK_SET); 210 223 211 rc = read_all(elf->fd, &segment_hdr,224 rc = my_read(elf->fd, &segment_hdr, 212 225 sizeof(elf_segment_header_t)); 213 if (rc != sizeof(elf_segment_header_t)) {226 if (rc < 0) { 214 227 DPRINTF("Read error.\n"); 215 228 return EE_INVALID; … … 231 244 + i * sizeof(elf_section_header_t), SEEK_SET); 232 245 233 rc = read_all(elf->fd, §ion_hdr,246 rc = my_read(elf->fd, §ion_hdr, 234 247 sizeof(elf_section_header_t)); 235 if (rc != sizeof(elf_section_header_t)) {248 if (rc < 0) { 236 249 DPRINTF("Read error.\n"); 237 250 return EE_INVALID; … … 321 334 uintptr_t seg_addr; 322 335 size_t mem_sz; 323 ssize_t rc;336 int rc; 324 337 325 338 bias = elf->bias; … … 399 412 if (now > left) now = left; 400 413 401 rc = read_all(elf->fd, dp, now);402 403 if (rc != (ssize_t) now) {414 rc = my_read(elf->fd, dp, now); 415 416 if (rc < 0) { 404 417 DPRINTF("Read error.\n"); 405 418 return EE_INVALID; -
uspace/lib/c/generic/vfs/vfs.c
r80e9e5e rc936c7f 417 417 } 418 418 419 /** Read entire buffer.420 *421 * In face of short reads this function continues reading until either422 * the entire buffer is read or no more data is available (at end of file).423 *424 * @param fildes File descriptor425 * @param buf Buffer, @a nbytes bytes long426 * @param nbytes Number of bytes to read427 *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 descriptor454 * @param buf Data, @a nbytes bytes long455 * @param nbytes Number of bytes to write456 *457 * @return EOK on error, return value from write() if writing458 * 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 481 419 int fsync(int fildes) 482 420 { -
uspace/lib/c/include/unistd.h
r80e9e5e rc936c7f 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 68 65 extern off64_t lseek(int, off64_t, int); 69 66 extern int ftruncate(int, aoff64_t); -
uspace/lib/fs/libfs.c
r80e9e5e rc936c7f 45 45 #include <mem.h> 46 46 #include <sys/stat.h> 47 #include <stdlib.h>48 47 49 48 #define on_error(rc, action) \ … … 62 61 } while (0) 63 62 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 else99 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 else144 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 else162 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 by226 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections227 * 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 286 63 /** Register file system server. 287 64 * … … 291 68 * 292 69 * @param sess Session for communication with VFS. 70 * @param reg File system registration structure. It will be 71 * initialized by this function. 293 72 * @param info VFS info structure supplied by the file system 294 73 * implementation. 295 * @param vops Address of the vfs_out_ops_t structure.296 * @param lops Address of the libfs_ops_t structure.74 * @param conn Connection fibril for handling all calls originating in 75 * VFS. 297 76 * 298 77 * @return EOK on success or a non-zero error code on errror. 299 78 * 300 79 */ 301 int fs_register(async_sess_t *sess, vfs_info_t *info, vfs_out_ops_t *vops,302 libfs_ops_t *lops)80 int fs_register(async_sess_t *sess, fs_reg_t *reg, vfs_info_t *info, 81 async_client_conn_t conn) 303 82 { 304 83 /* … … 325 104 326 105 /* 327 * Set VFS_OUT and libfs operations.328 */329 vfs_out_ops = vops;330 libfs_ops = lops;331 332 /*333 106 * Ask VFS for callback connection. 334 107 */ 335 async_connect_to_me(exch, 0, 0, 0, vfs_connection, NULL);108 async_connect_to_me(exch, 0, 0, 0, conn, NULL); 336 109 337 110 /* 338 111 * Allocate piece of address space for PLB. 339 112 */ 340 reg .plb_ro = as_get_mappable_page(PLB_SIZE);341 if (!reg .plb_ro) {113 reg->plb_ro = as_get_mappable_page(PLB_SIZE); 114 if (!reg->plb_ro) { 342 115 async_exchange_end(exch); 343 116 async_wait_for(req, NULL); … … 348 121 * Request sharing the Path Lookup Buffer with VFS. 349 122 */ 350 rc = async_share_in_start_0_0(exch, reg .plb_ro, PLB_SIZE);123 rc = async_share_in_start_0_0(exch, reg->plb_ro, PLB_SIZE); 351 124 352 125 async_exchange_end(exch); … … 361 134 */ 362 135 async_wait_for(req, NULL); 363 reg .fs_handle = (int) IPC_GET_ARG1(answer);136 reg->fs_handle = (int) IPC_GET_ARG1(answer); 364 137 365 138 /* … … 367 140 * the same connection fibril as well. 368 141 */ 369 async_set_client_connection( vfs_connection);142 async_set_client_connection(conn); 370 143 371 144 return IPC_GET_RETVAL(answer); … … 378 151 379 152 void libfs_mount(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid, 380 ipc_call_t *req )153 ipc_call_t *request) 381 154 { 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 );155 devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 156 fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request); 157 fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*request); 158 devmap_handle_t mr_devmap_handle = (devmap_handle_t) IPC_GET_ARG4(*request); 386 159 387 160 async_sess_t *mountee_sess = async_clone_receive(EXCHANGE_PARALLEL); … … 435 208 * Do not release the FS node so that it stays in memory. 436 209 */ 437 async_answer_ 4(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),438 IPC_GET_ARG3(answer) , IPC_GET_ARG4(answer));210 async_answer_3(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer), 211 IPC_GET_ARG3(answer)); 439 212 } 440 213 441 void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *req )214 void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *request) 442 215 { 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 );216 devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 217 fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request); 445 218 fs_node_t *fn; 446 219 int res; … … 486 259 } 487 260 488 static char plb_get_char(unsigned pos)489 {490 return reg.plb_ro[pos % PLB_SIZE];491 }492 493 261 /** Lookup VFS triplet by name in the file system name space. 494 262 * … … 505 273 */ 506 274 void libfs_lookup(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid, 507 ipc_call_t *req )275 ipc_call_t *request) 508 276 { 509 unsigned int first = IPC_GET_ARG1(*req );510 unsigned int last = IPC_GET_ARG2(*req );277 unsigned int first = IPC_GET_ARG1(*request); 278 unsigned int last = IPC_GET_ARG2(*request); 511 279 unsigned int next = first; 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 );280 devmap_handle_t devmap_handle = IPC_GET_ARG3(*request); 281 int lflag = IPC_GET_ARG4(*request); 282 fs_index_t index = IPC_GET_ARG5(*request); 515 283 char component[NAME_MAX + 1]; 516 284 int len; … … 530 298 async_exch_t *exch = async_exchange_begin(cur->mp_data.sess); 531 299 async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last, 532 cur->mp_data.devmap_handle, lflag, index, 533 IPC_FF_ROUTE_FROM_ME); 300 cur->mp_data.devmap_handle, lflag, index, IPC_FF_ROUTE_FROM_ME); 534 301 async_exchange_end(exch); 535 302 … … 539 306 540 307 /* Eat slash */ 541 if ( plb_get_char(next) == '/')308 if (ops->plb_get_char(next) == '/') 542 309 next++; 543 310 … … 552 319 /* Collect the component */ 553 320 len = 0; 554 while ((next <= last) && ( plb_get_char(next) != '/')) {321 while ((next <= last) && (ops->plb_get_char(next) != '/')) { 555 322 if (len + 1 == NAME_MAX) { 556 323 /* Component length overflow */ … … 558 325 goto out; 559 326 } 560 component[len++] = plb_get_char(next);327 component[len++] = ops->plb_get_char(next); 561 328 /* Process next character */ 562 329 next++; … … 590 357 591 358 async_exch_t *exch = async_exchange_begin(tmp->mp_data.sess); 592 async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, 593 last,tmp->mp_data.devmap_handle, lflag, index,359 async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last, 360 tmp->mp_data.devmap_handle, lflag, index, 594 361 IPC_FF_ROUTE_FROM_ME); 595 362 async_exchange_end(exch); … … 684 451 len = 0; 685 452 while (next <= last) { 686 if ( plb_get_char(next) == '/') {453 if (ops->plb_get_char(next) == '/') { 687 454 /* More than one component */ 688 455 async_answer_0(rid, ENOENT); … … 696 463 } 697 464 698 component[len++] = plb_get_char(next);465 component[len++] = ops->plb_get_char(next); 699 466 /* Process next character */ 700 467 next++; … … 870 637 rc = ops->node_open(fn); 871 638 aoff64_t size = ops->size_get(fn); 872 async_answer_4(rid, rc, LOWER32(size), UPPER32(size), 873 ops->lnkcnt_get(fn), 639 async_answer_4(rid, rc, LOWER32(size), UPPER32(size), ops->lnkcnt_get(fn), 874 640 (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0)); 875 641 -
uspace/lib/fs/libfs.h
r80e9e5e rc936c7f 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 {58 45 bool mp_active; 59 46 async_sess_t *sess; … … 84 71 int (* has_children)(bool *, fs_node_t *); 85 72 /* 86 * The second set of methods are usually mere getters that do not 87 * returnan integer error code.73 * The second set of methods are usually mere getters that do not return 74 * an integer error code. 88 75 */ 89 76 fs_index_t (* index_get)(fs_node_t *); 90 77 aoff64_t (* size_get)(fs_node_t *); 91 78 unsigned int (* lnkcnt_get)(fs_node_t *); 79 char (* plb_get_char)(unsigned pos); 92 80 bool (* is_directory)(fs_node_t *); 93 81 bool (* is_file)(fs_node_t *); … … 100 88 } fs_reg_t; 101 89 102 extern int fs_register(async_sess_t *, vfs_info_t *, vfs_out_ops_t *,103 libfs_ops_t *);90 extern int fs_register(async_sess_t *, fs_reg_t *, vfs_info_t *, 91 async_client_conn_t); 104 92 105 93 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 *); 106 101 107 102 #endif -
uspace/lib/scsi/include/scsi/sbc.h
r80e9e5e rc936c7f 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 74 58 /** SCSI Read (12) command */ 75 59 typedef struct { 76 60 /** Operation code (SCSI_CMD_READ_12) */ 77 61 uint8_t op_code; 78 /** RdProtect, DPO, FUA, Reserved, FUA_NV, Obsolete*/62 /** RdProtect, DPO, FUA, Reserved, FUA_NV, Reserved */ 79 63 uint8_t flags; 80 64 /** Logical block address */ … … 131 115 } scsi_read_capacity_10_data_t; 132 116 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 149 117 /** SCSI Write (12) command */ 150 118 typedef struct { 151 119 /** Operation code (SCSI_CMD_WRITE_12) */ 152 120 uint8_t op_code; 153 /** WrProtect, DPO, FUA, Reserved, FUA_NV, Obsolete*/121 /** WrProtect, DPO, FUA, Reserved, FUA_NV, Reserved */ 154 122 uint8_t flags; 155 123 /** Logical block address */ -
uspace/lib/scsi/include/scsi/spc.h
r80e9e5e rc936c7f 179 179 uint8_t additional_len; 180 180 /** Command-specific Information */ 181 uint 32_t cmd_spec;181 uint8_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, 208 209 SCSI_SK_LIMIT = 0x10 207 SCSI_SK_MISCOMPARE = 0xe 210 208 }; 211 209 212 210 extern const char *scsi_dev_type_str[SCSI_DEV_LIMIT]; 213 extern const char *scsi_sense_key_str[SCSI_SK_LIMIT];214 215 211 extern const char *scsi_get_dev_type_str(unsigned); 216 extern const char *scsi_get_sense_key_str(unsigned);217 212 218 213 #endif -
uspace/lib/scsi/src/spc.c
r80e9e5e rc936c7f 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 63 46 /** Get peripheral device type string. 64 47 * … … 70 53 { 71 54 if (dev_type >= SCSI_DEV_LIMIT || scsi_dev_type_str[dev_type] == NULL) 72 return " Unknown";55 return "<unknown>"; 73 56 74 57 return scsi_dev_type_str[dev_type]; 75 58 } 76 77 /** Get sense key string.78 *79 * Return string description of SCSI sense key.80 * The returned string is valid indefinitely, the caller should81 * 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
r80e9e5e rc936c7f 270 270 } 271 271 272 ssize_t read_bytes = read_all(fd, buf, len);272 ssize_t read_bytes = safe_read(fd, buf, len); 273 273 if (read_bytes <= 0) { 274 log_msg(LVL_ERROR, "Unable to read file '%s' (%zd).", conf_path, 275 read_bytes); 274 log_msg(LVL_ERROR, "Unable to read file '%s'.", conf_path); 276 275 goto cleanup; 277 276 } … … 422 421 } 423 422 424 insert_fun_node(tree, fun, str_dup(""), NULL);423 insert_fun_node(tree, fun, clone_string(""), NULL); 425 424 match_id_t *id = create_match_id(); 426 id->id = str_dup("root");425 id->id = clone_string("root"); 427 426 id->score = 100; 428 427 add_match_id(&fun->match_ids, id); -
uspace/srv/devman/util.c
r80e9e5e rc936c7f 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 93 104 void replace_char(char *str, char orig, char repl) 94 105 { … … 100 111 } 101 112 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 102 140 /** @} 103 141 */ -
uspace/srv/devman/util.h
r80e9e5e rc936c7f 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 *); 46 47 extern void replace_char(char *, char, char); 48 49 extern ssize_t safe_read(int, void *, size_t); 47 50 48 51 #endif -
uspace/srv/fs/devfs/devfs.c
r80e9e5e rc936c7f 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 59 120 int main(int argc, char *argv[]) 60 121 { … … 73 134 } 74 135 75 int rc = fs_register(vfs_sess, &devfs_ vfs_info, &devfs_ops,76 &devfs_libfs_ops);136 int rc = fs_register(vfs_sess, &devfs_reg, &devfs_vfs_info, 137 devfs_connection); 77 138 if (rc != EOK) { 78 139 printf("%s: Failed to register file system (%d)\n", NAME, rc); … … 91 152 * @} 92 153 */ 93 -
uspace/srv/fs/devfs/devfs.h
r80e9e5e rc936c7f 36 36 #include <libfs.h> 37 37 38 extern vfs_out_ops_t devfs_ops; 39 extern libfs_ops_t devfs_libfs_ops; 38 extern fs_reg_t devfs_reg; 40 39 41 40 #endif -
uspace/srv/fs/devfs/devfs_ops.c
r80e9e5e rc936c7f 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 405 410 static bool devfs_is_directory(fs_node_t *fn) 406 411 { … … 442 447 .size_get = devfs_size_get, 443 448 .lnkcnt_get = devfs_lnkcnt_get, 449 .plb_get_char = devfs_plb_get_char, 444 450 .is_directory = devfs_is_directory, 445 451 .is_file = devfs_is_file, … … 456 462 } 457 463 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 { 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 476 516 if (index == 0) { 477 517 ipc_callid_t callid; … … 479 519 if (!async_data_read_receive(&callid, &size)) { 480 520 async_answer_0(callid, EINVAL); 481 return EINVAL; 521 async_answer_0(rid, EINVAL); 522 return; 482 523 } 483 524 … … 499 540 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 500 541 free(desc); 501 *rbytes = 1;502 return EOK;542 async_answer_1(rid, EOK, 1); 543 return; 503 544 } 504 545 … … 514 555 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 515 556 free(desc); 516 *rbytes = 1;517 return EOK;557 async_answer_1(rid, EOK, 1); 558 return; 518 559 } 519 560 … … 522 563 523 564 async_answer_0(callid, ENOENT); 524 return ENOENT; 565 async_answer_1(rid, ENOENT, 0); 566 return; 525 567 } 526 568 … … 533 575 if (!async_data_read_receive(&callid, &size)) { 534 576 async_answer_0(callid, EINVAL); 535 return EINVAL; 577 async_answer_0(rid, EINVAL); 578 return; 536 579 } 537 580 … … 542 585 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 543 586 free(desc); 544 *rbytes = 1;545 return EOK;587 async_answer_1(rid, EOK, 1); 588 return; 546 589 } 547 590 548 591 free(desc); 549 592 async_answer_0(callid, ENOENT); 550 return ENOENT; 593 async_answer_1(rid, ENOENT, 0); 594 return; 551 595 } 552 596 … … 562 606 if (lnk == NULL) { 563 607 fibril_mutex_unlock(&devices_mutex); 564 return ENOENT; 608 async_answer_0(rid, ENOENT); 609 return; 565 610 } 566 611 … … 572 617 fibril_mutex_unlock(&devices_mutex); 573 618 async_answer_0(callid, EINVAL); 574 return EINVAL; 619 async_answer_0(rid, EINVAL); 620 return; 575 621 } 576 622 … … 579 625 580 626 ipc_call_t answer; 581 aid_t msg = async_send_4(exch, VFS_OUT_READ, devmap_handle, 582 index, LOWER32(pos), UPPER32(pos), &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); 583 630 584 631 /* Forward the IPC_M_DATA_READ request to the driver */ … … 592 639 sysarg_t rc; 593 640 async_wait_for(msg, &rc); 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; 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 } 608 658 609 659 devmap_handle_type_t type = devmap_handle_probe(index); … … 611 661 if (type == DEV_HANDLE_NAMESPACE) { 612 662 /* Namespace directory */ 613 return ENOTSUP; 663 async_answer_0(rid, ENOTSUP); 664 return; 614 665 } 615 666 … … 624 675 if (lnk == NULL) { 625 676 fibril_mutex_unlock(&devices_mutex); 626 return ENOENT; 677 async_answer_0(rid, ENOENT); 678 return; 627 679 } 628 680 … … 634 686 fibril_mutex_unlock(&devices_mutex); 635 687 async_answer_0(callid, EINVAL); 636 return EINVAL; 688 async_answer_0(rid, EINVAL); 689 return; 637 690 } 638 691 … … 641 694 642 695 ipc_call_t answer; 643 aid_t msg = async_send_4(exch, VFS_OUT_WRITE, devmap_handle, 644 index, LOWER32(pos), UPPER32(pos), &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); 645 699 646 700 /* Forward the IPC_M_DATA_WRITE request to the driver */ … … 654 708 sysarg_t rc; 655 709 async_wait_for(msg, &rc); 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; 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 } 675 733 676 734 devmap_handle_type_t type = devmap_handle_probe(index); … … 678 736 if (type == DEV_HANDLE_NAMESPACE) { 679 737 /* Namespace directory */ 680 return EOK; 738 async_answer_0(rid, EOK); 739 return; 681 740 } 682 741 … … 690 749 if (lnk == NULL) { 691 750 fibril_mutex_unlock(&devices_mutex); 692 return ENOENT; 751 async_answer_0(rid, ENOENT); 752 return; 693 753 } 694 754 … … 704 764 fibril_mutex_unlock(&devices_mutex); 705 765 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; 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 } 716 781 717 782 devmap_handle_type_t type = devmap_handle_probe(index); … … 719 784 if (type == DEV_HANDLE_NAMESPACE) { 720 785 /* Namespace directory */ 721 return EOK; 786 async_answer_0(rid, EOK); 787 return; 722 788 } 723 789 … … 731 797 if (lnk == NULL) { 732 798 fibril_mutex_unlock(&devices_mutex); 733 return ENOENT; 799 async_answer_0(rid, ENOENT); 800 return; 734 801 } 735 802 … … 741 808 742 809 ipc_call_t answer; 743 aid_t msg = async_send_2(exch, VFS_OUT_SYNC, devmap_handle,744 index, &answer);810 aid_t msg = async_send_2(exch, IPC_GET_IMETHOD(*request), 811 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer); 745 812 746 813 async_exchange_end(exch); … … 752 819 async_wait_for(msg, &rc); 753 820 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 }; 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 } 775 833 776 834 /** -
uspace/srv/fs/devfs/devfs_ops.h
r80e9e5e rc936c7f 34 34 #define DEVFS_DEVFS_OPS_H_ 35 35 36 #include <ipc/common.h> 36 37 #include <bool.h> 37 38 38 39 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 *); 39 54 40 55 #endif -
uspace/srv/fs/ext2fs/ext2fs.c
r80e9e5e rc936c7f 1 1 /* 2 2 * Copyright (c) 2006 Martin Decky 3 * Copyright (c) 2008 Jakub Jermar 3 4 * Copyright (c) 2011 Martin Sucha 4 5 * All rights reserved. … … 54 55 }; 55 56 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 one 64 * instance of the fibril, VFS will need to serialize all VFS requests it sends 65 * to EXT2FS. To overcome this bottleneck, VFS can send EXT2FS the IPC_M_CONNECT_ME_TO 66 * call. In that case, a new connection fibril will be created, which in turn 67 * 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 of 70 * available phones. In that case, VFS can close some other phones or use one 71 * phone for more serialized requests. Similarily, EXT2FS can refuse to duplicate 72 * the connection. VFS should then just make use of already existing phones and 73 * route its requests through them. To avoid paying the fibril creation price 74 * upon each request, EXT2FS might want to keep the connections open after the 75 * 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 by 82 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections 83 * 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 56 143 int main(int argc, char **argv) 57 144 { … … 71 158 } 72 159 73 rc = fs_register(vfs_sess, &ext2fs_vfs_info, &ext2fs_ops, 74 &ext2fs_libfs_ops); 160 rc = fs_register(vfs_sess, &ext2fs_reg, &ext2fs_vfs_info, ext2fs_connection); 75 161 if (rc != EOK) { 76 162 fprintf(stdout, NAME ": Failed to register fs (%d)\n", rc); -
uspace/srv/fs/ext2fs/ext2fs.h
r80e9e5e rc936c7f 1 1 /* 2 * Copyright (c) 2008 Jakub Jermar 2 3 * Copyright (c) 2011 Martin Sucha 3 4 * All rights reserved. … … 35 36 36 37 #include <libext2.h> 38 #include <fibril_synch.h> 37 39 #include <libfs.h> 40 #include <atomic.h> 38 41 #include <sys/types.h> 42 #include <bool.h> 43 #include "../../vfs/vfs.h" 44 45 #ifndef dprintf 46 #define dprintf(...) printf(__VA_ARGS__) 47 #endif 39 48 40 49 #define min(a, b) ((a) < (b) ? (a) : (b)) 41 50 42 extern vfs_out_ops_t ext2fs_ops; 43 extern libfs_ops_t ext2fs_libfs_ops; 51 extern fs_reg_t ext2fs_reg; 44 52 45 53 extern int ext2fs_global_init(void); 46 54 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 *); 47 69 48 70 #endif -
uspace/srv/fs/ext2fs/ext2fs_ops.c
r80e9e5e rc936c7f 1 1 /* 2 * Copyright (c) 2008 Jakub Jermar 2 3 * Copyright (c) 2011 Martin Sucha 3 4 * All rights reserved. … … 86 87 */ 87 88 static int ext2fs_instance_get(devmap_handle_t, ext2fs_instance_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 *);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 *); 92 93 static bool ext2fs_is_dots(const uint8_t *, size_t); 93 94 static int ext2fs_node_get_core(fs_node_t **, ext2fs_instance_t *, fs_index_t); … … 110 111 static aoff64_t ext2fs_size_get(fs_node_t *); 111 112 static unsigned ext2fs_lnkcnt_get(fs_node_t *); 113 static char ext2fs_plb_get_char(unsigned); 112 114 static bool ext2fs_is_directory(fs_node_t *); 113 115 static bool ext2fs_is_file(fs_node_t *node); … … 536 538 EXT2FS_DBG("%u", count); 537 539 return count; 540 } 541 542 char ext2fs_plb_get_char(unsigned pos) 543 { 544 return ext2fs_reg.plb_ro[pos % PLB_SIZE]; 538 545 } 539 546 … … 579 586 .size_get = ext2fs_size_get, 580 587 .lnkcnt_get = ext2fs_lnkcnt_get, 588 .plb_get_char = ext2fs_plb_get_char, 581 589 .is_directory = ext2fs_is_directory, 582 590 .is_file = ext2fs_is_file, … … 588 596 */ 589 597 590 static int ext2fs_mounted(devmap_handle_t devmap_handle, const char *opts, 591 fs_index_t *index, aoff64_t *size, unsigned *lnkcnt) 598 void ext2fs_mounted(ipc_callid_t rid, ipc_call_t *request) 592 599 { 593 600 EXT2FS_DBG(""); 594 601 int rc; 602 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 595 603 ext2_filesystem_t *fs; 596 604 ext2fs_instance_t *inst; 597 605 bool read_only; 598 606 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 599 618 /* Allocate libext2 filesystem structure */ 600 619 fs = (ext2_filesystem_t *) malloc(sizeof(ext2_filesystem_t)); 601 if (fs == NULL) 602 return ENOMEM; 620 if (fs == NULL) { 621 async_answer_0(rid, ENOMEM); 622 return; 623 } 603 624 604 625 /* Allocate instance structure */ … … 606 627 if (inst == NULL) { 607 628 free(fs); 608 return ENOMEM; 629 async_answer_0(rid, ENOMEM); 630 return; 609 631 } 610 632 … … 614 636 free(fs); 615 637 free(inst); 616 return rc; 638 async_answer_0(rid, rc); 639 return; 617 640 } 618 641 … … 623 646 free(fs); 624 647 free(inst); 625 return rc; 648 async_answer_0(rid, rc); 649 return; 626 650 } 627 651 … … 632 656 free(fs); 633 657 free(inst); 634 return rc; 658 async_answer_0(rid, rc); 659 return; 635 660 } 636 661 … … 648 673 free(fs); 649 674 free(inst); 650 return rc; 675 async_answer_0(rid, rc); 676 return; 651 677 } 652 678 ext2fs_node_t *enode = EXT2FS_NODE(root_node); … … 657 683 fibril_mutex_unlock(&instance_list_mutex); 658 684 659 *index = EXT2_INODE_ROOT_INDEX; 660 *size = 0; 661 *lnkcnt = ext2_inode_get_usage_count(enode->inode_ref->inode); 685 async_answer_3(rid, EOK, 686 EXT2_INODE_ROOT_INDEX, 687 0, 688 ext2_inode_get_usage_count(enode->inode_ref->inode)); 662 689 663 690 ext2fs_node_put(root_node); 664 665 return EOK; 666 } 667 668 static int ext2fs_unmounted(devmap_handle_t devmap_handle) 669 { 670 EXT2FS_DBG(""); 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); 671 703 ext2fs_instance_t *inst; 672 704 int rc; … … 674 706 rc = ext2fs_instance_get(devmap_handle, &inst); 675 707 676 if (rc != EOK) 677 return rc; 708 if (rc != EOK) { 709 async_answer_0(rid, rc); 710 return; 711 } 678 712 679 713 fibril_mutex_lock(&open_nodes_lock); … … 682 716 if (inst->open_nodes_count != 0) { 683 717 fibril_mutex_unlock(&open_nodes_lock); 684 return EBUSY; 718 async_answer_0(rid, EBUSY); 719 return; 685 720 } 686 721 … … 694 729 ext2_filesystem_fini(inst->filesystem); 695 730 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(""); 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)); 704 753 705 754 ext2fs_instance_t *inst; … … 714 763 if (!async_data_read_receive(&callid, &size)) { 715 764 async_answer_0(callid, EINVAL); 716 return EINVAL; 765 async_answer_0(rid, EINVAL); 766 return; 717 767 } 718 768 … … 720 770 if (rc != EOK) { 721 771 async_answer_0(callid, rc); 722 return rc; 772 async_answer_0(rid, rc); 773 return; 723 774 } 724 775 … … 726 777 if (rc != EOK) { 727 778 async_answer_0(callid, rc); 728 return rc; 779 async_answer_0(rid, rc); 780 return; 729 781 } 730 782 731 783 if (ext2_inode_is_type(inst->filesystem->superblock, inode_ref->inode, 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 {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 { 740 792 /* Other inode types not supported */ 741 793 async_answer_0(callid, ENOTSUP); 742 rc = ENOTSUP;794 async_answer_0(rid, ENOTSUP); 743 795 } 744 796 745 797 ext2_filesystem_put_inode_ref(inode_ref); 746 798 747 return rc;748 799 } 749 800 … … 763 814 } 764 815 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)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) 767 818 { 768 819 ext2_directory_iterator_t it; … … 776 827 if (rc != EOK) { 777 828 async_answer_0(callid, rc); 778 return rc; 829 async_answer_0(rid, rc); 830 return; 779 831 } 780 832 … … 789 841 790 842 name_size = ext2_directory_entry_ll_get_name_length( 791 843 inst->filesystem->superblock, it.current); 792 844 793 845 /* skip . and .. */ … … 797 849 798 850 /* The on-disk entry does not contain \0 at the end 799 800 801 851 * end of entry name, so we copy it to new buffer 852 * and add the \0 at the end 853 */ 802 854 buf = malloc(name_size+1); 803 855 if (buf == NULL) { 804 856 ext2_directory_iterator_fini(&it); 805 857 async_answer_0(callid, ENOMEM); 806 return ENOMEM; 858 async_answer_0(rid, ENOMEM); 859 return; 807 860 } 808 861 memcpy(buf, &it.current->name, name_size); 809 *(buf +name_size) = 0;862 *(buf+name_size) = 0; 810 863 found = true; 811 (void) async_data_read_finalize(callid, buf, name_size +1);864 (void) async_data_read_finalize(callid, buf, name_size+1); 812 865 free(buf); 813 866 break; … … 818 871 ext2_directory_iterator_fini(&it); 819 872 async_answer_0(callid, rc); 820 return rc; 873 async_answer_0(rid, rc); 874 return; 821 875 } 822 876 } … … 824 878 if (found) { 825 879 rc = ext2_directory_iterator_next(&it); 826 if (rc != EOK) 827 return rc; 880 if (rc != EOK) { 881 async_answer_0(rid, rc); 882 return; 883 } 828 884 next = it.current_offset; 829 885 } 830 886 831 887 rc = ext2_directory_iterator_fini(&it); 832 if (rc != EOK) 833 return rc; 888 if (rc != EOK) { 889 async_answer_0(rid, rc); 890 return; 891 } 834 892 835 893 if (found) { 836 *rbytes = next - pos;837 return EOK;838 }else {894 async_answer_1(rid, EOK, next-pos); 895 } 896 else { 839 897 async_answer_0(callid, ENOENT); 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)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) 846 904 { 847 905 int rc; … … 861 919 /* Read 0 bytes successfully */ 862 920 async_data_read_finalize(callid, NULL, 0); 863 *rbytes = 0;864 return EOK;921 async_answer_1(rid, EOK, 0); 922 return; 865 923 } 866 924 … … 881 939 if (rc != EOK) { 882 940 async_answer_0(callid, rc); 883 return rc; 941 async_answer_0(rid, rc); 942 return; 884 943 } 885 944 … … 893 952 if (buffer == NULL) { 894 953 async_answer_0(callid, ENOMEM); 895 return ENOMEM; 954 async_answer_0(rid, ENOMEM); 955 return; 896 956 } 897 957 … … 899 959 900 960 async_data_read_finalize(callid, buffer, bytes); 901 *rbytes = bytes;961 async_answer_1(rid, EOK, bytes); 902 962 903 963 free(buffer); 904 964 905 return EOK;965 return; 906 966 } 907 967 … … 910 970 if (rc != EOK) { 911 971 async_answer_0(callid, rc); 912 return rc; 972 async_answer_0(rid, rc); 973 return; 913 974 } 914 975 … … 917 978 918 979 rc = block_put(block); 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 }; 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 } 969 1049 970 1050 /** 971 1051 * @} 972 1052 */ 973 -
uspace/srv/fs/fat/fat.c
r80e9e5e rc936c7f 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 one 65 * instance of the fibril, VFS will need to serialize all VFS requests it sends 66 * to FAT. To overcome this bottleneck, VFS can send FAT the IPC_M_CONNECT_ME_TO 67 * call. In that case, a new connection fibril will be created, which in turn 68 * 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 of 71 * available phones. In that case, VFS can close some other phones or use one 72 * phone for more serialized requests. Similarily, FAT can refuse to duplicate 73 * the connection. VFS should then just make use of already existing phones and 74 * route its requests through them. To avoid paying the fibril creation price 75 * upon each request, FAT might want to keep the connections open after the 76 * 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 by 83 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections 84 * 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 58 145 int main(int argc, char **argv) 59 146 { … … 71 158 } 72 159 73 rc = fs_register(vfs_sess, &fat_ vfs_info, &fat_ops, &fat_libfs_ops);160 rc = fs_register(vfs_sess, &fat_reg, &fat_vfs_info, fat_connection); 74 161 if (rc != EOK) { 75 162 fat_idx_fini(); -
uspace/srv/fs/fat/fat.h
r80e9e5e rc936c7f 224 224 } fat_node_t; 225 225 226 extern vfs_out_ops_t fat_ops; 227 extern libfs_ops_t fat_libfs_ops; 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 *); 228 242 229 243 extern int fat_idx_get_new(fat_idx_t **, devmap_handle_t); -
uspace/srv/fs/fat/fat_ops.c
r80e9e5e rc936c7f 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); 87 88 static bool fat_is_directory(fs_node_t *); 88 89 static bool fat_is_file(fs_node_t *node); … … 900 901 } 901 902 903 char fat_plb_get_char(unsigned pos) 904 { 905 return fat_reg.plb_ro[pos % PLB_SIZE]; 906 } 907 902 908 bool fat_is_directory(fs_node_t *fn) 903 909 { … … 930 936 .size_get = fat_size_get, 931 937 .lnkcnt_get = fat_lnkcnt_get, 938 .plb_get_char = fat_plb_get_char, 932 939 .is_directory = fat_is_directory, 933 940 .is_file = fat_is_file, … … 936 943 937 944 /* 938 * FAT VFS_OUToperations.945 * VFS operations. 939 946 */ 940 947 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 { 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); 945 951 enum cache_mode cmode; 946 952 fat_bs_t *bs; 947 int rc; 948 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 949 963 /* Check for option enabling write through. */ 950 964 if (str_cmp(opts, "wtcache") == 0) … … 953 967 cmode = CACHE_MODE_WB; 954 968 969 free(opts); 970 955 971 /* initialize libblock */ 956 972 rc = block_init(EXCHANGE_SERIALIZE, devmap_handle, BS_SIZE); 957 if (rc != EOK) 958 return rc; 973 if (rc != EOK) { 974 async_answer_0(rid, rc); 975 return; 976 } 959 977 960 978 /* prepare the boot block */ … … 962 980 if (rc != EOK) { 963 981 block_fini(devmap_handle); 964 return rc; 982 async_answer_0(rid, rc); 983 return; 965 984 } 966 985 … … 970 989 if (BPS(bs) != BS_SIZE) { 971 990 block_fini(devmap_handle); 972 return ENOTSUP; 991 async_answer_0(rid, ENOTSUP); 992 return; 973 993 } 974 994 … … 977 997 if (rc != EOK) { 978 998 block_fini(devmap_handle); 979 return rc; 999 async_answer_0(rid, rc); 1000 return; 980 1001 } 981 1002 … … 985 1006 (void) block_cache_fini(devmap_handle); 986 1007 block_fini(devmap_handle); 987 return rc; 1008 async_answer_0(rid, rc); 1009 return; 988 1010 } 989 1011 … … 992 1014 (void) block_cache_fini(devmap_handle); 993 1015 block_fini(devmap_handle); 994 return rc; 1016 async_answer_0(rid, rc); 1017 return; 995 1018 } 996 1019 … … 1001 1024 block_fini(devmap_handle); 1002 1025 fat_idx_fini_by_devmap_handle(devmap_handle); 1003 return ENOMEM; 1026 async_answer_0(rid, ENOMEM); 1027 return; 1004 1028 } 1005 1029 fs_node_initialize(rfn); … … 1010 1034 block_fini(devmap_handle); 1011 1035 fat_idx_fini_by_devmap_handle(devmap_handle); 1012 return ENOMEM; 1036 async_answer_0(rid, ENOMEM); 1037 return; 1013 1038 } 1014 1039 fat_node_initialize(rootp); … … 1021 1046 block_fini(devmap_handle); 1022 1047 fat_idx_fini_by_devmap_handle(devmap_handle); 1023 return ENOMEM; 1048 async_answer_0(rid, ENOMEM); 1049 return; 1024 1050 } 1025 1051 assert(ridxp->index == 0); … … 1038 1064 fibril_mutex_unlock(&ridxp->lock); 1039 1065 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 { 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); 1049 1077 fs_node_t *fn; 1050 1078 fat_node_t *nodep; … … 1052 1080 1053 1081 rc = fat_root_get(&fn, devmap_handle); 1054 if (rc != EOK) 1055 return rc; 1082 if (rc != EOK) { 1083 async_answer_0(rid, rc); 1084 return; 1085 } 1056 1086 nodep = FAT_NODE(fn); 1057 1087 … … 1062 1092 if (nodep->refcnt != 2) { 1063 1093 (void) fat_node_put(fn); 1064 return EBUSY; 1094 async_answer_0(rid, EBUSY); 1095 return; 1065 1096 } 1066 1097 … … 1081 1112 block_fini(devmap_handle); 1082 1113 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 { 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)); 1090 1133 fs_node_t *fn; 1091 1134 fat_node_t *nodep; … … 1096 1139 1097 1140 rc = fat_node_get(&fn, devmap_handle, index); 1098 if (rc != EOK) 1099 return rc; 1100 if (!fn) 1101 return ENOENT; 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 } 1102 1149 nodep = FAT_NODE(fn); 1103 1150 … … 1107 1154 fat_node_put(fn); 1108 1155 async_answer_0(callid, EINVAL); 1109 return EINVAL; 1156 async_answer_0(rid, EINVAL); 1157 return; 1110 1158 } 1111 1159 … … 1130 1178 fat_node_put(fn); 1131 1179 async_answer_0(callid, rc); 1132 return rc; 1180 async_answer_0(rid, rc); 1181 return; 1133 1182 } 1134 1183 (void) async_data_read_finalize(callid, … … 1137 1186 if (rc != EOK) { 1138 1187 fat_node_put(fn); 1139 return rc; 1188 async_answer_0(rid, rc); 1189 return; 1140 1190 } 1141 1191 } … … 1194 1244 rc = fat_node_put(fn); 1195 1245 async_answer_0(callid, rc != EOK ? rc : ENOENT); 1196 *rbytes = 0;1197 return rc != EOK ? rc : ENOENT;1246 async_answer_1(rid, rc != EOK ? rc : ENOENT, 0); 1247 return; 1198 1248 1199 1249 err: 1200 1250 (void) fat_node_put(fn); 1201 1251 async_answer_0(callid, rc); 1202 return rc; 1252 async_answer_0(rid, rc); 1253 return; 1203 1254 1204 1255 hit: … … 1208 1259 1209 1260 rc = fat_node_put(fn); 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 { 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)); 1218 1270 fs_node_t *fn; 1219 1271 fat_node_t *nodep; 1220 1272 fat_bs_t *bs; 1221 size_t bytes ;1273 size_t bytes, size; 1222 1274 block_t *b; 1223 1275 aoff64_t boundary; … … 1226 1278 1227 1279 rc = fat_node_get(&fn, devmap_handle, index); 1228 if (rc != EOK) 1229 return rc; 1230 if (!fn) 1231 return ENOENT; 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 } 1232 1288 nodep = FAT_NODE(fn); 1233 1289 … … 1237 1293 (void) fat_node_put(fn); 1238 1294 async_answer_0(callid, EINVAL); 1239 return EINVAL; 1295 async_answer_0(rid, EINVAL); 1296 return; 1240 1297 } 1241 1298 … … 1265 1322 (void) fat_node_put(fn); 1266 1323 async_answer_0(callid, rc); 1267 return rc; 1324 async_answer_0(rid, rc); 1325 return; 1268 1326 } 1269 1327 rc = fat_block_get(&b, bs, nodep, pos / BPS(bs), flags); … … 1271 1329 (void) fat_node_put(fn); 1272 1330 async_answer_0(callid, rc); 1273 return rc; 1331 async_answer_0(rid, rc); 1332 return; 1274 1333 } 1275 1334 (void) async_data_write_finalize(callid, … … 1279 1338 if (rc != EOK) { 1280 1339 (void) fat_node_put(fn); 1281 return rc; 1340 async_answer_0(rid, rc); 1341 return; 1282 1342 } 1283 1343 if (pos + bytes > nodep->size) { … … 1285 1345 nodep->dirty = true; /* need to sync node */ 1286 1346 } 1287 *wbytes = bytes; 1288 *nsize = nodep->size; 1347 size = nodep->size; 1289 1348 rc = fat_node_put(fn); 1290 return rc; 1349 async_answer_2(rid, rc, bytes, nodep->size); 1350 return; 1291 1351 } else { 1292 1352 /* … … 1304 1364 (void) fat_node_put(fn); 1305 1365 async_answer_0(callid, rc); 1306 return rc; 1366 async_answer_0(rid, rc); 1367 return; 1307 1368 } 1308 1369 /* zero fill any gaps */ … … 1312 1373 (void) fat_node_put(fn); 1313 1374 async_answer_0(callid, rc); 1314 return rc; 1375 async_answer_0(rid, rc); 1376 return; 1315 1377 } 1316 1378 rc = _fat_block_get(&b, bs, devmap_handle, lcl, NULL, … … 1320 1382 (void) fat_node_put(fn); 1321 1383 async_answer_0(callid, rc); 1322 return rc; 1384 async_answer_0(rid, rc); 1385 return; 1323 1386 } 1324 1387 (void) async_data_write_finalize(callid, … … 1329 1392 (void) fat_free_clusters(bs, devmap_handle, mcl); 1330 1393 (void) fat_node_put(fn); 1331 return rc; 1394 async_answer_0(rid, rc); 1395 return; 1332 1396 } 1333 1397 /* … … 1339 1403 (void) fat_free_clusters(bs, devmap_handle, mcl); 1340 1404 (void) fat_node_put(fn); 1341 return rc; 1342 } 1343 *nsize = nodep->size = pos + bytes; 1405 async_answer_0(rid, rc); 1406 return; 1407 } 1408 nodep->size = size = pos + bytes; 1409 nodep->dirty = true; /* need to sync node */ 1344 1410 rc = fat_node_put(fn); 1345 nodep->dirty = true; /* need to sync node */ 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 { 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)); 1354 1422 fs_node_t *fn; 1355 1423 fat_node_t *nodep; … … 1358 1426 1359 1427 rc = fat_node_get(&fn, devmap_handle, index); 1360 if (rc != EOK) 1361 return rc; 1362 if (!fn) 1363 return ENOENT; 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 } 1364 1436 nodep = FAT_NODE(fn); 1365 1437 … … 1405 1477 out: 1406 1478 fat_node_put(fn); 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 { 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); 1417 1492 fs_node_t *fn; 1418 1493 fat_node_t *nodep; … … 1420 1495 1421 1496 rc = fat_node_get(&fn, devmap_handle, index); 1422 if (rc != EOK) 1423 return rc; 1424 if (!fn) 1425 return ENOENT; 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 } 1426 1505 1427 1506 nodep = FAT_NODE(fn); … … 1433 1512 1434 1513 rc = fat_destroy_node(fn); 1435 return rc; 1436 } 1437 1438 static int fat_sync(devmap_handle_t devmap_handle, fs_index_t index) 1439 { 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 1440 1532 fs_node_t *fn; 1441 1533 int rc = fat_node_get(&fn, devmap_handle, index); 1442 if (rc != EOK) 1443 return rc; 1444 if (!fn) 1445 return ENOENT; 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 } 1446 1542 1447 1543 fat_node_t *nodep = FAT_NODE(fn); … … 1451 1547 1452 1548 fat_node_put(fn); 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 }; 1549 async_answer_0(rid, rc); 1550 } 1466 1551 1467 1552 /** -
uspace/srv/fs/tmpfs/tmpfs.c
r80e9e5e rc936c7f 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 one 70 * instance of the fibril, VFS will need to serialize all VFS requests it sends 71 * to FAT. To overcome this bottleneck, VFS can send TMPFS the 72 * IPC_M_CONNECT_ME_TO call. In that case, a new connection fibril will be 73 * created, which in turn will accept the call. Thus, a new phone will be 74 * opened for VFS. 75 * 76 * There are few issues with this arrangement. First, VFS can run out of 77 * available phones. In that case, VFS can close some other phones or use one 78 * phone for more serialized requests. Similarily, TMPFS can refuse to duplicate 79 * the connection. VFS should then just make use of already existing phones and 80 * route its requests through them. To avoid paying the fibril creation price 81 * upon each request, TMPFS might want to keep the connections open after the 82 * 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 by 89 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections 90 * 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 63 151 int main(int argc, char **argv) 64 152 { … … 77 165 } 78 166 79 int rc = fs_register(vfs_sess, &tmpfs_ vfs_info, &tmpfs_ops,80 &tmpfs_libfs_ops);167 int rc = fs_register(vfs_sess, &tmpfs_reg, &tmpfs_vfs_info, 168 tmpfs_connection); 81 169 if (rc != EOK) { 82 170 printf(NAME ": Failed to register file system (%d)\n", rc); -
uspace/srv/fs/tmpfs/tmpfs.h
r80e9e5e rc936c7f 70 70 } tmpfs_node_t; 71 71 72 extern vfs_out_ops_t tmpfs_ops; 72 extern fs_reg_t tmpfs_reg; 73 73 74 extern libfs_ops_t tmpfs_libfs_ops; 74 75 75 76 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 76 92 extern bool tmpfs_restore(devmap_handle_t); 77 93 -
uspace/srv/fs/tmpfs/tmpfs_ops.c
r80e9e5e rc936c7f 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 106 111 static bool tmpfs_is_directory(fs_node_t *fn) 107 112 { … … 134 139 .size_get = tmpfs_size_get, 135 140 .lnkcnt_get = tmpfs_lnkcnt_get, 141 .plb_get_char = tmpfs_plb_get_char, 136 142 .is_directory = tmpfs_is_directory, 137 143 .is_file = tmpfs_is_file, … … 427 433 } 428 434 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 { 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); 437 438 fs_node_t *rootfn; 438 439 int rc; 439 440 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 440 449 /* Check if this device is not already mounted. */ 441 450 rc = tmpfs_root_get(&rootfn, devmap_handle); 442 451 if ((rc == EOK) && (rootfn)) { 443 452 (void) tmpfs_node_put(rootfn); 444 return EEXIST; 453 free(opts); 454 async_answer_0(rid, EEXIST); 455 return; 445 456 } 446 457 447 458 /* Initialize TMPFS instance. */ 448 if (!tmpfs_instance_init(devmap_handle)) 449 return ENOMEM; 459 if (!tmpfs_instance_init(devmap_handle)) { 460 free(opts); 461 async_answer_0(rid, ENOMEM); 462 return; 463 } 450 464 451 465 rc = tmpfs_root_get(&rootfn, devmap_handle); … … 453 467 tmpfs_node_t *rootp = TMPFS_NODE(rootfn); 454 468 if (str_cmp(opts, "restore") == 0) { 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 { 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 468 490 tmpfs_instance_done(devmap_handle); 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 { 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 475 511 /* 476 512 * Lookup the respective TMPFS node. … … 482 518 }; 483 519 hlp = hash_table_find(&nodes, key); 484 if (!hlp) 485 return ENOENT; 520 if (!hlp) { 521 async_answer_0(rid, ENOENT); 522 return; 523 } 486 524 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 487 525 nh_link); … … 494 532 if (!async_data_read_receive(&callid, &size)) { 495 533 async_answer_0(callid, EINVAL); 496 return EINVAL; 534 async_answer_0(rid, EINVAL); 535 return; 497 536 } 498 537 … … 517 556 if (lnk == NULL) { 518 557 async_answer_0(callid, ENOENT); 519 return ENOENT; 558 async_answer_1(rid, ENOENT, 0); 559 return; 520 560 } 521 561 … … 527 567 } 528 568 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 { 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 537 582 /* 538 583 * Lookup the respective TMPFS node. … … 544 589 }; 545 590 hlp = hash_table_find(&nodes, key); 546 if (!hlp) 547 return ENOENT; 591 if (!hlp) { 592 async_answer_0(rid, ENOENT); 593 return; 594 } 548 595 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 549 596 nh_link); … … 556 603 if (!async_data_write_receive(&callid, &size)) { 557 604 async_answer_0(callid, EINVAL); 558 return EINVAL; 605 async_answer_0(rid, EINVAL); 606 return; 559 607 } 560 608 … … 564 612 if (pos + size <= nodep->size) { 565 613 /* The file size is not changing. */ 566 (void) async_data_write_finalize(callid, nodep->data + pos, 567 568 goto out;614 (void) async_data_write_finalize(callid, nodep->data + pos, size); 615 async_answer_2(rid, EOK, size, nodep->size); 616 return; 569 617 } 570 618 size_t delta = (pos + size) - nodep->size; … … 579 627 if (!newdata) { 580 628 async_answer_0(callid, ENOMEM); 581 size = 0;582 goto out;629 async_answer_2(rid, EOK, 0, nodep->size); 630 return; 583 631 } 584 632 /* Clear any newly allocated memory in order to emulate gaps. */ … … 587 635 nodep->data = newdata; 588 636 (void) async_data_write_finalize(callid, nodep->data + pos, size); 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 { 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 599 647 /* 600 648 * Lookup the respective TMPFS node. … … 605 653 }; 606 654 link_t *hlp = hash_table_find(&nodes, key); 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; 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 } 616 671 617 672 void *newdata = realloc(nodep->data, size); 618 if (!newdata) 619 return ENOMEM; 673 if (!newdata) { 674 async_answer_0(rid, ENOMEM); 675 return; 676 } 620 677 621 678 if (size > nodep->size) { … … 626 683 nodep->size = size; 627 684 nodep->data = newdata; 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 { 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 638 699 link_t *hlp; 639 700 unsigned long key[] = { … … 642 703 }; 643 704 hlp = hash_table_find(&nodes, key); 644 if (!hlp) 645 return ENOENT; 705 if (!hlp) { 706 async_answer_0(rid, ENOENT); 707 return; 708 } 646 709 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 647 710 nh_link); 648 return tmpfs_destroy_node(FS_NODE(nodep)); 649 } 650 651 static int tmpfs_sync(devmap_handle_t devmap_handle, fs_index_t index) 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) 652 726 { 653 727 /* … … 655 729 * thus the sync operation is a no-op. 656 730 */ 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 }; 731 async_answer_0(rid, EOK); 732 } 670 733 671 734 /** 672 735 * @} 673 736 */ 674 -
uspace/srv/vfs/vfs_ops.c
r80e9e5e rc936c7f 76 76 vfs_node_t *mr_node; 77 77 fs_index_t rindex; 78 aoff64_t rsize;78 size_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 = ( aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));149 rlnkcnt = (unsigned) IPC_GET_ARG 4(answer);148 rsize = (size_t) IPC_GET_ARG2(answer); 149 rlnkcnt = (unsigned) IPC_GET_ARG3(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 = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer), 232 IPC_GET_ARG3(answer)); 233 rlnkcnt = (unsigned) IPC_GET_ARG4(answer); 231 rsize = (size_t) IPC_GET_ARG2(answer); 232 rlnkcnt = (unsigned) IPC_GET_ARG3(answer); 234 233 235 234 mr_res.triplet.fs_handle = fs_handle; … … 796 795 ipc_call_t answer; 797 796 if (read) { 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);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); 801 800 } else { 802 801 if (file->append) 803 802 file->pos = file->node->size; 804 803 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);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); 808 807 } 809 808 … … 822 821 /* Update the cached version of node's size. */ 823 822 if (rc == EOK) 824 file->node->size = MERGE_LOUP32(IPC_GET_ARG2(answer), 825 IPC_GET_ARG3(answer)); 823 file->node->size = IPC_GET_ARG2(answer); 826 824 fibril_rwlock_write_unlock(&file->node->contents_rwlock); 827 825 }
Note:
See TracChangeset
for help on using the changeset viewer.