Revision cc720ddb hw/9pfs/virtio-9p-local.c
b/hw/9pfs/virtio-9p-local.c | ||
---|---|---|
156 | 156 |
return tsize; |
157 | 157 |
} |
158 | 158 |
|
159 |
static int local_close(FsContext *ctx, int fd)
|
|
159 |
static int local_close(FsContext *ctx, V9fsFidOpenState *fs)
|
|
160 | 160 |
{ |
161 |
return close(fd); |
|
161 |
return close(fs->fd);
|
|
162 | 162 |
} |
163 | 163 |
|
164 |
static int local_closedir(FsContext *ctx, DIR *dir)
|
|
164 |
static int local_closedir(FsContext *ctx, V9fsFidOpenState *fs)
|
|
165 | 165 |
{ |
166 |
return closedir(dir); |
|
166 |
return closedir(fs->dir);
|
|
167 | 167 |
} |
168 | 168 |
|
169 |
static int local_open(FsContext *ctx, V9fsPath *fs_path, int flags) |
|
169 |
static int local_open(FsContext *ctx, V9fsPath *fs_path, |
|
170 |
int flags, V9fsFidOpenState *fs) |
|
170 | 171 |
{ |
171 | 172 |
char buffer[PATH_MAX]; |
172 | 173 |
char *path = fs_path->data; |
173 | 174 |
|
174 |
return open(rpath(ctx, path, buffer), flags); |
|
175 |
fs->fd = open(rpath(ctx, path, buffer), flags); |
|
176 |
return fs->fd; |
|
175 | 177 |
} |
176 | 178 |
|
177 |
static DIR *local_opendir(FsContext *ctx, V9fsPath *fs_path) |
|
179 |
static int local_opendir(FsContext *ctx, |
|
180 |
V9fsPath *fs_path, V9fsFidOpenState *fs) |
|
178 | 181 |
{ |
179 | 182 |
char buffer[PATH_MAX]; |
180 | 183 |
char *path = fs_path->data; |
181 | 184 |
|
182 |
return opendir(rpath(ctx, path, buffer)); |
|
185 |
fs->dir = opendir(rpath(ctx, path, buffer)); |
|
186 |
if (!fs->dir) { |
|
187 |
return -1; |
|
188 |
} |
|
189 |
return 0; |
|
183 | 190 |
} |
184 | 191 |
|
185 |
static void local_rewinddir(FsContext *ctx, DIR *dir)
|
|
192 |
static void local_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
|
|
186 | 193 |
{ |
187 |
return rewinddir(dir); |
|
194 |
return rewinddir(fs->dir);
|
|
188 | 195 |
} |
189 | 196 |
|
190 |
static off_t local_telldir(FsContext *ctx, DIR *dir)
|
|
197 |
static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs)
|
|
191 | 198 |
{ |
192 |
return telldir(dir); |
|
199 |
return telldir(fs->dir);
|
|
193 | 200 |
} |
194 | 201 |
|
195 |
static int local_readdir_r(FsContext *ctx, DIR *dir, struct dirent *entry, |
|
202 |
static int local_readdir_r(FsContext *ctx, V9fsFidOpenState *fs, |
|
203 |
struct dirent *entry, |
|
196 | 204 |
struct dirent **result) |
197 | 205 |
{ |
198 |
return readdir_r(dir, entry, result); |
|
206 |
return readdir_r(fs->dir, entry, result);
|
|
199 | 207 |
} |
200 | 208 |
|
201 |
static void local_seekdir(FsContext *ctx, DIR *dir, off_t off)
|
|
209 |
static void local_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
|
|
202 | 210 |
{ |
203 |
return seekdir(dir, off); |
|
211 |
return seekdir(fs->dir, off);
|
|
204 | 212 |
} |
205 | 213 |
|
206 |
static ssize_t local_preadv(FsContext *ctx, int fd, const struct iovec *iov, |
|
214 |
static ssize_t local_preadv(FsContext *ctx, V9fsFidOpenState *fs, |
|
215 |
const struct iovec *iov, |
|
207 | 216 |
int iovcnt, off_t offset) |
208 | 217 |
{ |
209 | 218 |
#ifdef CONFIG_PREADV |
210 |
return preadv(fd, iov, iovcnt, offset); |
|
219 |
return preadv(fs->fd, iov, iovcnt, offset);
|
|
211 | 220 |
#else |
212 |
int err = lseek(fd, offset, SEEK_SET); |
|
221 |
int err = lseek(fs->fd, offset, SEEK_SET);
|
|
213 | 222 |
if (err == -1) { |
214 | 223 |
return err; |
215 | 224 |
} else { |
216 |
return readv(fd, iov, iovcnt); |
|
225 |
return readv(fs->fd, iov, iovcnt);
|
|
217 | 226 |
} |
218 | 227 |
#endif |
219 | 228 |
} |
220 | 229 |
|
221 |
static ssize_t local_pwritev(FsContext *ctx, int fd, const struct iovec *iov, |
|
230 |
static ssize_t local_pwritev(FsContext *ctx, V9fsFidOpenState *fs, |
|
231 |
const struct iovec *iov, |
|
222 | 232 |
int iovcnt, off_t offset) |
223 | 233 |
{ |
224 | 234 |
ssize_t ret |
225 | 235 |
; |
226 | 236 |
#ifdef CONFIG_PREADV |
227 |
ret = pwritev(fd, iov, iovcnt, offset); |
|
237 |
ret = pwritev(fs->fd, iov, iovcnt, offset);
|
|
228 | 238 |
#else |
229 |
int err = lseek(fd, offset, SEEK_SET); |
|
239 |
int err = lseek(fs->fd, offset, SEEK_SET);
|
|
230 | 240 |
if (err == -1) { |
231 | 241 |
return err; |
232 | 242 |
} else { |
233 |
ret = writev(fd, iov, iovcnt); |
|
243 |
ret = writev(fs->fd, iov, iovcnt);
|
|
234 | 244 |
} |
235 | 245 |
#endif |
236 | 246 |
#ifdef CONFIG_SYNC_FILE_RANGE |
... | ... | |
240 | 250 |
* We want to ensure that we don't leave dirty pages in the cache |
241 | 251 |
* after write when writeout=immediate is sepcified. |
242 | 252 |
*/ |
243 |
sync_file_range(fd, offset, ret, |
|
253 |
sync_file_range(fs->fd, offset, ret,
|
|
244 | 254 |
SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE); |
245 | 255 |
} |
246 | 256 |
#endif |
... | ... | |
356 | 366 |
return err; |
357 | 367 |
} |
358 | 368 |
|
359 |
static int local_fstat(FsContext *fs_ctx, int fd, struct stat *stbuf) |
|
369 |
static int local_fstat(FsContext *fs_ctx, |
|
370 |
V9fsFidOpenState *fs, struct stat *stbuf) |
|
360 | 371 |
{ |
361 | 372 |
int err; |
362 |
err = fstat(fd, stbuf); |
|
373 |
err = fstat(fs->fd, stbuf);
|
|
363 | 374 |
if (err) { |
364 | 375 |
return err; |
365 | 376 |
} |
... | ... | |
370 | 381 |
mode_t tmp_mode; |
371 | 382 |
dev_t tmp_dev; |
372 | 383 |
|
373 |
if (fgetxattr(fd, "user.virtfs.uid", &tmp_uid, sizeof(uid_t)) > 0) { |
|
384 |
if (fgetxattr(fs->fd, "user.virtfs.uid", |
|
385 |
&tmp_uid, sizeof(uid_t)) > 0) { |
|
374 | 386 |
stbuf->st_uid = tmp_uid; |
375 | 387 |
} |
376 |
if (fgetxattr(fd, "user.virtfs.gid", &tmp_gid, sizeof(gid_t)) > 0) { |
|
388 |
if (fgetxattr(fs->fd, "user.virtfs.gid", |
|
389 |
&tmp_gid, sizeof(gid_t)) > 0) { |
|
377 | 390 |
stbuf->st_gid = tmp_gid; |
378 | 391 |
} |
379 |
if (fgetxattr(fd, "user.virtfs.mode", &tmp_mode, sizeof(mode_t)) > 0) { |
|
392 |
if (fgetxattr(fs->fd, "user.virtfs.mode", |
|
393 |
&tmp_mode, sizeof(mode_t)) > 0) { |
|
380 | 394 |
stbuf->st_mode = tmp_mode; |
381 | 395 |
} |
382 |
if (fgetxattr(fd, "user.virtfs.rdev", &tmp_dev, sizeof(dev_t)) > 0) { |
|
396 |
if (fgetxattr(fs->fd, "user.virtfs.rdev", |
|
397 |
&tmp_dev, sizeof(dev_t)) > 0) { |
|
383 | 398 |
stbuf->st_rdev = tmp_dev; |
384 | 399 |
} |
385 | 400 |
} |
... | ... | |
387 | 402 |
} |
388 | 403 |
|
389 | 404 |
static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, |
390 |
int flags, FsCred *credp) |
|
405 |
int flags, FsCred *credp, V9fsFidOpenState *fs)
|
|
391 | 406 |
{ |
392 | 407 |
char *path; |
393 | 408 |
int fd = -1; |
... | ... | |
428 | 443 |
} |
429 | 444 |
} |
430 | 445 |
err = fd; |
446 |
fs->fd = fd; |
|
431 | 447 |
goto out; |
432 | 448 |
|
433 | 449 |
err_end: |
... | ... | |
577 | 593 |
return remove(rpath(ctx, path, buffer)); |
578 | 594 |
} |
579 | 595 |
|
580 |
static int local_fsync(FsContext *ctx, int fd, int datasync)
|
|
596 |
static int local_fsync(FsContext *ctx, V9fsFidOpenState *fs, int datasync)
|
|
581 | 597 |
{ |
582 | 598 |
if (datasync) { |
583 |
return qemu_fdatasync(fd); |
|
599 |
return qemu_fdatasync(fs->fd);
|
|
584 | 600 |
} else { |
585 |
return fsync(fd); |
|
601 |
return fsync(fs->fd);
|
|
586 | 602 |
} |
587 | 603 |
} |
588 | 604 |
|
... | ... | |
677 | 693 |
static int local_ioc_getversion(FsContext *ctx, V9fsPath *path, |
678 | 694 |
mode_t st_mode, uint64_t *st_gen) |
679 | 695 |
{ |
680 |
int err, fd; |
|
696 |
int err; |
|
697 |
V9fsFidOpenState fid_open; |
|
698 |
|
|
681 | 699 |
/* |
682 | 700 |
* Do not try to open special files like device nodes, fifos etc |
683 | 701 |
* We can get fd for regular files and directories only |
... | ... | |
685 | 703 |
if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) { |
686 | 704 |
return 0; |
687 | 705 |
} |
688 |
fd = local_open(ctx, path, O_RDONLY);
|
|
689 |
if (fd < 0) {
|
|
690 |
return fd;
|
|
706 |
err = local_open(ctx, path, O_RDONLY, &fid_open);
|
|
707 |
if (err < 0) {
|
|
708 |
return err;
|
|
691 | 709 |
} |
692 |
err = ioctl(fd, FS_IOC_GETVERSION, st_gen); |
|
693 |
local_close(ctx, fd);
|
|
710 |
err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen);
|
|
711 |
local_close(ctx, &fid_open);
|
|
694 | 712 |
return err; |
695 | 713 |
} |
696 | 714 |
|
Also available in: Unified diff