Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp503568pxf; Thu, 25 Mar 2021 08:22:27 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyJltgbH0Fs573BmverO7kabi5F8lKUVC8+OP+54GkTgtRRQnwSxRwy0wdsgRQpFsPuCvBQ X-Received: by 2002:a17:906:32d1:: with SMTP id k17mr10082323ejk.94.1616685747740; Thu, 25 Mar 2021 08:22:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1616685747; cv=none; d=google.com; s=arc-20160816; b=APweJviFwR9EKJVRTQ3kan+v/Bpo248EAqIDSi7KjYT1dkPxlZToFdu72j6c0dRW1e RkhknhUQe+v2+/l6DTz46AmAlcMwqRQqqiBPIVRWqcriKdnv6X/g1t62IlPb7/rc3e1Q 0OzptGtzqu91mxctoCYHMjb4Ks8G93yo+fq8dd6vIahSA9kCWBhRDSdtPheSpZ1IutG6 H/xhiJFDuPW7wZVZ/AVvTWHPG0kP3lE0p0AJmqRBGooymTpB/LwofCU/VOztfiNdjZOi HTMcYQqqcm6gO7+p7LB2DvCZmKE2/yeejUYvbNDxJbqU/2Loihqs3SfDJu9BVZx7VLc+ TVxA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=rHW8ynUufSJO3sBpTf1Y0b3Ylr5myqW3HxMSPyzCTJ0=; b=NvaauB5x2/e35uiBL7n5ZFswx4oZ7HQTKpIJ20wiA1ZSJZ3Si4n+TfibU6+yCV2cfL KnWb+x9+7mIZRPdo72Ict25FjLJzoFrgik2UkKr3hocRSHg27yC+YGqmBZhCusAcUKEY UQZ3DnXSAu5oC+phIA5fuDnZAkG/KMNikOYdhRvWRNRa2AnwCPqyYE2/MD2w9iE5HRDR /9W4dI/epF4ZhFlCNUonCY0aBmzaVgwtmgX0bEVD/4Ojgc93Z6IRi1/YifG3ZmP+N5og gm75amWaYhmIWcC/b/w2lSrGFJCWujSvxRrjkYkm/WDReVskxvnWgdk5V8oS89E9shro U36Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Bwnmm7zr; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bx3si4448362edb.594.2021.03.25.08.22.03; Thu, 25 Mar 2021 08:22:27 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Bwnmm7zr; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230115AbhCYPTN (ORCPT + 99 others); Thu, 25 Mar 2021 11:19:13 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:52433 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230298AbhCYPTD (ORCPT ); Thu, 25 Mar 2021 11:19:03 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616685543; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rHW8ynUufSJO3sBpTf1Y0b3Ylr5myqW3HxMSPyzCTJ0=; b=Bwnmm7zrzhvR0w/0IwZ0r2QMmohCvNt9f/reima4xn8HBCvt/PYa3QnXu12n6VztYcMuXr fc438rnYdPLB/BxWb3pxSMHGE1vQeL8Z+Gptbvh5+MVZ/K9o7Tuz6nqeDEEHUF3tMnjcuT 11OsIh707JJ4jSNniyyoAXLeASWVieg= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-320-nCE3IV6WOpWNem0iSqho6g-1; Thu, 25 Mar 2021 11:18:59 -0400 X-MC-Unique: nCE3IV6WOpWNem0iSqho6g-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 0C4D0CC656; Thu, 25 Mar 2021 15:18:58 +0000 (UTC) Received: from horse.redhat.com (ovpn-118-78.rdu2.redhat.com [10.10.118.78]) by smtp.corp.redhat.com (Postfix) with ESMTP id E0E25891A5; Thu, 25 Mar 2021 15:18:45 +0000 (UTC) Received: by horse.redhat.com (Postfix, from userid 10451) id 72E8D223D98; Thu, 25 Mar 2021 11:18:45 -0400 (EDT) From: Vivek Goyal To: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, virtio-fs@redhat.com, miklos@szeredi.hu Cc: vgoyal@redhat.com, lhenriques@suse.de, dgilbert@redhat.com, seth.forshee@canonical.com Subject: [PATCH v2 1/2] fuse: Add support for FUSE_SETXATTR_V2 Date: Thu, 25 Mar 2021 11:18:22 -0400 Message-Id: <20210325151823.572089-2-vgoyal@redhat.com> In-Reply-To: <20210325151823.572089-1-vgoyal@redhat.com> References: <20210325151823.572089-1-vgoyal@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Fuse client needs to send additional information to file server when it calls SETXATTR(system.posix_acl_access). Right now there is no extra space in fuse_setxattr_in. So introduce a v2 of the structure which has more space in it and can be used to send extra flags. "struct fuse_setxattr_in_v2" is only used if file server opts-in for it using flag FUSE_SETXATTR_V2 during feature negotiations. Signed-off-by: Vivek Goyal --- fs/fuse/acl.c | 2 +- fs/fuse/fuse_i.h | 5 ++++- fs/fuse/inode.c | 4 +++- fs/fuse/xattr.c | 21 +++++++++++++++------ include/uapi/linux/fuse.h | 10 ++++++++++ 5 files changed, 33 insertions(+), 9 deletions(-) diff --git a/fs/fuse/acl.c b/fs/fuse/acl.c index e9c0f916349d..d31260a139d4 100644 --- a/fs/fuse/acl.c +++ b/fs/fuse/acl.c @@ -94,7 +94,7 @@ int fuse_set_acl(struct user_namespace *mnt_userns, struct inode *inode, return ret; } - ret = fuse_setxattr(inode, name, value, size, 0); + ret = fuse_setxattr(inode, name, value, size, 0, 0); kfree(value); } else { ret = fuse_removexattr(inode, name); diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 63d97a15ffde..d00bf0b9a38c 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -668,6 +668,9 @@ struct fuse_conn { /** Is setxattr not implemented by fs? */ unsigned no_setxattr:1; + /** Does file server support setxattr_v2 */ + unsigned setxattr_v2:1; + /** Is getxattr not implemented by fs? */ unsigned no_getxattr:1; @@ -1170,7 +1173,7 @@ void fuse_unlock_inode(struct inode *inode, bool locked); bool fuse_lock_inode(struct inode *inode); int fuse_setxattr(struct inode *inode, const char *name, const void *value, - size_t size, int flags); + size_t size, int flags, unsigned extra_flags); ssize_t fuse_getxattr(struct inode *inode, const char *name, void *value, size_t size); ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size); diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index b0e18b470e91..1c726df13f80 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -1052,6 +1052,8 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args, fc->handle_killpriv_v2 = 1; fm->sb->s_flags |= SB_NOSEC; } + if (arg->flags & FUSE_SETXATTR_V2) + fc->setxattr_v2 = 1; } else { ra_pages = fc->max_read / PAGE_SIZE; fc->no_lock = 1; @@ -1095,7 +1097,7 @@ void fuse_send_init(struct fuse_mount *fm) FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV | FUSE_POSIX_ACL | FUSE_ABORT_ERROR | FUSE_MAX_PAGES | FUSE_CACHE_SYMLINKS | FUSE_NO_OPENDIR_SUPPORT | FUSE_EXPLICIT_INVAL_DATA | - FUSE_HANDLE_KILLPRIV_V2; + FUSE_HANDLE_KILLPRIV_V2 | FUSE_SETXATTR_V2; #ifdef CONFIG_FUSE_DAX if (fm->fc->dax) ia->in.flags |= FUSE_MAP_ALIGNMENT; diff --git a/fs/fuse/xattr.c b/fs/fuse/xattr.c index 1a7d7ace54e1..f2aae72653dc 100644 --- a/fs/fuse/xattr.c +++ b/fs/fuse/xattr.c @@ -12,24 +12,33 @@ #include int fuse_setxattr(struct inode *inode, const char *name, const void *value, - size_t size, int flags) + size_t size, int flags, unsigned extra_flags) { struct fuse_mount *fm = get_fuse_mount(inode); FUSE_ARGS(args); struct fuse_setxattr_in inarg; + struct fuse_setxattr_in_v2 inarg_v2; + bool setxattr_v2 = fm->fc->setxattr_v2; int err; if (fm->fc->no_setxattr) return -EOPNOTSUPP; memset(&inarg, 0, sizeof(inarg)); - inarg.size = size; - inarg.flags = flags; + memset(&inarg_v2, 0, sizeof(inarg_v2)); + if (setxattr_v2) { + inarg_v2.size = size; + inarg_v2.flags = flags; + inarg_v2.setxattr_flags = extra_flags; + } else { + inarg.size = size; + inarg.flags = flags; + } args.opcode = FUSE_SETXATTR; args.nodeid = get_node_id(inode); args.in_numargs = 3; - args.in_args[0].size = sizeof(inarg); - args.in_args[0].value = &inarg; + args.in_args[0].size = setxattr_v2 ? sizeof(inarg_v2) : sizeof(inarg); + args.in_args[0].value = setxattr_v2 ? &inarg_v2 : (void *)&inarg; args.in_args[1].size = strlen(name) + 1; args.in_args[1].value = name; args.in_args[2].size = size; @@ -199,7 +208,7 @@ static int fuse_xattr_set(const struct xattr_handler *handler, if (!value) return fuse_removexattr(inode, name); - return fuse_setxattr(inode, name, value, size, flags); + return fuse_setxattr(inode, name, value, size, flags, 0); } static bool no_xattr_list(struct dentry *dentry) diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h index 54442612c48b..1bb555c1c117 100644 --- a/include/uapi/linux/fuse.h +++ b/include/uapi/linux/fuse.h @@ -179,6 +179,7 @@ * 7.33 * - add FUSE_HANDLE_KILLPRIV_V2, FUSE_WRITE_KILL_SUIDGID, FATTR_KILL_SUIDGID * - add FUSE_OPEN_KILL_SUIDGID + * - add FUSE_SETXATTR_V2 */ #ifndef _LINUX_FUSE_H @@ -330,6 +331,7 @@ struct fuse_file_lock { * does not have CAP_FSETID. Additionally upon * write/truncate sgid is killed only if file has group * execute permission. (Same as Linux VFS behavior). + * FUSE_SETXATTR_V2: Does file server support V2 of struct fuse_setxattr_in */ #define FUSE_ASYNC_READ (1 << 0) #define FUSE_POSIX_LOCKS (1 << 1) @@ -360,6 +362,7 @@ struct fuse_file_lock { #define FUSE_MAP_ALIGNMENT (1 << 26) #define FUSE_SUBMOUNTS (1 << 27) #define FUSE_HANDLE_KILLPRIV_V2 (1 << 28) +#define FUSE_SETXATTR_V2 (1 << 29) /** * CUSE INIT request/reply flags @@ -686,6 +689,13 @@ struct fuse_setxattr_in { uint32_t flags; }; +struct fuse_setxattr_in_v2 { + uint32_t size; + uint32_t flags; + uint32_t setxattr_flags; + uint32_t padding; +}; + struct fuse_getxattr_in { uint32_t size; uint32_t padding; -- 2.25.4