static Spfcall* ufs_read(Spfid *fid, u64 offset, u32 count, Spreq *req) { int n; Fid *f; Spfcall *ret; f = fid->aux; ret = sp_alloc_rread(count); if (f->dir) n = ufs_read_dir(fid, ret->data, offset, count, fid->conn->dotu); else { n = pread(f->fd, ret->data, count, offset); if (n < 0) create_rerror(errno); } if (sp_haserror()) { free(ret); ret = NULL; } else sp_set_rread_count(ret, n); return ret; }
static Spfcall* npfs_read(Spfid *fid, u64 offset, u32 count, Spreq *req) { int n; Fid *f; Spfcall *ret; f = fid->aux; ret = sp_alloc_rread(count); npfs_change_user(fid->user); if (f->dir) n = npfs_read_dir(f, ret->data, offset, count, fid->conn->dotu); else { if(mmapreads) { struct stat s; n = count; if(!f->aux) { fstat(f->fd, &s); f->aux=mmap(0, s.st_size, PROT_READ, MAP_SHARED, f->fd, 0); if(f->aux < 0) { create_rerror(errno); goto error; } } if(offset+count > s.st_size) n = s.st_size-offset; if(n>0) memcpy(ret->data, f->aux+offset, n); else n = 0; } else { n = pread(f->fd, ret->data, count, offset); if (n < 0) create_rerror(errno); } } error: if (sp_haserror()) { free(ret); ret = NULL; } else sp_set_rread_count(ret, n); return ret; }
static void xp_file_notify(Spcfd *spcfd, void *a) { int n, ecode; char *ename; Xpcopy *c; Xpfile *f; c = a; f = c->cfile; error: if (sp_haserror()) { sp_rerror(&ename, &ecode); if (c->finish) (*c->finish)(c, c->finishaux); // spcfd_remove(spcfd); return; } if (!spcfd_can_write(spcfd)) return; if (f->pos >= f->buflen) { if (!f->path) goto next_file; if (f->fd < 0) { f->fd = open(f->path, O_RDONLY); if (f->fd < 0) { sp_uerror(errno); goto error; } f->bufsize = Bufsize; f->buf = malloc(f->bufsize); if (!f->buf) { sp_werror(Enomem, ENOMEM); goto error; } } n = read(f->fd, f->buf, f->bufsize); if (n < 0) { sp_uerror(errno); goto error; } if (n == 0) { close(f->fd); f->fd = -1; free(f->buf); f->buf = NULL; f->buflen = 0; f->bufsize = 0; f->pos = 0; goto next_file; } f->buflen = n; f->pos = 0; } n = spcfd_write(spcfd, f->buf + f->pos, f->buflen - f->pos); if (n <= 0) goto error; f->pos += n; return; next_file: spcfd_remove(f->spcfd); f->spcfd = NULL; c->cfile = f->next; xp_file_copy(c); }