openbmc/build/tmp/deploy/sdk/witherspoon-2019-08-08/sysroots/armv6-openbmc-linux-gnueabi/usr/src/debug/nbd/3.19-r0/nbd-3.19/nbd-server.c
int expread(off_t a, char* buf, size_t len, CLIENT* client)
{
    off_t rdlen, offset;
    off_t mapcnt, mapl, maph, pagestart;

    DEBUG("Asked to read %u bytes at %llu.\n", (unsigned int)len,
          (unsigned long long)a);

    if (!(client->server->flags & F_COPYONWRITE) &&
        !((client->server->flags & F_WAIT) && (client->export == NULL)))
        return (rawexpread_fully(a, buf, len, client));

    mapl = a / DIFFPAGESIZE;
    maph = (a + len - 1) / DIFFPAGESIZE;

    for (mapcnt = mapl; mapcnt <= maph; mapcnt++)
    {
        pagestart = mapcnt * DIFFPAGESIZE;
        offset = a - pagestart;
        rdlen =
            (0 < DIFFPAGESIZE - offset && len < (size_t)(DIFFPAGESIZE - offset))
                ? len
                : (size_t)DIFFPAGESIZE - offset;
        if (!(client->server->flags & F_COPYONWRITE))
            pthread_rwlock_rdlock(&client->export_lock);
        if (client->difmap[mapcnt] != (u32)(-1))
        { /* the block is already there */
            DEBUG("Page %llu is at %lu\n", (unsigned long long)mapcnt,
                  (unsigned long)(client->difmap[mapcnt]));
            if (pread(client->difffile, buf, rdlen,
                      client->difmap[mapcnt] * DIFFPAGESIZE + offset) != rdlen)
                goto fail;
        }
        else
        { /* the block is not there */
            if ((client->server->flags & F_WAIT) && (client->export == NULL))
            {
                DEBUG("Page %llu is not here, and waiting for file\n",
                      (unsigned long long)mapcnt);
                goto fail;
            }
            else
            {
                DEBUG("Page %llu is not here, we read the original one\n",
                      (unsigned long long)mapcnt);
                if (rawexpread_fully(a, buf, rdlen, client))
                    goto fail;
            }
        }
        if (!(client->server->flags & F_COPYONWRITE))
            pthread_rwlock_unlock(&client->export_lock);
        len -= rdlen;
        a += rdlen;
        buf += rdlen;
    }
    return 0;
fail:
    if (!(client->server->flags & F_COPYONWRITE))
        pthread_rwlock_unlock(&client->export_lock);
    return -1;
}
/**
 * Read an amount of bytes at a given offset from the right file. This
 * abstracts the read-side of the copyonwrite stuff, and calls
 * rawexpread() with the right parameters to do the actual work.
 * @param a The offset where the read should start
 * @param buf A buffer to read into
 * @param len The size of buf
 * @param client The client we're going to read for
 * @return 0 on success, nonzero on failure
 **/
Read an amount of bytes at a given offset from the right file. This
abstracts the read-side of the copyonwrite stuff, and calls
rawexpread() with the right parameters to do the actual work.
Read an amount of bytes at a given offset from the right file . This abstracts the read - side of the copyonwrite stuff and calls rawexpread () with the right parameters to do the actual work .
int expread(off_t a, char* buf, size_t len, CLIENT* client)
{
    off_t rdlen, offset;
    off_t mapcnt, mapl, maph, pagestart;
    DEBUG("Asked to read %u bytes at %llu.\n", (unsigned int)len,
          (unsigned long long)a);
    if (!(client->server->flags & F_COPYONWRITE) &&
        !((client->server->flags & F_WAIT) && (client->export == NULL)))
        return (rawexpread_fully(a, buf, len, client));
    mapl = a / DIFFPAGESIZE;
    maph = (a + len - 1) / DIFFPAGESIZE;
    for (mapcnt = mapl; mapcnt <= maph; mapcnt++)
    {
        pagestart = mapcnt * DIFFPAGESIZE;
        offset = a - pagestart;
        rdlen =
            (0 < DIFFPAGESIZE - offset && len < (size_t)(DIFFPAGESIZE - offset))
                ? len
                : (size_t)DIFFPAGESIZE - offset;
        if (!(client->server->flags & F_COPYONWRITE))
            pthread_rwlock_rdlock(&client->export_lock);
        if (client->difmap[mapcnt] != (u32)(-1))
        { 
            DEBUG("Page %llu is at %lu\n", (unsigned long long)mapcnt,
                  (unsigned long)(client->difmap[mapcnt]));
            if (pread(client->difffile, buf, rdlen,
                      client->difmap[mapcnt] * DIFFPAGESIZE + offset) != rdlen)
                goto fail;
        }
        else
        { 
            if ((client->server->flags & F_WAIT) && (client->export == NULL))
            {
                DEBUG("Page %llu is not here, and waiting for file\n",
                      (unsigned long long)mapcnt);
                goto fail;
            }
            else
            {
                DEBUG("Page %llu is not here, we read the original one\n",
                      (unsigned long long)mapcnt);
                if (rawexpread_fully(a, buf, rdlen, client))
                    goto fail;
            }
        }
        if (!(client->server->flags & F_COPYONWRITE))
            pthread_rwlock_unlock(&client->export_lock);
        len -= rdlen;
        a += rdlen;
        buf += rdlen;
    }
    return 0;
fail:
    if (!(client->server->flags & F_COPYONWRITE))
        pthread_rwlock_unlock(&client->export_lock);
    return -1;
}
int expread ( off_t a , char * buf , size_t len , CLIENT * client ) { off_t rdlen , offset ; off_t mapcnt , mapl , maph , pagestart ; DEBUG ( " \n " , ( unsigned int ) len , ( unsigned long long ) a ) ; if ( ! ( client -> server -> flags & F_COPYONWRITE ) && ! ( ( client -> server -> flags & F_WAIT ) && ( client -> export == NULL ) ) ) return ( rawexpread_fully ( a , buf , len , client ) ) ; mapl = a / DIFFPAGESIZE ; maph = ( a + len - 1 ) / DIFFPAGESIZE ; for ( mapcnt = mapl ; mapcnt <= maph ; mapcnt ++ ) { pagestart = mapcnt * DIFFPAGESIZE ; offset = a - pagestart ; rdlen = ( 0 < DIFFPAGESIZE - offset && len < ( size_t ) ( DIFFPAGESIZE - offset ) ) ? len : ( size_t ) DIFFPAGESIZE - offset ; if ( ! ( client -> server -> flags & F_COPYONWRITE ) ) pthread_rwlock_rdlock ( & client -> export_lock ) ; if ( client -> difmap [ mapcnt ] != ( u32 ) ( -1 ) ) { DEBUG ( " \n " , ( unsigned long long ) mapcnt , ( unsigned long ) ( client -> difmap [ mapcnt ] ) ) ; if ( pread ( client -> difffile , buf , rdlen , client -> difmap [ mapcnt ] * DIFFPAGESIZE + offset ) != rdlen ) goto fail ; } else { if ( ( client -> server -> flags & F_WAIT ) && ( client -> export == NULL ) ) { DEBUG ( " \n " , ( unsigned long long ) mapcnt ) ; goto fail ; } else { DEBUG ( " \n " , ( unsigned long long ) mapcnt ) ; if ( rawexpread_fully ( a , buf , rdlen , client ) ) goto fail ; } } if ( ! ( client -> server -> flags & F_COPYONWRITE ) ) pthread_rwlock_unlock ( & client -> export_lock ) ; len -= rdlen ; a += rdlen ; buf += rdlen ; } return 0 ; fail : if ( ! ( client -> server -> flags & F_COPYONWRITE ) ) pthread_rwlock_unlock ( & client -> export_lock ) ; return -1 ; }
Read an amount of bytes at a given offset from the right file.
Read an amount of bytes at a given offset from the right file .
/* the block is already there */ /* the block is not there */