From patchwork Mon Jun 27 09:41:37 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kurz X-Patchwork-Id: 9200223 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2157C60752 for ; Mon, 27 Jun 2016 09:50:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0E4871FF10 for ; Mon, 27 Jun 2016 09:50:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0101F28326; Mon, 27 Jun 2016 09:50:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 484741FF10 for ; Mon, 27 Jun 2016 09:50:42 +0000 (UTC) Received: from localhost ([::1]:57537 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bHTBh-0002cs-4T for patchwork-qemu-devel@patchwork.kernel.org; Mon, 27 Jun 2016 05:50:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33286) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bHT37-0007uY-Gm for qemu-devel@nongnu.org; Mon, 27 Jun 2016 05:41:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bHT33-0004zY-Pu for qemu-devel@nongnu.org; Mon, 27 Jun 2016 05:41:48 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:40148) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bHT33-0004zP-Hb for qemu-devel@nongnu.org; Mon, 27 Jun 2016 05:41:45 -0400 Received: from pps.filterd (m0098393.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.11/8.16.0.11) with SMTP id u5R9dIvj131473 for ; Mon, 27 Jun 2016 05:41:45 -0400 Received: from e32.co.us.ibm.com (e32.co.us.ibm.com [32.97.110.150]) by mx0a-001b2d01.pphosted.com with ESMTP id 23sjug1m3g-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Mon, 27 Jun 2016 05:41:44 -0400 Received: from localhost by e32.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 27 Jun 2016 03:41:44 -0600 Received: from d03dlp02.boulder.ibm.com (9.17.202.178) by e32.co.us.ibm.com (192.168.1.132) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 27 Jun 2016 03:41:41 -0600 X-IBM-Helo: d03dlp02.boulder.ibm.com X-IBM-MailFrom: groug@kaod.org Received: from b03cxnp08026.gho.boulder.ibm.com (b03cxnp08026.gho.boulder.ibm.com [9.17.130.18]) by d03dlp02.boulder.ibm.com (Postfix) with ESMTP id 931113E4004C; Mon, 27 Jun 2016 03:41:40 -0600 (MDT) Received: from b03ledav004.gho.boulder.ibm.com (b03ledav004.gho.boulder.ibm.com [9.17.130.235]) by b03cxnp08026.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u5R9fe0k43843666; Mon, 27 Jun 2016 02:41:40 -0700 Received: from b03ledav004.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6EE5590003; Mon, 27 Jun 2016 03:41:40 -0600 (MDT) Received: from bahia.lan (unknown [9.164.189.130]) by b03ledav004.gho.boulder.ibm.com (Postfix) with ESMTP id 1F02B78010; Mon, 27 Jun 2016 03:41:38 -0600 (MDT) From: Greg Kurz To: qemu-devel@nongnu.org Date: Mon, 27 Jun 2016 11:41:37 +0200 In-Reply-To: <146702045511.5764.17551224268217330628.stgit@bahia.lan> References: <146702045511.5764.17551224268217330628.stgit@bahia.lan> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16062709-0004-0000-0000-00000FC71402 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16062709-0005-0000-0000-000076897CB0 Message-Id: <146702049783.5764.10514201575160012308.stgit@bahia.lan> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-06-27_06:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1604210000 definitions=main-1606270110 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] X-Received-From: 148.163.156.1 Subject: [Qemu-devel] [PATCH 05/13] 9p: introduce ftruncate file op X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eric Van Hensbergen , v9fs-developer@lists.sourceforge.net, "Aneesh Kumar K.V" , Greg Kurz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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