From patchwork Mon Jun 27 09:42:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kurz X-Patchwork-Id: 640908 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3rdPHr6GNfz9sdb for ; Mon, 27 Jun 2016 19:47:52 +1000 (AEST) Received: from localhost ([::1]:57522 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bHT8w-00007H-Q7 for incoming@patchwork.ozlabs.org; Mon, 27 Jun 2016 05:47:50 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33652) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bHT3Y-0000FU-O5 for qemu-devel@nongnu.org; Mon, 27 Jun 2016 05:42:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bHT3U-00057V-Dc for qemu-devel@nongnu.org; Mon, 27 Jun 2016 05:42:15 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:54723) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bHT3U-00057M-1K for qemu-devel@nongnu.org; Mon, 27 Jun 2016 05:42:12 -0400 Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.11/8.16.0.11) with SMTP id u5R9dLIF045007 for ; Mon, 27 Jun 2016 05:42:11 -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 23sn8uq0am-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Mon, 27 Jun 2016 05:42:11 -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:42:10 -0600 Received: from d03dlp03.boulder.ibm.com (9.17.202.179) 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:42:07 -0600 X-IBM-Helo: d03dlp03.boulder.ibm.com X-IBM-MailFrom: groug@kaod.org Received: from b01cxnp22036.gho.pok.ibm.com (b01cxnp22036.gho.pok.ibm.com [9.57.198.26]) by d03dlp03.boulder.ibm.com (Postfix) with ESMTP id 91CC819D801C; Mon, 27 Jun 2016 03:41:44 -0600 (MDT) Received: from b01ledav001.gho.pok.ibm.com (b01ledav001.gho.pok.ibm.com [9.57.199.106]) by b01cxnp22036.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u5R9g67W62521382; Mon, 27 Jun 2016 09:42:06 GMT Received: from b01ledav001.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id EED072803A; Mon, 27 Jun 2016 05:42:05 -0400 (EDT) Received: from bahia.lan (unknown [9.164.189.130]) by b01ledav001.gho.pok.ibm.com (Postfix) with ESMTP id 3D95828050; Mon, 27 Jun 2016 05:42:04 -0400 (EDT) From: Greg Kurz To: qemu-devel@nongnu.org Date: Mon, 27 Jun 2016 11:42:03 +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-00000FC71487 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16062709-0005-0000-0000-000076897D81 Message-Id: <146702052303.5764.4062835425206070448.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=3 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 08/13] 9p: add a fd argument to xattr helpers 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch adds the plumbing to be able to use fgetxattr(), fsetxattr(), flistxattr() and fremovexattr(). It does not change any functionality. Signed-off-by: Greg Kurz --- hw/9pfs/9p-local.c | 44 +++++++++++++++++--------- hw/9pfs/9p-posix-acl.c | 80 ++++++++++++++++++++++++++++++++--------------- hw/9pfs/9p-xattr-user.c | 41 ++++++++++++++++-------- hw/9pfs/9p-xattr.c | 35 +++++++++++++-------- hw/9pfs/9p-xattr.h | 67 ++++++++++++++++++++++++--------------- 5 files changed, 172 insertions(+), 95 deletions(-) diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c index 46ac7aab7c47..873bd4b9d997 100644 --- a/hw/9pfs/9p-local.c +++ b/hw/9pfs/9p-local.c @@ -269,34 +269,48 @@ err_out: return ret; } -static int local_set_xattr(const char *path, FsCred *credp) +static int local_do_setxattr(int fd, const char *path, + const char *name, void *value, size_t size) +{ + if (path) { + return setxattr(path, name, value, size, 0); + } else { + return fsetxattr(fd, name, value, size, 0); + } +} + +static int local_set_xattr(int fd, const char *path, FsCred *credp) { int err; if (credp->fc_uid != -1) { uint32_t tmp_uid = cpu_to_le32(credp->fc_uid); - err = setxattr(path, "user.virtfs.uid", &tmp_uid, sizeof(uid_t), 0); + err = local_do_setxattr(fd, path, "user.virtfs.uid", &tmp_uid, + sizeof(uid_t)); if (err) { return err; } } if (credp->fc_gid != -1) { uint32_t tmp_gid = cpu_to_le32(credp->fc_gid); - err = setxattr(path, "user.virtfs.gid", &tmp_gid, sizeof(gid_t), 0); + err = local_do_setxattr(fd, path, "user.virtfs.gid", &tmp_gid, + sizeof(gid_t)); if (err) { return err; } } if (credp->fc_mode != -1) { uint32_t tmp_mode = cpu_to_le32(credp->fc_mode); - err = setxattr(path, "user.virtfs.mode", &tmp_mode, sizeof(mode_t), 0); + err = local_do_setxattr(fd, path, "user.virtfs.mode", &tmp_mode, + sizeof(mode_t)); if (err) { return err; } } if (credp->fc_rdev != -1) { uint64_t tmp_rdev = cpu_to_le64(credp->fc_rdev); - err = setxattr(path, "user.virtfs.rdev", &tmp_rdev, sizeof(dev_t), 0); + err = local_do_setxattr(fd, path, "user.virtfs.rdev", &tmp_rdev, + sizeof(dev_t)); if (err) { return err; } @@ -489,7 +503,7 @@ static int local_chmod(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp) if (fs_ctx->export_flags & V9FS_SM_MAPPED) { buffer = rpath(fs_ctx, path); - ret = local_set_xattr(buffer, credp); + ret = local_set_xattr(-1, buffer, credp); g_free(buffer); } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) { return local_set_mapped_file_attr(fs_ctx, path, credp); @@ -522,7 +536,7 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path, if (err == -1) { goto out; } - err = local_set_xattr(buffer, credp); + err = local_set_xattr(-1, buffer, credp); if (err == -1) { serrno = errno; goto err_end; @@ -584,7 +598,7 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path, goto out; } credp->fc_mode = credp->fc_mode|S_IFDIR; - err = local_set_xattr(buffer, credp); + err = local_set_xattr(-1, buffer, credp); if (err == -1) { serrno = errno; goto err_end; @@ -674,7 +688,7 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, } credp->fc_mode = credp->fc_mode|S_IFREG; /* Set cleint credentials in xattr */ - err = local_set_xattr(buffer, credp); + err = local_set_xattr(-1, buffer, credp); if (err == -1) { serrno = errno; goto err_end; @@ -760,7 +774,7 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath, close(fd); /* Set cleint credentials in symlink's xattr */ credp->fc_mode = credp->fc_mode|S_IFLNK; - err = local_set_xattr(buffer, credp); + err = local_set_xattr(-1, buffer, credp); if (err == -1) { serrno = errno; goto err_end; @@ -932,7 +946,7 @@ static int local_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp) g_free(buffer); } else if (fs_ctx->export_flags & V9FS_SM_MAPPED) { buffer = rpath(fs_ctx, path); - ret = local_set_xattr(buffer, credp); + ret = local_set_xattr(-1, buffer, credp); g_free(buffer); } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) { return local_set_mapped_file_attr(fs_ctx, path, credp); @@ -1046,7 +1060,7 @@ static ssize_t local_lgetxattr(FsContext *ctx, V9fsPath *fs_path, { char *path = fs_path->data; - return v9fs_get_xattr(ctx, path, name, value, size); + return v9fs_get_xattr(ctx, -1, path, name, value, size); } static ssize_t local_llistxattr(FsContext *ctx, V9fsPath *fs_path, @@ -1054,7 +1068,7 @@ static ssize_t local_llistxattr(FsContext *ctx, V9fsPath *fs_path, { char *path = fs_path->data; - return v9fs_list_xattr(ctx, path, value, size); + return v9fs_list_xattr(ctx, -1, path, value, size); } static int local_lsetxattr(FsContext *ctx, V9fsPath *fs_path, const char *name, @@ -1062,7 +1076,7 @@ static int local_lsetxattr(FsContext *ctx, V9fsPath *fs_path, const char *name, { char *path = fs_path->data; - return v9fs_set_xattr(ctx, path, name, value, size, flags); + return v9fs_set_xattr(ctx, -1, path, name, value, size, flags); } static int local_lremovexattr(FsContext *ctx, V9fsPath *fs_path, @@ -1070,7 +1084,7 @@ static int local_lremovexattr(FsContext *ctx, V9fsPath *fs_path, { char *path = fs_path->data; - return v9fs_remove_xattr(ctx, path, name); + return v9fs_remove_xattr(ctx, -1, path, name); } static int local_name_to_path(FsContext *ctx, V9fsPath *dir_path, diff --git a/hw/9pfs/9p-posix-acl.c b/hw/9pfs/9p-posix-acl.c index ec003181cd33..287e8cf68396 100644 --- a/hw/9pfs/9p-posix-acl.c +++ b/hw/9pfs/9p-posix-acl.c @@ -22,19 +22,23 @@ #define ACL_ACCESS "system.posix_acl_access" #define ACL_DEFAULT "system.posix_acl_default" -static ssize_t mp_pacl_getxattr(FsContext *ctx, const char *path, +static ssize_t mp_pacl_getxattr(FsContext *ctx, int fd, const char *path, const char *name, void *value, size_t size) { char *buffer; ssize_t ret; - buffer = rpath(ctx, path); - ret = lgetxattr(buffer, MAP_ACL_ACCESS, value, size); - g_free(buffer); + if (path) { + buffer = rpath(ctx, path); + ret = lgetxattr(buffer, MAP_ACL_ACCESS, value, size); + g_free(buffer); + } else { + ret = fgetxattr(fd, MAP_ACL_ACCESS, value, size); + } return ret; } -static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path, +static ssize_t mp_pacl_listxattr(FsContext *ctx, int fd, const char *path, char *name, void *value, size_t osize) { ssize_t len = sizeof(ACL_ACCESS); @@ -53,26 +57,36 @@ static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path, return 0; } -static int mp_pacl_setxattr(FsContext *ctx, const char *path, const char *name, - void *value, size_t size, int flags) +static int mp_pacl_setxattr(FsContext *ctx, int fd, const char *path, + const char *name, void *value, size_t size, + int flags) { char *buffer; int ret; - buffer = rpath(ctx, path); - ret = lsetxattr(buffer, MAP_ACL_ACCESS, value, size, flags); - g_free(buffer); + if (path) { + buffer = rpath(ctx, path); + ret = lsetxattr(buffer, MAP_ACL_ACCESS, value, size, flags); + g_free(buffer); + } else { + ret = fsetxattr(fd, MAP_ACL_ACCESS, value, size, flags); + } return ret; } -static int mp_pacl_removexattr(FsContext *ctx, +static int mp_pacl_removexattr(FsContext *ctx, int fd, const char *path, const char *name) { int ret; char *buffer; - buffer = rpath(ctx, path); - ret = lremovexattr(buffer, MAP_ACL_ACCESS); + if (path) { + buffer = rpath(ctx, path); + ret = lremovexattr(buffer, MAP_ACL_ACCESS); + } else { + buffer = NULL; + ret = fremovexattr(fd, MAP_ACL_ACCESS); + } if (ret == -1 && errno == ENODATA) { /* * We don't get ENODATA error when trying to remove a @@ -86,19 +100,23 @@ static int mp_pacl_removexattr(FsContext *ctx, return ret; } -static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path, +static ssize_t mp_dacl_getxattr(FsContext *ctx, int fd, const char *path, const char *name, void *value, size_t size) { char *buffer; ssize_t ret; - buffer = rpath(ctx, path); - ret = lgetxattr(buffer, MAP_ACL_DEFAULT, value, size); - g_free(buffer); + if (path) { + buffer = rpath(ctx, path); + ret = lgetxattr(buffer, MAP_ACL_DEFAULT, value, size); + g_free(buffer); + } else { + ret = fgetxattr(fd, MAP_ACL_DEFAULT, value, size); + } return ret; } -static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path, +static ssize_t mp_dacl_listxattr(FsContext *ctx, int fd, const char *path, char *name, void *value, size_t osize) { ssize_t len = sizeof(ACL_DEFAULT); @@ -117,26 +135,36 @@ static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path, return 0; } -static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name, - void *value, size_t size, int flags) +static int mp_dacl_setxattr(FsContext *ctx, int fd, const char *path, + const char *name, void *value, size_t size, + int flags) { char *buffer; int ret; - buffer = rpath(ctx, path); - ret = lsetxattr(buffer, MAP_ACL_DEFAULT, value, size, flags); - g_free(buffer); + if (path) { + buffer = rpath(ctx, path); + ret = lsetxattr(buffer, MAP_ACL_DEFAULT, value, size, flags); + g_free(buffer); + } else { + ret = fsetxattr(fd, MAP_ACL_DEFAULT, value, size, flags); + } return ret; } -static int mp_dacl_removexattr(FsContext *ctx, +static int mp_dacl_removexattr(FsContext *ctx, int fd, const char *path, const char *name) { int ret; char *buffer; - buffer = rpath(ctx, path); - ret = lremovexattr(buffer, MAP_ACL_DEFAULT); + if (path) { + buffer = rpath(ctx, path); + ret = lremovexattr(buffer, MAP_ACL_DEFAULT); + } else { + buffer = NULL; + ret = fremovexattr(fd, MAP_ACL_DEFAULT); + } if (ret == -1 && errno == ENODATA) { /* * We don't get ENODATA error when trying to remove a diff --git a/hw/9pfs/9p-xattr-user.c b/hw/9pfs/9p-xattr-user.c index f87530c8b526..aa93ab926da9 100644 --- a/hw/9pfs/9p-xattr-user.c +++ b/hw/9pfs/9p-xattr-user.c @@ -17,7 +17,7 @@ #include "9p-xattr.h" -static ssize_t mp_user_getxattr(FsContext *ctx, const char *path, +static ssize_t mp_user_getxattr(FsContext *ctx, int fd, const char *path, const char *name, void *value, size_t size) { char *buffer; @@ -31,13 +31,17 @@ static ssize_t mp_user_getxattr(FsContext *ctx, const char *path, errno = ENOATTR; return -1; } - buffer = rpath(ctx, path); - ret = lgetxattr(buffer, name, value, size); - g_free(buffer); + if (path) { + buffer = rpath(ctx, path); + ret = lgetxattr(buffer, name, value, size); + g_free(buffer); + } else { + ret = fgetxattr(fd, name, value, size); + } return ret; } -static ssize_t mp_user_listxattr(FsContext *ctx, const char *path, +static ssize_t mp_user_listxattr(FsContext *ctx, int fd, const char *path, char *name, void *value, size_t size) { int name_size = strlen(name) + 1; @@ -70,8 +74,9 @@ static ssize_t mp_user_listxattr(FsContext *ctx, const char *path, return name_size; } -static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name, - void *value, size_t size, int flags) +static int mp_user_setxattr(FsContext *ctx, int fd, const char *path, + const char *name, void *value, size_t size, + int flags) { char *buffer; int ret; @@ -84,13 +89,17 @@ static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name, errno = EACCES; return -1; } - buffer = rpath(ctx, path); - ret = lsetxattr(buffer, name, value, size, flags); - g_free(buffer); + if (path) { + buffer = rpath(ctx, path); + ret = lsetxattr(buffer, name, value, size, flags); + g_free(buffer); + } else { + ret = fsetxattr(fd, name, value, size, flags); + } return ret; } -static int mp_user_removexattr(FsContext *ctx, +static int mp_user_removexattr(FsContext *ctx, int fd, const char *path, const char *name) { char *buffer; @@ -104,9 +113,13 @@ static int mp_user_removexattr(FsContext *ctx, errno = EACCES; return -1; } - buffer = rpath(ctx, path); - ret = lremovexattr(buffer, name); - g_free(buffer); + if (path) { + buffer = rpath(ctx, path); + ret = lremovexattr(buffer, name); + g_free(buffer); + } else { + ret = fremovexattr(fd, name); + } return ret; } diff --git a/hw/9pfs/9p-xattr.c b/hw/9pfs/9p-xattr.c index 5d8595ed932a..cd8c634b6364 100644 --- a/hw/9pfs/9p-xattr.c +++ b/hw/9pfs/9p-xattr.c @@ -29,18 +29,18 @@ static XattrOperations *get_xattr_operations(XattrOperations **h, return NULL; } -ssize_t v9fs_get_xattr(FsContext *ctx, const char *path, +ssize_t v9fs_get_xattr(FsContext *ctx, int fd, const char *path, const char *name, void *value, size_t size) { XattrOperations *xops = get_xattr_operations(ctx->xops, name); if (xops) { - return xops->getxattr(ctx, path, name, value, size); + return xops->getxattr(ctx, fd, path, name, value, size); } errno = EOPNOTSUPP; return -1; } -ssize_t pt_listxattr(FsContext *ctx, const char *path, +ssize_t pt_listxattr(FsContext *ctx, int fd, const char *path, char *name, void *value, size_t size) { int name_size = strlen(name) + 1; @@ -63,7 +63,7 @@ ssize_t pt_listxattr(FsContext *ctx, const char *path, * Get the list and pass to each layer to find out whether * to send the data or not */ -ssize_t v9fs_list_xattr(FsContext *ctx, const char *path, +ssize_t v9fs_list_xattr(FsContext *ctx, int fd, const char *path, void *value, size_t vsize) { ssize_t size = 0; @@ -74,8 +74,13 @@ ssize_t v9fs_list_xattr(FsContext *ctx, const char *path, ssize_t xattr_len, parsed_len = 0, attr_len; /* Get the actual len */ - buffer = rpath(ctx, path); - xattr_len = llistxattr(buffer, value, 0); + if (path) { + buffer = rpath(ctx, path); + xattr_len = llistxattr(buffer, value, 0); + } else { + buffer = NULL; + xattr_len = flistxattr(fd, value, 0); + } if (xattr_len <= 0) { g_free(buffer); return xattr_len; @@ -83,7 +88,11 @@ ssize_t v9fs_list_xattr(FsContext *ctx, const char *path, /* Now fetch the xattr and find the actual size */ orig_value = g_malloc(xattr_len); - xattr_len = llistxattr(buffer, orig_value, xattr_len); + if (path) { + xattr_len = llistxattr(buffer, orig_value, xattr_len); + } else { + xattr_len = flistxattr(fd, orig_value, xattr_len); + } g_free(buffer); /* store the orig pointer */ @@ -95,9 +104,9 @@ ssize_t v9fs_list_xattr(FsContext *ctx, const char *path, } if (!value) { - size += xops->listxattr(ctx, path, orig_value, value, vsize); + size += xops->listxattr(ctx, fd, path, orig_value, value, vsize); } else { - size = xops->listxattr(ctx, path, orig_value, value, vsize); + size = xops->listxattr(ctx, fd, path, orig_value, value, vsize); if (size < 0) { goto err_out; } @@ -119,24 +128,24 @@ err_out: return size; } -int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name, +int v9fs_set_xattr(FsContext *ctx, int fd, const char *path, const char *name, void *value, size_t size, int flags) { XattrOperations *xops = get_xattr_operations(ctx->xops, name); if (xops) { - return xops->setxattr(ctx, path, name, value, size, flags); + return xops->setxattr(ctx, fd, path, name, value, size, flags); } errno = EOPNOTSUPP; return -1; } -int v9fs_remove_xattr(FsContext *ctx, +int v9fs_remove_xattr(FsContext *ctx, int fd, const char *path, const char *name) { XattrOperations *xops = get_xattr_operations(ctx->xops, name); if (xops) { - return xops->removexattr(ctx, path, name); + return xops->removexattr(ctx, fd, path, name); } errno = EOPNOTSUPP; return -1; diff --git a/hw/9pfs/9p-xattr.h b/hw/9pfs/9p-xattr.h index 4d39a20262ad..dacb423c0968 100644 --- a/hw/9pfs/9p-xattr.h +++ b/hw/9pfs/9p-xattr.h @@ -18,13 +18,13 @@ typedef struct xattr_operations { const char *name; - ssize_t (*getxattr)(FsContext *ctx, const char *path, + ssize_t (*getxattr)(FsContext *ctx, int fd, const char *path, const char *name, void *value, size_t size); - ssize_t (*listxattr)(FsContext *ctx, const char *path, + ssize_t (*listxattr)(FsContext *ctx, int fd, const char *path, char *name, void *value, size_t size); - int (*setxattr)(FsContext *ctx, const char *path, const char *name, + int (*setxattr)(FsContext *ctx, int fd, const char *path, const char *name, void *value, size_t size, int flags); - int (*removexattr)(FsContext *ctx, + int (*removexattr)(FsContext *ctx, int fd, const char *path, const char *name); } XattrOperations; @@ -41,54 +41,67 @@ extern XattrOperations *mapped_xattr_ops[]; extern XattrOperations *passthrough_xattr_ops[]; extern XattrOperations *none_xattr_ops[]; -ssize_t v9fs_get_xattr(FsContext *ctx, const char *path, const char *name, - void *value, size_t size); -ssize_t v9fs_list_xattr(FsContext *ctx, const char *path, void *value, +ssize_t v9fs_get_xattr(FsContext *ctx, int fd, const char *path, + const char *name, void *value, size_t size); +ssize_t v9fs_list_xattr(FsContext *ctx, int fd, const char *path, void *value, size_t vsize); -int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name, +int v9fs_set_xattr(FsContext *ctx, int fd, const char *path, const char *name, void *value, size_t size, int flags); -int v9fs_remove_xattr(FsContext *ctx, const char *path, const char *name); -ssize_t pt_listxattr(FsContext *ctx, const char *path, char *name, void *value, - size_t size); +int v9fs_remove_xattr(FsContext *ctx, int fd, const char *path, + const char *name); +ssize_t pt_listxattr(FsContext *ctx, int fd, const char *path, char *name, + void *value, size_t size); -static inline ssize_t pt_getxattr(FsContext *ctx, const char *path, +static inline ssize_t pt_getxattr(FsContext *ctx, int fd, const char *path, const char *name, void *value, size_t size) { char *buffer; ssize_t ret; - buffer = rpath(ctx, path); - ret = lgetxattr(buffer, name, value, size); - g_free(buffer); + if (path) { + buffer = rpath(ctx, path); + ret = lgetxattr(buffer, name, value, size); + g_free(buffer); + } else { + ret = fgetxattr(fd, name, value, size); + } return ret; } -static inline int pt_setxattr(FsContext *ctx, const char *path, +static inline int pt_setxattr(FsContext *ctx, int fd, const char *path, const char *name, void *value, size_t size, int flags) { char *buffer; int ret; - buffer = rpath(ctx, path); - ret = lsetxattr(buffer, name, value, size, flags); - g_free(buffer); + if (path) { + buffer = rpath(ctx, path); + ret = lsetxattr(buffer, name, value, size, flags); + g_free(buffer); + } else { + ret = fsetxattr(fd, name, value, size, flags); + } return ret; } -static inline int pt_removexattr(FsContext *ctx, +static inline int pt_removexattr(FsContext *ctx, int fd, const char *path, const char *name) { char *buffer; int ret; - buffer = rpath(ctx, path); - ret = lremovexattr(path, name); - g_free(buffer); + if (path) { + buffer = rpath(ctx, path); + ret = lremovexattr(path, name); + g_free(buffer); + } else { + ret = fremovexattr(fd, name); + } return ret; } -static inline ssize_t notsup_getxattr(FsContext *ctx, const char *path, +static inline ssize_t notsup_getxattr(FsContext *ctx, int fd, const char *path, const char *name, void *value, size_t size) { @@ -96,7 +109,7 @@ static inline ssize_t notsup_getxattr(FsContext *ctx, const char *path, return -1; } -static inline int notsup_setxattr(FsContext *ctx, const char *path, +static inline int notsup_setxattr(FsContext *ctx, int fd, const char *path, const char *name, void *value, size_t size, int flags) { @@ -104,13 +117,13 @@ static inline int notsup_setxattr(FsContext *ctx, const char *path, return -1; } -static inline ssize_t notsup_listxattr(FsContext *ctx, const char *path, +static inline ssize_t notsup_listxattr(FsContext *ctx, int fd, const char *path, char *name, void *value, size_t size) { return 0; } -static inline int notsup_removexattr(FsContext *ctx, +static inline int notsup_removexattr(FsContext *ctx, int fd, const char *path, const char *name) { errno = ENOTSUP;