Changes in / [c936c7f:80e9e5e] in mainline


Ignore:
Files:
2 added
40 edited

Legend:

Unmodified
Added
Removed
  • HelenOS.config

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

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

    rc936c7f r80e9e5e  
    5656MKTMPFS = $(TOOLS_PATH)/mktmpfs.py
    5757MKFAT = $(TOOLS_PATH)/mkfat.py
     58MKEXT2 = $(TOOLS_PATH)/mkext2.py
    5859MKUIMAGE = $(TOOLS_PATH)/mkuimage.py
    5960
     
    8283ifeq ($(RDFMT),fat)
    8384        INIT_TASKS += $(USPACE_PATH)/srv/fs/fat/fat
     85endif
     86
     87ifeq ($(RDFMT),ext2fs)
     88        INIT_TASKS += $(USPACE_PATH)/srv/fs/ext2fs/ext2fs
    8489endif
    8590
  • tools/mkfat.py

    rc936c7f r80e9e5e  
    3737import xstruct
    3838import array
    39 
    40 exclude_names = set(['.svn', '.bzr'])
    41 
    42 def align_up(size, alignment):
    43         "Return size aligned up to alignment"
    44        
    45         if (size % alignment == 0):
    46                 return size
    47        
    48         return ((size // alignment) + 1) * alignment
     39from imgutil import *
    4940
    5041def subtree_size(root, cluster_size, dirent_size):
     
    5445        files = 2
    5546       
    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)
     47        for item in listdir_items(root):
     48                if item.is_file:
     49                        size += align_up(item.size, cluster_size)
    6150                        files += 1
    62                
    63                 if (os.path.isdir(canon) and (not name in exclude_names)):
    64                         size += subtree_size(canon, cluster_size, dirent_size)
     51                elif item.is_dir:
     52                        size += subtree_size(item.path, cluster_size, dirent_size)
    6553                        files += 1
    6654       
     
    7260        return len(os.listdir(root))
    7361
    74 def write_file(path, outf, cluster_size, data_start, fat, reserved_clusters):
     62def write_file(item, outf, cluster_size, data_start, fat, reserved_clusters):
    7563        "Store the contents of a file"
    7664       
    77         size = os.path.getsize(path)
    7865        prev = -1
    7966        first = 0
    8067       
    81         inf = open(path, "rb")
    82         rd = 0;
    83         while (rd < size):
     68        for data in chunks(item, cluster_size):
    8469                empty_cluster = fat.index(0)
    8570                fat[empty_cluster] = 0xffff
     
    9277                prev = empty_cluster
    9378               
    94                 data = bytes(inf.read(cluster_size));
    9579                outf.seek(data_start + (empty_cluster - reserved_clusters) * cluster_size)
    9680                outf.write(data)
    97                 rd += len(data)
    98         inf.close()
    99        
    100         return first, size
     81       
     82        return first, item.size
    10183
    10284def write_directory(directory, outf, cluster_size, data_start, fat, reserved_clusters, dirent_size, empty_cluster):
     
    303285                empty_cluster = 0
    304286       
    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]))
     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]))
    315294       
    316295        if (head):
  • tools/mktmpfs.py

    rc936c7f r80e9e5e  
    3535import os
    3636import xstruct
    37 
    38 exclude_names = set(['.svn', '.bzr'])
     37from imgutil import listdir_items, chunks
    3938
    4039HEADER = """little:
     
    7170        "Recursive directory walk"
    7271       
    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))
     72        for item in listdir_items(root):               
     73                if item.is_file:                       
     74                        dentry = xstruct.create(DENTRY_FILE % len(item.name))
    8075                        dentry.kind = TMPFS_FILE
    81                         dentry.fname_len = len(name)
    82                         dentry.fname = name.encode('ascii')
    83                         dentry.flen = size
     76                        dentry.fname_len = len(item.name)
     77                        dentry.fname = item.name.encode('ascii')
     78                        dentry.flen = item.size
    8479                       
    8580                        outf.write(dentry.pack())
    8681                       
    87                         inf = open(canon, "rb")
    88                         rd = 0;
    89                         while (rd < size):
    90                                 data = inf.read(4096);
     82                        for data in chunks(item, 4096):
    9183                                outf.write(data)
    92                                 rd += len(data)
    93                         inf.close()
    9484               
    95                 if (os.path.isdir(canon) and (not name in exclude_names)):
    96                         dentry = xstruct.create(DENTRY_DIRECTORY % len(name))
     85                elif item.is_dir:
     86                        dentry = xstruct.create(DENTRY_DIRECTORY % len(item.name))
    9787                        dentry.kind = TMPFS_DIRECTORY
    98                         dentry.fname_len = len(name)
    99                         dentry.fname = name.encode('ascii')
     88                        dentry.fname_len = len(item.name)
     89                        dentry.fname = item.name.encode('ascii')
    10090                       
    10191                        outf.write(dentry.pack())
    10292                       
    103                         recursion(canon, outf)
     93                        recursion(item.path, outf)
    10494                       
    10595                        dentry = xstruct.create(DENTRY_NONE)
  • tools/xstruct.py

    rc936c7f r80e9e5e  
    11#
    22# Copyright (c) 2008 Martin Decky
     3# Copyright (c) 2011 Martin Sucha
    34# All rights reserved.
    45#
     
    3132
    3233import struct
     34import types
     35
     36ranges = {
     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
     47def 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)))
    3359
    3460class Struct:
     
    3864        def pack(self):
    3965                args = []
    40                 for variable in self._args_:
    41                         if (isinstance(self.__dict__[variable], list)):
    42                                 for item in self.__dict__[variable]:
     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)
    4374                                        args.append(item)
    4475                        else:
    45                                 args.append(self.__dict__[variable])
    46                
     76                                check_range(variable, fmt, value)
     77                                args.append(value)             
    4778                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
    4886
    4987def create(definition):
     
    77115                        subtokens = token.split("[")
    78116                       
     117                        length = None
    79118                        if (len(subtokens) > 1):
    80                                 format += "%d" % int(subtokens[1].split("]")[0])
     119                                length = int(subtokens[1].split("]")[0])
     120                                format += "%d" % length
    81121                       
    82122                        format += variable
    83123                       
    84124                        inst.__dict__[subtokens[0]] = None
    85                         args.append(subtokens[0])
     125                        args.append((subtokens[0], variable, length))
    86126                       
    87127                        variable = None
  • uspace/app/bdsh/cmds/modules/cp/cp.c

    rc936c7f r80e9e5e  
    7171        size_t blen, int vb)
    7272{
    73         int fd1, fd2, bytes = 0;
    74         off64_t total = 0;
     73        int fd1, fd2, bytes;
     74        off64_t total;
    7575        int64_t copied = 0;
    7676        char *buff = NULL;
     
    104104        }
    105105
    106         for (;;) {
    107                 ssize_t res;
    108                 size_t written = 0;
    109 
    110                 bytes = read(fd1, buff, blen);
    111                 if (bytes <= 0)
     106        while ((bytes = read_all(fd1, buff, blen)) > 0) {
     107                if ((bytes = write_all(fd2, buff, bytes)) < 0)
    112108                        break;
    113109                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                 }
    135110        }
    136111
    137112        if (bytes < 0) {
    138 err:
    139113                printf("\nError copying %s, (%d)\n", src, bytes);
    140114                copied = bytes;
  • uspace/app/bdsh/compl.c

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

    rc936c7f r80e9e5e  
    6767
    6868static off64_t align_foff_up(off64_t, uintptr_t, size_t);
    69 static int write_all(int, const void *, size_t);
    7069static int align_pos(int, size_t);
    7170static int write_mem_area(int, as_area_info_t *, async_sess_t *);
     
    10099
    101100        int fd;
    102         int rc;
     101        ssize_t rc;
    103102        unsigned int i;
    104103
     
    204203
    205204        rc = write_all(fd, &elf_hdr, sizeof(elf_hdr));
    206         if (rc != EOK) {
     205        if (rc != sizeof(elf_hdr)) {
    207206                printf("Failed writing ELF header.\n");
    208207                free(p_hdr);
     
    212211        for (i = 0; i < n_ph; ++i) {
    213212                rc = write_all(fd, &p_hdr[i], sizeof(p_hdr[i]));
    214                 if (rc != EOK) {
     213                if (rc != sizeof(p_hdr[i])) {
    215214                        printf("Failed writing program header.\n");
    216215                        free(p_hdr);
     
    233232
    234233        rc = write_all(fd, &note, sizeof(elf_note_t));
    235         if (rc != EOK) {
     234        if (rc != sizeof(elf_note_t)) {
    236235                printf("Failed writing note header.\n");
    237236                free(p_hdr);
     
    240239
    241240        rc = write_all(fd, "CORE", note.namesz);
    242         if (rc != EOK) {
     241        if (rc != (ssize_t) note.namesz) {
    243242                printf("Failed writing note header.\n");
    244243                free(p_hdr);
     
    254253
    255254        rc = write_all(fd, &pr_status, sizeof(elf_prstatus_t));
    256         if (rc != EOK) {
     255        if (rc != sizeof(elf_prstatus_t)) {
    257256                printf("Failed writing register data.\n");
    258257                free(p_hdr);
     
    304303        size_t total;
    305304        uintptr_t addr;
    306         int rc;
     305        ssize_t rc;
    307306
    308307        addr = area->start_addr;
     
    318317
    319318                rc = write_all(fd, buffer, to_copy);
    320                 if (rc != EOK) {
     319                if (rc != (ssize_t) to_copy) {
    321320                        printf("Failed writing memory contents.\n");
    322321                        return EIO;
     
    326325                total += to_copy;
    327326        }
    328 
    329         return EOK;
    330 }
    331 
    332 /** Write until the buffer is written in its entirety.
    333  *
    334  * This function fails if it cannot write exactly @a len bytes to the file.
    335  *
    336  * @param fd            The file to write to.
    337  * @param buf           Data, @a len bytes long.
    338  * @param len           Number of bytes to write.
    339  *
    340  * @return              EOK on error, return value from write() if writing
    341  *                      failed.
    342  */
    343 static int write_all(int fd, const void *data, size_t len)
    344 {
    345         int cnt = 0;
    346 
    347         do {
    348                 data += cnt;
    349                 len -= cnt;
    350                 cnt = write(fd, data, len);
    351         } while (cnt > 0 && (len - cnt) > 0);
    352 
    353         if (cnt < 0)
    354                 return cnt;
    355 
    356         if (len - cnt > 0)
    357                 return EIO;
    358327
    359328        return EOK;
  • uspace/app/taskdump/symtab.c

    rc936c7f r80e9e5e  
    5050    elf_section_header_t *shdr);
    5151static int chunk_load(int fd, off64_t start, size_t size, void **ptr);
    52 static int read_all(int fd, void *buf, size_t len);
    5352
    5453/** Load symbol table from an ELF file.
     
    9089
    9190        rc = read_all(fd, &elf_hdr, sizeof(elf_header_t));
    92         if (rc != EOK) {
     91        if (rc != sizeof(elf_header_t)) {
    9392                printf("failed reading elf header\n");
    9493                free(stab);
     
    312311
    313312        rc = read_all(fd, sec_hdr, sizeof(elf_section_header_t));
    314         if (rc != EOK)
     313        if (rc != sizeof(elf_section_header_t))
    315314                return EIO;
    316315
     
    331330static int chunk_load(int fd, off64_t start, size_t size, void **ptr)
    332331{
    333         int rc;
    334 
    335         rc = lseek(fd, start, SEEK_SET);
    336         if (rc == (off64_t) -1) {
     332        ssize_t rc;
     333        off64_t offs;
     334
     335        offs = lseek(fd, start, SEEK_SET);
     336        if (offs == (off64_t) -1) {
    337337                printf("failed seeking chunk\n");
    338338                *ptr = NULL;
     
    347347
    348348        rc = read_all(fd, *ptr, size);
    349         if (rc != EOK) {
     349        if (rc != (ssize_t) size) {
    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  */
    370 static int read_all(int fd, void *buf, size_t len)
    371 {
    372         int cnt = 0;
    373 
    374         do {
    375                 buf += cnt;
    376                 len -= cnt;
    377                 cnt = read(fd, buf, len);
    378         } while (cnt > 0 && (len - cnt) > 0);
    379 
    380         if (cnt < 0)
    381                 return cnt;
    382 
    383         if (len - cnt > 0)
    384                 return EIO;
    385 
    386         return EOK;
    387 }
    388 
    389359/** @}
    390360 */
  • uspace/drv/bus/usb/usbmast/bo_trans.c

    rc936c7f r80e9e5e  
    5858 * @param tag           Command block wrapper tag (automatically compared
    5959 *                      with answer)
    60  * @param cmd           Command block
    61  * @param cmd_size      Command block size in bytes
    62  * @param ddir          Direction in which data will be transferred
    63  * @param dbuf          Data send/receive buffer
    64  * @param dbuf_size     Size of the data buffer
    65  * @param xferred_size  Number of bytes actually transferred
     60 * @param cmd           SCSI command
    6661 *
    6762 * @return              Error code
    6863 */
    69 static int usb_massstor_cmd(usbmast_fun_t *mfun, uint32_t tag, const void *cmd,
    70     size_t cmd_size, usb_direction_t ddir, void *dbuf, size_t dbuf_size,
    71     size_t *xferred_size)
     64int usb_massstor_cmd(usbmast_fun_t *mfun, uint32_t tag, scsi_cmd_t *cmd)
    7265{
    7366        int rc;
     67        int retval = EOK;
    7468        size_t act_size;
    7569        usb_pipe_t *bulk_in_pipe = mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe;
    7670        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        }
    7786
    7887        /* Prepare CBW - command block wrapper */
    7988        usb_massstor_cbw_t cbw;
    8089        usb_massstor_cbw_prepare(&cbw, tag, dbuf_size, ddir, mfun->lun,
    81             cmd_size, cmd);
     90            cmd->cdb_size, cmd->cdb);
    8291
    8392        /* Send the CBW. */
     93        MASTLOG("Sending CBW.\n");
    8494        rc = usb_pipe_write(bulk_out_pipe, &cbw, sizeof(cbw));
    8595        MASTLOG("CBW '%s' sent: %s.\n",
    8696            usb_debug_str_buffer((uint8_t *) &cbw, sizeof(cbw), 0),
    8797            str_error(rc));
    88         if (rc != EOK) {
    89                 return rc;
    90         }
    91 
     98        if (rc != EOK)
     99                return EIO;
     100
     101        MASTLOG("Transferring data.\n");
    92102        if (ddir == USB_DIRECTION_IN) {
    93103                /* Recieve data from the device. */
     
    104114        }
    105115
    106         if (rc != EOK) {
    107                 /*
    108                  * XXX If the pipe is stalled, we should clear it
    109                  * and read CSW.
    110                  */
    111                 return rc;
     116        if (rc == ESTALL) {
     117                /* Clear stall condition and continue below to read CSW. */
     118                if (ddir == USB_DIRECTION_IN) {
     119                        usb_pipe_clear_halt(&mfun->mdev->usb_dev->ctrl_pipe,
     120                            mfun->mdev->usb_dev->pipes[BULK_IN_EP].pipe);
     121                } else {
     122                        usb_pipe_clear_halt(&mfun->mdev->usb_dev->ctrl_pipe,
     123                            mfun->mdev->usb_dev->pipes[BULK_OUT_EP].pipe);
     124                }
     125        } else if (rc != EOK) {
     126                return EIO;
    112127        }
    113128
     
    115130        usb_massstor_csw_t csw;
    116131        size_t csw_size;
     132        MASTLOG("Reading CSW.\n");
    117133        rc = usb_pipe_read(bulk_in_pipe, &csw, sizeof(csw), &csw_size);
    118134        MASTLOG("CSW '%s' received (%zu bytes): %s.\n",
     
    121137        if (rc != EOK) {
    122138                MASTLOG("rc != EOK\n");
    123                 return rc;
     139                return EIO;
    124140        }
    125141
    126142        if (csw_size != sizeof(csw)) {
    127143                MASTLOG("csw_size != sizeof(csw)\n");
    128                 return ERANGE;
     144                return EIO;
    129145        }
    130146
    131147        if (csw.dCSWTag != tag) {
    132148                MASTLOG("csw.dCSWTag != tag\n");
    133                 return EBADCHECKSUM;
     149                return EIO;
    134150        }
    135151
     
    137153         * Determine the actual return value from the CSW.
    138154         */
    139         if (csw.dCSWStatus != 0) {
    140                 MASTLOG("csw.dCSWStatus != 0\n");
    141                 // FIXME: better error code
    142                 // FIXME: distinguish 0x01 and 0x02
    143                 return EXDEV;
     155        switch (csw.dCSWStatus) {
     156        case cbs_passed:
     157                cmd->status = CMDS_GOOD;
     158                break;
     159        case cbs_failed:
     160                MASTLOG("Command failed\n");
     161                cmd->status = CMDS_FAILED;
     162                break;
     163        case cbs_phase_error:
     164                MASTLOG("Phase error\n");
     165                retval = EIO;
     166                break;
     167        default:
     168                retval = EIO;
     169                break;
    144170        }
    145171
     
    147173        if (residue > dbuf_size) {
    148174                MASTLOG("residue > dbuf_size\n");
    149                 return ERANGE;
     175                return EIO;
    150176        }
    151177
     
    158184         */
    159185
    160         if (xferred_size != NULL)
    161                 *xferred_size = dbuf_size - residue;
    162 
    163         return EOK;
    164 }
    165 
    166 /** Perform data-in command.
    167  *
    168  * @param mfun          Mass storage function
    169  * @param tag           Command block wrapper tag (automatically compared with
    170  *                      answer)
    171  * @param cmd           CDB (Command Descriptor)
    172  * @param cmd_size      CDB length in bytes
    173  * @param dbuf          Data receive buffer
    174  * @param dbuf_size     Data receive buffer size in bytes
    175  * @param proc_size     Number of bytes actually processed by device
    176  *
    177  * @return Error code
    178  */
    179 int usb_massstor_data_in(usbmast_fun_t *mfun, uint32_t tag, const void *cmd,
    180     size_t cmd_size, void *dbuf, size_t dbuf_size, size_t *proc_size)
    181 {
    182         return usb_massstor_cmd(mfun, tag, cmd, cmd_size, USB_DIRECTION_IN,
    183             dbuf, dbuf_size, proc_size);
    184 }
    185 
    186 /** Perform data-out command.
    187  *
    188  * @param mfun          Mass storage function
    189  * @param tag           Command block wrapper tag (automatically compared with
    190  *                      answer)
    191  * @param cmd           CDB (Command Descriptor)
    192  * @param cmd_size      CDB length in bytes
    193  * @param data          Command data
    194  * @param data_size     Size of @a data in bytes
    195  * @param proc_size     Number of bytes actually processed by device
    196  *
    197  * @return Error code
    198  */
    199 int usb_massstor_data_out(usbmast_fun_t *mfun, uint32_t tag, const void *cmd,
    200     size_t cmd_size, const void *data, size_t data_size, size_t *proc_size)
    201 {
    202         return usb_massstor_cmd(mfun, tag, cmd, cmd_size, USB_DIRECTION_OUT,
    203             (void *) data, data_size, proc_size);
     186        if (ddir == USB_DIRECTION_IN)
     187                cmd->rcvd_size = dbuf_size - residue;
     188
     189        return retval;
    204190}
    205191
  • uspace/drv/bus/usb/usbmast/bo_trans.h

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

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

    rc936c7f r80e9e5e  
    6161}
    6262
     63static 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 */
     80static 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
    63122/** Perform SCSI Inquiry command on USB mass storage device.
    64123 *
     
    70129{
    71130        scsi_std_inquiry_data_t inq_data;
    72         size_t response_len;
     131        scsi_cmd_t cmd;
    73132        scsi_cdb_inquiry_t cdb;
    74133        int rc;
     
    78137        cdb.alloc_len = host2uint16_t_be(sizeof(inq_data));
    79138
    80         rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
    81             sizeof(cdb), &inq_data, sizeof(inq_data), &response_len);
     139        memset(&cmd, 0, sizeof(cmd));
     140        cmd.cdb = &cdb;
     141        cmd.cdb_size = sizeof(cdb);
     142        cmd.data_in = &inq_data;
     143        cmd.data_in_size = sizeof(inq_data);
     144
     145        rc = usb_massstor_cmd(mfun, 0xDEADBEEF, &cmd);
    82146
    83147        if (rc != EOK) {
    84                 usb_log_error("Inquiry failed, device %s: %s.\n",
    85                    mfun->mdev->ddf_dev->name, str_error(rc));
    86                 return rc;
    87         }
    88 
    89         if (response_len < SCSI_STD_INQUIRY_DATA_MIN_SIZE) {
     148                usb_log_error("Inquiry transport failed, device %s: %s.\n",
     149                   mfun->mdev->ddf_dev->name, str_error(rc));
     150                return rc;
     151        }
     152
     153        if (cmd.status != CMDS_GOOD) {
     154                usb_log_error("Inquiry command failed, device %s.\n",
     155                   mfun->mdev->ddf_dev->name);
     156                return EIO;
     157        }
     158
     159        if (cmd.rcvd_size < SCSI_STD_INQUIRY_DATA_MIN_SIZE) {
    90160                usb_log_error("SCSI Inquiry response too short (%zu).\n",
    91                     response_len);
     161                    cmd.rcvd_size);
    92162                return EIO;
    93163        }
     
    127197int usbmast_request_sense(usbmast_fun_t *mfun, void *buf, size_t size)
    128198{
     199        scsi_cmd_t cmd;
    129200        scsi_cdb_request_sense_t cdb;
    130         size_t data_len;
    131201        int rc;
    132202
     
    135205        cdb.alloc_len = min(size, SCSI_SENSE_DATA_MAX_SIZE);
    136206
    137         rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
    138             sizeof(cdb), buf, size, &data_len);
    139 
    140         if (rc != EOK) {
     207        memset(&cmd, 0, sizeof(cmd));
     208        cmd.cdb = &cdb;
     209        cmd.cdb_size = sizeof(cdb);
     210        cmd.data_in = buf;
     211        cmd.data_in_size = size;
     212
     213        rc = usb_massstor_cmd(mfun, 0xDEADBEEF, &cmd);
     214
     215        if (rc != EOK || cmd.status != CMDS_GOOD) {
    141216                usb_log_error("Request Sense failed, device %s: %s.\n",
    142217                   mfun->mdev->ddf_dev->name, str_error(rc));
     
    144219        }
    145220
    146         if (data_len < SCSI_SENSE_DATA_MIN_SIZE) {
     221        if (cmd.rcvd_size < SCSI_SENSE_DATA_MIN_SIZE) {
    147222                /* The missing bytes should be considered to be zeroes. */
    148                 memset((uint8_t *)buf + data_len, 0,
    149                     SCSI_SENSE_DATA_MIN_SIZE - data_len);
     223                memset((uint8_t *)buf + cmd.rcvd_size, 0,
     224                    SCSI_SENSE_DATA_MIN_SIZE - cmd.rcvd_size);
    150225        }
    151226
     
    164239    uint32_t *block_size)
    165240{
     241        scsi_cmd_t cmd;
    166242        scsi_cdb_read_capacity_10_t cdb;
    167243        scsi_read_capacity_10_data_t data;
    168         size_t data_len;
    169244        int rc;
    170245
     
    172247        cdb.op_code = SCSI_CMD_READ_CAPACITY_10;
    173248
    174         rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
    175             sizeof(cdb), &data, sizeof(data), &data_len);
     249        memset(&cmd, 0, sizeof(cmd));
     250        cmd.cdb = &cdb;
     251        cmd.cdb_size = sizeof(cdb);
     252        cmd.data_in = &data;
     253        cmd.data_in_size = sizeof(data);
     254
     255        rc = usbmast_run_cmd(mfun, &cmd);
    176256
    177257        if (rc != EOK) {
    178                 usb_log_error("Read Capacity (10) failed, device %s: %s.\n",
    179                    mfun->mdev->ddf_dev->name, str_error(rc));
    180                 return rc;
    181         }
    182 
    183         if (data_len < sizeof(data)) {
     258                usb_log_error("Read Capacity (10) transport failed, device %s: %s.\n",
     259                   mfun->mdev->ddf_dev->name, str_error(rc));
     260                return rc;
     261        }
     262
     263        if (cmd.status != CMDS_GOOD) {
     264                usb_log_error("Read Capacity (10) command failed, device %s.\n",
     265                   mfun->mdev->ddf_dev->name);
     266                return EIO;
     267        }
     268
     269        if (cmd.rcvd_size < sizeof(data)) {
    184270                usb_log_error("SCSI Read Capacity response too short (%zu).\n",
    185                     data_len);
     271                    cmd.rcvd_size);
    186272                return EIO;
    187273        }
     
    203289int usbmast_read(usbmast_fun_t *mfun, uint64_t ba, size_t nblocks, void *buf)
    204290{
    205         scsi_cdb_read_12_t cdb;
    206         size_t data_len;
    207         int rc;
    208 
    209         /* XXX Need softstate to store block size. */
     291        scsi_cmd_t cmd;
     292        scsi_cdb_read_10_t cdb;
     293        int rc;
    210294
    211295        if (ba > UINT32_MAX)
    212296                return ELIMIT;
    213297
    214         if ((uint64_t)nblocks * mfun->block_size > UINT32_MAX)
     298        if (nblocks > UINT16_MAX)
    215299                return ELIMIT;
    216300
    217301        memset(&cdb, 0, sizeof(cdb));
    218         cdb.op_code = SCSI_CMD_READ_12;
     302        cdb.op_code = SCSI_CMD_READ_10;
    219303        cdb.lba = host2uint32_t_be(ba);
    220         cdb.xfer_len = host2uint32_t_be(nblocks);
    221 
    222         rc = usb_massstor_data_in(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
    223             sizeof(cdb), buf, nblocks * mfun->block_size, &data_len);
     304        cdb.xfer_len = host2uint16_t_be(nblocks);
     305
     306        memset(&cmd, 0, sizeof(cmd));
     307        cmd.cdb = &cdb;
     308        cmd.cdb_size = sizeof(cdb);
     309        cmd.data_in = buf;
     310        cmd.data_in_size = nblocks * mfun->block_size;
     311
     312        rc = usbmast_run_cmd(mfun, &cmd);
    224313
    225314        if (rc != EOK) {
    226                 usb_log_error("Read (12) failed, device %s: %s.\n",
    227                    mfun->mdev->ddf_dev->name, str_error(rc));
    228                 return rc;
    229         }
    230 
    231         if (data_len < nblocks * mfun->block_size) {
     315                usb_log_error("Read (10) transport failed, device %s: %s.\n",
     316                   mfun->mdev->ddf_dev->name, str_error(rc));
     317                return rc;
     318        }
     319
     320        if (cmd.status != CMDS_GOOD) {
     321                usb_log_error("Read (10) command failed, device %s.\n",
     322                   mfun->mdev->ddf_dev->name);
     323                return EIO;
     324        }
     325
     326        if (cmd.rcvd_size < nblocks * mfun->block_size) {
    232327                usb_log_error("SCSI Read response too short (%zu).\n",
    233                     data_len);
     328                    cmd.rcvd_size);
    234329                return EIO;
    235330        }
     
    250345    const void *data)
    251346{
    252         scsi_cdb_write_12_t cdb;
    253         size_t sent_len;
     347        scsi_cmd_t cmd;
     348        scsi_cdb_write_10_t cdb;
    254349        int rc;
    255350
     
    257352                return ELIMIT;
    258353
    259         if ((uint64_t)nblocks * mfun->block_size > UINT32_MAX)
     354        if (nblocks > UINT16_MAX)
    260355                return ELIMIT;
    261356
    262357        memset(&cdb, 0, sizeof(cdb));
    263         cdb.op_code = SCSI_CMD_WRITE_12;
     358        cdb.op_code = SCSI_CMD_WRITE_10;
    264359        cdb.lba = host2uint32_t_be(ba);
    265         cdb.xfer_len = host2uint32_t_be(nblocks);
    266 
    267         rc = usb_massstor_data_out(mfun, 0xDEADBEEF, (uint8_t *) &cdb,
    268             sizeof(cdb), data, nblocks * mfun->block_size, &sent_len);
     360        cdb.xfer_len = host2uint16_t_be(nblocks);
     361
     362        memset(&cmd, 0, sizeof(cmd));
     363        cmd.cdb = &cdb;
     364        cmd.cdb_size = sizeof(cdb);
     365        cmd.data_out = data;
     366        cmd.data_out_size = nblocks * mfun->block_size;
     367
     368        rc = usbmast_run_cmd(mfun, &cmd);
    269369
    270370        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);
     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);
    279379                return EIO;
    280380        }
  • uspace/lib/block/libblock.c

    rc936c7f r80e9e5e  
    258258static hash_index_t cache_hash(unsigned long *key)
    259259{
    260         return *key & (CACHE_BUCKETS - 1);
     260        return MERGE_LOUP32(key[0], key[1]) & (CACHE_BUCKETS - 1);
    261261}
    262262
     
    264264{
    265265        block_t *b = hash_table_get_instance(item, block_t, hash_link);
    266         return b->lba == *key;
     266        return b->lba == MERGE_LOUP32(key[0], key[1]);
    267267}
    268268
     
    305305        cache->blocks_cluster = cache->lblock_size / devcon->pblock_size;
    306306
    307         if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
     307        if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 2,
    308308            &cache_ops)) {
    309309                free(cache);
     
    344344                }
    345345
    346                 unsigned long key = b->lba;
    347                 hash_table_remove(&cache->block_hash, &key, 1);
     346                unsigned long key[2] = {
     347                        LOWER32(b->lba),
     348                        UPPER32(b->lba)
     349                };
     350                hash_table_remove(&cache->block_hash, key, 2);
    348351               
    349352                free(b->data);
     
    398401        block_t *b;
    399402        link_t *l;
    400         unsigned long key = ba;
     403        unsigned long key[2] = {
     404                LOWER32(ba),
     405                UPPER32(ba)
     406        };
     407
    401408        int rc;
    402409       
     
    413420
    414421        fibril_mutex_lock(&cache->lock);
    415         l = hash_table_find(&cache->block_hash, &key);
     422        l = hash_table_find(&cache->block_hash, key);
    416423        if (l) {
    417424found:
     
    451458                         * Try to recycle a block from the free list.
    452459                         */
    453                         unsigned long temp_key;
    454460recycle:
    455461                        if (list_empty(&cache->free_list)) {
     
    499505                                        goto retry;
    500506                                }
    501                                 l = hash_table_find(&cache->block_hash, &key);
     507                                l = hash_table_find(&cache->block_hash, key);
    502508                                if (l) {
    503509                                        /*
     
    522528                         */
    523529                        list_remove(&b->free_link);
    524                         temp_key = b->lba;
    525                         hash_table_remove(&cache->block_hash, &temp_key, 1);
     530                        unsigned long temp_key[2] = {
     531                                LOWER32(b->lba),
     532                                UPPER32(b->lba)
     533                        };
     534                        hash_table_remove(&cache->block_hash, temp_key, 2);
    526535                }
    527536
     
    531540                b->lba = ba;
    532541                b->pba = ba_ltop(devcon, b->lba);
    533                 hash_table_insert(&cache->block_hash, &key, &b->hash_link);
     542                hash_table_insert(&cache->block_hash, key, &b->hash_link);
    534543
    535544                /*
     
    643652                         * Take the block out of the cache and free it.
    644653                         */
    645                         unsigned long key = block->lba;
    646                         hash_table_remove(&cache->block_hash, &key, 1);
     654                        unsigned long key[2] = {
     655                                LOWER32(block->lba),
     656                                UPPER32(block->lba)
     657                        };
     658                        hash_table_remove(&cache->block_hash, key, 2);
    647659                        fibril_mutex_unlock(&block->lock);
    648660                        free(block->data);
  • uspace/lib/c/generic/elf/elf_load.c

    rc936c7f r80e9e5e  
    7474static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
    7575
    76 /** Read until the buffer is read in its entirety. */
    77 static int my_read(int fd, void *buf, size_t len)
    78 {
    79         int cnt = 0;
    80         do {
    81                 buf += cnt;
    82                 len -= cnt;
    83                 cnt = read(fd, buf, len);
    84         } while ((cnt > 0) && ((len - cnt) > 0));
    85 
    86         return cnt;
    87 }
    88 
    8976/** Load ELF binary from a file.
    9077 *
     
    160147        int i, rc;
    161148
    162         rc = my_read(elf->fd, header, sizeof(elf_header_t));
    163         if (rc < 0) {
     149        rc = read_all(elf->fd, header, sizeof(elf_header_t));
     150        if (rc != sizeof(elf_header_t)) {
    164151                DPRINTF("Read error.\n");
    165152                return EE_INVALID;
     
    222209                        + i * sizeof(elf_segment_header_t), SEEK_SET);
    223210
    224                 rc = my_read(elf->fd, &segment_hdr,
     211                rc = read_all(elf->fd, &segment_hdr,
    225212                    sizeof(elf_segment_header_t));
    226                 if (rc < 0) {
     213                if (rc != sizeof(elf_segment_header_t)) {
    227214                        DPRINTF("Read error.\n");
    228215                        return EE_INVALID;
     
    244231                    + i * sizeof(elf_section_header_t), SEEK_SET);
    245232
    246                 rc = my_read(elf->fd, &section_hdr,
     233                rc = read_all(elf->fd, &section_hdr,
    247234                    sizeof(elf_section_header_t));
    248                 if (rc < 0) {
     235                if (rc != sizeof(elf_section_header_t)) {
    249236                        DPRINTF("Read error.\n");
    250237                        return EE_INVALID;
     
    334321        uintptr_t seg_addr;
    335322        size_t mem_sz;
    336         int rc;
     323        ssize_t rc;
    337324
    338325        bias = elf->bias;
     
    412399                if (now > left) now = left;
    413400
    414                 rc = my_read(elf->fd, dp, now);
    415 
    416                 if (rc < 0) {
     401                rc = read_all(elf->fd, dp, now);
     402
     403                if (rc != (ssize_t) now) {
    417404                        DPRINTF("Read error.\n");
    418405                        return EE_INVALID;
  • uspace/lib/c/generic/vfs/vfs.c

    rc936c7f r80e9e5e  
    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 */
     431ssize_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 */
     460ssize_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
    419481int fsync(int fildes)
    420482{
  • uspace/lib/c/include/unistd.h

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

    rc936c7f r80e9e5e  
    4545#include <mem.h>
    4646#include <sys/stat.h>
     47#include <stdlib.h>
    4748
    4849#define on_error(rc, action) \
     
    6162        } while (0)
    6263
     64static fs_reg_t reg;
     65
     66static vfs_out_ops_t *vfs_out_ops = NULL;
     67static libfs_ops_t *libfs_ops = NULL;
     68
     69static void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
     70static void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);
     71static void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t,
     72    ipc_call_t *);
     73static void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
     74static void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t,
     75    ipc_call_t *);
     76
     77static 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
     104static 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
     109static 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
     119static void vfs_out_unmount(ipc_callid_t rid, ipc_call_t *req)
     120{
     121               
     122        libfs_unmount(libfs_ops, rid, req);
     123}
     124
     125static 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
     130static 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
     147static 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
     165static 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
     178static 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
     189static 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
     200static 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
     205static 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
     210static 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
     221static 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
    63286/** Register file system server.
    64287 *
     
    68291 *
    69292 * @param sess Session for communication with VFS.
    70  * @param reg  File system registration structure. It will be
    71  *             initialized by this function.
    72293 * @param info VFS info structure supplied by the file system
    73294 *             implementation.
    74  * @param conn Connection fibril for handling all calls originating in
    75  *             VFS.
     295 * @param vops Address of the vfs_out_ops_t structure.
     296 * @param lops Address of the libfs_ops_t structure.
    76297 *
    77298 * @return EOK on success or a non-zero error code on errror.
    78299 *
    79300 */
    80 int fs_register(async_sess_t *sess, fs_reg_t *reg, vfs_info_t *info,
    81     async_client_conn_t conn)
     301int fs_register(async_sess_t *sess, vfs_info_t *info, vfs_out_ops_t *vops,
     302    libfs_ops_t *lops)
    82303{
    83304        /*
     
    104325       
    105326        /*
     327         * Set VFS_OUT and libfs operations.
     328         */
     329        vfs_out_ops = vops;
     330        libfs_ops = lops;
     331
     332        /*
    106333         * Ask VFS for callback connection.
    107334         */
    108         async_connect_to_me(exch, 0, 0, 0, conn, NULL);
     335        async_connect_to_me(exch, 0, 0, 0, vfs_connection, NULL);
    109336       
    110337        /*
    111338         * Allocate piece of address space for PLB.
    112339         */
    113         reg->plb_ro = as_get_mappable_page(PLB_SIZE);
    114         if (!reg->plb_ro) {
     340        reg.plb_ro = as_get_mappable_page(PLB_SIZE);
     341        if (!reg.plb_ro) {
    115342                async_exchange_end(exch);
    116343                async_wait_for(req, NULL);
     
    121348         * Request sharing the Path Lookup Buffer with VFS.
    122349         */
    123         rc = async_share_in_start_0_0(exch, reg->plb_ro, PLB_SIZE);
     350        rc = async_share_in_start_0_0(exch, reg.plb_ro, PLB_SIZE);
    124351       
    125352        async_exchange_end(exch);
     
    134361         */
    135362        async_wait_for(req, NULL);
    136         reg->fs_handle = (int) IPC_GET_ARG1(answer);
     363        reg.fs_handle = (int) IPC_GET_ARG1(answer);
    137364       
    138365        /*
     
    140367         * the same connection fibril as well.
    141368         */
    142         async_set_client_connection(conn);
     369        async_set_client_connection(vfs_connection);
    143370       
    144371        return IPC_GET_RETVAL(answer);
     
    151378
    152379void libfs_mount(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
    153     ipc_call_t *request)
    154 {
    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);
     380    ipc_call_t *req)
     381{
     382        devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     383        fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req);
     384        fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*req);
     385        devmap_handle_t mr_devmap_handle = (devmap_handle_t) IPC_GET_ARG4(*req);
    159386       
    160387        async_sess_t *mountee_sess = async_clone_receive(EXCHANGE_PARALLEL);
     
    208435         * Do not release the FS node so that it stays in memory.
    209436         */
    210         async_answer_3(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
    211             IPC_GET_ARG3(answer));
    212 }
    213 
    214 void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *request)
    215 {
    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);
     437        async_answer_4(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
     438            IPC_GET_ARG3(answer), IPC_GET_ARG4(answer));
     439}
     440
     441void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *req)
     442{
     443        devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     444        fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req);
    218445        fs_node_t *fn;
    219446        int res;
     
    259486}
    260487
     488static char plb_get_char(unsigned pos)
     489{
     490        return reg.plb_ro[pos % PLB_SIZE];
     491}
     492
    261493/** Lookup VFS triplet by name in the file system name space.
    262494 *
     
    273505 */
    274506void libfs_lookup(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
    275     ipc_call_t *request)
    276 {
    277         unsigned int first = IPC_GET_ARG1(*request);
    278         unsigned int last = IPC_GET_ARG2(*request);
     507    ipc_call_t *req)
     508{
     509        unsigned int first = IPC_GET_ARG1(*req);
     510        unsigned int last = IPC_GET_ARG2(*req);
    279511        unsigned int next = first;
    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);
     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);
    283515        char component[NAME_MAX + 1];
    284516        int len;
     
    298530                async_exch_t *exch = async_exchange_begin(cur->mp_data.sess);
    299531                async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last,
    300                     cur->mp_data.devmap_handle, lflag, index, IPC_FF_ROUTE_FROM_ME);
     532                    cur->mp_data.devmap_handle, lflag, index,
     533                    IPC_FF_ROUTE_FROM_ME);
    301534                async_exchange_end(exch);
    302535               
     
    306539       
    307540        /* Eat slash */
    308         if (ops->plb_get_char(next) == '/')
     541        if (plb_get_char(next) == '/')
    309542                next++;
    310543       
     
    319552                /* Collect the component */
    320553                len = 0;
    321                 while ((next <= last) && (ops->plb_get_char(next) != '/')) {
     554                while ((next <= last) && (plb_get_char(next) != '/')) {
    322555                        if (len + 1 == NAME_MAX) {
    323556                                /* Component length overflow */
     
    325558                                goto out;
    326559                        }
    327                         component[len++] = ops->plb_get_char(next);
     560                        component[len++] = plb_get_char(next);
    328561                        /* Process next character */
    329562                        next++;
     
    357590                       
    358591                        async_exch_t *exch = async_exchange_begin(tmp->mp_data.sess);
    359                         async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last,
    360                             tmp->mp_data.devmap_handle, lflag, index,
     592                        async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next,
     593                            last, tmp->mp_data.devmap_handle, lflag, index,
    361594                            IPC_FF_ROUTE_FROM_ME);
    362595                        async_exchange_end(exch);
     
    451684                        len = 0;
    452685                        while (next <= last) {
    453                                 if (ops->plb_get_char(next) == '/') {
     686                                if (plb_get_char(next) == '/') {
    454687                                        /* More than one component */
    455688                                        async_answer_0(rid, ENOENT);
     
    463696                                }
    464697                               
    465                                 component[len++] = ops->plb_get_char(next);
     698                                component[len++] = plb_get_char(next);
    466699                                /* Process next character */
    467700                                next++;
     
    637870        rc = ops->node_open(fn);
    638871        aoff64_t size = ops->size_get(fn);
    639         async_answer_4(rid, rc, LOWER32(size), UPPER32(size), ops->lnkcnt_get(fn),
     872        async_answer_4(rid, rc, LOWER32(size), UPPER32(size),
     873            ops->lnkcnt_get(fn),
    640874            (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0));
    641875       
  • uspace/lib/fs/libfs.h

    rc936c7f r80e9e5e  
    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
     57typedef struct {
    4558        bool mp_active;
    4659        async_sess_t *sess;
     
    7184        int (* has_children)(bool *, fs_node_t *);
    7285        /*
    73          * The second set of methods are usually mere getters that do not return
    74          * an integer error code.
     86         * The second set of methods are usually mere getters that do not
     87         * return an integer error code.
    7588         */
    7689        fs_index_t (* index_get)(fs_node_t *);
    7790        aoff64_t (* size_get)(fs_node_t *);
    7891        unsigned int (* lnkcnt_get)(fs_node_t *);
    79         char (* plb_get_char)(unsigned pos);
    8092        bool (* is_directory)(fs_node_t *);
    8193        bool (* is_file)(fs_node_t *);
     
    88100} fs_reg_t;
    89101
    90 extern int fs_register(async_sess_t *, fs_reg_t *, vfs_info_t *,
    91     async_client_conn_t);
     102extern int fs_register(async_sess_t *, vfs_info_t *, vfs_out_ops_t *,
     103    libfs_ops_t *);
    92104
    93105extern void fs_node_initialize(fs_node_t *);
    94 
    95 extern void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    96 extern void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);
    97 extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    98 extern void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    99 extern void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t,
    100     ipc_call_t *);
    101106
    102107#endif
  • uspace/lib/scsi/include/scsi/sbc.h

    rc936c7f r80e9e5e  
    5656};
    5757
     58/** SCSI Read (10) command */
     59typedef 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
    5874/** SCSI Read (12) command */
    5975typedef struct {
    6076        /** Operation code (SCSI_CMD_READ_12) */
    6177        uint8_t op_code;
    62         /** RdProtect, DPO, FUA, Reserved, FUA_NV, Reserved */
     78        /** RdProtect, DPO, FUA, Reserved, FUA_NV, Obsolete */
    6379        uint8_t flags;
    6480        /** Logical block address */
     
    115131} scsi_read_capacity_10_data_t;
    116132
     133/** SCSI Write (10) command */
     134typedef 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
    117149/** SCSI Write (12) command */
    118150typedef struct {
    119151        /** Operation code (SCSI_CMD_WRITE_12) */
    120152        uint8_t op_code;
    121         /** WrProtect, DPO, FUA, Reserved, FUA_NV, Reserved */
     153        /** WrProtect, DPO, FUA, Reserved, FUA_NV, Obsolete */
    122154        uint8_t flags;
    123155        /** Logical block address */
  • uspace/lib/scsi/include/scsi/spc.h

    rc936c7f r80e9e5e  
    179179        uint8_t additional_len;
    180180        /** Command-specific Information */
    181         uint8_t cmd_spec;
     181        uint32_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
     207        SCSI_SK_MISCOMPARE      = 0xe,
     208
     209        SCSI_SK_LIMIT           = 0x10
    208210};
    209211
    210212extern const char *scsi_dev_type_str[SCSI_DEV_LIMIT];
     213extern const char *scsi_sense_key_str[SCSI_SK_LIMIT];
     214
    211215extern const char *scsi_get_dev_type_str(unsigned);
     216extern const char *scsi_get_sense_key_str(unsigned);
    212217
    213218#endif
  • uspace/lib/scsi/src/spc.c

    rc936c7f r80e9e5e  
    4444};
    4545
     46const 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
    4663/** Get peripheral device type string.
    4764 *
     
    5370{
    5471        if (dev_type >= SCSI_DEV_LIMIT || scsi_dev_type_str[dev_type] == NULL)
    55                 return "<unknown>";
     72                return "Unknown";
    5673
    5774        return scsi_dev_type_str[dev_type];
    5875}
     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 */
     83const 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

    rc936c7f r80e9e5e  
    270270        }
    271271       
    272         ssize_t read_bytes = safe_read(fd, buf, len);
     272        ssize_t read_bytes = read_all(fd, buf, len);
    273273        if (read_bytes <= 0) {
    274                 log_msg(LVL_ERROR, "Unable to read file '%s'.", conf_path);
     274                log_msg(LVL_ERROR, "Unable to read file '%s' (%zd).", conf_path,
     275                    read_bytes);
    275276                goto cleanup;
    276277        }
     
    421422        }
    422423       
    423         insert_fun_node(tree, fun, clone_string(""), NULL);
     424        insert_fun_node(tree, fun, str_dup(""), NULL);
    424425        match_id_t *id = create_match_id();
    425         id->id = clone_string("root");
     426        id->id = str_dup("root");
    426427        id->score = 100;
    427428        add_match_id(&fun->match_ids, id);
  • uspace/srv/devman/util.c

    rc936c7f r80e9e5e  
    9191}
    9292
    93 char *clone_string(const char *s)
    94 {
    95         size_t size = str_size(s) + 1;
    96         char *str;
    97        
    98         str = (char *) malloc(size);
    99         if (str != NULL)
    100                 str_cpy(str, size, s);
    101         return str;
    102 }
    103 
    10493void replace_char(char *str, char orig, char repl)
    10594{
     
    111100}
    112101
    113 ssize_t safe_read(int fd, void *buffer, size_t size)
    114 {
    115         if (size == 0) {
    116                 return 0;
    117         }
    118 
    119         uint8_t *buf_ptr = (uint8_t *) buffer;
    120 
    121         size_t total_read = 0;
    122         while (total_read < size) {
    123                 ssize_t bytes_read = read(fd, buf_ptr, size - total_read);
    124                 if (bytes_read < 0) {
    125                         /* Error. */
    126                         return bytes_read;
    127                 } else if (bytes_read == 0) {
    128                         /* Possibly end of file. */
    129                         break;
    130                 } else {
    131                         /* Read at least something. */
    132                         buf_ptr += bytes_read;
    133                         total_read += bytes_read;
    134                 }
    135         }
    136 
    137         return (ssize_t) total_read;
    138 }
    139 
    140102/** @}
    141103 */
  • uspace/srv/devman/util.h

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

    rc936c7f r80e9e5e  
    5757};
    5858
    59 fs_reg_t devfs_reg;
    60 
    61 static void devfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    62 {
    63         if (iid)
    64                 async_answer_0(iid, EOK);
    65        
    66         while (true) {
    67                 ipc_call_t call;
    68                 ipc_callid_t callid = async_get_call(&call);
    69                
    70                 if (!IPC_GET_IMETHOD(call))
    71                         return;
    72                
    73                 switch (IPC_GET_IMETHOD(call)) {
    74                 case VFS_OUT_MOUNTED:
    75                         devfs_mounted(callid, &call);
    76                         break;
    77                 case VFS_OUT_MOUNT:
    78                         devfs_mount(callid, &call);
    79                         break;
    80                 case VFS_OUT_UNMOUNTED:
    81                         devfs_unmounted(callid, &call);
    82                         break;
    83                 case VFS_OUT_UNMOUNT:
    84                         devfs_unmount(callid, &call);
    85                         break;
    86                 case VFS_OUT_LOOKUP:
    87                         devfs_lookup(callid, &call);
    88                         break;
    89                 case VFS_OUT_OPEN_NODE:
    90                         devfs_open_node(callid, &call);
    91                         break;
    92                 case VFS_OUT_STAT:
    93                         devfs_stat(callid, &call);
    94                         break;
    95                 case VFS_OUT_READ:
    96                         devfs_read(callid, &call);
    97                         break;
    98                 case VFS_OUT_WRITE:
    99                         devfs_write(callid, &call);
    100                         break;
    101                 case VFS_OUT_TRUNCATE:
    102                         devfs_truncate(callid, &call);
    103                         break;
    104                 case VFS_OUT_CLOSE:
    105                         devfs_close(callid, &call);
    106                         break;
    107                 case VFS_OUT_SYNC:
    108                         devfs_sync(callid, &call);
    109                         break;
    110                 case VFS_OUT_DESTROY:
    111                         devfs_destroy(callid, &call);
    112                         break;
    113                 default:
    114                         async_answer_0(callid, ENOTSUP);
    115                         break;
    116                 }
    117         }
    118 }
    119 
    12059int main(int argc, char *argv[])
    12160{
     
    13473        }
    13574       
    136         int rc = fs_register(vfs_sess, &devfs_reg, &devfs_vfs_info,
    137             devfs_connection);
     75        int rc = fs_register(vfs_sess, &devfs_vfs_info, &devfs_ops,
     76            &devfs_libfs_ops);
    13877        if (rc != EOK) {
    13978                printf("%s: Failed to register file system (%d)\n", NAME, rc);
     
    15291 * @}
    15392 */
     93
  • uspace/srv/fs/devfs/devfs.h

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

    rc936c7f r80e9e5e  
    403403}
    404404
    405 static char devfs_plb_get_char(unsigned pos)
    406 {
    407         return devfs_reg.plb_ro[pos % PLB_SIZE];
    408 }
    409 
    410405static bool devfs_is_directory(fs_node_t *fn)
    411406{
     
    447442        .size_get = devfs_size_get,
    448443        .lnkcnt_get = devfs_lnkcnt_get,
    449         .plb_get_char = devfs_plb_get_char,
    450444        .is_directory = devfs_is_directory,
    451445        .is_file = devfs_is_file,
     
    462456}
    463457
    464 void devfs_mounted(ipc_callid_t rid, ipc_call_t *request)
    465 {
    466         char *opts;
    467        
    468         /* Accept the mount options */
    469         sysarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0,
    470             0, NULL);
    471         if (retval != EOK) {
    472                 async_answer_0(rid, retval);
    473                 return;
    474         }
    475        
    476         free(opts);
    477         async_answer_3(rid, EOK, 0, 0, 0);
    478 }
    479 
    480 void devfs_mount(ipc_callid_t rid, ipc_call_t *request)
    481 {
    482         libfs_mount(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
    483 }
    484 
    485 void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
    486 {
    487         async_answer_0(rid, ENOTSUP);
    488 }
    489 
    490 void devfs_unmount(ipc_callid_t rid, ipc_call_t *request)
    491 {
    492         libfs_unmount(&devfs_libfs_ops, rid, request);
    493 }
    494 
    495 void devfs_lookup(ipc_callid_t rid, ipc_call_t *request)
    496 {
    497         libfs_lookup(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
    498 }
    499 
    500 void devfs_open_node(ipc_callid_t rid, ipc_call_t *request)
    501 {
    502         libfs_open_node(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
    503 }
    504 
    505 void devfs_stat(ipc_callid_t rid, ipc_call_t *request)
    506 {
    507         libfs_stat(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
    508 }
    509 
    510 void devfs_read(ipc_callid_t rid, ipc_call_t *request)
    511 {
    512         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    513         aoff64_t pos =
    514             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    515        
     458static 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
     467static int devfs_unmounted(devmap_handle_t devmap_handle)
     468{
     469        return ENOTSUP;
     470}
     471
     472static int
     473devfs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     474    size_t *rbytes)
     475{
    516476        if (index == 0) {
    517477                ipc_callid_t callid;
     
    519479                if (!async_data_read_receive(&callid, &size)) {
    520480                        async_answer_0(callid, EINVAL);
    521                         async_answer_0(rid, EINVAL);
    522                         return;
     481                        return EINVAL;
    523482                }
    524483               
     
    540499                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    541500                        free(desc);
    542                         async_answer_1(rid, EOK, 1);
    543                         return;
     501                        *rbytes = 1;
     502                        return EOK;
    544503                }
    545504               
     
    555514                                async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    556515                                free(desc);
    557                                 async_answer_1(rid, EOK, 1);
    558                                 return;
     516                                *rbytes = 1;
     517                                return EOK;
    559518                        }
    560519                       
     
    563522               
    564523                async_answer_0(callid, ENOENT);
    565                 async_answer_1(rid, ENOENT, 0);
    566                 return;
     524                return ENOENT;
    567525        }
    568526       
     
    575533                if (!async_data_read_receive(&callid, &size)) {
    576534                        async_answer_0(callid, EINVAL);
    577                         async_answer_0(rid, EINVAL);
    578                         return;
     535                        return EINVAL;
    579536                }
    580537               
     
    585542                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    586543                        free(desc);
    587                         async_answer_1(rid, EOK, 1);
    588                         return;
     544                        *rbytes = 1;
     545                        return EOK;
    589546                }
    590547               
    591548                free(desc);
    592549                async_answer_0(callid, ENOENT);
    593                 async_answer_1(rid, ENOENT, 0);
    594                 return;
     550                return ENOENT;
    595551        }
    596552       
     
    606562                if (lnk == NULL) {
    607563                        fibril_mutex_unlock(&devices_mutex);
    608                         async_answer_0(rid, ENOENT);
    609                         return;
     564                        return ENOENT;
    610565                }
    611566               
     
    617572                        fibril_mutex_unlock(&devices_mutex);
    618573                        async_answer_0(callid, EINVAL);
    619                         async_answer_0(rid, EINVAL);
    620                         return;
     574                        return EINVAL;
    621575                }
    622576               
     
    625579               
    626580                ipc_call_t answer;
    627                 aid_t msg = async_send_3(exch, IPC_GET_IMETHOD(*request),
    628                     IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
    629                     IPC_GET_ARG3(*request), &answer);
     581                aid_t msg = async_send_4(exch, VFS_OUT_READ, devmap_handle,
     582                    index, LOWER32(pos), UPPER32(pos), &answer);
    630583               
    631584                /* Forward the IPC_M_DATA_READ request to the driver */
     
    639592                sysarg_t rc;
    640593                async_wait_for(msg, &rc);
    641                 size_t bytes = IPC_GET_ARG1(answer);
    642                
    643                 /* Driver reply is the final result of the whole operation */
    644                 async_answer_1(rid, rc, bytes);
    645                 return;
    646         }
    647        
    648         async_answer_0(rid, ENOENT);
    649 }
    650 
    651 void devfs_write(ipc_callid_t rid, ipc_call_t *request)
    652 {
    653         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    654         if (index == 0) {
    655                 async_answer_0(rid, ENOTSUP);
    656                 return;
    657         }
     594               
     595                *rbytes = IPC_GET_ARG1(answer);
     596                return rc;
     597        }
     598       
     599        return ENOENT;
     600}
     601
     602static int
     603devfs_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;
    658608       
    659609        devmap_handle_type_t type = devmap_handle_probe(index);
     
    661611        if (type == DEV_HANDLE_NAMESPACE) {
    662612                /* Namespace directory */
    663                 async_answer_0(rid, ENOTSUP);
    664                 return;
     613                return ENOTSUP;
    665614        }
    666615       
     
    675624                if (lnk == NULL) {
    676625                        fibril_mutex_unlock(&devices_mutex);
    677                         async_answer_0(rid, ENOENT);
    678                         return;
     626                        return ENOENT;
    679627                }
    680628               
     
    686634                        fibril_mutex_unlock(&devices_mutex);
    687635                        async_answer_0(callid, EINVAL);
    688                         async_answer_0(rid, EINVAL);
    689                         return;
     636                        return EINVAL;
    690637                }
    691638               
     
    694641               
    695642                ipc_call_t answer;
    696                 aid_t msg = async_send_3(exch, IPC_GET_IMETHOD(*request),
    697                     IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
    698                     IPC_GET_ARG3(*request), &answer);
     643                aid_t msg = async_send_4(exch, VFS_OUT_WRITE, devmap_handle,
     644                    index, LOWER32(pos), UPPER32(pos), &answer);
    699645               
    700646                /* Forward the IPC_M_DATA_WRITE request to the driver */
     
    708654                sysarg_t rc;
    709655                async_wait_for(msg, &rc);
    710                 size_t bytes = IPC_GET_ARG1(answer);
    711                
    712                 /* Driver reply is the final result of the whole operation */
    713                 async_answer_1(rid, rc, bytes);
    714                 return;
    715         }
    716        
    717         async_answer_0(rid, ENOENT);
    718 }
    719 
    720 void devfs_truncate(ipc_callid_t rid, ipc_call_t *request)
    721 {
    722         async_answer_0(rid, ENOTSUP);
    723 }
    724 
    725 void devfs_close(ipc_callid_t rid, ipc_call_t *request)
    726 {
    727         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    728        
    729         if (index == 0) {
    730                 async_answer_0(rid, EOK);
    731                 return;
    732         }
     656               
     657                *wbytes = IPC_GET_ARG1(answer);
     658                *nsize = 0;
     659                return rc;
     660        }
     661       
     662        return ENOENT;
     663}
     664
     665static int
     666devfs_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size)
     667{
     668        return ENOTSUP;
     669}
     670
     671static int devfs_close(devmap_handle_t devmap_handle, fs_index_t index)
     672{
     673        if (index == 0)
     674                return EOK;
    733675       
    734676        devmap_handle_type_t type = devmap_handle_probe(index);
     
    736678        if (type == DEV_HANDLE_NAMESPACE) {
    737679                /* Namespace directory */
    738                 async_answer_0(rid, EOK);
    739                 return;
     680                return EOK;
    740681        }
    741682       
     
    749690                if (lnk == NULL) {
    750691                        fibril_mutex_unlock(&devices_mutex);
    751                         async_answer_0(rid, ENOENT);
    752                         return;
     692                        return ENOENT;
    753693                }
    754694               
     
    764704                fibril_mutex_unlock(&devices_mutex);
    765705               
    766                 async_answer_0(rid, EOK);
    767                 return;
    768         }
    769        
    770         async_answer_0(rid, ENOENT);
    771 }
    772 
    773 void devfs_sync(ipc_callid_t rid, ipc_call_t *request)
    774 {
    775         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    776        
    777         if (index == 0) {
    778                 async_answer_0(rid, EOK);
    779                 return;
    780         }
     706                return EOK;
     707        }
     708       
     709        return ENOENT;
     710}
     711
     712static int devfs_sync(devmap_handle_t devmap_handle, fs_index_t index)
     713{
     714        if (index == 0)
     715                return EOK;
    781716       
    782717        devmap_handle_type_t type = devmap_handle_probe(index);
     
    784719        if (type == DEV_HANDLE_NAMESPACE) {
    785720                /* Namespace directory */
    786                 async_answer_0(rid, EOK);
    787                 return;
     721                return EOK;
    788722        }
    789723       
     
    797731                if (lnk == NULL) {
    798732                        fibril_mutex_unlock(&devices_mutex);
    799                         async_answer_0(rid, ENOENT);
    800                         return;
     733                        return ENOENT;
    801734                }
    802735               
     
    808741               
    809742                ipc_call_t answer;
    810                 aid_t msg = async_send_2(exch, IPC_GET_IMETHOD(*request),
    811                     IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer);
     743                aid_t msg = async_send_2(exch, VFS_OUT_SYNC, devmap_handle,
     744                    index, &answer);
    812745               
    813746                async_exchange_end(exch);
     
    819752                async_wait_for(msg, &rc);
    820753               
    821                 /* Driver reply is the final result of the whole operation */
    822                 async_answer_0(rid, rc);
    823                 return;
    824         }
    825        
    826         async_answer_0(rid, ENOENT);
    827 }
    828 
    829 void devfs_destroy(ipc_callid_t rid, ipc_call_t *request)
    830 {
    831         async_answer_0(rid, ENOTSUP);
    832 }
     754                return rc;
     755        }
     756       
     757        return  ENOENT;
     758}
     759
     760static int devfs_destroy(devmap_handle_t devmap_handle, fs_index_t index)
     761{
     762        return ENOTSUP;
     763}
     764
     765vfs_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};
    833775
    834776/**
  • uspace/srv/fs/devfs/devfs_ops.h

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

    rc936c7f r80e9e5e  
    11/*
    22 * Copyright (c) 2006 Martin Decky
    3  * Copyright (c) 2008 Jakub Jermar
    43 * Copyright (c) 2011 Martin Sucha
    54 * All rights reserved.
     
    5554};
    5655
    57 fs_reg_t ext2fs_reg;
    58 
    59 /**
    60  * This connection fibril processes VFS requests from VFS.
    61  *
    62  * In order to support simultaneous VFS requests, our design is as follows.
    63  * The connection fibril accepts VFS requests from VFS. If there is only one
    64  * instance of the fibril, VFS will need to serialize all VFS requests it sends
    65  * to EXT2FS. To overcome this bottleneck, VFS can send EXT2FS the IPC_M_CONNECT_ME_TO
    66  * call. In that case, a new connection fibril will be created, which in turn
    67  * will accept the call. Thus, a new phone will be opened for VFS.
    68  *
    69  * There are few issues with this arrangement. First, VFS can run out of
    70  * available phones. In that case, VFS can close some other phones or use one
    71  * phone for more serialized requests. Similarily, EXT2FS can refuse to duplicate
    72  * the connection. VFS should then just make use of already existing phones and
    73  * route its requests through them. To avoid paying the fibril creation price
    74  * upon each request, EXT2FS might want to keep the connections open after the
    75  * request has been completed.
    76  */
    77 static void ext2fs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    78 {
    79         if (iid) {
    80                 /*
    81                  * This only happens for connections opened by
    82                  * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
    83                  * created by IPC_M_CONNECT_TO_ME.
    84                  */
    85                 async_answer_0(iid, EOK);
    86         }
    87        
    88         dprintf(NAME ": connection opened\n");
    89         while (true) {
    90                 ipc_call_t call;
    91                 ipc_callid_t callid = async_get_call(&call);
    92                
    93                 if (!IPC_GET_IMETHOD(call))
    94                         return;
    95                
    96                 switch (IPC_GET_IMETHOD(call)) {
    97                 case VFS_OUT_MOUNTED:
    98                         ext2fs_mounted(callid, &call);
    99                         break;
    100                 case VFS_OUT_MOUNT:
    101                         ext2fs_mount(callid, &call);
    102                         break;
    103                 case VFS_OUT_UNMOUNTED:
    104                         ext2fs_unmounted(callid, &call);
    105                         break;
    106                 case VFS_OUT_UNMOUNT:
    107                         ext2fs_unmount(callid, &call);
    108                         break;
    109                 case VFS_OUT_LOOKUP:
    110                         ext2fs_lookup(callid, &call);
    111                         break;
    112                 case VFS_OUT_READ:
    113                         ext2fs_read(callid, &call);
    114                         break;
    115                 case VFS_OUT_WRITE:
    116                         ext2fs_write(callid, &call);
    117                         break;
    118                 case VFS_OUT_TRUNCATE:
    119                         ext2fs_truncate(callid, &call);
    120                         break;
    121                 case VFS_OUT_STAT:
    122                         ext2fs_stat(callid, &call);
    123                         break;
    124                 case VFS_OUT_CLOSE:
    125                         ext2fs_close(callid, &call);
    126                         break;
    127                 case VFS_OUT_DESTROY:
    128                         ext2fs_destroy(callid, &call);
    129                         break;
    130                 case VFS_OUT_OPEN_NODE:
    131                         ext2fs_open_node(callid, &call);
    132                         break;
    133                 case VFS_OUT_SYNC:
    134                         ext2fs_sync(callid, &call);
    135                         break;
    136                 default:
    137                         async_answer_0(callid, ENOTSUP);
    138                         break;
    139                 }
    140         }
    141 }
    142 
    14356int main(int argc, char **argv)
    14457{
     
    15871        }       
    15972               
    160         rc = fs_register(vfs_sess, &ext2fs_reg, &ext2fs_vfs_info, ext2fs_connection);
     73        rc = fs_register(vfs_sess, &ext2fs_vfs_info, &ext2fs_ops,
     74            &ext2fs_libfs_ops);
    16175        if (rc != EOK) {
    16276                fprintf(stdout, NAME ": Failed to register fs (%d)\n", rc);
  • uspace/srv/fs/ext2fs/ext2fs.h

    rc936c7f r80e9e5e  
    11/*
    2  * Copyright (c) 2008 Jakub Jermar
    32 * Copyright (c) 2011 Martin Sucha
    43 * All rights reserved.
     
    3635
    3736#include <libext2.h>
    38 #include <fibril_synch.h>
    3937#include <libfs.h>
    40 #include <atomic.h>
    4138#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
    4839
    4940#define min(a, b)               ((a) < (b) ? (a) : (b))
    5041
    51 extern fs_reg_t ext2fs_reg;
     42extern vfs_out_ops_t ext2fs_ops;
     43extern libfs_ops_t ext2fs_libfs_ops;
    5244
    5345extern int ext2fs_global_init(void);
    5446extern int ext2fs_global_fini(void);
    55 extern void ext2fs_mounted(ipc_callid_t, ipc_call_t *);
    56 extern void ext2fs_mount(ipc_callid_t, ipc_call_t *);
    57 extern void ext2fs_unmounted(ipc_callid_t, ipc_call_t *);
    58 extern void ext2fs_unmount(ipc_callid_t, ipc_call_t *);
    59 extern void ext2fs_lookup(ipc_callid_t, ipc_call_t *);
    60 extern void ext2fs_read(ipc_callid_t, ipc_call_t *);
    61 extern void ext2fs_write(ipc_callid_t, ipc_call_t *);
    62 extern void ext2fs_truncate(ipc_callid_t, ipc_call_t *);
    63 extern void ext2fs_stat(ipc_callid_t, ipc_call_t *);
    64 extern void ext2fs_close(ipc_callid_t, ipc_call_t *);
    65 extern void ext2fs_destroy(ipc_callid_t, ipc_call_t *);
    66 extern void ext2fs_open_node(ipc_callid_t, ipc_call_t *);
    67 extern void ext2fs_stat(ipc_callid_t, ipc_call_t *);
    68 extern void ext2fs_sync(ipc_callid_t, ipc_call_t *);
    6947
    7048#endif
  • uspace/srv/fs/ext2fs/ext2fs_ops.c

    rc936c7f r80e9e5e  
    11/*
    2  * Copyright (c) 2008 Jakub Jermar
    32 * Copyright (c) 2011 Martin Sucha
    43 * All rights reserved.
     
    8786 */
    8887static int ext2fs_instance_get(devmap_handle_t, ext2fs_instance_t **);
    89 static void ext2fs_read_directory(ipc_callid_t, ipc_callid_t, aoff64_t,
    90         size_t, ext2fs_instance_t *, ext2_inode_ref_t *);
    91 static void ext2fs_read_file(ipc_callid_t, ipc_callid_t, aoff64_t,
    92         size_t, ext2fs_instance_t *, ext2_inode_ref_t *);
     88static int ext2fs_read_directory(ipc_callid_t, aoff64_t, size_t,
     89    ext2fs_instance_t *, ext2_inode_ref_t *, size_t *);
     90static int ext2fs_read_file(ipc_callid_t, aoff64_t, size_t, ext2fs_instance_t *,
     91    ext2_inode_ref_t *, size_t *);
    9392static bool ext2fs_is_dots(const uint8_t *, size_t);
    9493static int ext2fs_node_get_core(fs_node_t **, ext2fs_instance_t *, fs_index_t);
     
    111110static aoff64_t ext2fs_size_get(fs_node_t *);
    112111static unsigned ext2fs_lnkcnt_get(fs_node_t *);
    113 static char ext2fs_plb_get_char(unsigned);
    114112static bool ext2fs_is_directory(fs_node_t *);
    115113static bool ext2fs_is_file(fs_node_t *node);
     
    538536        EXT2FS_DBG("%u", count);
    539537        return count;
    540 }
    541 
    542 char ext2fs_plb_get_char(unsigned pos)
    543 {
    544         return ext2fs_reg.plb_ro[pos % PLB_SIZE];
    545538}
    546539
     
    586579        .size_get = ext2fs_size_get,
    587580        .lnkcnt_get = ext2fs_lnkcnt_get,
    588         .plb_get_char = ext2fs_plb_get_char,
    589581        .is_directory = ext2fs_is_directory,
    590582        .is_file = ext2fs_is_file,
     
    596588 */
    597589
    598 void ext2fs_mounted(ipc_callid_t rid, ipc_call_t *request)
    599 {
    600         EXT2FS_DBG("");
    601         int rc;
    602         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     590static int ext2fs_mounted(devmap_handle_t devmap_handle, const char *opts,
     591   fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
     592{
     593        EXT2FS_DBG("");
     594        int rc;
    603595        ext2_filesystem_t *fs;
    604596        ext2fs_instance_t *inst;
    605597        bool read_only;
    606598       
    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        
    618599        /* Allocate libext2 filesystem structure */
    619600        fs = (ext2_filesystem_t *) malloc(sizeof(ext2_filesystem_t));
    620         if (fs == NULL) {
    621                 async_answer_0(rid, ENOMEM);
    622                 return;
    623         }
     601        if (fs == NULL)
     602                return ENOMEM;
    624603       
    625604        /* Allocate instance structure */
     
    627606        if (inst == NULL) {
    628607                free(fs);
    629                 async_answer_0(rid, ENOMEM);
    630                 return;
     608                return ENOMEM;
    631609        }
    632610       
     
    636614                free(fs);
    637615                free(inst);
    638                 async_answer_0(rid, rc);
    639                 return;
     616                return rc;
    640617        }
    641618       
     
    646623                free(fs);
    647624                free(inst);
    648                 async_answer_0(rid, rc);
    649                 return;
     625                return rc;
    650626        }
    651627       
     
    656632                free(fs);
    657633                free(inst);
    658                 async_answer_0(rid, rc);
    659                 return;
     634                return rc;
    660635        }
    661636       
     
    673648                free(fs);
    674649                free(inst);
    675                 async_answer_0(rid, rc);
    676                 return;
     650                return rc;
    677651        }
    678652        ext2fs_node_t *enode = EXT2FS_NODE(root_node);
     
    683657        fibril_mutex_unlock(&instance_list_mutex);
    684658       
    685         async_answer_3(rid, EOK,
    686             EXT2_INODE_ROOT_INDEX,
    687             0,
    688             ext2_inode_get_usage_count(enode->inode_ref->inode));
     659        *index = EXT2_INODE_ROOT_INDEX;
     660        *size = 0;
     661        *lnkcnt = ext2_inode_get_usage_count(enode->inode_ref->inode);
    689662       
    690663        ext2fs_node_put(root_node);
    691 }
    692 
    693 void ext2fs_mount(ipc_callid_t rid, ipc_call_t *request)
    694 {
    695         EXT2FS_DBG("");
    696         libfs_mount(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request);
    697 }
    698 
    699 void ext2fs_unmounted(ipc_callid_t rid, ipc_call_t *request)
    700 {
    701         EXT2FS_DBG("");
    702         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     664
     665        return EOK;
     666}
     667
     668static int ext2fs_unmounted(devmap_handle_t devmap_handle)
     669{
     670        EXT2FS_DBG("");
    703671        ext2fs_instance_t *inst;
    704672        int rc;
     
    706674        rc = ext2fs_instance_get(devmap_handle, &inst);
    707675       
    708         if (rc != EOK) {
    709                 async_answer_0(rid, rc);
    710                 return;
    711         }
     676        if (rc != EOK)
     677                return rc;
    712678       
    713679        fibril_mutex_lock(&open_nodes_lock);
     
    716682        if (inst->open_nodes_count != 0) {
    717683                fibril_mutex_unlock(&open_nodes_lock);
    718                 async_answer_0(rid, EBUSY);
    719                 return;
     684                return EBUSY;
    720685        }
    721686       
     
    729694        ext2_filesystem_fini(inst->filesystem);
    730695       
    731         async_answer_0(rid, EOK);
    732 }
    733 
    734 void ext2fs_unmount(ipc_callid_t rid, ipc_call_t *request)
    735 {
    736         EXT2FS_DBG("");
    737         libfs_unmount(&ext2fs_libfs_ops, rid, request);
    738 }
    739 
    740 void ext2fs_lookup(ipc_callid_t rid, ipc_call_t *request)
    741 {
    742         EXT2FS_DBG("");
    743         libfs_lookup(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request);
    744 }
    745 
    746 void ext2fs_read(ipc_callid_t rid, ipc_call_t *request)
    747 {
    748         EXT2FS_DBG("");
    749         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    750         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    751         aoff64_t pos =
    752             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     696        return EOK;
     697}
     698
     699static int
     700ext2fs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     701    size_t *rbytes)
     702{
     703        EXT2FS_DBG("");
    753704       
    754705        ext2fs_instance_t *inst;
     
    763714        if (!async_data_read_receive(&callid, &size)) {
    764715                async_answer_0(callid, EINVAL);
    765                 async_answer_0(rid, EINVAL);
    766                 return;
     716                return EINVAL;
    767717        }
    768718       
     
    770720        if (rc != EOK) {
    771721                async_answer_0(callid, rc);
    772                 async_answer_0(rid, rc);
    773                 return;
     722                return rc;
    774723        }
    775724       
     
    777726        if (rc != EOK) {
    778727                async_answer_0(callid, rc);
    779                 async_answer_0(rid, rc);
    780                 return;
     728                return rc;
    781729        }
    782730       
    783731        if (ext2_inode_is_type(inst->filesystem->superblock, inode_ref->inode,
    784                     EXT2_INODE_MODE_FILE)) {
    785                 ext2fs_read_file(rid, callid, pos, size, inst, inode_ref);
    786         }
    787         else if (ext2_inode_is_type(inst->filesystem->superblock, inode_ref->inode,
    788                     EXT2_INODE_MODE_DIRECTORY)) {
    789                 ext2fs_read_directory(rid, callid, pos, size, inst, inode_ref);
    790         }
    791         else {
     732            EXT2_INODE_MODE_FILE)) {
     733                rc = ext2fs_read_file(callid, pos, size, inst, inode_ref,
     734                    rbytes);
     735        } else if (ext2_inode_is_type(inst->filesystem->superblock,
     736            inode_ref->inode, EXT2_INODE_MODE_DIRECTORY)) {
     737                rc = ext2fs_read_directory(callid, pos, size, inst, inode_ref,
     738                    rbytes);
     739        } else {
    792740                /* Other inode types not supported */
    793741                async_answer_0(callid, ENOTSUP);
    794                 async_answer_0(rid, ENOTSUP);
     742                rc = ENOTSUP;
    795743        }
    796744       
    797745        ext2_filesystem_put_inode_ref(inode_ref);
    798746       
     747        return rc;
    799748}
    800749
     
    814763}
    815764
    816 void ext2fs_read_directory(ipc_callid_t rid, ipc_callid_t callid, aoff64_t pos,
    817         size_t size, ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref)
     765int 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)
    818767{
    819768        ext2_directory_iterator_t it;
     
    827776        if (rc != EOK) {
    828777                async_answer_0(callid, rc);
    829                 async_answer_0(rid, rc);
    830                 return;
     778                return rc;
    831779        }
    832780       
     
    841789               
    842790                name_size = ext2_directory_entry_ll_get_name_length(
    843                         inst->filesystem->superblock, it.current);
     791                    inst->filesystem->superblock, it.current);
    844792               
    845793                /* skip . and .. */
     
    849797               
    850798                /* The on-disk entry does not contain \0 at the end
    851                         * end of entry name, so we copy it to new buffer
    852                         * and add the \0 at the end
    853                         */
     799                 * end of entry name, so we copy it to new buffer
     800                 * and add the \0 at the end
     801                 */
    854802                buf = malloc(name_size+1);
    855803                if (buf == NULL) {
    856804                        ext2_directory_iterator_fini(&it);
    857805                        async_answer_0(callid, ENOMEM);
    858                         async_answer_0(rid, ENOMEM);
    859                         return;
     806                        return ENOMEM;
    860807                }
    861808                memcpy(buf, &it.current->name, name_size);
    862                 *(buf+name_size) = 0;
     809                *(buf + name_size) = 0;
    863810                found = true;
    864                 (void) async_data_read_finalize(callid, buf, name_size+1);
     811                (void) async_data_read_finalize(callid, buf, name_size + 1);
    865812                free(buf);
    866813                break;
     
    871818                        ext2_directory_iterator_fini(&it);
    872819                        async_answer_0(callid, rc);
    873                         async_answer_0(rid, rc);
    874                         return;
     820                        return rc;
    875821                }
    876822        }
     
    878824        if (found) {
    879825                rc = ext2_directory_iterator_next(&it);
    880                 if (rc != EOK) {
    881                         async_answer_0(rid, rc);
    882                         return;
    883                 }
     826                if (rc != EOK)
     827                        return rc;
    884828                next = it.current_offset;
    885829        }
    886830       
    887831        rc = ext2_directory_iterator_fini(&it);
    888         if (rc != EOK) {
    889                 async_answer_0(rid, rc);
    890                 return;
    891         }
     832        if (rc != EOK)
     833                return rc;
    892834       
    893835        if (found) {
    894                 async_answer_1(rid, EOK, next-pos);
    895         }
    896         else {
     836                *rbytes = next - pos;
     837                return EOK;
     838        } else {
    897839                async_answer_0(callid, ENOENT);
    898                 async_answer_0(rid, ENOENT);
    899         }
    900 }
    901 
    902 void ext2fs_read_file(ipc_callid_t rid, ipc_callid_t callid, aoff64_t pos,
    903         size_t size, ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref)
     840                return ENOENT;
     841        }
     842}
     843
     844int 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)
    904846{
    905847        int rc;
     
    919861                /* Read 0 bytes successfully */
    920862                async_data_read_finalize(callid, NULL, 0);
    921                 async_answer_1(rid, EOK, 0);
    922                 return;
     863                *rbytes = 0;
     864                return EOK;
    923865        }
    924866       
     
    939881        if (rc != EOK) {
    940882                async_answer_0(callid, rc);
    941                 async_answer_0(rid, rc);
    942                 return;
     883                return rc;
    943884        }
    944885       
     
    952893                if (buffer == NULL) {
    953894                        async_answer_0(callid, ENOMEM);
    954                         async_answer_0(rid, ENOMEM);
    955                         return;
     895                        return ENOMEM;
    956896                }
    957897               
     
    959899               
    960900                async_data_read_finalize(callid, buffer, bytes);
    961                 async_answer_1(rid, EOK, bytes);
     901                *rbytes = bytes;
    962902               
    963903                free(buffer);
    964904               
    965                 return;
     905                return EOK;
    966906        }
    967907       
     
    970910        if (rc != EOK) {
    971911                async_answer_0(callid, rc);
    972                 async_answer_0(rid, rc);
    973                 return;
     912                return rc;
    974913        }
    975914       
     
    978917       
    979918        rc = block_put(block);
    980         if (rc != EOK) {
    981                 async_answer_0(rid, rc);
    982                 return;
    983         }
    984                
    985         async_answer_1(rid, EOK, bytes);
    986 }
    987 
    988 void ext2fs_write(ipc_callid_t rid, ipc_call_t *request)
    989 {
    990         EXT2FS_DBG("");
    991 //      devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    992 //      fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    993 //      aoff64_t pos =
    994 //          (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    995        
    996         // TODO
    997         async_answer_0(rid, ENOTSUP);
    998 }
    999 
    1000 void ext2fs_truncate(ipc_callid_t rid, ipc_call_t *request)
    1001 {
    1002         EXT2FS_DBG("");
    1003 //      devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1004 //      fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1005 //      aoff64_t size =
    1006 //          (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    1007        
    1008         // TODO
    1009         async_answer_0(rid, ENOTSUP);
    1010 }
    1011 
    1012 void ext2fs_close(ipc_callid_t rid, ipc_call_t *request)
    1013 {
    1014         EXT2FS_DBG("");
    1015         async_answer_0(rid, EOK);
    1016 }
    1017 
    1018 void ext2fs_destroy(ipc_callid_t rid, ipc_call_t *request)
    1019 {
    1020         EXT2FS_DBG("");
    1021 //      devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request);
    1022 //      fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    1023        
    1024         // TODO
    1025         async_answer_0(rid, ENOTSUP);
    1026 }
    1027 
    1028 void ext2fs_open_node(ipc_callid_t rid, ipc_call_t *request)
    1029 {
    1030         EXT2FS_DBG("");
    1031         libfs_open_node(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request);
    1032 }
    1033 
    1034 void ext2fs_stat(ipc_callid_t rid, ipc_call_t *request)
    1035 {
    1036         EXT2FS_DBG("");
    1037         libfs_stat(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request);
    1038 }
    1039 
    1040 void ext2fs_sync(ipc_callid_t rid, ipc_call_t *request)
    1041 {
    1042         EXT2FS_DBG("");
    1043 //      devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1044 //      fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1045        
    1046         // TODO
    1047         async_answer_0(rid, ENOTSUP);
    1048 }
     919        if (rc != EOK)
     920                return rc;
     921       
     922        *rbytes = bytes;
     923        return EOK;
     924}
     925
     926static int
     927ext2fs_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
     934static int
     935ext2fs_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size)
     936{
     937        EXT2FS_DBG("");
     938        return ENOTSUP;
     939}
     940
     941static int ext2fs_close(devmap_handle_t devmap_handle, fs_index_t index)
     942{
     943        EXT2FS_DBG("");
     944        return EOK;
     945}
     946
     947static int ext2fs_destroy(devmap_handle_t devmap_handle, fs_index_t index)
     948{
     949        EXT2FS_DBG("");
     950        return ENOTSUP;
     951}
     952
     953static int ext2fs_sync(devmap_handle_t devmap_handle, fs_index_t index)
     954{
     955        EXT2FS_DBG("");
     956        return ENOTSUP;
     957}
     958
     959vfs_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};
    1049969
    1050970/**
    1051971 * @}
    1052972 */
     973
  • uspace/srv/fs/fat/fat.c

    rc936c7f r80e9e5e  
    5656};
    5757
    58 fs_reg_t fat_reg;
    59 
    60 /**
    61  * This connection fibril processes VFS requests from VFS.
    62  *
    63  * In order to support simultaneous VFS requests, our design is as follows.
    64  * The connection fibril accepts VFS requests from VFS. If there is only one
    65  * instance of the fibril, VFS will need to serialize all VFS requests it sends
    66  * to FAT. To overcome this bottleneck, VFS can send FAT the IPC_M_CONNECT_ME_TO
    67  * call. In that case, a new connection fibril will be created, which in turn
    68  * will accept the call. Thus, a new phone will be opened for VFS.
    69  *
    70  * There are few issues with this arrangement. First, VFS can run out of
    71  * available phones. In that case, VFS can close some other phones or use one
    72  * phone for more serialized requests. Similarily, FAT can refuse to duplicate
    73  * the connection. VFS should then just make use of already existing phones and
    74  * route its requests through them. To avoid paying the fibril creation price
    75  * upon each request, FAT might want to keep the connections open after the
    76  * request has been completed.
    77  */
    78 static void fat_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    79 {
    80         if (iid) {
    81                 /*
    82                  * This only happens for connections opened by
    83                  * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
    84                  * created by IPC_M_CONNECT_TO_ME.
    85                  */
    86                 async_answer_0(iid, EOK);
    87         }
    88        
    89         dprintf(NAME ": connection opened\n");
    90        
    91         while (true) {
    92                 ipc_call_t call;
    93                 ipc_callid_t callid = async_get_call(&call);
    94                
    95                 if (!IPC_GET_IMETHOD(call))
    96                         return;
    97                
    98                 switch (IPC_GET_IMETHOD(call)) {
    99                 case VFS_OUT_MOUNTED:
    100                         fat_mounted(callid, &call);
    101                         break;
    102                 case VFS_OUT_MOUNT:
    103                         fat_mount(callid, &call);
    104                         break;
    105                 case VFS_OUT_UNMOUNTED:
    106                         fat_unmounted(callid, &call);
    107                         break;
    108                 case VFS_OUT_UNMOUNT:
    109                         fat_unmount(callid, &call);
    110                         break;
    111                 case VFS_OUT_LOOKUP:
    112                         fat_lookup(callid, &call);
    113                         break;
    114                 case VFS_OUT_READ:
    115                         fat_read(callid, &call);
    116                         break;
    117                 case VFS_OUT_WRITE:
    118                         fat_write(callid, &call);
    119                         break;
    120                 case VFS_OUT_TRUNCATE:
    121                         fat_truncate(callid, &call);
    122                         break;
    123                 case VFS_OUT_STAT:
    124                         fat_stat(callid, &call);
    125                         break;
    126                 case VFS_OUT_CLOSE:
    127                         fat_close(callid, &call);
    128                         break;
    129                 case VFS_OUT_DESTROY:
    130                         fat_destroy(callid, &call);
    131                         break;
    132                 case VFS_OUT_OPEN_NODE:
    133                         fat_open_node(callid, &call);
    134                         break;
    135                 case VFS_OUT_SYNC:
    136                         fat_sync(callid, &call);
    137                         break;
    138                 default:
    139                         async_answer_0(callid, ENOTSUP);
    140                         break;
    141                 }
    142         }
    143 }
    144 
    14558int main(int argc, char **argv)
    14659{
     
    15871        }
    15972       
    160         rc = fs_register(vfs_sess, &fat_reg, &fat_vfs_info, fat_connection);
     73        rc = fs_register(vfs_sess, &fat_vfs_info, &fat_ops, &fat_libfs_ops);
    16174        if (rc != EOK) {
    16275                fat_idx_fini();
  • uspace/srv/fs/fat/fat.h

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

    rc936c7f r80e9e5e  
    8585static aoff64_t fat_size_get(fs_node_t *);
    8686static unsigned fat_lnkcnt_get(fs_node_t *);
    87 static char fat_plb_get_char(unsigned);
    8887static bool fat_is_directory(fs_node_t *);
    8988static bool fat_is_file(fs_node_t *node);
     
    901900}
    902901
    903 char fat_plb_get_char(unsigned pos)
    904 {
    905         return fat_reg.plb_ro[pos % PLB_SIZE];
    906 }
    907 
    908902bool fat_is_directory(fs_node_t *fn)
    909903{
     
    936930        .size_get = fat_size_get,
    937931        .lnkcnt_get = fat_lnkcnt_get,
    938         .plb_get_char = fat_plb_get_char,
    939932        .is_directory = fat_is_directory,
    940933        .is_file = fat_is_file,
     
    943936
    944937/*
    945  * VFS operations.
     938 * FAT VFS_OUT operations.
    946939 */
    947940
    948 void fat_mounted(ipc_callid_t rid, ipc_call_t *request)
    949 {
    950         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     941static int
     942fat_mounted(devmap_handle_t devmap_handle, const char *opts, fs_index_t *index,
     943    aoff64_t *size, unsigned *linkcnt)
     944{
    951945        enum cache_mode cmode;
    952946        fat_bs_t *bs;
    953        
    954         /* Accept the mount options */
    955         char *opts;
    956         int rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
    957        
    958         if (rc != EOK) {
    959                 async_answer_0(rid, rc);
    960                 return;
    961         }
    962 
     947        int rc;
     948       
    963949        /* Check for option enabling write through. */
    964950        if (str_cmp(opts, "wtcache") == 0)
     
    967953                cmode = CACHE_MODE_WB;
    968954
    969         free(opts);
    970 
    971955        /* initialize libblock */
    972956        rc = block_init(EXCHANGE_SERIALIZE, devmap_handle, BS_SIZE);
    973         if (rc != EOK) {
    974                 async_answer_0(rid, rc);
    975                 return;
    976         }
     957        if (rc != EOK)
     958                return rc;
    977959
    978960        /* prepare the boot block */
     
    980962        if (rc != EOK) {
    981963                block_fini(devmap_handle);
    982                 async_answer_0(rid, rc);
    983                 return;
     964                return rc;
    984965        }
    985966
     
    989970        if (BPS(bs) != BS_SIZE) {
    990971                block_fini(devmap_handle);
    991                 async_answer_0(rid, ENOTSUP);
    992                 return;
     972                return ENOTSUP;
    993973        }
    994974
     
    997977        if (rc != EOK) {
    998978                block_fini(devmap_handle);
    999                 async_answer_0(rid, rc);
    1000                 return;
     979                return rc;
    1001980        }
    1002981
     
    1006985                (void) block_cache_fini(devmap_handle);
    1007986                block_fini(devmap_handle);
    1008                 async_answer_0(rid, rc);
    1009                 return;
     987                return rc;
    1010988        }
    1011989
     
    1014992                (void) block_cache_fini(devmap_handle);
    1015993                block_fini(devmap_handle);
    1016                 async_answer_0(rid, rc);
    1017                 return;
     994                return rc;
    1018995        }
    1019996
     
    10241001                block_fini(devmap_handle);
    10251002                fat_idx_fini_by_devmap_handle(devmap_handle);
    1026                 async_answer_0(rid, ENOMEM);
    1027                 return;
     1003                return ENOMEM;
    10281004        }
    10291005        fs_node_initialize(rfn);
     
    10341010                block_fini(devmap_handle);
    10351011                fat_idx_fini_by_devmap_handle(devmap_handle);
    1036                 async_answer_0(rid, ENOMEM);
    1037                 return;
     1012                return ENOMEM;
    10381013        }
    10391014        fat_node_initialize(rootp);
     
    10461021                block_fini(devmap_handle);
    10471022                fat_idx_fini_by_devmap_handle(devmap_handle);
    1048                 async_answer_0(rid, ENOMEM);
    1049                 return;
     1023                return ENOMEM;
    10501024        }
    10511025        assert(ridxp->index == 0);
     
    10641038        fibril_mutex_unlock(&ridxp->lock);
    10651039
    1066         async_answer_3(rid, EOK, ridxp->index, rootp->size, rootp->lnkcnt);
    1067 }
    1068 
    1069 void fat_mount(ipc_callid_t rid, ipc_call_t *request)
    1070 {
    1071         libfs_mount(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1072 }
    1073 
    1074 void fat_unmounted(ipc_callid_t rid, ipc_call_t *request)
    1075 {
    1076         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     1040        *index = ridxp->index;
     1041        *size = rootp->size;
     1042        *linkcnt = rootp->lnkcnt;
     1043
     1044        return EOK;
     1045}
     1046
     1047static int fat_unmounted(devmap_handle_t devmap_handle)
     1048{
    10771049        fs_node_t *fn;
    10781050        fat_node_t *nodep;
     
    10801052
    10811053        rc = fat_root_get(&fn, devmap_handle);
    1082         if (rc != EOK) {
    1083                 async_answer_0(rid, rc);
    1084                 return;
    1085         }
     1054        if (rc != EOK)
     1055                return rc;
    10861056        nodep = FAT_NODE(fn);
    10871057
     
    10921062        if (nodep->refcnt != 2) {
    10931063                (void) fat_node_put(fn);
    1094                 async_answer_0(rid, EBUSY);
    1095                 return;
     1064                return EBUSY;
    10961065        }
    10971066       
     
    11121081        block_fini(devmap_handle);
    11131082
    1114         async_answer_0(rid, EOK);
    1115 }
    1116 
    1117 void fat_unmount(ipc_callid_t rid, ipc_call_t *request)
    1118 {
    1119         libfs_unmount(&fat_libfs_ops, rid, request);
    1120 }
    1121 
    1122 void fat_lookup(ipc_callid_t rid, ipc_call_t *request)
    1123 {
    1124         libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1125 }
    1126 
    1127 void fat_read(ipc_callid_t rid, ipc_call_t *request)
    1128 {
    1129         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1130         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1131         aoff64_t pos =
    1132             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     1083        return EOK;
     1084}
     1085
     1086static int
     1087fat_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     1088    size_t *rbytes)
     1089{
    11331090        fs_node_t *fn;
    11341091        fat_node_t *nodep;
     
    11391096
    11401097        rc = fat_node_get(&fn, devmap_handle, index);
    1141         if (rc != EOK) {
    1142                 async_answer_0(rid, rc);
    1143                 return;
    1144         }
    1145         if (!fn) {
    1146                 async_answer_0(rid, ENOENT);
    1147                 return;
    1148         }
     1098        if (rc != EOK)
     1099                return rc;
     1100        if (!fn)
     1101                return ENOENT;
    11491102        nodep = FAT_NODE(fn);
    11501103
     
    11541107                fat_node_put(fn);
    11551108                async_answer_0(callid, EINVAL);
    1156                 async_answer_0(rid, EINVAL);
    1157                 return;
     1109                return EINVAL;
    11581110        }
    11591111
     
    11781130                                fat_node_put(fn);
    11791131                                async_answer_0(callid, rc);
    1180                                 async_answer_0(rid, rc);
    1181                                 return;
     1132                                return rc;
    11821133                        }
    11831134                        (void) async_data_read_finalize(callid,
     
    11861137                        if (rc != EOK) {
    11871138                                fat_node_put(fn);
    1188                                 async_answer_0(rid, rc);
    1189                                 return;
     1139                                return rc;
    11901140                        }
    11911141                }
     
    12441194                rc = fat_node_put(fn);
    12451195                async_answer_0(callid, rc != EOK ? rc : ENOENT);
    1246                 async_answer_1(rid, rc != EOK ? rc : ENOENT, 0);
    1247                 return;
     1196                *rbytes = 0;
     1197                return rc != EOK ? rc : ENOENT;
    12481198
    12491199err:
    12501200                (void) fat_node_put(fn);
    12511201                async_answer_0(callid, rc);
    1252                 async_answer_0(rid, rc);
    1253                 return;
     1202                return rc;
    12541203
    12551204hit:
     
    12591208
    12601209        rc = fat_node_put(fn);
    1261         async_answer_1(rid, rc, (sysarg_t)bytes);
    1262 }
    1263 
    1264 void fat_write(ipc_callid_t rid, ipc_call_t *request)
    1265 {
    1266         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1267         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1268         aoff64_t pos =
    1269             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     1210        *rbytes = bytes;
     1211        return rc;
     1212}
     1213
     1214static int
     1215fat_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     1216    size_t *wbytes, aoff64_t *nsize)
     1217{
    12701218        fs_node_t *fn;
    12711219        fat_node_t *nodep;
    12721220        fat_bs_t *bs;
    1273         size_t bytes, size;
     1221        size_t bytes;
    12741222        block_t *b;
    12751223        aoff64_t boundary;
     
    12781226       
    12791227        rc = fat_node_get(&fn, devmap_handle, index);
    1280         if (rc != EOK) {
    1281                 async_answer_0(rid, rc);
    1282                 return;
    1283         }
    1284         if (!fn) {
    1285                 async_answer_0(rid, ENOENT);
    1286                 return;
    1287         }
     1228        if (rc != EOK)
     1229                return rc;
     1230        if (!fn)
     1231                return ENOENT;
    12881232        nodep = FAT_NODE(fn);
    12891233       
     
    12931237                (void) fat_node_put(fn);
    12941238                async_answer_0(callid, EINVAL);
    1295                 async_answer_0(rid, EINVAL);
    1296                 return;
     1239                return EINVAL;
    12971240        }
    12981241
     
    13221265                        (void) fat_node_put(fn);
    13231266                        async_answer_0(callid, rc);
    1324                         async_answer_0(rid, rc);
    1325                         return;
     1267                        return rc;
    13261268                }
    13271269                rc = fat_block_get(&b, bs, nodep, pos / BPS(bs), flags);
     
    13291271                        (void) fat_node_put(fn);
    13301272                        async_answer_0(callid, rc);
    1331                         async_answer_0(rid, rc);
    1332                         return;
     1273                        return rc;
    13331274                }
    13341275                (void) async_data_write_finalize(callid,
     
    13381279                if (rc != EOK) {
    13391280                        (void) fat_node_put(fn);
    1340                         async_answer_0(rid, rc);
    1341                         return;
     1281                        return rc;
    13421282                }
    13431283                if (pos + bytes > nodep->size) {
     
    13451285                        nodep->dirty = true;    /* need to sync node */
    13461286                }
    1347                 size = nodep->size;
     1287                *wbytes = bytes;
     1288                *nsize = nodep->size;
    13481289                rc = fat_node_put(fn);
    1349                 async_answer_2(rid, rc, bytes, nodep->size);
    1350                 return;
     1290                return rc;
    13511291        } else {
    13521292                /*
     
    13641304                        (void) fat_node_put(fn);
    13651305                        async_answer_0(callid, rc);
    1366                         async_answer_0(rid, rc);
    1367                         return;
     1306                        return rc;
    13681307                }
    13691308                /* zero fill any gaps */
     
    13731312                        (void) fat_node_put(fn);
    13741313                        async_answer_0(callid, rc);
    1375                         async_answer_0(rid, rc);
    1376                         return;
     1314                        return rc;
    13771315                }
    13781316                rc = _fat_block_get(&b, bs, devmap_handle, lcl, NULL,
     
    13821320                        (void) fat_node_put(fn);
    13831321                        async_answer_0(callid, rc);
    1384                         async_answer_0(rid, rc);
    1385                         return;
     1322                        return rc;
    13861323                }
    13871324                (void) async_data_write_finalize(callid,
     
    13921329                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    13931330                        (void) fat_node_put(fn);
    1394                         async_answer_0(rid, rc);
    1395                         return;
     1331                        return rc;
    13961332                }
    13971333                /*
     
    14031339                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    14041340                        (void) fat_node_put(fn);
    1405                         async_answer_0(rid, rc);
    1406                         return;
    1407                 }
    1408                 nodep->size = size = pos + bytes;
     1341                        return rc;
     1342                }
     1343                *nsize = nodep->size = pos + bytes;
     1344                rc = fat_node_put(fn);
    14091345                nodep->dirty = true;            /* need to sync node */
    1410                 rc = fat_node_put(fn);
    1411                 async_answer_2(rid, rc, bytes, size);
    1412                 return;
    1413         }
    1414 }
    1415 
    1416 void fat_truncate(ipc_callid_t rid, ipc_call_t *request)
    1417 {
    1418         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1419         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1420         aoff64_t size =
    1421             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     1346                *wbytes = bytes;
     1347                return rc;
     1348        }
     1349}
     1350
     1351static int
     1352fat_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size)
     1353{
    14221354        fs_node_t *fn;
    14231355        fat_node_t *nodep;
     
    14261358
    14271359        rc = fat_node_get(&fn, devmap_handle, index);
    1428         if (rc != EOK) {
    1429                 async_answer_0(rid, rc);
    1430                 return;
    1431         }
    1432         if (!fn) {
    1433                 async_answer_0(rid, ENOENT);
    1434                 return;
    1435         }
     1360        if (rc != EOK)
     1361                return rc;
     1362        if (!fn)
     1363                return ENOENT;
    14361364        nodep = FAT_NODE(fn);
    14371365
     
    14771405out:
    14781406        fat_node_put(fn);
    1479         async_answer_0(rid, rc);
    1480         return;
    1481 }
    1482 
    1483 void fat_close(ipc_callid_t rid, ipc_call_t *request)
    1484 {
    1485         async_answer_0(rid, EOK);
    1486 }
    1487 
    1488 void fat_destroy(ipc_callid_t rid, ipc_call_t *request)
    1489 {
    1490         devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request);
    1491         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
     1407        return rc;
     1408}
     1409
     1410static int fat_close(devmap_handle_t devmap_handle, fs_index_t index)
     1411{
     1412        return EOK;
     1413}
     1414
     1415static int fat_destroy(devmap_handle_t devmap_handle, fs_index_t index)
     1416{
    14921417        fs_node_t *fn;
    14931418        fat_node_t *nodep;
     
    14951420
    14961421        rc = fat_node_get(&fn, devmap_handle, index);
    1497         if (rc != EOK) {
    1498                 async_answer_0(rid, rc);
    1499                 return;
    1500         }
    1501         if (!fn) {
    1502                 async_answer_0(rid, ENOENT);
    1503                 return;
    1504         }
     1422        if (rc != EOK)
     1423                return rc;
     1424        if (!fn)
     1425                return ENOENT;
    15051426
    15061427        nodep = FAT_NODE(fn);
     
    15121433
    15131434        rc = fat_destroy_node(fn);
    1514         async_answer_0(rid, rc);
    1515 }
    1516 
    1517 void fat_open_node(ipc_callid_t rid, ipc_call_t *request)
    1518 {
    1519         libfs_open_node(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1520 }
    1521 
    1522 void fat_stat(ipc_callid_t rid, ipc_call_t *request)
    1523 {
    1524         libfs_stat(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1525 }
    1526 
    1527 void fat_sync(ipc_callid_t rid, ipc_call_t *request)
    1528 {
    1529         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1530         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1531        
     1435        return rc;
     1436}
     1437
     1438static int fat_sync(devmap_handle_t devmap_handle, fs_index_t index)
     1439{
    15321440        fs_node_t *fn;
    15331441        int rc = fat_node_get(&fn, devmap_handle, index);
    1534         if (rc != EOK) {
    1535                 async_answer_0(rid, rc);
    1536                 return;
    1537         }
    1538         if (!fn) {
    1539                 async_answer_0(rid, ENOENT);
    1540                 return;
    1541         }
     1442        if (rc != EOK)
     1443                return rc;
     1444        if (!fn)
     1445                return ENOENT;
    15421446       
    15431447        fat_node_t *nodep = FAT_NODE(fn);
     
    15471451       
    15481452        fat_node_put(fn);
    1549         async_answer_0(rid, rc);
    1550 }
     1453        return rc;
     1454}
     1455
     1456vfs_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};
    15511466
    15521467/**
  • uspace/srv/fs/tmpfs/tmpfs.c

    rc936c7f r80e9e5e  
    6161};
    6262
    63 fs_reg_t tmpfs_reg;
    64 
    65 /**
    66  * This connection fibril processes VFS requests from VFS.
    67  *
    68  * In order to support simultaneous VFS requests, our design is as follows.
    69  * The connection fibril accepts VFS requests from VFS. If there is only one
    70  * instance of the fibril, VFS will need to serialize all VFS requests it sends
    71  * to FAT. To overcome this bottleneck, VFS can send TMPFS the
    72  * IPC_M_CONNECT_ME_TO call. In that case, a new connection fibril will be
    73  * created, which in turn will accept the call. Thus, a new phone will be
    74  * opened for VFS.
    75  *
    76  * There are few issues with this arrangement. First, VFS can run out of
    77  * available phones. In that case, VFS can close some other phones or use one
    78  * phone for more serialized requests. Similarily, TMPFS can refuse to duplicate
    79  * the connection. VFS should then just make use of already existing phones and
    80  * route its requests through them. To avoid paying the fibril creation price
    81  * upon each request, TMPFS might want to keep the connections open after the
    82  * request has been completed.
    83  */
    84 static void tmpfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    85 {
    86         if (iid) {
    87                 /*
    88                  * This only happens for connections opened by
    89                  * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
    90                  * created by IPC_M_CONNECT_TO_ME.
    91                  */
    92                 async_answer_0(iid, EOK);
    93         }
    94        
    95         dprintf(NAME ": connection opened\n");
    96        
    97         while (true) {
    98                 ipc_call_t call;
    99                 ipc_callid_t callid = async_get_call(&call);
    100                
    101                 if (!IPC_GET_IMETHOD(call))
    102                         return;
    103                
    104                 switch (IPC_GET_IMETHOD(call)) {
    105                 case VFS_OUT_MOUNTED:
    106                         tmpfs_mounted(callid, &call);
    107                         break;
    108                 case VFS_OUT_MOUNT:
    109                         tmpfs_mount(callid, &call);
    110                         break;
    111                 case VFS_OUT_UNMOUNTED:
    112                         tmpfs_unmounted(callid, &call);
    113                         break;
    114                 case VFS_OUT_UNMOUNT:
    115                         tmpfs_unmount(callid, &call);
    116                         break;
    117                 case VFS_OUT_LOOKUP:
    118                         tmpfs_lookup(callid, &call);
    119                         break;
    120                 case VFS_OUT_READ:
    121                         tmpfs_read(callid, &call);
    122                         break;
    123                 case VFS_OUT_WRITE:
    124                         tmpfs_write(callid, &call);
    125                         break;
    126                 case VFS_OUT_TRUNCATE:
    127                         tmpfs_truncate(callid, &call);
    128                         break;
    129                 case VFS_OUT_CLOSE:
    130                         tmpfs_close(callid, &call);
    131                         break;
    132                 case VFS_OUT_DESTROY:
    133                         tmpfs_destroy(callid, &call);
    134                         break;
    135                 case VFS_OUT_OPEN_NODE:
    136                         tmpfs_open_node(callid, &call);
    137                         break;
    138                 case VFS_OUT_STAT:
    139                         tmpfs_stat(callid, &call);
    140                         break;
    141                 case VFS_OUT_SYNC:
    142                         tmpfs_sync(callid, &call);
    143                         break;
    144                 default:
    145                         async_answer_0(callid, ENOTSUP);
    146                         break;
    147                 }
    148         }
    149 }
    150 
    15163int main(int argc, char **argv)
    15264{
     
    16577        }
    16678       
    167         int rc = fs_register(vfs_sess, &tmpfs_reg, &tmpfs_vfs_info,
    168             tmpfs_connection);
     79        int rc = fs_register(vfs_sess, &tmpfs_vfs_info, &tmpfs_ops,
     80            &tmpfs_libfs_ops);
    16981        if (rc != EOK) {
    17082                printf(NAME ": Failed to register file system (%d)\n", rc);
  • uspace/srv/fs/tmpfs/tmpfs.h

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

    rc936c7f r80e9e5e  
    104104}
    105105
    106 static char tmpfs_plb_get_char(unsigned pos)
    107 {
    108         return tmpfs_reg.plb_ro[pos % PLB_SIZE];
    109 }
    110 
    111106static bool tmpfs_is_directory(fs_node_t *fn)
    112107{
     
    139134        .size_get = tmpfs_size_get,
    140135        .lnkcnt_get = tmpfs_lnkcnt_get,
    141         .plb_get_char = tmpfs_plb_get_char,
    142136        .is_directory = tmpfs_is_directory,
    143137        .is_file = tmpfs_is_file,
     
    433427}
    434428
    435 void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request)
    436 {
    437         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     429/*
     430 * Implementation of the VFS_OUT interface.
     431 */
     432
     433static int
     434tmpfs_mounted(devmap_handle_t devmap_handle, const char *opts,
     435    fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
     436{
    438437        fs_node_t *rootfn;
    439438        int rc;
    440439       
    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 
    449440        /* Check if this device is not already mounted. */
    450441        rc = tmpfs_root_get(&rootfn, devmap_handle);
    451442        if ((rc == EOK) && (rootfn)) {
    452443                (void) tmpfs_node_put(rootfn);
    453                 free(opts);
    454                 async_answer_0(rid, EEXIST);
    455                 return;
     444                return EEXIST;
    456445        }
    457446
    458447        /* Initialize TMPFS instance. */
    459         if (!tmpfs_instance_init(devmap_handle)) {
    460                 free(opts);
    461                 async_answer_0(rid, ENOMEM);
    462                 return;
    463         }
     448        if (!tmpfs_instance_init(devmap_handle))
     449                return ENOMEM;
    464450
    465451        rc = tmpfs_root_get(&rootfn, devmap_handle);
     
    467453        tmpfs_node_t *rootp = TMPFS_NODE(rootfn);
    468454        if (str_cmp(opts, "restore") == 0) {
    469                 if (tmpfs_restore(devmap_handle))
    470                         async_answer_3(rid, EOK, rootp->index, rootp->size,
    471                             rootp->lnkcnt);
    472                 else
    473                         async_answer_0(rid, ELIMIT);
    474         } else {
    475                 async_answer_3(rid, EOK, rootp->index, rootp->size,
    476                     rootp->lnkcnt);
    477         }
    478         free(opts);
    479 }
    480 
    481 void tmpfs_mount(ipc_callid_t rid, ipc_call_t *request)
    482 {
    483         libfs_mount(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
    484 }
    485 
    486 void tmpfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
    487 {
    488         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    489 
     455                if (!tmpfs_restore(devmap_handle))
     456                        return ELIMIT;
     457        }
     458
     459        *index = rootp->index;
     460        *size = rootp->size;
     461        *lnkcnt = rootp->lnkcnt;
     462
     463        return EOK;
     464}
     465
     466static int tmpfs_unmounted(devmap_handle_t devmap_handle)
     467{
    490468        tmpfs_instance_done(devmap_handle);
    491         async_answer_0(rid, EOK);
    492 }
    493 
    494 void tmpfs_unmount(ipc_callid_t rid, ipc_call_t *request)
    495 {
    496         libfs_unmount(&tmpfs_libfs_ops, rid, request);
    497 }
    498 
    499 void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request)
    500 {
    501         libfs_lookup(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
    502 }
    503 
    504 void tmpfs_read(ipc_callid_t rid, ipc_call_t *request)
    505 {
    506         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    507         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    508         aoff64_t pos =
    509             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    510        
     469        return EOK;
     470}
     471
     472static int tmpfs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     473    size_t *rbytes)
     474{
    511475        /*
    512476         * Lookup the respective TMPFS node.
     
    518482        };
    519483        hlp = hash_table_find(&nodes, key);
    520         if (!hlp) {
    521                 async_answer_0(rid, ENOENT);
    522                 return;
    523         }
     484        if (!hlp)
     485                return ENOENT;
    524486        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    525487            nh_link);
     
    532494        if (!async_data_read_receive(&callid, &size)) {
    533495                async_answer_0(callid, EINVAL);
    534                 async_answer_0(rid, EINVAL);
    535                 return;
     496                return EINVAL;
    536497        }
    537498
     
    556517                if (lnk == NULL) {
    557518                        async_answer_0(callid, ENOENT);
    558                         async_answer_1(rid, ENOENT, 0);
    559                         return;
     519                        return ENOENT;
    560520                }
    561521
     
    567527        }
    568528
    569         /*
    570          * Answer the VFS_READ call.
    571          */
    572         async_answer_1(rid, EOK, bytes);
    573 }
    574 
    575 void tmpfs_write(ipc_callid_t rid, ipc_call_t *request)
    576 {
    577         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    578         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    579         aoff64_t pos =
    580             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    581        
     529        *rbytes = bytes;
     530        return EOK;
     531}
     532
     533static int
     534tmpfs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     535    size_t *wbytes, aoff64_t *nsize)
     536{
    582537        /*
    583538         * Lookup the respective TMPFS node.
     
    589544        };
    590545        hlp = hash_table_find(&nodes, key);
    591         if (!hlp) {
    592                 async_answer_0(rid, ENOENT);
    593                 return;
    594         }
     546        if (!hlp)
     547                return ENOENT;
    595548        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    596549            nh_link);
     
    603556        if (!async_data_write_receive(&callid, &size)) {
    604557                async_answer_0(callid, EINVAL);
    605                 async_answer_0(rid, EINVAL);
    606                 return;
     558                return EINVAL;
    607559        }
    608560
     
    612564        if (pos + size <= nodep->size) {
    613565                /* The file size is not changing. */
    614                 (void) async_data_write_finalize(callid, nodep->data + pos, size);
    615                 async_answer_2(rid, EOK, size, nodep->size);
    616                 return;
     566                (void) async_data_write_finalize(callid, nodep->data + pos,
     567                    size);
     568                goto out;
    617569        }
    618570        size_t delta = (pos + size) - nodep->size;
     
    627579        if (!newdata) {
    628580                async_answer_0(callid, ENOMEM);
    629                 async_answer_2(rid, EOK, 0, nodep->size);
    630                 return;
     581                size = 0;
     582                goto out;
    631583        }
    632584        /* Clear any newly allocated memory in order to emulate gaps. */
     
    635587        nodep->data = newdata;
    636588        (void) async_data_write_finalize(callid, nodep->data + pos, size);
    637         async_answer_2(rid, EOK, size, nodep->size);
    638 }
    639 
    640 void tmpfs_truncate(ipc_callid_t rid, ipc_call_t *request)
    641 {
    642         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    643         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    644         aoff64_t size =
    645             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    646        
     589
     590out:
     591        *wbytes = size;
     592        *nsize = nodep->size;
     593        return EOK;
     594}
     595
     596static int tmpfs_truncate(devmap_handle_t devmap_handle, fs_index_t index,
     597    aoff64_t size)
     598{
    647599        /*
    648600         * Lookup the respective TMPFS node.
     
    653605        };
    654606        link_t *hlp = hash_table_find(&nodes, key);
    655         if (!hlp) {
    656                 async_answer_0(rid, ENOENT);
    657                 return;
    658         }
    659         tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    660             nh_link);
    661        
    662         if (size == nodep->size) {
    663                 async_answer_0(rid, EOK);
    664                 return;
    665         }
    666        
    667         if (size > SIZE_MAX) {
    668                 async_answer_0(rid, ENOMEM);
    669                 return;
    670         }
     607        if (!hlp)
     608                return ENOENT;
     609        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, nh_link);
     610       
     611        if (size == nodep->size)
     612                return EOK;
     613       
     614        if (size > SIZE_MAX)
     615                return ENOMEM;
    671616       
    672617        void *newdata = realloc(nodep->data, size);
    673         if (!newdata) {
    674                 async_answer_0(rid, ENOMEM);
    675                 return;
    676         }
     618        if (!newdata)
     619                return ENOMEM;
    677620       
    678621        if (size > nodep->size) {
     
    683626        nodep->size = size;
    684627        nodep->data = newdata;
    685         async_answer_0(rid, EOK);
    686 }
    687 
    688 void tmpfs_close(ipc_callid_t rid, ipc_call_t *request)
    689 {
    690         async_answer_0(rid, EOK);
    691 }
    692 
    693 void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request)
    694 {
    695         devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request);
    696         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    697         int rc;
    698 
     628        return EOK;
     629}
     630
     631static int tmpfs_close(devmap_handle_t devmap_handle, fs_index_t index)
     632{
     633        return EOK;
     634}
     635
     636static int tmpfs_destroy(devmap_handle_t devmap_handle, fs_index_t index)
     637{
    699638        link_t *hlp;
    700639        unsigned long key[] = {
     
    703642        };
    704643        hlp = hash_table_find(&nodes, key);
    705         if (!hlp) {
    706                 async_answer_0(rid, ENOENT);
    707                 return;
    708         }
     644        if (!hlp)
     645                return ENOENT;
    709646        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    710647            nh_link);
    711         rc = tmpfs_destroy_node(FS_NODE(nodep));
    712         async_answer_0(rid, rc);
    713 }
    714 
    715 void tmpfs_open_node(ipc_callid_t rid, ipc_call_t *request)
    716 {
    717         libfs_open_node(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
    718 }
    719 
    720 void tmpfs_stat(ipc_callid_t rid, ipc_call_t *request)
    721 {
    722         libfs_stat(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
    723 }
    724 
    725 void tmpfs_sync(ipc_callid_t rid, ipc_call_t *request)
     648        return tmpfs_destroy_node(FS_NODE(nodep));
     649}
     650
     651static int tmpfs_sync(devmap_handle_t devmap_handle, fs_index_t index)
    726652{
    727653        /*
     
    729655         * thus the sync operation is a no-op.
    730656         */
    731         async_answer_0(rid, EOK);
    732 }
     657        return EOK;
     658}
     659
     660vfs_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};
    733670
    734671/**
    735672 * @}
    736673 */
     674
  • uspace/srv/vfs/vfs_ops.c

    rc936c7f r80e9e5e  
    7676        vfs_node_t *mr_node;
    7777        fs_index_t rindex;
    78         size_t rsize;
     78        aoff64_t rsize;
    7979        unsigned rlnkcnt;
    8080        async_exch_t *exch;
     
    146146
    147147                        rindex = (fs_index_t) IPC_GET_ARG1(answer);
    148                         rsize = (size_t) IPC_GET_ARG2(answer);
    149                         rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
     148                        rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer), IPC_GET_ARG3(answer));
     149                        rlnkcnt = (unsigned) IPC_GET_ARG4(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 = (size_t) IPC_GET_ARG2(answer);
    232                 rlnkcnt = (unsigned) IPC_GET_ARG3(answer);
     231                rsize = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG2(answer),
     232                    IPC_GET_ARG3(answer));
     233                rlnkcnt = (unsigned) IPC_GET_ARG4(answer);
    233234               
    234235                mr_res.triplet.fs_handle = fs_handle;
     
    795796        ipc_call_t answer;
    796797        if (read) {
    797                 rc = async_data_read_forward_3_1(fs_exch, VFS_OUT_READ,
    798                     file->node->devmap_handle, file->node->index, file->pos,
    799                     &answer);
     798                rc = async_data_read_forward_4_1(fs_exch, VFS_OUT_READ,
     799                    file->node->devmap_handle, file->node->index,
     800                    LOWER32(file->pos), UPPER32(file->pos), &answer);
    800801        } else {
    801802                if (file->append)
    802803                        file->pos = file->node->size;
    803804               
    804                 rc = async_data_write_forward_3_1(fs_exch, VFS_OUT_WRITE,
    805                     file->node->devmap_handle, file->node->index, file->pos,
    806                     &answer);
     805                rc = async_data_write_forward_4_1(fs_exch, VFS_OUT_WRITE,
     806                    file->node->devmap_handle, file->node->index,
     807                    LOWER32(file->pos), UPPER32(file->pos), &answer);
    807808        }
    808809       
     
    821822                /* Update the cached version of node's size. */
    822823                if (rc == EOK)
    823                         file->node->size = IPC_GET_ARG2(answer);
     824                        file->node->size = MERGE_LOUP32(IPC_GET_ARG2(answer),
     825                            IPC_GET_ARG3(answer));
    824826                fibril_rwlock_write_unlock(&file->node->contents_rwlock);
    825827        }
Note: See TracChangeset for help on using the changeset viewer.