Changes in / [80e9e5e:c936c7f] in mainline


Ignore:
Files:
2 deleted
40 edited

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    r80e9e5e rc936c7f  
    8888@ "tmpfs" TMPFS image
    8989@ "fat" FAT16 image
    90 @ "ext2fs" EXT2 image
    9190! RDFMT (choice)
    9291
  • boot/Makefile

    r80e9e5e rc936c7f  
    5050        $(MKFAT) 1048576 $(DIST_PATH) $@
    5151endif
    52 ifeq ($(RDFMT),ext2fs)
    53         $(MKEXT2) 1048576 $(DIST_PATH) $@
    54 endif
    5552
    5653build_dist: clean_dist
  • boot/Makefile.common

    r80e9e5e rc936c7f  
    5656MKTMPFS = $(TOOLS_PATH)/mktmpfs.py
    5757MKFAT = $(TOOLS_PATH)/mkfat.py
    58 MKEXT2 = $(TOOLS_PATH)/mkext2.py
    5958MKUIMAGE = $(TOOLS_PATH)/mkuimage.py
    6059
     
    8382ifeq ($(RDFMT),fat)
    8483        INIT_TASKS += $(USPACE_PATH)/srv/fs/fat/fat
    85 endif
    86 
    87 ifeq ($(RDFMT),ext2fs)
    88         INIT_TASKS += $(USPACE_PATH)/srv/fs/ext2fs/ext2fs
    8984endif
    9085
  • tools/mkfat.py

    r80e9e5e rc936c7f  
    3737import xstruct
    3838import array
    39 from imgutil import *
     39
     40exclude_names = set(['.svn', '.bzr'])
     41
     42def 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
    4049
    4150def subtree_size(root, cluster_size, dirent_size):
     
    4554        files = 2
    4655       
    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)
    5061                        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)
    5365                        files += 1
    5466       
     
    6072        return len(os.listdir(root))
    6173
    62 def write_file(item, outf, cluster_size, data_start, fat, reserved_clusters):
     74def write_file(path, outf, cluster_size, data_start, fat, reserved_clusters):
    6375        "Store the contents of a file"
    6476       
     77        size = os.path.getsize(path)
    6578        prev = -1
    6679        first = 0
    6780       
    68         for data in chunks(item, cluster_size):
     81        inf = open(path, "rb")
     82        rd = 0;
     83        while (rd < size):
    6984                empty_cluster = fat.index(0)
    7085                fat[empty_cluster] = 0xffff
     
    7792                prev = empty_cluster
    7893               
     94                data = bytes(inf.read(cluster_size));
    7995                outf.seek(data_start + (empty_cluster - reserved_clusters) * cluster_size)
    8096                outf.write(data)
    81        
    82         return first, item.size
     97                rd += len(data)
     98        inf.close()
     99       
     100        return first, size
    83101
    84102def write_directory(directory, outf, cluster_size, data_start, fat, reserved_clusters, dirent_size, empty_cluster):
     
    285303                empty_cluster = 0
    286304       
    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]))
    294315       
    295316        if (head):
  • tools/mktmpfs.py

    r80e9e5e rc936c7f  
    3535import os
    3636import xstruct
    37 from imgutil import listdir_items, chunks
     37
     38exclude_names = set(['.svn', '.bzr'])
    3839
    3940HEADER = """little:
     
    7071        "Recursive directory walk"
    7172       
    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))
    7580                        dentry.kind = TMPFS_FILE
    76                         dentry.fname_len = len(item.name)
    77                         dentry.fname = item.name.encode('ascii')
    78                         dentry.flen = item.size
     81                        dentry.fname_len = len(name)
     82                        dentry.fname = name.encode('ascii')
     83                        dentry.flen = size
    7984                       
    8085                        outf.write(dentry.pack())
    8186                       
    82                         for data in chunks(item, 4096):
     87                        inf = open(canon, "rb")
     88                        rd = 0;
     89                        while (rd < size):
     90                                data = inf.read(4096);
    8391                                outf.write(data)
     92                                rd += len(data)
     93                        inf.close()
    8494               
    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))
    8797                        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')
    90100                       
    91101                        outf.write(dentry.pack())
    92102                       
    93                         recursion(item.path, outf)
     103                        recursion(canon, outf)
    94104                       
    95105                        dentry = xstruct.create(DENTRY_NONE)
  • tools/xstruct.py

    r80e9e5e rc936c7f  
    11#
    22# Copyright (c) 2008 Martin Decky
    3 # Copyright (c) 2011 Martin Sucha
    43# All rights reserved.
    54#
     
    3231
    3332import struct
    34 import types
    35 
    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                 return
    52         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)))
    5933
    6034class Struct:
     
    6438        def pack(self):
    6539                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]:
    7443                                        args.append(item)
    7544                        else:
    76                                 check_range(variable, fmt, value)
    77                                 args.append(value)             
     45                                args.append(self.__dict__[variable])
     46               
    7847                return struct.pack(self._format_, *args)
    79        
    80         def unpack(self, data):
    81                 values = struct.unpack(self._format_, data)
    82                 i = 0
    83                 for variable, fmt, length in self._args_:
    84                         self.__dict__[variable] = values[i]
    85                         i += 1
    8648
    8749def create(definition):
     
    11577                        subtokens = token.split("[")
    11678                       
    117                         length = None
    11879                        if (len(subtokens) > 1):
    119                                 length = int(subtokens[1].split("]")[0])
    120                                 format += "%d" % length
     80                                format += "%d" % int(subtokens[1].split("]")[0])
    12181                       
    12282                        format += variable
    12383                       
    12484                        inst.__dict__[subtokens[0]] = None
    125                         args.append((subtokens[0], variable, length))
     85                        args.append(subtokens[0])
    12686                       
    12787                        variable = None
  • uspace/app/bdsh/cmds/modules/cp/cp.c

    r80e9e5e rc936c7f  
    7171        size_t blen, int vb)
    7272{
    73         int fd1, fd2, bytes;
    74         off64_t total;
     73        int fd1, fd2, bytes = 0;
     74        off64_t total = 0;
    7575        int64_t copied = 0;
    7676        char *buff = NULL;
     
    104104        }
    105105
    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)
    108112                        break;
    109113                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                }
    110135        }
    111136
    112137        if (bytes < 0) {
     138err:
    113139                printf("\nError copying %s, (%d)\n", src, bytes);
    114140                copied = bytes;
  • uspace/app/bdsh/compl.c

    r80e9e5e rc936c7f  
    280280
    281281                                cs->dir = opendir(*cs->path);
    282 
    283                                 /* Skip directories that we fail to open. */
    284                                 if (cs->dir == NULL)
    285                                         cs->path++;
    286282                        }
    287283
  • uspace/app/taskdump/elf_core.c

    r80e9e5e rc936c7f  
    6767
    6868static off64_t align_foff_up(off64_t, uintptr_t, size_t);
     69static int write_all(int, const void *, size_t);
    6970static int align_pos(int, size_t);
    7071static int write_mem_area(int, as_area_info_t *, async_sess_t *);
     
    99100
    100101        int fd;
    101         ssize_t rc;
     102        int rc;
    102103        unsigned int i;
    103104
     
    203204
    204205        rc = write_all(fd, &elf_hdr, sizeof(elf_hdr));
    205         if (rc != sizeof(elf_hdr)) {
     206        if (rc != EOK) {
    206207                printf("Failed writing ELF header.\n");
    207208                free(p_hdr);
     
    211212        for (i = 0; i < n_ph; ++i) {
    212213                rc = write_all(fd, &p_hdr[i], sizeof(p_hdr[i]));
    213                 if (rc != sizeof(p_hdr[i])) {
     214                if (rc != EOK) {
    214215                        printf("Failed writing program header.\n");
    215216                        free(p_hdr);
     
    232233
    233234        rc = write_all(fd, &note, sizeof(elf_note_t));
    234         if (rc != sizeof(elf_note_t)) {
     235        if (rc != EOK) {
    235236                printf("Failed writing note header.\n");
    236237                free(p_hdr);
     
    239240
    240241        rc = write_all(fd, "CORE", note.namesz);
    241         if (rc != (ssize_t) note.namesz) {
     242        if (rc != EOK) {
    242243                printf("Failed writing note header.\n");
    243244                free(p_hdr);
     
    253254
    254255        rc = write_all(fd, &pr_status, sizeof(elf_prstatus_t));
    255         if (rc != sizeof(elf_prstatus_t)) {
     256        if (rc != EOK) {
    256257                printf("Failed writing register data.\n");
    257258                free(p_hdr);
     
    303304        size_t total;
    304305        uintptr_t addr;
    305         ssize_t rc;
     306        int rc;
    306307
    307308        addr = area->start_addr;
     
    317318
    318319                rc = write_all(fd, buffer, to_copy);
    319                 if (rc != (ssize_t) to_copy) {
     320                if (rc != EOK) {
    320321                        printf("Failed writing memory contents.\n");
    321322                        return EIO;
     
    325326                total += to_copy;
    326327        }
     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 */
     343static 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;
    327358
    328359        return EOK;
  • uspace/app/taskdump/symtab.c

    r80e9e5e rc936c7f  
    5050    elf_section_header_t *shdr);
    5151static int chunk_load(int fd, off64_t start, size_t size, void **ptr);
     52static int read_all(int fd, void *buf, size_t len);
    5253
    5354/** Load symbol table from an ELF file.
     
    8990
    9091        rc = read_all(fd, &elf_hdr, sizeof(elf_header_t));
    91         if (rc != sizeof(elf_header_t)) {
     92        if (rc != EOK) {
    9293                printf("failed reading elf header\n");
    9394                free(stab);
     
    311312
    312313        rc = read_all(fd, sec_hdr, sizeof(elf_section_header_t));
    313         if (rc != sizeof(elf_section_header_t))
     314        if (rc != EOK)
    314315                return EIO;
    315316
     
    330331static int chunk_load(int fd, off64_t start, size_t size, void **ptr)
    331332{
    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) {
    337337                printf("failed seeking chunk\n");
    338338                *ptr = NULL;
     
    347347
    348348        rc = read_all(fd, *ptr, size);
    349         if (rc != (ssize_t) size) {
     349        if (rc != EOK) {
    350350                printf("failed reading chunk\n");
    351351                free(*ptr);
     
    357357}
    358358
     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 */
     370static 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
    359389/** @}
    360390 */
  • uspace/drv/bus/usb/usbmast/bo_trans.c

    r80e9e5e rc936c7f  
    5858 * @param tag           Command block wrapper tag (automatically compared
    5959 *                      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
    6166 *
    6267 * @return              Error code
    6368 */
    64 int usb_massstor_cmd(usbmast_fun_t *mfun, uint32_t tag, scsi_cmd_t *cmd)
     69static 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)
    6572{
    6673        int rc;
    67         int retval = EOK;
    6874        size_t act_size;
    6975        usb_pipe_t *bulk_in_pipe = mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe;
    7076        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         }
    8677
    8778        /* Prepare CBW - command block wrapper */
    8879        usb_massstor_cbw_t cbw;
    8980        usb_massstor_cbw_prepare(&cbw, tag, dbuf_size, ddir, mfun->lun,
    90             cmd->cdb_size, cmd->cdb);
     81            cmd_size, cmd);
    9182
    9283        /* Send the CBW. */
    93         MASTLOG("Sending CBW.\n");
    9484        rc = usb_pipe_write(bulk_out_pipe, &cbw, sizeof(cbw));
    9585        MASTLOG("CBW '%s' sent: %s.\n",
    9686            usb_debug_str_buffer((uint8_t *) &cbw, sizeof(cbw), 0),
    9787            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
    10292        if (ddir == USB_DIRECTION_IN) {
    10393                /* Recieve data from the device. */
     
    114104        }
    115105
    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;
    127112        }
    128113
     
    130115        usb_massstor_csw_t csw;
    131116        size_t csw_size;
    132         MASTLOG("Reading CSW.\n");
    133117        rc = usb_pipe_read(bulk_in_pipe, &csw, sizeof(csw), &csw_size);
    134118        MASTLOG("CSW '%s' received (%zu bytes): %s.\n",
     
    137121        if (rc != EOK) {
    138122                MASTLOG("rc != EOK\n");
    139                 return EIO;
     123                return rc;
    140124        }
    141125
    142126        if (csw_size != sizeof(csw)) {
    143127                MASTLOG("csw_size != sizeof(csw)\n");
    144                 return EIO;
     128                return ERANGE;
    145129        }
    146130
    147131        if (csw.dCSWTag != tag) {
    148132                MASTLOG("csw.dCSWTag != tag\n");
    149                 return EIO;
     133                return EBADCHECKSUM;
    150134        }
    151135
     
    153137         * Determine the actual return value from the CSW.
    154138         */
    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;
    170144        }
    171145
     
    173147        if (residue > dbuf_size) {
    174148                MASTLOG("residue > dbuf_size\n");
    175                 return EIO;
     149                return ERANGE;
    176150        }
    177151
     
    184158         */
    185159
    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 */
     179int 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 */
     199int 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);
    190204}
    191205
  • uspace/drv/bus/usb/usbmast/bo_trans.h

    r80e9e5e rc936c7f  
    4747#define BULK_OUT_EP 1
    4848
    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 *);
     49extern int usb_massstor_data_in(usbmast_fun_t *, uint32_t, const void *,
     50    size_t, void *, size_t, size_t *);
     51extern int usb_massstor_data_out(usbmast_fun_t *, uint32_t, const void *,
     52    size_t, const void *, size_t, size_t *);
    9153extern int usb_massstor_reset(usbmast_dev_t *);
    9254extern void usb_massstor_reset_recovery(usbmast_dev_t *);
  • uspace/drv/bus/usb/usbmast/cmdw.h

    r80e9e5e rc936c7f  
    5757} __attribute__((packed)) usb_massstor_csw_t;
    5858
    59 enum cmd_block_status {
    60         cbs_passed      = 0x00,
    61         cbs_failed      = 0x01,
    62         cbs_phase_error = 0x02
    63 };
    64 
    6559extern void usb_massstor_cbw_prepare(usb_massstor_cbw_t *, uint32_t, uint32_t,
    6660    usb_direction_t, uint8_t, uint8_t, const uint8_t *);
  • uspace/drv/bus/usb/usbmast/scsi_ms.c

    r80e9e5e rc936c7f  
    6161}
    6262
    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 
    12263/** Perform SCSI Inquiry command on USB mass storage device.
    12364 *
     
    12970{
    13071        scsi_std_inquiry_data_t inq_data;
    131         scsi_cmd_t cmd;
     72        size_t response_len;
    13273        scsi_cdb_inquiry_t cdb;
    13374        int rc;
     
    13778        cdb.alloc_len = host2uint16_t_be(sizeof(inq_data));
    13879
    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);
    14682
    14783        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) {
    16090                usb_log_error("SCSI Inquiry response too short (%zu).\n",
    161                     cmd.rcvd_size);
     91                    response_len);
    16292                return EIO;
    16393        }
     
    197127int usbmast_request_sense(usbmast_fun_t *mfun, void *buf, size_t size)
    198128{
    199         scsi_cmd_t cmd;
    200129        scsi_cdb_request_sense_t cdb;
     130        size_t data_len;
    201131        int rc;
    202132
     
    205135        cdb.alloc_len = min(size, SCSI_SENSE_DATA_MAX_SIZE);
    206136
    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) {
    216141                usb_log_error("Request Sense failed, device %s: %s.\n",
    217142                   mfun->mdev->ddf_dev->name, str_error(rc));
     
    219144        }
    220145
    221         if (cmd.rcvd_size < SCSI_SENSE_DATA_MIN_SIZE) {
     146        if (data_len < SCSI_SENSE_DATA_MIN_SIZE) {
    222147                /* 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);
    225150        }
    226151
     
    239164    uint32_t *block_size)
    240165{
    241         scsi_cmd_t cmd;
    242166        scsi_cdb_read_capacity_10_t cdb;
    243167        scsi_read_capacity_10_data_t data;
     168        size_t data_len;
    244169        int rc;
    245170
     
    247172        cdb.op_code = SCSI_CMD_READ_CAPACITY_10;
    248173
    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)) {
    270184                usb_log_error("SCSI Read Capacity response too short (%zu).\n",
    271                     cmd.rcvd_size);
     185                    data_len);
    272186                return EIO;
    273187        }
     
    289203int usbmast_read(usbmast_fun_t *mfun, uint64_t ba, size_t nblocks, void *buf)
    290204{
    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. */
    294210
    295211        if (ba > UINT32_MAX)
    296212                return ELIMIT;
    297213
    298         if (nblocks > UINT16_MAX)
    299                 return ELIMIT;
    300 
    301         memset(&cdb, 0, sizeof(cdb));
    302         cdb.op_code = SCSI_CMD_READ_10;
     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;
    303219        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) {
    327232                usb_log_error("SCSI Read response too short (%zu).\n",
    328                     cmd.rcvd_size);
     233                    data_len);
    329234                return EIO;
    330235        }
     
    345250    const void *data)
    346251{
    347         scsi_cmd_t cmd;
    348         scsi_cdb_write_10_t cdb;
     252        scsi_cdb_write_12_t cdb;
     253        size_t sent_len;
    349254        int rc;
    350255
     
    352257                return ELIMIT;
    353258
    354         if (nblocks > UINT16_MAX)
    355                 return ELIMIT;
    356 
    357         memset(&cdb, 0, sizeof(cdb));
    358         cdb.op_code = SCSI_CMD_WRITE_10;
     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;
    359264        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);
    379279                return EIO;
    380280        }
  • uspace/lib/block/libblock.c

    r80e9e5e rc936c7f  
    258258static hash_index_t cache_hash(unsigned long *key)
    259259{
    260         return MERGE_LOUP32(key[0], key[1]) & (CACHE_BUCKETS - 1);
     260        return *key & (CACHE_BUCKETS - 1);
    261261}
    262262
     
    264264{
    265265        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;
    267267}
    268268
     
    305305        cache->blocks_cluster = cache->lblock_size / devcon->pblock_size;
    306306
    307         if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 2,
     307        if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
    308308            &cache_ops)) {
    309309                free(cache);
     
    344344                }
    345345
    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);
    351348               
    352349                free(b->data);
     
    401398        block_t *b;
    402399        link_t *l;
    403         unsigned long key[2] = {
    404                 LOWER32(ba),
    405                 UPPER32(ba)
    406         };
    407 
     400        unsigned long key = ba;
    408401        int rc;
    409402       
     
    420413
    421414        fibril_mutex_lock(&cache->lock);
    422         l = hash_table_find(&cache->block_hash, key);
     415        l = hash_table_find(&cache->block_hash, &key);
    423416        if (l) {
    424417found:
     
    458451                         * Try to recycle a block from the free list.
    459452                         */
     453                        unsigned long temp_key;
    460454recycle:
    461455                        if (list_empty(&cache->free_list)) {
     
    505499                                        goto retry;
    506500                                }
    507                                 l = hash_table_find(&cache->block_hash, key);
     501                                l = hash_table_find(&cache->block_hash, &key);
    508502                                if (l) {
    509503                                        /*
     
    528522                         */
    529523                        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);
    535526                }
    536527
     
    540531                b->lba = ba;
    541532                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);
    543534
    544535                /*
     
    652643                         * Take the block out of the cache and free it.
    653644                         */
    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);
    659647                        fibril_mutex_unlock(&block->lock);
    660648                        free(block->data);
  • uspace/lib/c/generic/elf/elf_load.c

    r80e9e5e rc936c7f  
    7474static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
    7575
     76/** Read until the buffer is read in its entirety. */
     77static 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
    7689/** Load ELF binary from a file.
    7790 *
     
    147160        int i, rc;
    148161
    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) {
    151164                DPRINTF("Read error.\n");
    152165                return EE_INVALID;
     
    209222                        + i * sizeof(elf_segment_header_t), SEEK_SET);
    210223
    211                 rc = read_all(elf->fd, &segment_hdr,
     224                rc = my_read(elf->fd, &segment_hdr,
    212225                    sizeof(elf_segment_header_t));
    213                 if (rc != sizeof(elf_segment_header_t)) {
     226                if (rc < 0) {
    214227                        DPRINTF("Read error.\n");
    215228                        return EE_INVALID;
     
    231244                    + i * sizeof(elf_section_header_t), SEEK_SET);
    232245
    233                 rc = read_all(elf->fd, &section_hdr,
     246                rc = my_read(elf->fd, &section_hdr,
    234247                    sizeof(elf_section_header_t));
    235                 if (rc != sizeof(elf_section_header_t)) {
     248                if (rc < 0) {
    236249                        DPRINTF("Read error.\n");
    237250                        return EE_INVALID;
     
    321334        uintptr_t seg_addr;
    322335        size_t mem_sz;
    323         ssize_t rc;
     336        int rc;
    324337
    325338        bias = elf->bias;
     
    399412                if (now > left) now = left;
    400413
    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) {
    404417                        DPRINTF("Read error.\n");
    405418                        return EE_INVALID;
  • uspace/lib/c/generic/vfs/vfs.c

    r80e9e5e rc936c7f  
    417417}
    418418
    419 /** Read entire buffer.
    420  *
    421  * In face of short reads this function continues reading until either
    422  * the entire buffer is read or no more data is available (at end of file).
    423  *
    424  * @param fildes        File descriptor
    425  * @param buf           Buffer, @a nbytes bytes long
    426  * @param nbytes        Number of bytes to read
    427  *
    428  * @return              On success, positive number of bytes read.
    429  *                      On failure, negative error code from read().
    430  */
    431 ssize_t read_all(int fildes, void *buf, size_t nbyte)
    432 {
    433         ssize_t cnt = 0;
    434         size_t nread = 0;
    435         uint8_t *bp = (uint8_t *) buf;
    436 
    437         do {
    438                 bp += cnt;
    439                 nread += cnt;
    440                 cnt = read(fildes, bp, nbyte - nread);
    441         } while (cnt > 0 && (nbyte - nread - cnt) > 0);
    442 
    443         if (cnt < 0)
    444                 return cnt;
    445 
    446         return nread + cnt;
    447 }
    448 
    449 /** Write entire buffer.
    450  *
    451  * This function fails if it cannot write exactly @a len bytes to the file.
    452  *
    453  * @param fildes        File descriptor
    454  * @param buf           Data, @a nbytes bytes long
    455  * @param nbytes        Number of bytes to write
    456  *
    457  * @return              EOK on error, return value from write() if writing
    458  *                      failed.
    459  */
    460 ssize_t write_all(int fildes, const void *buf, size_t nbyte)
    461 {
    462         ssize_t cnt = 0;
    463         ssize_t nwritten = 0;
    464         const uint8_t *bp = (uint8_t *) buf;
    465 
    466         do {
    467                 bp += cnt;
    468                 nwritten += cnt;
    469                 cnt = write(fildes, bp, nbyte - nwritten);
    470         } while (cnt > 0 && ((ssize_t )nbyte - nwritten - cnt) > 0);
    471 
    472         if (cnt < 0)
    473                 return cnt;
    474 
    475         if ((ssize_t)nbyte - nwritten - cnt > 0)
    476                 return EIO;
    477 
    478         return nbyte;
    479 }
    480 
    481419int fsync(int fildes)
    482420{
  • uspace/lib/c/include/unistd.h

    r80e9e5e rc936c7f  
    6363extern ssize_t read(int, void *, size_t);
    6464
    65 extern ssize_t read_all(int, void *, size_t);
    66 extern ssize_t write_all(int, const void *, size_t);
    67 
    6865extern off64_t lseek(int, off64_t, int);
    6966extern int ftruncate(int, aoff64_t);
  • uspace/lib/fs/libfs.c

    r80e9e5e rc936c7f  
    4545#include <mem.h>
    4646#include <sys/stat.h>
    47 #include <stdlib.h>
    4847
    4948#define on_error(rc, action) \
     
    6261        } while (0)
    6362
    64 static fs_reg_t reg;
    65 
    66 static vfs_out_ops_t *vfs_out_ops = NULL;
    67 static libfs_ops_t *libfs_ops = NULL;
    68 
    69 static void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    70 static void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);
    71 static void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t,
    72     ipc_call_t *);
    73 static void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    74 static void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t,
    75     ipc_call_t *);
    76 
    77 static void vfs_out_mounted(ipc_callid_t rid, ipc_call_t *req)
    78 {
    79         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    80         char *opts;
    81         int rc;
    82        
    83         /* Accept the mount options. */
    84         rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
    85         if (rc != EOK) {
    86                 async_answer_0(rid, rc);
    87                 return;
    88         }
    89 
    90         fs_index_t index;
    91         aoff64_t size;
    92         unsigned lnkcnt;
    93         rc = vfs_out_ops->mounted(devmap_handle, opts, &index, &size, &lnkcnt);
    94 
    95         if (rc == EOK)
    96                 async_answer_4(rid, EOK, index, LOWER32(size), UPPER32(size),
    97                     lnkcnt);
    98         else
    99                 async_answer_0(rid, rc);
    100 
    101         free(opts);
    102 }
    103 
    104 static void vfs_out_mount(ipc_callid_t rid, ipc_call_t *req)
    105 {
    106         libfs_mount(libfs_ops, reg.fs_handle, rid, req);
    107 }
    108 
    109 static void vfs_out_unmounted(ipc_callid_t rid, ipc_call_t *req)
    110 {
    111         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    112         int rc;
    113 
    114         rc = vfs_out_ops->unmounted(devmap_handle);
    115 
    116         async_answer_0(rid, rc);
    117 }
    118 
    119 static void vfs_out_unmount(ipc_callid_t rid, ipc_call_t *req)
    120 {
    121                
    122         libfs_unmount(libfs_ops, rid, req);
    123 }
    124 
    125 static void vfs_out_lookup(ipc_callid_t rid, ipc_call_t *req)
    126 {
    127         libfs_lookup(libfs_ops, reg.fs_handle, rid, req);
    128 }
    129 
    130 static void vfs_out_read(ipc_callid_t rid, ipc_call_t *req)
    131 {
    132         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    133         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
    134         aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
    135             IPC_GET_ARG4(*req));
    136         size_t rbytes;
    137         int rc;
    138 
    139         rc = vfs_out_ops->read(devmap_handle, index, pos, &rbytes);
    140 
    141         if (rc == EOK)
    142                 async_answer_1(rid, EOK, rbytes);
    143         else
    144                 async_answer_0(rid, rc);
    145 }
    146 
    147 static void vfs_out_write(ipc_callid_t rid, ipc_call_t *req)
    148 {
    149         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    150         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
    151         aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
    152             IPC_GET_ARG4(*req));
    153         size_t wbytes;
    154         aoff64_t nsize;
    155         int rc;
    156 
    157         rc = vfs_out_ops->write(devmap_handle, index, pos, &wbytes, &nsize);
    158 
    159         if (rc == EOK)
    160                 async_answer_3(rid, EOK, wbytes, LOWER32(nsize), UPPER32(nsize));
    161         else
    162                 async_answer_0(rid, rc);
    163 }
    164 
    165 static void vfs_out_truncate(ipc_callid_t rid, ipc_call_t *req)
    166 {
    167         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    168         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
    169         aoff64_t size = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
    170             IPC_GET_ARG4(*req));
    171         int rc;
    172 
    173         rc = vfs_out_ops->truncate(devmap_handle, index, size);
    174 
    175         async_answer_0(rid, rc);
    176 }
    177 
    178 static void vfs_out_close(ipc_callid_t rid, ipc_call_t *req)
    179 {
    180         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    181         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
    182         int rc;
    183 
    184         rc = vfs_out_ops->close(devmap_handle, index);
    185 
    186         async_answer_0(rid, rc);
    187 }
    188 
    189 static void vfs_out_destroy(ipc_callid_t rid, ipc_call_t *req)
    190 {
    191         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    192         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
    193         int rc;
    194 
    195         rc = vfs_out_ops->destroy(devmap_handle, index);
    196 
    197         async_answer_0(rid, rc);
    198 }
    199 
    200 static void vfs_out_open_node(ipc_callid_t rid, ipc_call_t *req)
    201 {
    202         libfs_open_node(libfs_ops, reg.fs_handle, rid, req);
    203 }
    204 
    205 static void vfs_out_stat(ipc_callid_t rid, ipc_call_t *req)
    206 {
    207         libfs_stat(libfs_ops, reg.fs_handle, rid, req);
    208 }
    209 
    210 static void vfs_out_sync(ipc_callid_t rid, ipc_call_t *req)
    211 {
    212         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    213         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
    214         int rc;
    215 
    216         rc = vfs_out_ops->sync(devmap_handle, index);
    217 
    218         async_answer_0(rid, rc);
    219 }
    220 
    221 static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    222 {
    223         if (iid) {
    224                 /*
    225                  * This only happens for connections opened by
    226                  * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
    227                  * created by IPC_M_CONNECT_TO_ME.
    228                  */
    229                 async_answer_0(iid, EOK);
    230         }
    231        
    232         while (true) {
    233                 ipc_call_t call;
    234                 ipc_callid_t callid = async_get_call(&call);
    235                
    236                 if (!IPC_GET_IMETHOD(call))
    237                         return;
    238                
    239                 switch (IPC_GET_IMETHOD(call)) {
    240                 case VFS_OUT_MOUNTED:
    241                         vfs_out_mounted(callid, &call);
    242                         break;
    243                 case VFS_OUT_MOUNT:
    244                         vfs_out_mount(callid, &call);
    245                         break;
    246                 case VFS_OUT_UNMOUNTED:
    247                         vfs_out_unmounted(callid, &call);
    248                         break;
    249                 case VFS_OUT_UNMOUNT:
    250                         vfs_out_unmount(callid, &call);
    251                         break;
    252                 case VFS_OUT_LOOKUP:
    253                         vfs_out_lookup(callid, &call);
    254                         break;
    255                 case VFS_OUT_READ:
    256                         vfs_out_read(callid, &call);
    257                         break;
    258                 case VFS_OUT_WRITE:
    259                         vfs_out_write(callid, &call);
    260                         break;
    261                 case VFS_OUT_TRUNCATE:
    262                         vfs_out_truncate(callid, &call);
    263                         break;
    264                 case VFS_OUT_CLOSE:
    265                         vfs_out_close(callid, &call);
    266                         break;
    267                 case VFS_OUT_DESTROY:
    268                         vfs_out_destroy(callid, &call);
    269                         break;
    270                 case VFS_OUT_OPEN_NODE:
    271                         vfs_out_open_node(callid, &call);
    272                         break;
    273                 case VFS_OUT_STAT:
    274                         vfs_out_stat(callid, &call);
    275                         break;
    276                 case VFS_OUT_SYNC:
    277                         vfs_out_sync(callid, &call);
    278                         break;
    279                 default:
    280                         async_answer_0(callid, ENOTSUP);
    281                         break;
    282                 }
    283         }
    284 }
    285 
    28663/** Register file system server.
    28764 *
     
    29168 *
    29269 * @param sess Session for communication with VFS.
     70 * @param reg  File system registration structure. It will be
     71 *             initialized by this function.
    29372 * @param info VFS info structure supplied by the file system
    29473 *             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.
    29776 *
    29877 * @return EOK on success or a non-zero error code on errror.
    29978 *
    30079 */
    301 int fs_register(async_sess_t *sess, vfs_info_t *info, vfs_out_ops_t *vops,
    302     libfs_ops_t *lops)
     80int fs_register(async_sess_t *sess, fs_reg_t *reg, vfs_info_t *info,
     81    async_client_conn_t conn)
    30382{
    30483        /*
     
    325104       
    326105        /*
    327          * Set VFS_OUT and libfs operations.
    328          */
    329         vfs_out_ops = vops;
    330         libfs_ops = lops;
    331 
    332         /*
    333106         * Ask VFS for callback connection.
    334107         */
    335         async_connect_to_me(exch, 0, 0, 0, vfs_connection, NULL);
     108        async_connect_to_me(exch, 0, 0, 0, conn, NULL);
    336109       
    337110        /*
    338111         * Allocate piece of address space for PLB.
    339112         */
    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) {
    342115                async_exchange_end(exch);
    343116                async_wait_for(req, NULL);
     
    348121         * Request sharing the Path Lookup Buffer with VFS.
    349122         */
    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);
    351124       
    352125        async_exchange_end(exch);
     
    361134         */
    362135        async_wait_for(req, NULL);
    363         reg.fs_handle = (int) IPC_GET_ARG1(answer);
     136        reg->fs_handle = (int) IPC_GET_ARG1(answer);
    364137       
    365138        /*
     
    367140         * the same connection fibril as well.
    368141         */
    369         async_set_client_connection(vfs_connection);
     142        async_set_client_connection(conn);
    370143       
    371144        return IPC_GET_RETVAL(answer);
     
    378151
    379152void 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)
    381154{
    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);
    386159       
    387160        async_sess_t *mountee_sess = async_clone_receive(EXCHANGE_PARALLEL);
     
    435208         * Do not release the FS node so that it stays in memory.
    436209         */
    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));
    439212}
    440213
    441 void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *req)
     214void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *request)
    442215{
    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);
    445218        fs_node_t *fn;
    446219        int res;
     
    486259}
    487260
    488 static char plb_get_char(unsigned pos)
    489 {
    490         return reg.plb_ro[pos % PLB_SIZE];
    491 }
    492 
    493261/** Lookup VFS triplet by name in the file system name space.
    494262 *
     
    505273 */
    506274void 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)
    508276{
    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);
    511279        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);
    515283        char component[NAME_MAX + 1];
    516284        int len;
     
    530298                async_exch_t *exch = async_exchange_begin(cur->mp_data.sess);
    531299                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);
    534301                async_exchange_end(exch);
    535302               
     
    539306       
    540307        /* Eat slash */
    541         if (plb_get_char(next) == '/')
     308        if (ops->plb_get_char(next) == '/')
    542309                next++;
    543310       
     
    552319                /* Collect the component */
    553320                len = 0;
    554                 while ((next <= last) && (plb_get_char(next) != '/')) {
     321                while ((next <= last) && (ops->plb_get_char(next) != '/')) {
    555322                        if (len + 1 == NAME_MAX) {
    556323                                /* Component length overflow */
     
    558325                                goto out;
    559326                        }
    560                         component[len++] = plb_get_char(next);
     327                        component[len++] = ops->plb_get_char(next);
    561328                        /* Process next character */
    562329                        next++;
     
    590357                       
    591358                        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,
    594361                            IPC_FF_ROUTE_FROM_ME);
    595362                        async_exchange_end(exch);
     
    684451                        len = 0;
    685452                        while (next <= last) {
    686                                 if (plb_get_char(next) == '/') {
     453                                if (ops->plb_get_char(next) == '/') {
    687454                                        /* More than one component */
    688455                                        async_answer_0(rid, ENOENT);
     
    696463                                }
    697464                               
    698                                 component[len++] = plb_get_char(next);
     465                                component[len++] = ops->plb_get_char(next);
    699466                                /* Process next character */
    700467                                next++;
     
    870637        rc = ops->node_open(fn);
    871638        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),
    874640            (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0));
    875641       
  • uspace/lib/fs/libfs.h

    r80e9e5e rc936c7f  
    4343
    4444typedef 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 {
    5845        bool mp_active;
    5946        async_sess_t *sess;
     
    8471        int (* has_children)(bool *, fs_node_t *);
    8572        /*
    86          * The second set of methods are usually mere getters that do not
    87          * return an integer error code.
     73         * The second set of methods are usually mere getters that do not return
     74         * an integer error code.
    8875         */
    8976        fs_index_t (* index_get)(fs_node_t *);
    9077        aoff64_t (* size_get)(fs_node_t *);
    9178        unsigned int (* lnkcnt_get)(fs_node_t *);
     79        char (* plb_get_char)(unsigned pos);
    9280        bool (* is_directory)(fs_node_t *);
    9381        bool (* is_file)(fs_node_t *);
     
    10088} fs_reg_t;
    10189
    102 extern int fs_register(async_sess_t *, vfs_info_t *, vfs_out_ops_t *,
    103     libfs_ops_t *);
     90extern int fs_register(async_sess_t *, fs_reg_t *, vfs_info_t *,
     91    async_client_conn_t);
    10492
    10593extern void fs_node_initialize(fs_node_t *);
     94
     95extern void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
     96extern void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);
     97extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
     98extern void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
     99extern void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t,
     100    ipc_call_t *);
    106101
    107102#endif
  • uspace/lib/scsi/include/scsi/sbc.h

    r80e9e5e rc936c7f  
    5656};
    5757
    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 
    7458/** SCSI Read (12) command */
    7559typedef struct {
    7660        /** Operation code (SCSI_CMD_READ_12) */
    7761        uint8_t op_code;
    78         /** RdProtect, DPO, FUA, Reserved, FUA_NV, Obsolete */
     62        /** RdProtect, DPO, FUA, Reserved, FUA_NV, Reserved */
    7963        uint8_t flags;
    8064        /** Logical block address */
     
    131115} scsi_read_capacity_10_data_t;
    132116
    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 
    149117/** SCSI Write (12) command */
    150118typedef struct {
    151119        /** Operation code (SCSI_CMD_WRITE_12) */
    152120        uint8_t op_code;
    153         /** WrProtect, DPO, FUA, Reserved, FUA_NV, Obsolete */
     121        /** WrProtect, DPO, FUA, Reserved, FUA_NV, Reserved */
    154122        uint8_t flags;
    155123        /** Logical block address */
  • uspace/lib/scsi/include/scsi/spc.h

    r80e9e5e rc936c7f  
    179179        uint8_t additional_len;
    180180        /** Command-specific Information */
    181         uint32_t cmd_spec;
     181        uint8_t cmd_spec;
    182182        /** Additional Sense Code */
    183183        uint8_t additional_code;
     
    205205        SCSI_SK_ABORTED_COMMAND = 0xb,
    206206        SCSI_SK_VOLUME_OVERFLOW = 0xd,
    207         SCSI_SK_MISCOMPARE      = 0xe,
    208 
    209         SCSI_SK_LIMIT           = 0x10
     207        SCSI_SK_MISCOMPARE      = 0xe
    210208};
    211209
    212210extern const char *scsi_dev_type_str[SCSI_DEV_LIMIT];
    213 extern const char *scsi_sense_key_str[SCSI_SK_LIMIT];
    214 
    215211extern const char *scsi_get_dev_type_str(unsigned);
    216 extern const char *scsi_get_sense_key_str(unsigned);
    217212
    218213#endif
  • uspace/lib/scsi/src/spc.c

    r80e9e5e rc936c7f  
    4444};
    4545
    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 
    6346/** Get peripheral device type string.
    6447 *
     
    7053{
    7154        if (dev_type >= SCSI_DEV_LIMIT || scsi_dev_type_str[dev_type] == NULL)
    72                 return "Unknown";
     55                return "<unknown>";
    7356
    7457        return scsi_dev_type_str[dev_type];
    7558}
    76 
    77 /** Get sense key string.
    78  *
    79  * Return string description of SCSI sense key.
    80  * The returned string is valid indefinitely, the caller should
    81  * not attempt to free it.
    82  */
    83 const char *scsi_get_sense_key_str(unsigned sense_key)
    84 {
    85         if (sense_key >= SCSI_SK_LIMIT || scsi_sense_key_str[sense_key] == NULL)
    86                 return "Unknown";
    87 
    88         return scsi_sense_key_str[sense_key];
    89 }
    90 
  • uspace/srv/devman/devman.c

    r80e9e5e rc936c7f  
    270270        }
    271271       
    272         ssize_t read_bytes = read_all(fd, buf, len);
     272        ssize_t read_bytes = safe_read(fd, buf, len);
    273273        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);
    276275                goto cleanup;
    277276        }
     
    422421        }
    423422       
    424         insert_fun_node(tree, fun, str_dup(""), NULL);
     423        insert_fun_node(tree, fun, clone_string(""), NULL);
    425424        match_id_t *id = create_match_id();
    426         id->id = str_dup("root");
     425        id->id = clone_string("root");
    427426        id->score = 100;
    428427        add_match_id(&fun->match_ids, id);
  • uspace/srv/devman/util.c

    r80e9e5e rc936c7f  
    9191}
    9292
     93char *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
    93104void replace_char(char *str, char orig, char repl)
    94105{
     
    100111}
    101112
     113ssize_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
    102140/** @}
    103141 */
  • uspace/srv/devman/util.h

    r80e9e5e rc936c7f  
    4444extern size_t get_nonspace_len(const char *);
    4545extern void free_not_null(const void *);
     46extern char *clone_string(const char *);
    4647extern void replace_char(char *, char, char);
     48
     49extern ssize_t safe_read(int, void *, size_t);
    4750
    4851#endif
  • uspace/srv/fs/devfs/devfs.c

    r80e9e5e rc936c7f  
    5757};
    5858
     59fs_reg_t devfs_reg;
     60
     61static 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
    59120int main(int argc, char *argv[])
    60121{
     
    73134        }
    74135       
    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);
    77138        if (rc != EOK) {
    78139                printf("%s: Failed to register file system (%d)\n", NAME, rc);
     
    91152 * @}
    92153 */
    93 
  • uspace/srv/fs/devfs/devfs.h

    r80e9e5e rc936c7f  
    3636#include <libfs.h>
    3737
    38 extern vfs_out_ops_t devfs_ops;
    39 extern libfs_ops_t devfs_libfs_ops;
     38extern fs_reg_t devfs_reg;
    4039
    4140#endif
  • uspace/srv/fs/devfs/devfs_ops.c

    r80e9e5e rc936c7f  
    403403}
    404404
     405static char devfs_plb_get_char(unsigned pos)
     406{
     407        return devfs_reg.plb_ro[pos % PLB_SIZE];
     408}
     409
    405410static bool devfs_is_directory(fs_node_t *fn)
    406411{
     
    442447        .size_get = devfs_size_get,
    443448        .lnkcnt_get = devfs_lnkcnt_get,
     449        .plb_get_char = devfs_plb_get_char,
    444450        .is_directory = devfs_is_directory,
    445451        .is_file = devfs_is_file,
     
    456462}
    457463
    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 {
     464void 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
     480void 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
     485void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
     486{
     487        async_answer_0(rid, ENOTSUP);
     488}
     489
     490void devfs_unmount(ipc_callid_t rid, ipc_call_t *request)
     491{
     492        libfs_unmount(&devfs_libfs_ops, rid, request);
     493}
     494
     495void 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
     500void 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
     505void 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
     510void 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       
    476516        if (index == 0) {
    477517                ipc_callid_t callid;
     
    479519                if (!async_data_read_receive(&callid, &size)) {
    480520                        async_answer_0(callid, EINVAL);
    481                         return EINVAL;
     521                        async_answer_0(rid, EINVAL);
     522                        return;
    482523                }
    483524               
     
    499540                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    500541                        free(desc);
    501                         *rbytes = 1;
    502                         return EOK;
     542                        async_answer_1(rid, EOK, 1);
     543                        return;
    503544                }
    504545               
     
    514555                                async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    515556                                free(desc);
    516                                 *rbytes = 1;
    517                                 return EOK;
     557                                async_answer_1(rid, EOK, 1);
     558                                return;
    518559                        }
    519560                       
     
    522563               
    523564                async_answer_0(callid, ENOENT);
    524                 return ENOENT;
     565                async_answer_1(rid, ENOENT, 0);
     566                return;
    525567        }
    526568       
     
    533575                if (!async_data_read_receive(&callid, &size)) {
    534576                        async_answer_0(callid, EINVAL);
    535                         return EINVAL;
     577                        async_answer_0(rid, EINVAL);
     578                        return;
    536579                }
    537580               
     
    542585                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    543586                        free(desc);
    544                         *rbytes = 1;
    545                         return EOK;
     587                        async_answer_1(rid, EOK, 1);
     588                        return;
    546589                }
    547590               
    548591                free(desc);
    549592                async_answer_0(callid, ENOENT);
    550                 return ENOENT;
     593                async_answer_1(rid, ENOENT, 0);
     594                return;
    551595        }
    552596       
     
    562606                if (lnk == NULL) {
    563607                        fibril_mutex_unlock(&devices_mutex);
    564                         return ENOENT;
     608                        async_answer_0(rid, ENOENT);
     609                        return;
    565610                }
    566611               
     
    572617                        fibril_mutex_unlock(&devices_mutex);
    573618                        async_answer_0(callid, EINVAL);
    574                         return EINVAL;
     619                        async_answer_0(rid, EINVAL);
     620                        return;
    575621                }
    576622               
     
    579625               
    580626                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);
    583630               
    584631                /* Forward the IPC_M_DATA_READ request to the driver */
     
    592639                sysarg_t rc;
    593640                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
     651void 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        }
    608658       
    609659        devmap_handle_type_t type = devmap_handle_probe(index);
     
    611661        if (type == DEV_HANDLE_NAMESPACE) {
    612662                /* Namespace directory */
    613                 return ENOTSUP;
     663                async_answer_0(rid, ENOTSUP);
     664                return;
    614665        }
    615666       
     
    624675                if (lnk == NULL) {
    625676                        fibril_mutex_unlock(&devices_mutex);
    626                         return ENOENT;
     677                        async_answer_0(rid, ENOENT);
     678                        return;
    627679                }
    628680               
     
    634686                        fibril_mutex_unlock(&devices_mutex);
    635687                        async_answer_0(callid, EINVAL);
    636                         return EINVAL;
     688                        async_answer_0(rid, EINVAL);
     689                        return;
    637690                }
    638691               
     
    641694               
    642695                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);
    645699               
    646700                /* Forward the IPC_M_DATA_WRITE request to the driver */
     
    654708                sysarg_t rc;
    655709                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
     720void devfs_truncate(ipc_callid_t rid, ipc_call_t *request)
     721{
     722        async_answer_0(rid, ENOTSUP);
     723}
     724
     725void 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        }
    675733       
    676734        devmap_handle_type_t type = devmap_handle_probe(index);
     
    678736        if (type == DEV_HANDLE_NAMESPACE) {
    679737                /* Namespace directory */
    680                 return EOK;
     738                async_answer_0(rid, EOK);
     739                return;
    681740        }
    682741       
     
    690749                if (lnk == NULL) {
    691750                        fibril_mutex_unlock(&devices_mutex);
    692                         return ENOENT;
     751                        async_answer_0(rid, ENOENT);
     752                        return;
    693753                }
    694754               
     
    704764                fibril_mutex_unlock(&devices_mutex);
    705765               
    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
     773void 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        }
    716781       
    717782        devmap_handle_type_t type = devmap_handle_probe(index);
     
    719784        if (type == DEV_HANDLE_NAMESPACE) {
    720785                /* Namespace directory */
    721                 return EOK;
     786                async_answer_0(rid, EOK);
     787                return;
    722788        }
    723789       
     
    731797                if (lnk == NULL) {
    732798                        fibril_mutex_unlock(&devices_mutex);
    733                         return ENOENT;
     799                        async_answer_0(rid, ENOENT);
     800                        return;
    734801                }
    735802               
     
    741808               
    742809                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);
    745812               
    746813                async_exchange_end(exch);
     
    752819                async_wait_for(msg, &rc);
    753820               
    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
     829void devfs_destroy(ipc_callid_t rid, ipc_call_t *request)
     830{
     831        async_answer_0(rid, ENOTSUP);
     832}
    775833
    776834/**
  • uspace/srv/fs/devfs/devfs_ops.h

    r80e9e5e rc936c7f  
    3434#define DEVFS_DEVFS_OPS_H_
    3535
     36#include <ipc/common.h>
    3637#include <bool.h>
    3738
    3839extern bool devfs_init(void);
     40
     41extern void devfs_mounted(ipc_callid_t, ipc_call_t *);
     42extern void devfs_mount(ipc_callid_t, ipc_call_t *);
     43extern void devfs_unmounted(ipc_callid_t, ipc_call_t *);
     44extern void devfs_unmount(ipc_callid_t, ipc_call_t *);
     45extern void devfs_lookup(ipc_callid_t, ipc_call_t *);
     46extern void devfs_open_node(ipc_callid_t, ipc_call_t *);
     47extern void devfs_stat(ipc_callid_t, ipc_call_t *);
     48extern void devfs_sync(ipc_callid_t, ipc_call_t *);
     49extern void devfs_read(ipc_callid_t, ipc_call_t *);
     50extern void devfs_write(ipc_callid_t, ipc_call_t *);
     51extern void devfs_truncate(ipc_callid_t, ipc_call_t *);
     52extern void devfs_close(ipc_callid_t, ipc_call_t *);
     53extern void devfs_destroy(ipc_callid_t, ipc_call_t *);
    3954
    4055#endif
  • uspace/srv/fs/ext2fs/ext2fs.c

    r80e9e5e rc936c7f  
    11/*
    22 * Copyright (c) 2006 Martin Decky
     3 * Copyright (c) 2008 Jakub Jermar
    34 * Copyright (c) 2011 Martin Sucha
    45 * All rights reserved.
     
    5455};
    5556
     57fs_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 */
     77static 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
    56143int main(int argc, char **argv)
    57144{
     
    71158        }       
    72159               
    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);
    75161        if (rc != EOK) {
    76162                fprintf(stdout, NAME ": Failed to register fs (%d)\n", rc);
  • uspace/srv/fs/ext2fs/ext2fs.h

    r80e9e5e rc936c7f  
    11/*
     2 * Copyright (c) 2008 Jakub Jermar
    23 * Copyright (c) 2011 Martin Sucha
    34 * All rights reserved.
     
    3536
    3637#include <libext2.h>
     38#include <fibril_synch.h>
    3739#include <libfs.h>
     40#include <atomic.h>
    3841#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
    3948
    4049#define min(a, b)               ((a) < (b) ? (a) : (b))
    4150
    42 extern vfs_out_ops_t ext2fs_ops;
    43 extern libfs_ops_t ext2fs_libfs_ops;
     51extern fs_reg_t ext2fs_reg;
    4452
    4553extern int ext2fs_global_init(void);
    4654extern int ext2fs_global_fini(void);
     55extern void ext2fs_mounted(ipc_callid_t, ipc_call_t *);
     56extern void ext2fs_mount(ipc_callid_t, ipc_call_t *);
     57extern void ext2fs_unmounted(ipc_callid_t, ipc_call_t *);
     58extern void ext2fs_unmount(ipc_callid_t, ipc_call_t *);
     59extern void ext2fs_lookup(ipc_callid_t, ipc_call_t *);
     60extern void ext2fs_read(ipc_callid_t, ipc_call_t *);
     61extern void ext2fs_write(ipc_callid_t, ipc_call_t *);
     62extern void ext2fs_truncate(ipc_callid_t, ipc_call_t *);
     63extern void ext2fs_stat(ipc_callid_t, ipc_call_t *);
     64extern void ext2fs_close(ipc_callid_t, ipc_call_t *);
     65extern void ext2fs_destroy(ipc_callid_t, ipc_call_t *);
     66extern void ext2fs_open_node(ipc_callid_t, ipc_call_t *);
     67extern void ext2fs_stat(ipc_callid_t, ipc_call_t *);
     68extern void ext2fs_sync(ipc_callid_t, ipc_call_t *);
    4769
    4870#endif
  • uspace/srv/fs/ext2fs/ext2fs_ops.c

    r80e9e5e rc936c7f  
    11/*
     2 * Copyright (c) 2008 Jakub Jermar
    23 * Copyright (c) 2011 Martin Sucha
    34 * All rights reserved.
     
    8687 */
    8788static 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 *);
     89static void ext2fs_read_directory(ipc_callid_t, ipc_callid_t, aoff64_t,
     90        size_t, ext2fs_instance_t *, ext2_inode_ref_t *);
     91static void ext2fs_read_file(ipc_callid_t, ipc_callid_t, aoff64_t,
     92        size_t, ext2fs_instance_t *, ext2_inode_ref_t *);
    9293static bool ext2fs_is_dots(const uint8_t *, size_t);
    9394static int ext2fs_node_get_core(fs_node_t **, ext2fs_instance_t *, fs_index_t);
     
    110111static aoff64_t ext2fs_size_get(fs_node_t *);
    111112static unsigned ext2fs_lnkcnt_get(fs_node_t *);
     113static char ext2fs_plb_get_char(unsigned);
    112114static bool ext2fs_is_directory(fs_node_t *);
    113115static bool ext2fs_is_file(fs_node_t *node);
     
    536538        EXT2FS_DBG("%u", count);
    537539        return count;
     540}
     541
     542char ext2fs_plb_get_char(unsigned pos)
     543{
     544        return ext2fs_reg.plb_ro[pos % PLB_SIZE];
    538545}
    539546
     
    579586        .size_get = ext2fs_size_get,
    580587        .lnkcnt_get = ext2fs_lnkcnt_get,
     588        .plb_get_char = ext2fs_plb_get_char,
    581589        .is_directory = ext2fs_is_directory,
    582590        .is_file = ext2fs_is_file,
     
    588596 */
    589597
    590 static int ext2fs_mounted(devmap_handle_t devmap_handle, const char *opts,
    591    fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
     598void ext2fs_mounted(ipc_callid_t rid, ipc_call_t *request)
    592599{
    593600        EXT2FS_DBG("");
    594601        int rc;
     602        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    595603        ext2_filesystem_t *fs;
    596604        ext2fs_instance_t *inst;
    597605        bool read_only;
    598606       
     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       
    599618        /* Allocate libext2 filesystem structure */
    600619        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        }
    603624       
    604625        /* Allocate instance structure */
     
    606627        if (inst == NULL) {
    607628                free(fs);
    608                 return ENOMEM;
     629                async_answer_0(rid, ENOMEM);
     630                return;
    609631        }
    610632       
     
    614636                free(fs);
    615637                free(inst);
    616                 return rc;
     638                async_answer_0(rid, rc);
     639                return;
    617640        }
    618641       
     
    623646                free(fs);
    624647                free(inst);
    625                 return rc;
     648                async_answer_0(rid, rc);
     649                return;
    626650        }
    627651       
     
    632656                free(fs);
    633657                free(inst);
    634                 return rc;
     658                async_answer_0(rid, rc);
     659                return;
    635660        }
    636661       
     
    648673                free(fs);
    649674                free(inst);
    650                 return rc;
     675                async_answer_0(rid, rc);
     676                return;
    651677        }
    652678        ext2fs_node_t *enode = EXT2FS_NODE(root_node);
     
    657683        fibril_mutex_unlock(&instance_list_mutex);
    658684       
    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));
    662689       
    663690        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
     693void 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
     699void 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);
    671703        ext2fs_instance_t *inst;
    672704        int rc;
     
    674706        rc = ext2fs_instance_get(devmap_handle, &inst);
    675707       
    676         if (rc != EOK)
    677                 return rc;
     708        if (rc != EOK) {
     709                async_answer_0(rid, rc);
     710                return;
     711        }
    678712       
    679713        fibril_mutex_lock(&open_nodes_lock);
     
    682716        if (inst->open_nodes_count != 0) {
    683717                fibril_mutex_unlock(&open_nodes_lock);
    684                 return EBUSY;
     718                async_answer_0(rid, EBUSY);
     719                return;
    685720        }
    686721       
     
    694729        ext2_filesystem_fini(inst->filesystem);
    695730       
    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
     734void ext2fs_unmount(ipc_callid_t rid, ipc_call_t *request)
     735{
     736        EXT2FS_DBG("");
     737        libfs_unmount(&ext2fs_libfs_ops, rid, request);
     738}
     739
     740void 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
     746void 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));
    704753       
    705754        ext2fs_instance_t *inst;
     
    714763        if (!async_data_read_receive(&callid, &size)) {
    715764                async_answer_0(callid, EINVAL);
    716                 return EINVAL;
     765                async_answer_0(rid, EINVAL);
     766                return;
    717767        }
    718768       
     
    720770        if (rc != EOK) {
    721771                async_answer_0(callid, rc);
    722                 return rc;
     772                async_answer_0(rid, rc);
     773                return;
    723774        }
    724775       
     
    726777        if (rc != EOK) {
    727778                async_answer_0(callid, rc);
    728                 return rc;
     779                async_answer_0(rid, rc);
     780                return;
    729781        }
    730782       
    731783        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 {
    740792                /* Other inode types not supported */
    741793                async_answer_0(callid, ENOTSUP);
    742                 rc = ENOTSUP;
     794                async_answer_0(rid, ENOTSUP);
    743795        }
    744796       
    745797        ext2_filesystem_put_inode_ref(inode_ref);
    746798       
    747         return rc;
    748799}
    749800
     
    763814}
    764815
    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)
     816void 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)
    767818{
    768819        ext2_directory_iterator_t it;
     
    776827        if (rc != EOK) {
    777828                async_answer_0(callid, rc);
    778                 return rc;
     829                async_answer_0(rid, rc);
     830                return;
    779831        }
    780832       
     
    789841               
    790842                name_size = ext2_directory_entry_ll_get_name_length(
    791                     inst->filesystem->superblock, it.current);
     843                        inst->filesystem->superblock, it.current);
    792844               
    793845                /* skip . and .. */
     
    797849               
    798850                /* The on-disk entry does not contain \0 at the end
    799                  * end of entry name, so we copy it to new buffer
    800                  * and add the \0 at the end
    801                  */
     851                        * end of entry name, so we copy it to new buffer
     852                        * and add the \0 at the end
     853                        */
    802854                buf = malloc(name_size+1);
    803855                if (buf == NULL) {
    804856                        ext2_directory_iterator_fini(&it);
    805857                        async_answer_0(callid, ENOMEM);
    806                         return ENOMEM;
     858                        async_answer_0(rid, ENOMEM);
     859                        return;
    807860                }
    808861                memcpy(buf, &it.current->name, name_size);
    809                 *(buf + name_size) = 0;
     862                *(buf+name_size) = 0;
    810863                found = true;
    811                 (void) async_data_read_finalize(callid, buf, name_size + 1);
     864                (void) async_data_read_finalize(callid, buf, name_size+1);
    812865                free(buf);
    813866                break;
     
    818871                        ext2_directory_iterator_fini(&it);
    819872                        async_answer_0(callid, rc);
    820                         return rc;
     873                        async_answer_0(rid, rc);
     874                        return;
    821875                }
    822876        }
     
    824878        if (found) {
    825879                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                }
    828884                next = it.current_offset;
    829885        }
    830886       
    831887        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        }
    834892       
    835893        if (found) {
    836                 *rbytes = next - pos;
    837                 return EOK;
    838         } else {
     894                async_answer_1(rid, EOK, next-pos);
     895        }
     896        else {
    839897                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
     902void 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)
    846904{
    847905        int rc;
     
    861919                /* Read 0 bytes successfully */
    862920                async_data_read_finalize(callid, NULL, 0);
    863                 *rbytes = 0;
    864                 return EOK;
     921                async_answer_1(rid, EOK, 0);
     922                return;
    865923        }
    866924       
     
    881939        if (rc != EOK) {
    882940                async_answer_0(callid, rc);
    883                 return rc;
     941                async_answer_0(rid, rc);
     942                return;
    884943        }
    885944       
     
    893952                if (buffer == NULL) {
    894953                        async_answer_0(callid, ENOMEM);
    895                         return ENOMEM;
     954                        async_answer_0(rid, ENOMEM);
     955                        return;
    896956                }
    897957               
     
    899959               
    900960                async_data_read_finalize(callid, buffer, bytes);
    901                 *rbytes = bytes;
     961                async_answer_1(rid, EOK, bytes);
    902962               
    903963                free(buffer);
    904964               
    905                 return EOK;
     965                return;
    906966        }
    907967       
     
    910970        if (rc != EOK) {
    911971                async_answer_0(callid, rc);
    912                 return rc;
     972                async_answer_0(rid, rc);
     973                return;
    913974        }
    914975       
     
    917978       
    918979        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
     988void 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
     1000void 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
     1012void ext2fs_close(ipc_callid_t rid, ipc_call_t *request)
     1013{
     1014        EXT2FS_DBG("");
     1015        async_answer_0(rid, EOK);
     1016}
     1017
     1018void 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
     1028void 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
     1034void 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
     1040void 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}
    9691049
    9701050/**
    9711051 * @}
    9721052 */
    973 
  • uspace/srv/fs/fat/fat.c

    r80e9e5e rc936c7f  
    5656};
    5757
     58fs_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 */
     78static 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
    58145int main(int argc, char **argv)
    59146{
     
    71158        }
    72159       
    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);
    74161        if (rc != EOK) {
    75162                fat_idx_fini();
  • uspace/srv/fs/fat/fat.h

    r80e9e5e rc936c7f  
    224224} fat_node_t;
    225225
    226 extern vfs_out_ops_t fat_ops;
    227 extern libfs_ops_t fat_libfs_ops;
     226extern fs_reg_t fat_reg;
     227
     228extern void fat_mounted(ipc_callid_t, ipc_call_t *);
     229extern void fat_mount(ipc_callid_t, ipc_call_t *);
     230extern void fat_unmounted(ipc_callid_t, ipc_call_t *);
     231extern void fat_unmount(ipc_callid_t, ipc_call_t *);
     232extern void fat_lookup(ipc_callid_t, ipc_call_t *);
     233extern void fat_read(ipc_callid_t, ipc_call_t *);
     234extern void fat_write(ipc_callid_t, ipc_call_t *);
     235extern void fat_truncate(ipc_callid_t, ipc_call_t *);
     236extern void fat_stat(ipc_callid_t, ipc_call_t *);
     237extern void fat_close(ipc_callid_t, ipc_call_t *);
     238extern void fat_destroy(ipc_callid_t, ipc_call_t *);
     239extern void fat_open_node(ipc_callid_t, ipc_call_t *);
     240extern void fat_stat(ipc_callid_t, ipc_call_t *);
     241extern void fat_sync(ipc_callid_t, ipc_call_t *);
    228242
    229243extern int fat_idx_get_new(fat_idx_t **, devmap_handle_t);
  • uspace/srv/fs/fat/fat_ops.c

    r80e9e5e rc936c7f  
    8585static aoff64_t fat_size_get(fs_node_t *);
    8686static unsigned fat_lnkcnt_get(fs_node_t *);
     87static char fat_plb_get_char(unsigned);
    8788static bool fat_is_directory(fs_node_t *);
    8889static bool fat_is_file(fs_node_t *node);
     
    900901}
    901902
     903char fat_plb_get_char(unsigned pos)
     904{
     905        return fat_reg.plb_ro[pos % PLB_SIZE];
     906}
     907
    902908bool fat_is_directory(fs_node_t *fn)
    903909{
     
    930936        .size_get = fat_size_get,
    931937        .lnkcnt_get = fat_lnkcnt_get,
     938        .plb_get_char = fat_plb_get_char,
    932939        .is_directory = fat_is_directory,
    933940        .is_file = fat_is_file,
     
    936943
    937944/*
    938  * FAT VFS_OUT operations.
     945 * VFS operations.
    939946 */
    940947
    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 {
     948void fat_mounted(ipc_callid_t rid, ipc_call_t *request)
     949{
     950        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    945951        enum cache_mode cmode;
    946952        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
    949963        /* Check for option enabling write through. */
    950964        if (str_cmp(opts, "wtcache") == 0)
     
    953967                cmode = CACHE_MODE_WB;
    954968
     969        free(opts);
     970
    955971        /* initialize libblock */
    956972        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        }
    959977
    960978        /* prepare the boot block */
     
    962980        if (rc != EOK) {
    963981                block_fini(devmap_handle);
    964                 return rc;
     982                async_answer_0(rid, rc);
     983                return;
    965984        }
    966985
     
    970989        if (BPS(bs) != BS_SIZE) {
    971990                block_fini(devmap_handle);
    972                 return ENOTSUP;
     991                async_answer_0(rid, ENOTSUP);
     992                return;
    973993        }
    974994
     
    977997        if (rc != EOK) {
    978998                block_fini(devmap_handle);
    979                 return rc;
     999                async_answer_0(rid, rc);
     1000                return;
    9801001        }
    9811002
     
    9851006                (void) block_cache_fini(devmap_handle);
    9861007                block_fini(devmap_handle);
    987                 return rc;
     1008                async_answer_0(rid, rc);
     1009                return;
    9881010        }
    9891011
     
    9921014                (void) block_cache_fini(devmap_handle);
    9931015                block_fini(devmap_handle);
    994                 return rc;
     1016                async_answer_0(rid, rc);
     1017                return;
    9951018        }
    9961019
     
    10011024                block_fini(devmap_handle);
    10021025                fat_idx_fini_by_devmap_handle(devmap_handle);
    1003                 return ENOMEM;
     1026                async_answer_0(rid, ENOMEM);
     1027                return;
    10041028        }
    10051029        fs_node_initialize(rfn);
     
    10101034                block_fini(devmap_handle);
    10111035                fat_idx_fini_by_devmap_handle(devmap_handle);
    1012                 return ENOMEM;
     1036                async_answer_0(rid, ENOMEM);
     1037                return;
    10131038        }
    10141039        fat_node_initialize(rootp);
     
    10211046                block_fini(devmap_handle);
    10221047                fat_idx_fini_by_devmap_handle(devmap_handle);
    1023                 return ENOMEM;
     1048                async_answer_0(rid, ENOMEM);
     1049                return;
    10241050        }
    10251051        assert(ridxp->index == 0);
     
    10381064        fibril_mutex_unlock(&ridxp->lock);
    10391065
    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
     1069void 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
     1074void fat_unmounted(ipc_callid_t rid, ipc_call_t *request)
     1075{
     1076        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    10491077        fs_node_t *fn;
    10501078        fat_node_t *nodep;
     
    10521080
    10531081        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        }
    10561086        nodep = FAT_NODE(fn);
    10571087
     
    10621092        if (nodep->refcnt != 2) {
    10631093                (void) fat_node_put(fn);
    1064                 return EBUSY;
     1094                async_answer_0(rid, EBUSY);
     1095                return;
    10651096        }
    10661097       
     
    10811112        block_fini(devmap_handle);
    10821113
    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
     1117void fat_unmount(ipc_callid_t rid, ipc_call_t *request)
     1118{
     1119        libfs_unmount(&fat_libfs_ops, rid, request);
     1120}
     1121
     1122void 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
     1127void 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));
    10901133        fs_node_t *fn;
    10911134        fat_node_t *nodep;
     
    10961139
    10971140        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        }
    11021149        nodep = FAT_NODE(fn);
    11031150
     
    11071154                fat_node_put(fn);
    11081155                async_answer_0(callid, EINVAL);
    1109                 return EINVAL;
     1156                async_answer_0(rid, EINVAL);
     1157                return;
    11101158        }
    11111159
     
    11301178                                fat_node_put(fn);
    11311179                                async_answer_0(callid, rc);
    1132                                 return rc;
     1180                                async_answer_0(rid, rc);
     1181                                return;
    11331182                        }
    11341183                        (void) async_data_read_finalize(callid,
     
    11371186                        if (rc != EOK) {
    11381187                                fat_node_put(fn);
    1139                                 return rc;
     1188                                async_answer_0(rid, rc);
     1189                                return;
    11401190                        }
    11411191                }
     
    11941244                rc = fat_node_put(fn);
    11951245                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;
    11981248
    11991249err:
    12001250                (void) fat_node_put(fn);
    12011251                async_answer_0(callid, rc);
    1202                 return rc;
     1252                async_answer_0(rid, rc);
     1253                return;
    12031254
    12041255hit:
     
    12081259
    12091260        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
     1264void 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));
    12181270        fs_node_t *fn;
    12191271        fat_node_t *nodep;
    12201272        fat_bs_t *bs;
    1221         size_t bytes;
     1273        size_t bytes, size;
    12221274        block_t *b;
    12231275        aoff64_t boundary;
     
    12261278       
    12271279        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        }
    12321288        nodep = FAT_NODE(fn);
    12331289       
     
    12371293                (void) fat_node_put(fn);
    12381294                async_answer_0(callid, EINVAL);
    1239                 return EINVAL;
     1295                async_answer_0(rid, EINVAL);
     1296                return;
    12401297        }
    12411298
     
    12651322                        (void) fat_node_put(fn);
    12661323                        async_answer_0(callid, rc);
    1267                         return rc;
     1324                        async_answer_0(rid, rc);
     1325                        return;
    12681326                }
    12691327                rc = fat_block_get(&b, bs, nodep, pos / BPS(bs), flags);
     
    12711329                        (void) fat_node_put(fn);
    12721330                        async_answer_0(callid, rc);
    1273                         return rc;
     1331                        async_answer_0(rid, rc);
     1332                        return;
    12741333                }
    12751334                (void) async_data_write_finalize(callid,
     
    12791338                if (rc != EOK) {
    12801339                        (void) fat_node_put(fn);
    1281                         return rc;
     1340                        async_answer_0(rid, rc);
     1341                        return;
    12821342                }
    12831343                if (pos + bytes > nodep->size) {
     
    12851345                        nodep->dirty = true;    /* need to sync node */
    12861346                }
    1287                 *wbytes = bytes;
    1288                 *nsize = nodep->size;
     1347                size = nodep->size;
    12891348                rc = fat_node_put(fn);
    1290                 return rc;
     1349                async_answer_2(rid, rc, bytes, nodep->size);
     1350                return;
    12911351        } else {
    12921352                /*
     
    13041364                        (void) fat_node_put(fn);
    13051365                        async_answer_0(callid, rc);
    1306                         return rc;
     1366                        async_answer_0(rid, rc);
     1367                        return;
    13071368                }
    13081369                /* zero fill any gaps */
     
    13121373                        (void) fat_node_put(fn);
    13131374                        async_answer_0(callid, rc);
    1314                         return rc;
     1375                        async_answer_0(rid, rc);
     1376                        return;
    13151377                }
    13161378                rc = _fat_block_get(&b, bs, devmap_handle, lcl, NULL,
     
    13201382                        (void) fat_node_put(fn);
    13211383                        async_answer_0(callid, rc);
    1322                         return rc;
     1384                        async_answer_0(rid, rc);
     1385                        return;
    13231386                }
    13241387                (void) async_data_write_finalize(callid,
     
    13291392                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    13301393                        (void) fat_node_put(fn);
    1331                         return rc;
     1394                        async_answer_0(rid, rc);
     1395                        return;
    13321396                }
    13331397                /*
     
    13391403                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    13401404                        (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 */
    13441410                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
     1416void 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));
    13541422        fs_node_t *fn;
    13551423        fat_node_t *nodep;
     
    13581426
    13591427        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        }
    13641436        nodep = FAT_NODE(fn);
    13651437
     
    14051477out:
    14061478        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
     1483void fat_close(ipc_callid_t rid, ipc_call_t *request)
     1484{
     1485        async_answer_0(rid, EOK);
     1486}
     1487
     1488void 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);
    14171492        fs_node_t *fn;
    14181493        fat_node_t *nodep;
     
    14201495
    14211496        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        }
    14261505
    14271506        nodep = FAT_NODE(fn);
     
    14331512
    14341513        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
     1517void 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
     1522void 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
     1527void 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       
    14401532        fs_node_t *fn;
    14411533        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        }
    14461542       
    14471543        fat_node_t *nodep = FAT_NODE(fn);
     
    14511547       
    14521548        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}
    14661551
    14671552/**
  • uspace/srv/fs/tmpfs/tmpfs.c

    r80e9e5e rc936c7f  
    6161};
    6262
     63fs_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 */
     84static 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
    63151int main(int argc, char **argv)
    64152{
     
    77165        }
    78166       
    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);
    81169        if (rc != EOK) {
    82170                printf(NAME ": Failed to register file system (%d)\n", rc);
  • uspace/srv/fs/tmpfs/tmpfs.h

    r80e9e5e rc936c7f  
    7070} tmpfs_node_t;
    7171
    72 extern vfs_out_ops_t tmpfs_ops;
     72extern fs_reg_t tmpfs_reg;
     73
    7374extern libfs_ops_t tmpfs_libfs_ops;
    7475
    7576extern bool tmpfs_init(void);
     77
     78extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *);
     79extern void tmpfs_mount(ipc_callid_t, ipc_call_t *);
     80extern void tmpfs_unmounted(ipc_callid_t, ipc_call_t *);
     81extern void tmpfs_unmount(ipc_callid_t, ipc_call_t *);
     82extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *);
     83extern void tmpfs_read(ipc_callid_t, ipc_call_t *);
     84extern void tmpfs_write(ipc_callid_t, ipc_call_t *);
     85extern void tmpfs_truncate(ipc_callid_t, ipc_call_t *);
     86extern void tmpfs_stat(ipc_callid_t, ipc_call_t *);
     87extern void tmpfs_close(ipc_callid_t, ipc_call_t *);
     88extern void tmpfs_destroy(ipc_callid_t, ipc_call_t *);
     89extern void tmpfs_open_node(ipc_callid_t, ipc_call_t *);
     90extern void tmpfs_sync(ipc_callid_t, ipc_call_t *);
     91
    7692extern bool tmpfs_restore(devmap_handle_t);
    7793
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    r80e9e5e rc936c7f  
    104104}
    105105
     106static char tmpfs_plb_get_char(unsigned pos)
     107{
     108        return tmpfs_reg.plb_ro[pos % PLB_SIZE];
     109}
     110
    106111static bool tmpfs_is_directory(fs_node_t *fn)
    107112{
     
    134139        .size_get = tmpfs_size_get,
    135140        .lnkcnt_get = tmpfs_lnkcnt_get,
     141        .plb_get_char = tmpfs_plb_get_char,
    136142        .is_directory = tmpfs_is_directory,
    137143        .is_file = tmpfs_is_file,
     
    427433}
    428434
    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 {
     435void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request)
     436{
     437        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    437438        fs_node_t *rootfn;
    438439        int rc;
    439440       
     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
    440449        /* Check if this device is not already mounted. */
    441450        rc = tmpfs_root_get(&rootfn, devmap_handle);
    442451        if ((rc == EOK) && (rootfn)) {
    443452                (void) tmpfs_node_put(rootfn);
    444                 return EEXIST;
     453                free(opts);
     454                async_answer_0(rid, EEXIST);
     455                return;
    445456        }
    446457
    447458        /* 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        }
    450464
    451465        rc = tmpfs_root_get(&rootfn, devmap_handle);
     
    453467        tmpfs_node_t *rootp = TMPFS_NODE(rootfn);
    454468        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
     481void 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
     486void 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
    468490        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
     494void tmpfs_unmount(ipc_callid_t rid, ipc_call_t *request)
     495{
     496        libfs_unmount(&tmpfs_libfs_ops, rid, request);
     497}
     498
     499void 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
     504void 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       
    475511        /*
    476512         * Lookup the respective TMPFS node.
     
    482518        };
    483519        hlp = hash_table_find(&nodes, key);
    484         if (!hlp)
    485                 return ENOENT;
     520        if (!hlp) {
     521                async_answer_0(rid, ENOENT);
     522                return;
     523        }
    486524        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    487525            nh_link);
     
    494532        if (!async_data_read_receive(&callid, &size)) {
    495533                async_answer_0(callid, EINVAL);
    496                 return EINVAL;
     534                async_answer_0(rid, EINVAL);
     535                return;
    497536        }
    498537
     
    517556                if (lnk == NULL) {
    518557                        async_answer_0(callid, ENOENT);
    519                         return ENOENT;
     558                        async_answer_1(rid, ENOENT, 0);
     559                        return;
    520560                }
    521561
     
    527567        }
    528568
    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
     575void 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       
    537582        /*
    538583         * Lookup the respective TMPFS node.
     
    544589        };
    545590        hlp = hash_table_find(&nodes, key);
    546         if (!hlp)
    547                 return ENOENT;
     591        if (!hlp) {
     592                async_answer_0(rid, ENOENT);
     593                return;
     594        }
    548595        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    549596            nh_link);
     
    556603        if (!async_data_write_receive(&callid, &size)) {
    557604                async_answer_0(callid, EINVAL);
    558                 return EINVAL;
     605                async_answer_0(rid, EINVAL);
     606                return;
    559607        }
    560608
     
    564612        if (pos + size <= nodep->size) {
    565613                /* The file size is not changing. */
    566                 (void) async_data_write_finalize(callid, nodep->data + pos,
    567                     size);
    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;
    569617        }
    570618        size_t delta = (pos + size) - nodep->size;
     
    579627        if (!newdata) {
    580628                async_answer_0(callid, ENOMEM);
    581                 size = 0;
    582                 goto out;
     629                async_answer_2(rid, EOK, 0, nodep->size);
     630                return;
    583631        }
    584632        /* Clear any newly allocated memory in order to emulate gaps. */
     
    587635        nodep->data = newdata;
    588636        (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
     640void 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       
    599647        /*
    600648         * Lookup the respective TMPFS node.
     
    605653        };
    606654        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        }
    616671       
    617672        void *newdata = realloc(nodep->data, size);
    618         if (!newdata)
    619                 return ENOMEM;
     673        if (!newdata) {
     674                async_answer_0(rid, ENOMEM);
     675                return;
     676        }
    620677       
    621678        if (size > nodep->size) {
     
    626683        nodep->size = size;
    627684        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
     688void tmpfs_close(ipc_callid_t rid, ipc_call_t *request)
     689{
     690        async_answer_0(rid, EOK);
     691}
     692
     693void 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
    638699        link_t *hlp;
    639700        unsigned long key[] = {
     
    642703        };
    643704        hlp = hash_table_find(&nodes, key);
    644         if (!hlp)
    645                 return ENOENT;
     705        if (!hlp) {
     706                async_answer_0(rid, ENOENT);
     707                return;
     708        }
    646709        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    647710            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
     715void 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
     720void 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
     725void tmpfs_sync(ipc_callid_t rid, ipc_call_t *request)
    652726{
    653727        /*
     
    655729         * thus the sync operation is a no-op.
    656730         */
    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}
    670733
    671734/**
    672735 * @}
    673736 */
    674 
  • uspace/srv/vfs/vfs_ops.c

    r80e9e5e rc936c7f  
    7676        vfs_node_t *mr_node;
    7777        fs_index_t rindex;
    78         aoff64_t rsize;
     78        size_t rsize;
    7979        unsigned rlnkcnt;
    8080        async_exch_t *exch;
     
    146146
    147147                        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_ARG4(answer);
     148                        rsize = (size_t) IPC_GET_ARG2(answer);
     149                        rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
    150150                       
    151151                        mr_res.triplet.fs_handle = fs_handle;
     
    229229        if (rc == EOK) {
    230230                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);
    234233               
    235234                mr_res.triplet.fs_handle = fs_handle;
     
    796795        ipc_call_t answer;
    797796        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);
    801800        } else {
    802801                if (file->append)
    803802                        file->pos = file->node->size;
    804803               
    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);
    808807        }
    809808       
     
    822821                /* Update the cached version of node's size. */
    823822                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);
    826824                fibril_rwlock_write_unlock(&file->node->contents_rwlock);
    827825        }
Note: See TracChangeset for help on using the changeset viewer.