From patchwork Thu Apr 29 12:14:49 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Aneesh Kumar K.V" X-Patchwork-Id: 51279 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C45DAB7D2D for ; Thu, 29 Apr 2010 22:32:37 +1000 (EST) Received: from localhost ([127.0.0.1]:48063 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1O7SuX-0000yY-Kw for incoming@patchwork.ozlabs.org; Thu, 29 Apr 2010 08:32:09 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1O7Sec-0005cr-FI for qemu-devel@nongnu.org; Thu, 29 Apr 2010 08:15:42 -0400 Received: from [140.186.70.92] (port=45834 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1O7SeZ-0005bZ-Cx for qemu-devel@nongnu.org; Thu, 29 Apr 2010 08:15:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1O7SeW-0006rM-7Q for qemu-devel@nongnu.org; Thu, 29 Apr 2010 08:15:38 -0400 Received: from e23smtp07.au.ibm.com ([202.81.31.140]:57081) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1O7SeV-0006qt-Et for qemu-devel@nongnu.org; Thu, 29 Apr 2010 08:15:36 -0400 Received: from d23relay03.au.ibm.com (d23relay03.au.ibm.com [202.81.31.245]) by e23smtp07.au.ibm.com (8.14.3/8.13.1) with ESMTP id o3TCFdhN023769 for ; Thu, 29 Apr 2010 22:15:39 +1000 Received: from d23av04.au.ibm.com (d23av04.au.ibm.com [9.190.235.139]) by d23relay03.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id o3TCFY8j1892582 for ; Thu, 29 Apr 2010 22:15:34 +1000 Received: from d23av04.au.ibm.com (loopback [127.0.0.1]) by d23av04.au.ibm.com (8.14.3/8.13.1/NCO v10.0 AVout) with ESMTP id o3TCFXS3019587 for ; Thu, 29 Apr 2010 22:15:33 +1000 Received: from skywalker.in.ibm.com ([9.124.222.113]) by d23av04.au.ibm.com (8.14.3/8.13.1/NCO v10.0 AVin) with ESMTP id o3TCF894018931; Thu, 29 Apr 2010 22:15:31 +1000 From: "Aneesh Kumar K.V" To: qemu-devel@nongnu.org Date: Thu, 29 Apr 2010 17:44:49 +0530 Message-Id: <1272543303-9830-8-git-send-email-aneesh.kumar@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.0.4.360.g11766c In-Reply-To: <1272543303-9830-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com> References: <1272543303-9830-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) Cc: ericvh@gmail.com, aliguori@us.ibm.com, jvrao@linux.vnet.ibm.com, aneesh.kumar@linux.vnet.ibm.com Subject: [Qemu-devel] [PATCH -V6 07/21] virtio-9p: Add stat and mode related helper functions. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Anthony Liguori Add helpers to obtain file stat and mode details. Signed-off-by: Anthony Liguori Signed-off-by: Aneesh Kumar K.V --- hw/virtio-9p.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 186 insertions(+), 0 deletions(-) diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c index 4467aea..b37cdf2 100644 --- a/hw/virtio-9p.c +++ b/hw/virtio-9p.c @@ -580,6 +580,188 @@ static void complete_pdu(V9fsState *s, V9fsPDU *pdu, ssize_t len) free_pdu(s, pdu); } +static mode_t v9mode_to_mode(uint32_t mode, V9fsString *extension) +{ + mode_t ret; + + ret = mode & 0777; + if (mode & P9_STAT_MODE_DIR) { + ret |= S_IFDIR; + } + + if (dotu) { + if (mode & P9_STAT_MODE_SYMLINK) { + ret |= S_IFLNK; + } + if (mode & P9_STAT_MODE_SOCKET) { + ret |= S_IFSOCK; + } + if (mode & P9_STAT_MODE_NAMED_PIPE) { + ret |= S_IFIFO; + } + if (mode & P9_STAT_MODE_DEVICE) { + if (extension && extension->data[0] == 'c') { + ret |= S_IFCHR; + } else { + ret |= S_IFBLK; + } + } + } + + if (!(ret&~0777)) { + ret |= S_IFREG; + } + + if (mode & P9_STAT_MODE_SETUID) { + ret |= S_ISUID; + } + if (mode & P9_STAT_MODE_SETGID) { + ret |= S_ISGID; + } + if (mode & P9_STAT_MODE_SETVTX) { + ret |= S_ISVTX; + } + + return ret; +} + +static int donttouch_stat(V9fsStat *stat) +{ + if (stat->type == -1 && + stat->dev == -1 && + stat->qid.type == -1 && + stat->qid.version == -1 && + stat->qid.path == -1 && + stat->mode == -1 && + stat->atime == -1 && + stat->mtime == -1 && + stat->length == -1 && + !stat->name.size && + !stat->uid.size && + !stat->gid.size && + !stat->muid.size && + stat->n_uid == -1 && + stat->n_gid == -1 && + stat->n_muid == -1) { + return 1; + } + + return 0; +} + +static void v9fs_stat_free(V9fsStat *stat) +{ + v9fs_string_free(&stat->name); + v9fs_string_free(&stat->uid); + v9fs_string_free(&stat->gid); + v9fs_string_free(&stat->muid); + v9fs_string_free(&stat->extension); +} + +static uint32_t stat_to_v9mode(const struct stat *stbuf) +{ + uint32_t mode; + + mode = stbuf->st_mode & 0777; + if (S_ISDIR(stbuf->st_mode)) { + mode |= P9_STAT_MODE_DIR; + } + + if (dotu) { + if (S_ISLNK(stbuf->st_mode)) { + mode |= P9_STAT_MODE_SYMLINK; + } + + if (S_ISSOCK(stbuf->st_mode)) { + mode |= P9_STAT_MODE_SOCKET; + } + + if (S_ISFIFO(stbuf->st_mode)) { + mode |= P9_STAT_MODE_NAMED_PIPE; + } + + if (S_ISBLK(stbuf->st_mode) || S_ISCHR(stbuf->st_mode)) { + mode |= P9_STAT_MODE_DEVICE; + } + + if (stbuf->st_mode & S_ISUID) { + mode |= P9_STAT_MODE_SETUID; + } + + if (stbuf->st_mode & S_ISGID) { + mode |= P9_STAT_MODE_SETGID; + } + + if (stbuf->st_mode & S_ISVTX) { + mode |= P9_STAT_MODE_SETVTX; + } + } + + return mode; +} + +static int stat_to_v9stat(V9fsState *s, V9fsString *name, + const struct stat *stbuf, + V9fsStat *v9stat) +{ + int err; + const char *str; + + memset(v9stat, 0, sizeof(*v9stat)); + + stat_to_qid(stbuf, &v9stat->qid); + v9stat->mode = stat_to_v9mode(stbuf); + v9stat->atime = stbuf->st_atime; + v9stat->mtime = stbuf->st_mtime; + v9stat->length = stbuf->st_size; + + v9fs_string_null(&v9stat->uid); + v9fs_string_null(&v9stat->gid); + v9fs_string_null(&v9stat->muid); + + if (dotu) { + v9stat->n_uid = stbuf->st_uid; + v9stat->n_gid = stbuf->st_gid; + v9stat->n_muid = 0; + + v9fs_string_null(&v9stat->extension); + + if (v9stat->mode & P9_STAT_MODE_SYMLINK) { + err = v9fs_do_readlink(s, name, &v9stat->extension); + if (err == -1) { + err = -errno; + return err; + } + v9stat->extension.data[err] = 0; + v9stat->extension.size = err; + } else if (v9stat->mode & P9_STAT_MODE_DEVICE) { + v9fs_string_sprintf(&v9stat->extension, "%c %u %u", + S_ISCHR(stbuf->st_mode) ? 'c' : 'b', + major(stbuf->st_rdev), minor(stbuf->st_rdev)); + } else if (S_ISDIR(stbuf->st_mode) || S_ISREG(stbuf->st_mode)) { + v9fs_string_sprintf(&v9stat->extension, "%s %u", + "HARDLINKCOUNT", stbuf->st_nlink); + } + } + + str = strrchr(name->data, '/'); + if (str) { + str += 1; + } else { + str = name->data; + } + + v9fs_string_sprintf(&v9stat->name, "%s", str); + + v9stat->size = 61 + + v9fs_string_size(&v9stat->name) + + v9fs_string_size(&v9stat->uid) + + v9fs_string_size(&v9stat->gid) + + v9fs_string_size(&v9stat->muid) + + v9fs_string_size(&v9stat->extension); + return 0; +} + static void v9fs_dummy(V9fsState *s, V9fsPDU *pdu) { /* Note: The following have been added to prevent GCC from complaining @@ -600,6 +782,10 @@ static void v9fs_dummy(V9fsState *s, V9fsPDU *pdu) (void) alloc_fid; (void) free_fid; (void) fid_to_qid; + (void) v9mode_to_mode; + (void) donttouch_stat; + (void) v9fs_stat_free; + (void) stat_to_v9stat; } static void v9fs_version(V9fsState *s, V9fsPDU *pdu)