Revision 56d15a53

b/hw/file-op-9p.h
80 80
    off_t (*telldir)(FsContext *, DIR *);
81 81
    struct dirent *(*readdir)(FsContext *, DIR *);
82 82
    void (*seekdir)(FsContext *, DIR *, off_t);
83
    ssize_t (*readv)(FsContext *, int, const struct iovec *, int);
84
    ssize_t (*writev)(FsContext *, int, const struct iovec *, int);
85
    off_t (*lseek)(FsContext *, int, off_t, int);
83
    ssize_t (*preadv)(FsContext *, int, const struct iovec *, int, off_t);
84
    ssize_t (*pwritev)(FsContext *, int, const struct iovec *, int, off_t);
86 85
    int (*mkdir)(FsContext *, const char *, FsCred *);
87 86
    int (*fstat)(FsContext *, int, struct stat *);
88 87
    int (*rename)(FsContext *, const char *, const char *);
b/hw/virtio-9p-local.c
168 168
    return seekdir(dir, off);
169 169
}
170 170

  
171
static ssize_t local_readv(FsContext *ctx, int fd, const struct iovec *iov,
172
                            int iovcnt)
171
static ssize_t local_preadv(FsContext *ctx, int fd, const struct iovec *iov,
172
                            int iovcnt, off_t offset)
173 173
{
174
    return readv(fd, iov, iovcnt);
175
}
176

  
177
static off_t local_lseek(FsContext *ctx, int fd, off_t offset, int whence)
178
{
179
    return lseek(fd, offset, whence);
174
#ifdef CONFIG_PREADV
175
    return preadv(fd, iov, iovcnt, offset);
176
#else
177
    int err = lseek(fd, offset, SEEK_SET);
178
    if (err == -1) {
179
        return err;
180
    } else {
181
        return readv(fd, iov, iovcnt);
182
    }
183
#endif
180 184
}
181 185

  
182
static ssize_t local_writev(FsContext *ctx, int fd, const struct iovec *iov,
183
                            int iovcnt)
186
static ssize_t local_pwritev(FsContext *ctx, int fd, const struct iovec *iov,
187
                            int iovcnt, off_t offset)
184 188
{
185
    return writev(fd, iov, iovcnt);
189
#ifdef CONFIG_PREADV
190
    return pwritev(fd, iov, iovcnt, offset);
191
#else
192
    int err = lseek(fd, offset, SEEK_SET);
193
    if (err == -1) {
194
        return err;
195
    } else {
196
        return writev(fd, iov, iovcnt);
197
    }
198
#endif
186 199
}
187 200

  
188 201
static int local_chmod(FsContext *fs_ctx, const char *path, FsCred *credp)
......
523 536
    .telldir = local_telldir,
524 537
    .readdir = local_readdir,
525 538
    .seekdir = local_seekdir,
526
    .readv = local_readv,
527
    .lseek = local_lseek,
528
    .writev = local_writev,
539
    .preadv = local_preadv,
540
    .pwritev = local_pwritev,
529 541
    .chmod = local_chmod,
530 542
    .mknod = local_mknod,
531 543
    .mkdir = local_mkdir,
b/hw/virtio-9p.c
135 135
    return s->ops->seekdir(&s->ctx, dir, off);
136 136
}
137 137

  
138
static int v9fs_do_readv(V9fsState *s, int fd, const struct iovec *iov,
139
                            int iovcnt)
138
static int v9fs_do_preadv(V9fsState *s, int fd, const struct iovec *iov,
139
                            int iovcnt, int64_t offset)
140 140
{
141
    return s->ops->readv(&s->ctx, fd, iov, iovcnt);
141
    return s->ops->preadv(&s->ctx, fd, iov, iovcnt, offset);
142 142
}
143 143

  
144
static off_t v9fs_do_lseek(V9fsState *s, int fd, off_t offset, int whence)
144
static int v9fs_do_pwritev(V9fsState *s, int fd, const struct iovec *iov,
145
                       int iovcnt, int64_t offset)
145 146
{
146
    return s->ops->lseek(&s->ctx, fd, offset, whence);
147
}
148

  
149
static int v9fs_do_writev(V9fsState *s, int fd, const struct iovec *iov,
150
                       int iovcnt)
151
{
152
    return s->ops->writev(&s->ctx, fd, iov, iovcnt);
147
    return s->ops->pwritev(&s->ctx, fd, iov, iovcnt, offset);
153 148
}
154 149

  
155 150
static int v9fs_do_chmod(V9fsState *s, V9fsString *path, mode_t mode)
......
1975 1970
    return;
1976 1971
}
1977 1972

  
1978
static void v9fs_read_post_readv(V9fsState *s, V9fsReadState *vs, ssize_t err)
1973
static void v9fs_read_post_preadv(V9fsState *s, V9fsReadState *vs, ssize_t err)
1979 1974
{
1980 1975
    if (err  < 0) {
1981 1976
        /* IO error return the error */
......
1989 1984
            if (0) {
1990 1985
                print_sg(vs->sg, vs->cnt);
1991 1986
            }
1992
            vs->len = v9fs_do_readv(s, vs->fidp->fs.fd, vs->sg, vs->cnt);
1987
            vs->len = v9fs_do_preadv(s, vs->fidp->fs.fd, vs->sg, vs->cnt,
1988
                      vs->off);
1989
            if (vs->len > 0) {
1990
                vs->off += vs->len;
1991
            }
1993 1992
        } while (vs->len == -1 && errno == EINTR);
1994 1993
        if (vs->len == -1) {
1995 1994
            err  = -errno;
1996 1995
        }
1997
        v9fs_read_post_readv(s, vs, err);
1996
        v9fs_read_post_preadv(s, vs, err);
1998 1997
        return;
1999 1998
    }
2000 1999
    vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->total);
......
2006 2005
    qemu_free(vs);
2007 2006
}
2008 2007

  
2009
static void v9fs_read_post_lseek(V9fsState *s, V9fsReadState *vs, ssize_t err)
2010
{
2011
    if (err == -1) {
2012
        err = -errno;
2013
        goto out;
2014
    }
2015
    vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt);
2016

  
2017
    if (vs->total < vs->count) {
2018
        do {
2019
            if (0) {
2020
                print_sg(vs->sg, vs->cnt);
2021
            }
2022
            vs->len = v9fs_do_readv(s, vs->fidp->fs.fd, vs->sg, vs->cnt);
2023
        } while (vs->len == -1 && errno == EINTR);
2024
        if (vs->len == -1) {
2025
            err  = -errno;
2026
        }
2027
        v9fs_read_post_readv(s, vs, err);
2028
        return;
2029
    }
2030
out:
2031
    complete_pdu(s, vs->pdu, err);
2032
    qemu_free(vs);
2033
}
2034

  
2035 2008
static void v9fs_xattr_read(V9fsState *s, V9fsReadState *vs)
2036 2009
{
2037 2010
    ssize_t err = 0;
......
2089 2062
    } else if (vs->fidp->fid_type == P9_FID_FILE) {
2090 2063
        vs->sg = vs->iov;
2091 2064
        pdu_marshal(vs->pdu, vs->offset + 4, "v", vs->sg, &vs->cnt);
2092
        err = v9fs_do_lseek(s, vs->fidp->fs.fd, vs->off, SEEK_SET);
2093
        v9fs_read_post_lseek(s, vs, err);
2065
        vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt);
2066
        if (vs->total <= vs->count) {
2067
            vs->len = v9fs_do_preadv(s, vs->fidp->fs.fd, vs->sg, vs->cnt,
2068
                                    vs->off);
2069
            if (vs->len > 0) {
2070
                vs->off += vs->len;
2071
            }
2072
            err = vs->len;
2073
            v9fs_read_post_preadv(s, vs, err);
2074
        }
2094 2075
        return;
2095 2076
    } else if (vs->fidp->fid_type == P9_FID_XATTR) {
2096 2077
        v9fs_xattr_read(s, vs);
......
2224 2205
    return;
2225 2206
}
2226 2207

  
2227
static void v9fs_write_post_writev(V9fsState *s, V9fsWriteState *vs,
2208
static void v9fs_write_post_pwritev(V9fsState *s, V9fsWriteState *vs,
2228 2209
                                   ssize_t err)
2229 2210
{
2230 2211
    if (err  < 0) {
......
2239 2220
            if (0) {
2240 2221
                print_sg(vs->sg, vs->cnt);
2241 2222
            }
2242
            vs->len =  v9fs_do_writev(s, vs->fidp->fs.fd, vs->sg, vs->cnt);
2223
            vs->len = v9fs_do_pwritev(s, vs->fidp->fs.fd, vs->sg, vs->cnt,
2224
                      vs->off);
2225
            if (vs->len > 0) {
2226
                vs->off += vs->len;
2227
            }
2243 2228
        } while (vs->len == -1 && errno == EINTR);
2244 2229
        if (vs->len == -1) {
2245 2230
            err  = -errno;
2246 2231
        }
2247
        v9fs_write_post_writev(s, vs, err);
2232
        v9fs_write_post_pwritev(s, vs, err);
2248 2233
        return;
2249 2234
    }
2250 2235
    vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->total);
2251

  
2252 2236
    err = vs->offset;
2253 2237
out:
2254 2238
    complete_pdu(s, vs->pdu, err);
2255 2239
    qemu_free(vs);
2256 2240
}
2257 2241

  
2258
static void v9fs_write_post_lseek(V9fsState *s, V9fsWriteState *vs, ssize_t err)
2259
{
2260
    if (err == -1) {
2261
        err = -errno;
2262
        goto out;
2263
    }
2264
    vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt);
2265

  
2266
    if (vs->total < vs->count) {
2267
        do {
2268
            if (0) {
2269
                print_sg(vs->sg, vs->cnt);
2270
            }
2271
            vs->len = v9fs_do_writev(s, vs->fidp->fs.fd, vs->sg, vs->cnt);
2272
        } while (vs->len == -1 && errno == EINTR);
2273
        if (vs->len == -1) {
2274
            err  = -errno;
2275
        }
2276
        v9fs_write_post_writev(s, vs, err);
2277
        return;
2278
    }
2279

  
2280
out:
2281
    complete_pdu(s, vs->pdu, err);
2282
    qemu_free(vs);
2283
}
2284

  
2285 2242
static void v9fs_xattr_write(V9fsState *s, V9fsWriteState *vs)
2286 2243
{
2287 2244
    int i, to_copy;
......
2362 2319
        err = -EINVAL;
2363 2320
        goto out;
2364 2321
    }
2365
    err = v9fs_do_lseek(s, vs->fidp->fs.fd, vs->off, SEEK_SET);
2366

  
2367
    v9fs_write_post_lseek(s, vs, err);
2322
    vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt);
2323
    if (vs->total <= vs->count) {
2324
        vs->len = v9fs_do_pwritev(s, vs->fidp->fs.fd, vs->sg, vs->cnt, vs->off);
2325
        if (vs->len > 0) {
2326
            vs->off += vs->len;
2327
        }
2328
        err = vs->len;
2329
        v9fs_write_post_pwritev(s, vs, err);
2330
    }
2368 2331
    return;
2369

  
2370 2332
out:
2371 2333
    complete_pdu(s, vs->pdu, err);
2372 2334
    qemu_free(vs);

Also available in: Unified diff