Changeset bb4d0b5 in mainline for uspace/lib


Ignore:
Timestamp:
2025-10-18T19:29:40Z (2 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
3e41cc4
Parents:
856a7b49
Message:

Allow user to decide whether to retry or abort when I/O error occurs.

Location:
uspace/lib/fmgt
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/fmgt/include/types/fmgt.h

    r856a7b49 rbb4d0b5  
    3939
    4040#include <capa.h>
     41#include <errno.h>
    4142#include <fibril_synch.h>
    4243#include <stdbool.h>
     
    5253} fmgt_progress_t;
    5354
     55/** File management I/O operation type */
     56typedef enum {
     57        /** Read */
     58        fmgt_io_read,
     59        /** Write */
     60        fmgt_io_write
     61} fmgt_io_op_type_t;
     62
     63/** File management I/O error report */
     64typedef struct {
     65        /** File name */
     66        const char *fname;
     67        /** Operation type */
     68        fmgt_io_op_type_t optype;
     69        /** Error code */
     70        errno_t rc;
     71} fmgt_io_error_t;
     72
     73/** File management I/O error recovery action */
     74typedef enum {
     75        /** Retry */
     76        fmgt_er_retry,
     77        /** Abort */
     78        fmgt_er_abort
     79} fmgt_error_action_t;
     80
    5481/** File management callbacks */
    5582typedef struct {
    5683        bool (*abort_query)(void *);
     84        fmgt_error_action_t (*io_error_query)(void *, fmgt_io_error_t *);
    5785        void (*progress)(void *, fmgt_progress_t *);
    5886} fmgt_cb_t;
  • uspace/lib/fmgt/src/fmgt.c

    r856a7b49 rbb4d0b5  
    221221}
    222222
     223/** Stop progress update timer.
     224 *
     225 * @param fmgt File management object
     226 */
     227static void fmgt_timer_stop(fmgt_t *fmgt)
     228{
     229        (void)fibril_timer_clear(fmgt->timer);
     230}
     231
    223232/** Query caller whether operation should be aborted.
    224233 *
     
    232241        else
    233242                return false;
     243}
     244
     245/** Query caller how to recover from I/O error.
     246 *
     247 * @param fmgt File management object
     248 * @param err I/O error report
     249 * @return What error recovery action should be taken.
     250 */
     251static fmgt_error_action_t fmgt_io_error_query(fmgt_t *fmgt,
     252    fmgt_io_error_t *err)
     253{
     254        if (fmgt->cb != NULL && fmgt->cb->io_error_query != NULL)
     255                return fmgt->cb->io_error_query(fmgt->cb_arg, err);
     256        else
     257                return fmgt_er_abort;
    234258}
    235259
     
    250274        uint64_t now;
    251275        char *buffer;
     276        fmgt_io_error_t err;
     277        fmgt_error_action_t action;
    252278        errno_t rc;
    253279
     
    270296        fmgt_initial_progress_update(fmgt);
    271297
     298        /* Create sparse file? */
    272299        if ((flags & nf_sparse) != 0) {
    273300                fmgt->curf_procb = fsize - 1;
     
    280307                        now = BUFFER_SIZE;
    281308
    282                 rc = vfs_write(fd, &pos, buffer, now, &nw);
     309                do {
     310                        rc = vfs_write(fd, &pos, buffer, now, &nw);
     311                        if (rc == EOK)
     312                                break;
     313
     314                        /* I/O error */
     315                        err.fname = fname;
     316                        err.optype = fmgt_io_write;
     317                        err.rc = rc;
     318                        fmgt_timer_stop(fmgt);
     319                        action = fmgt_io_error_query(fmgt, &err);
     320                        fmgt_timer_start(fmgt);
     321                } while (action == fmgt_er_retry);
     322
     323                /* Not recovered? */
    283324                if (rc != EOK) {
    284325                        free(buffer);
Note: See TracChangeset for help on using the changeset viewer.