[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 05/13] 9p: introduce ftruncate file op
From: |
Greg Kurz |
Subject: |
[Qemu-devel] [PATCH 05/13] 9p: introduce ftruncate file op |
Date: |
Mon, 27 Jun 2016 11:41:37 +0200 |
User-agent: |
StGit/0.17.1-dirty |
This patch adds a ftruncate operation to the fsdev API. It is then used if
we have an open fd, so that ftruncate() in the guest is functional even
if the file was unlinked or its file permissions would cause truncate() to
fail.
Signed-off-by: Greg Kurz <address@hidden>
---
fsdev/file-op-9p.h | 1 +
hw/9pfs/9p-handle.c | 15 +++++++++++++++
hw/9pfs/9p-local.c | 15 +++++++++++++++
hw/9pfs/9p-proxy.c | 14 ++++++++++++++
hw/9pfs/9p-synth.c | 8 ++++++++
hw/9pfs/9p.c | 17 +++++++++++++++--
hw/9pfs/cofs.c | 18 ++++++++++++++++++
hw/9pfs/coth.h | 1 +
8 files changed, 87 insertions(+), 2 deletions(-)
diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h
index 55614949740d..930bcc623f8b 100644
--- a/fsdev/file-op-9p.h
+++ b/fsdev/file-op-9p.h
@@ -140,6 +140,7 @@ struct FileOperations
int (*renameat)(FsContext *ctx, V9fsPath *olddir, const char *old_name,
V9fsPath *newdir, const char *new_name);
int (*unlinkat)(FsContext *ctx, V9fsPath *dir, const char *name, int
flags);
+ int (*ftruncate)(FsContext *, int, V9fsFidOpenState *, off_t);
void *opaque;
};
diff --git a/hw/9pfs/9p-handle.c b/hw/9pfs/9p-handle.c
index 2e741535df24..e48e48a7145d 100644
--- a/hw/9pfs/9p-handle.c
+++ b/hw/9pfs/9p-handle.c
@@ -349,6 +349,20 @@ static int handle_truncate(FsContext *ctx, V9fsPath
*fs_path, off_t size)
return ret;
}
+static int handle_ftruncate(FsContext *ctx, int fid_type, V9fsFidOpenState *fs,
+ off_t size)
+{
+ int fd;
+
+ if (fid_type == P9_FID_DIR) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ fd = v9fs_get_fd_fid(fid_type, fs);
+ return ftruncate(fd, size);
+}
+
static int handle_rename(FsContext *ctx, const char *oldpath,
const char *newpath)
{
@@ -696,4 +710,5 @@ FileOperations handle_ops = {
.name_to_path = handle_name_to_path,
.renameat = handle_renameat,
.unlinkat = handle_unlinkat,
+ .ftruncate = handle_ftruncate,
};
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index 6804c6558b8e..b4c31c49da69 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -874,6 +874,20 @@ static int local_truncate(FsContext *ctx, V9fsPath
*fs_path, off_t size)
return ret;
}
+static int local_ftruncate(FsContext *ctx, int fid_type, V9fsFidOpenState *fs,
+ off_t size)
+{
+ int fd;
+
+ if (fid_type == P9_FID_DIR) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ fd = v9fs_get_fd_fid(fid_type, fs);
+ return ftruncate(fd, size);
+}
+
static int local_rename(FsContext *ctx, const char *oldpath,
const char *newpath)
{
@@ -1275,4 +1289,5 @@ FileOperations local_ops = {
.name_to_path = local_name_to_path,
.renameat = local_renameat,
.unlinkat = local_unlinkat,
+ .ftruncate = local_ftruncate,
};
diff --git a/hw/9pfs/9p-proxy.c b/hw/9pfs/9p-proxy.c
index d78ff7b1bd8d..9abcc201bd67 100644
--- a/hw/9pfs/9p-proxy.c
+++ b/hw/9pfs/9p-proxy.c
@@ -864,6 +864,19 @@ static int proxy_truncate(FsContext *ctx, V9fsPath
*fs_path, off_t size)
return 0;
}
+static int proxy_ftruncate(FsContext *ctx, int fid_type, V9fsFidOpenState *fs,
+ off_t size)
+{
+ int fd;
+
+ if (fid_type == P9_FID_DIR) {
+ return -EINVAL;
+ }
+
+ fd = v9fs_get_fd_fid(fid_type, fs);
+ return ftruncate(fd, size);
+}
+
static int proxy_rename(FsContext *ctx, const char *oldpath,
const char *newpath)
{
@@ -1207,4 +1220,5 @@ FileOperations proxy_ops = {
.name_to_path = proxy_name_to_path,
.renameat = proxy_renameat,
.unlinkat = proxy_unlinkat,
+ .ftruncate = proxy_ftruncate,
};
diff --git a/hw/9pfs/9p-synth.c b/hw/9pfs/9p-synth.c
index 4b6d4e6a3f1c..70c71ce305c9 100644
--- a/hw/9pfs/9p-synth.c
+++ b/hw/9pfs/9p-synth.c
@@ -344,6 +344,13 @@ static int synth_truncate(FsContext *ctx, V9fsPath *path,
off_t offset)
return -1;
}
+static int synth_ftruncate(FsContext *ctx, int fid_type, V9fsFidOpenState *fs,
+ off_t size)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
static int synth_chmod(FsContext *fs_ctx, V9fsPath *path, FsCred *credp)
{
errno = EPERM;
@@ -566,4 +573,5 @@ FileOperations synth_ops = {
.name_to_path = synth_name_to_path,
.renameat = synth_renameat,
.unlinkat = synth_unlinkat,
+ .ftruncate = synth_ftruncate,
};
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index 3301cef0980d..3aa4c8e22ed9 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -1181,6 +1181,19 @@ out_nofid:
pdu_complete(pdu, retval);
}
+static int v9fs_do_truncate(V9fsPDU *pdu, V9fsFidState *fidp, off_t size)
+{
+ int err;
+
+ if (fid_has_file(fidp)) {
+ err = v9fs_co_ftruncate(pdu, fidp, size);
+ } else {
+ err = v9fs_co_truncate(pdu, &fidp->path, size);
+ }
+
+ return err;
+}
+
/* Attribute flags */
#define P9_ATTR_MODE (1 << 0)
#define P9_ATTR_UID (1 << 1)
@@ -1266,7 +1279,7 @@ static void v9fs_setattr(void *opaque)
}
}
if (v9iattr.valid & (P9_ATTR_SIZE)) {
- err = v9fs_co_truncate(pdu, &fidp->path, v9iattr.size);
+ err = v9fs_do_truncate(pdu, fidp, v9iattr.size);
if (err < 0) {
goto out;
}
@@ -2754,7 +2767,7 @@ static void v9fs_wstat(void *opaque)
}
}
if (v9stat.length != -1) {
- err = v9fs_co_truncate(pdu, &fidp->path, v9stat.length);
+ err = v9fs_do_truncate(pdu, fidp, v9stat.length);
if (err < 0) {
goto out;
}
diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c
index 70f584fcbd21..969c24730cb0 100644
--- a/hw/9pfs/cofs.c
+++ b/hw/9pfs/cofs.c
@@ -177,6 +177,24 @@ int v9fs_co_truncate(V9fsPDU *pdu, V9fsPath *path, off_t
size)
return err;
}
+int v9fs_co_ftruncate(V9fsPDU *pdu, V9fsFidState *fidp, off_t size)
+{
+ int err;
+ V9fsState *s = pdu->s;
+
+ if (v9fs_request_cancelled(pdu)) {
+ return -EINTR;
+ }
+ v9fs_co_run_in_worker(
+ {
+ err = s->ops->ftruncate(&s->ctx, fidp->fid_type, &fidp->fs, size);
+ if (err < 0) {
+ err = -errno;
+ }
+ });
+ return err;
+}
+
int v9fs_co_mknod(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, uid_t
uid,
gid_t gid, dev_t dev, mode_t mode, struct stat *stbuf)
{
diff --git a/hw/9pfs/coth.h b/hw/9pfs/coth.h
index 5b02a63ad9fd..4f493ad29ec4 100644
--- a/hw/9pfs/coth.h
+++ b/hw/9pfs/coth.h
@@ -94,5 +94,6 @@ extern int v9fs_co_name_to_path(V9fsPDU *, V9fsPath *,
const char *, V9fsPath *);
extern int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t,
V9fsStatDotl *v9stat);
+extern int v9fs_co_ftruncate(V9fsPDU *, V9fsFidState *, off_t);
#endif
- [Qemu-devel] [PATCH 00/13] 9p: reconcile virtfs with unlinked files, Greg Kurz, 2016/06/27
- [Qemu-devel] [PATCH 01/13] 9p: synth: drop v9fs_ prefix, Greg Kurz, 2016/06/27
- [Qemu-devel] [PATCH 02/13] 9p: factour out duplicate code from local_fstat() and local_lstat(), Greg Kurz, 2016/06/27
- [Qemu-devel] [PATCH 03/13] 9p: introduce the v9fs_get_fd_fid() helper, Greg Kurz, 2016/06/27
- [Qemu-devel] [PATCH 04/13] 9p: getattr: use fstat if we have a fd, Greg Kurz, 2016/06/27
- [Qemu-devel] [PATCH 05/13] 9p: introduce ftruncate file op,
Greg Kurz <=
- [Qemu-devel] [PATCH 06/13] oslib: support futimens() if available, Greg Kurz, 2016/06/27
- [Qemu-devel] [PATCH 07/13] 9p: introduce futimens file op, Greg Kurz, 2016/06/27
- [Qemu-devel] [PATCH 08/13] 9p: add a fd argument to xattr helpers, Greg Kurz, 2016/06/27
- [Qemu-devel] [PATCH 09/13] 9p: introduce fchown file op, Greg Kurz, 2016/06/27
- [Qemu-devel] [PATCH 10/13] 9p: introduce fchmod file op, Greg Kurz, 2016/06/27
- [Qemu-devel] [PATCH 11/13] 9p: xattr fid to reference file fid, Greg Kurz, 2016/06/27
- [Qemu-devel] [PATCH 12/13] 9p: introduce fgetxattr file op, Greg Kurz, 2016/06/27
- [Qemu-devel] [PATCH 13/13] 9p: introduce flistxattr file op, Greg Kurz, 2016/06/27