From patchwork Fri Nov 30 20:03:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 10707101 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C8EC314D6 for ; Fri, 30 Nov 2018 20:03:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BC7AC2883D for ; Fri, 30 Nov 2018 20:03:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B101D28899; Fri, 30 Nov 2018 20:03:55 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3295C2890E for ; Fri, 30 Nov 2018 20:03:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726340AbeLAHOR (ORCPT ); Sat, 1 Dec 2018 02:14:17 -0500 Received: from mail-oi1-f194.google.com ([209.85.167.194]:45306 "EHLO mail-oi1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725790AbeLAHOR (ORCPT ); Sat, 1 Dec 2018 02:14:17 -0500 Received: by mail-oi1-f194.google.com with SMTP id b141so5749750oii.12; Fri, 30 Nov 2018 12:03:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=S2oPgo+TaTI6N0xr3S6Ve1tH4nozGA1RfIUTKrPc69I=; b=Q7wVQwPfN4tsjWN7wM81C4tzDe1wmgVDai0EYel9s41bCaU7iqCJlUWwHxcPRDvvWN jCb3F9x2xEo1qZIPZCmIVkGsnT/TBOYPb8NHUpm7e30cU+E+4KjKMxt2WHFlhOF0QMc8 ptTMEfvRNsHXPgW6XAaDtp9xAkGB4TdGZpZwXGJtJRFX9b1jH16E938kQZjIaDe7+maY 7DLAla41JUPC8iTZ4YLnsfvV6ArKR9Yl5u6XFXBxBF+xGxuhS2zX3BHZWzSe3I6akDRp UM9fW/xslgpoColH3IvRO15495GDv4ZSkZvZnwwpS7MHOvNQQqYhoy/FSVQnrXInoLKe yZew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=S2oPgo+TaTI6N0xr3S6Ve1tH4nozGA1RfIUTKrPc69I=; b=dG5yuPNFQ+AmzCtVg59ZMHe9JczOYD3M4ny7jspLA+jdRK5yfurbk/yppVzFpHYb25 xu5+zTKD9FQcuEucyS2/CyH9WNuRAcrQRevAUcGaU1myEa2DCtblOKCtn+CUquHsVriD cVieXtibSVy0t/EAdmM7liWS3wzDpegjufBu3zPT1bd3N0MQlOmAOV15hdGRqXN23UF8 3SEo8rEHSeerhhlk4Sx6VP4ViBYA/+f+/LVTEeAKZNeqPV9CsN750aVlIeTChoPtux1c jGslUHkJdz2PfLlyy5uM3MYTPtIhT2Gn2GE2htZ5tEJUBKRTqvx1yweOBrrCTbq44CAj xPDg== X-Gm-Message-State: AA+aEWYFzJlaVvEHa34XASU9+PendMNuDmBr+o3UwgVGwkg4VX8q1WA4 mAPrygsCS8+SiCm5Ta0+7Ks= X-Google-Smtp-Source: AFSGD/XpmDtMeLLAHDBIWy/Y0aXS51anUt/00yS5LBHETeMPBgcwxgX7Oyiyhot/uxrrqOMOCQv7ZQ== X-Received: by 2002:a54:4581:: with SMTP id z1mr4304054oib.192.1543608232580; Fri, 30 Nov 2018 12:03:52 -0800 (PST) Received: from Olgas-MBP-195.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id q10sm2065289otl.15.2018.11.30.12.03.50 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 30 Nov 2018 12:03:50 -0800 (PST) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 01/10] VFS generic copy_file_range() support Date: Fri, 30 Nov 2018 15:03:39 -0500 Message-Id: <20181130200348.59524-2-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20181130200348.59524-1-olga.kornievskaia@gmail.com> References: <20181130200348.59524-1-olga.kornievskaia@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Relax the condition that input files must be from the same file systems. Add checks that input parameters adhere semantics. If no copy_file_range() support is found, then do generic checks for the unsupported page cache ranges, LFS, limits, and clear setuid/setgid if not running as root before calling do_splice_direct(). Update atime,ctime,mtime afterwards. Signed-off-by: Olga Kornievskaia --- fs/read_write.c | 66 ++++++++++++++++++++++++++++++++++++++++++------------ include/linux/fs.h | 7 ++++++ mm/filemap.c | 6 ++--- 3 files changed, 61 insertions(+), 18 deletions(-) diff --git a/fs/read_write.c b/fs/read_write.c index 7b9e59d..2d309b0 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1540,6 +1540,44 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, } #endif +ssize_t generic_copy_file_range(struct file *file_in, loff_t pos_in, + struct file *file_out, loff_t pos_out, + loff_t len, unsigned int flags) +{ + ssize_t ret; + loff_t size_in = i_size_read(file_inode(file_in)), count; + + /* preform generic checks for unsupported page cache ranges, LFS + * limits. If pos exceeds the limit, returns EFBIG + */ + count = min(len, size_in - pos_in); + ret = generic_access_check_limits(file_in, pos_in, &count); + if (ret) + goto done; + ret = generic_write_check_limits(file_out, pos_out, &count); + if (ret) + goto done; + /* If not running as root, clear setuid/setgid bits. This keeps + * people from modifying setuid and setgid binaries. + */ + if (!IS_NOSEC(file_inode(file_out))) { + ret = file_remove_privs(file_out); + if (ret) + goto done; + } + + ret = do_splice_direct(file_in, &pos_in, file_out, &pos_out, + count > MAX_RW_COUNT ? MAX_RW_COUNT : count, 0); + + file_accessed(file_in); + if (!(file_out->f_mode & FMODE_NOCMTIME)) + file_update_time(file_out); + +done: + return ret; +} +EXPORT_SYMBOL(generic_copy_file_range); + /* * copy_file_range() differs from regular file read and write in that it * specifically allows return partial success. When it does so is up to @@ -1552,6 +1590,7 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in, struct inode *inode_in = file_inode(file_in); struct inode *inode_out = file_inode(file_out); ssize_t ret; + loff_t size_in; if (flags != 0) return -EINVAL; @@ -1577,6 +1616,15 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in, if (len == 0) return 0; + /* Ensure offsets don't wrap. */ + if (pos_in + len < pos_in || pos_out + len < pos_out) + return -EINVAL; + + size_in = i_size_read(inode_in); + /* Ensure that source range is within EOF. */ + if (pos_in >= size_in || pos_in + len > size_in) + return -EINVAL; + file_start_write(file_out); /* @@ -1597,22 +1645,12 @@ ssize_t vfs_copy_file_range(struct file *file_in, loff_t pos_in, } } - if (file_out->f_op->copy_file_range) { + if (file_out->f_op->copy_file_range) ret = file_out->f_op->copy_file_range(file_in, pos_in, file_out, pos_out, len, flags); - if (ret != -EOPNOTSUPP) - goto done; - } - - /* this could be relaxed once generic cross fs support is added */ - if (inode_in->i_sb != inode_out->i_sb) { - ret = -EXDEV; - goto done; - } - - ret = do_splice_direct(file_in, &pos_in, file_out, &pos_out, - len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0); - + else + ret = generic_copy_file_range(file_in, pos_in, file_out, + pos_out, len, flags); done: if (ret > 0) { fsnotify_access(file_in); diff --git a/include/linux/fs.h b/include/linux/fs.h index c95c080..c88ad09 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1874,6 +1874,9 @@ extern ssize_t vfs_readv(struct file *, const struct iovec __user *, unsigned long, loff_t *, rwf_t); extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *, loff_t, size_t, unsigned int); +extern ssize_t generic_copy_file_range(struct file *file_int, loff_t pos_in, + struct file *file_out, loff_t pos_out, + loff_t len, unsigned int flags); extern int generic_remap_file_range_prep(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, loff_t *count, @@ -3016,6 +3019,10 @@ static inline void remove_inode_hash(struct inode *inode) extern int generic_file_mmap(struct file *, struct vm_area_struct *); extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *); extern ssize_t generic_write_checks(struct kiocb *, struct iov_iter *); +extern int generic_access_check_limits(struct file *file, loff_t pos, + loff_t *count); +extern int generic_write_check_limits(struct file *file, loff_t pos, + loff_t *count); extern int generic_remap_checks(struct file *file_in, loff_t pos_in, struct file *file_out, loff_t pos_out, loff_t *count, unsigned int remap_flags); diff --git a/mm/filemap.c b/mm/filemap.c index 81adec8..894f3ae 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2829,8 +2829,7 @@ struct page *read_cache_page_gfp(struct address_space *mapping, * LFS limits. If pos is under the limit it becomes a short access. If it * exceeds the limit we return -EFBIG. */ -static int generic_access_check_limits(struct file *file, loff_t pos, - loff_t *count) +int generic_access_check_limits(struct file *file, loff_t pos, loff_t *count) { struct inode *inode = file->f_mapping->host; loff_t max_size = inode->i_sb->s_maxbytes; @@ -2844,8 +2843,7 @@ static int generic_access_check_limits(struct file *file, loff_t pos, return 0; } -static int generic_write_check_limits(struct file *file, loff_t pos, - loff_t *count) +int generic_write_check_limits(struct file *file, loff_t pos, loff_t *count) { loff_t limit = rlimit(RLIMIT_FSIZE); From patchwork Fri Nov 30 20:03:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 10707105 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B3DC514D6 for ; Fri, 30 Nov 2018 20:03:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A7A5B2883D for ; Fri, 30 Nov 2018 20:03:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9BF482890E; Fri, 30 Nov 2018 20:03:57 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 586722883D for ; Fri, 30 Nov 2018 20:03:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726489AbeLAHOU (ORCPT ); Sat, 1 Dec 2018 02:14:20 -0500 Received: from mail-ot1-f68.google.com ([209.85.210.68]:36555 "EHLO mail-ot1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725790AbeLAHOT (ORCPT ); Sat, 1 Dec 2018 02:14:19 -0500 Received: by mail-ot1-f68.google.com with SMTP id k98so6237730otk.3; Fri, 30 Nov 2018 12:03:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=IvT+zChRdZmo9Z/HWpUoiYO/PRDAUFPXOTb7glWeIsY=; b=mxZKrbW/SPzKZzsJpxo6/N8Tk2V2GNkgU489BhLx3Qs5wdm8peAi77ouSQTl/Sr+ZY dVZrX+VmJwUBf6c6AQ2BkKg+BYEv/LfigNSHdJDk14PE1mKaQQYgqc9Qdlc24SpFYWw6 gqpc35tUwLjz3O0J9CW6edRs99bF9v1UYDjBSAyAiWEwWI4/ytjYKlxr/t8LWECMZ0m0 2he3r4s1E/+mY/LcBpatlUqEzSMCjsiE2Z3AOlCscv3kE3ESwnc5eqggm587jBTVauqr DiFOfZl6BM/JR7wFUpypMLtFtLwdVc+yvMWjkO6ahFJRxKzyj8fpYTthB+sczX+vE2vk dSJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=IvT+zChRdZmo9Z/HWpUoiYO/PRDAUFPXOTb7glWeIsY=; b=KuLiOKCIETCty3INgW6S+k8eMLs+kNtbHWymKrnmoSBFMue+nEyym95kkSf1jZaf6d QyUnC0T6BOyW25jGAAs2ZPFhcSc5ou4lz5skuOj6nKrTqrHegQ+hbW1GuYxROvDJCwut hwwRz8corBeftyw2bdUyg+7Z6cy5McI1gZ0vZJnFskBJ1J0UAlMzFCoYOacaJmVh+Chb rZ14qtla3GUf1F3YLqcR2tz/rUVBXhr0reg0O/fCr85WPndoleJHQ6o76+PemtZSCvFD imxpoZBIDlKhBbmsjP95DBpgVgd4TuZyiKs1OgMPKoWvRPjd7siUTwlzmyFnOzSuEzun WyZQ== X-Gm-Message-State: AA+aEWbzAgp3+Yk/5vKeBTLcn31TsSENd1r13CFRTIHdimjcpGe2XbIC RQ8BKzWXSRj/ADUgi0a8vIY= X-Google-Smtp-Source: AFSGD/UWZtNnYRNCiXIxJzgnFcGm9DxjXJjxP1Fv0CkPfIET1qmfeSU/sg3noloNOhuJN7LOBhvrEQ== X-Received: by 2002:a9d:1982:: with SMTP id k2mr4138813otk.197.1543608235257; Fri, 30 Nov 2018 12:03:55 -0800 (PST) Received: from Olgas-MBP-195.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id q10sm2065289otl.15.2018.11.30.12.03.52 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 30 Nov 2018 12:03:53 -0800 (PST) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 02/10] NFS fallback to generic_copy_file_range Date: Fri, 30 Nov 2018 15:03:40 -0500 Message-Id: <20181130200348.59524-3-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20181130200348.59524-1-olga.kornievskaia@gmail.com> References: <20181130200348.59524-1-olga.kornievskaia@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If NFS unable to handle the copy then fallback to the generic VFS copy_file_range functionality. Also remove the offset check, as the check was added at the VFS. Signed-off-by: Olga Kornievskaia --- fs/nfs/nfs4file.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 4fe9fc1..78e163a 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -139,17 +139,16 @@ static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in, nfs4_stateid *cnrs = NULL; ssize_t ret; - if (pos_in >= i_size_read(file_inode(file_in))) - return -EINVAL; - if (file_in->f_op != &nfs4_file_operations) - return -EXDEV; + return generic_copy_file_range(file_in, pos_in, file_out, + pos_out, count, flags); if (file_inode(file_in) == file_inode(file_out)) return -EINVAL; if (!nfs_server_capable(file_inode(file_out), NFS_CAP_COPY)) - return -EOPNOTSUPP; + return generic_copy_file_range(file_in, pos_in, file_out, + pos_out, count, flags); retry: if (!nfs42_files_from_same_server(file_in, file_out)) { cn_resp = kzalloc(sizeof(struct nfs42_copy_notify_res), From patchwork Fri Nov 30 20:03:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 10707109 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8EACE13B0 for ; Fri, 30 Nov 2018 20:04:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8399028899 for ; Fri, 30 Nov 2018 20:04:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 77AA928922; Fri, 30 Nov 2018 20:04:01 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C56AA28899 for ; Fri, 30 Nov 2018 20:03:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726629AbeLAHOW (ORCPT ); Sat, 1 Dec 2018 02:14:22 -0500 Received: from mail-oi1-f193.google.com ([209.85.167.193]:42859 "EHLO mail-oi1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725790AbeLAHOW (ORCPT ); Sat, 1 Dec 2018 02:14:22 -0500 Received: by mail-oi1-f193.google.com with SMTP id w13so5763835oiw.9; Fri, 30 Nov 2018 12:03:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=1adVQGu3EzleOzF5553sjm9Y+OTh0F8rRsMvzXeiYLM=; b=Zw/9LYLtl29uqW/YnJZj+22JU0fgMEofliECH1R+e7N5JMHy6ZqMR5UgCbrrz5s8Lv 4t0QjFAhnorPuas5LvzoIAd3qP8QXfhhNTkchLs2TCwMkXujvFPa7/QNIn4la3qil9kk IbiBVNkIzRbi5yRx1typ7oPdUTkmdJZL3qr5chgJlk49J/CX6Eh0o+hg1ibaJzS6Pr9J q9Ccw1r8qfetzgkbGA4Etazh3Bmw7Gu5wm7jHfzLybOP52Sm63OBYHSRgmrtEIKCZQK1 g6rn3Rz9YhD5hnA/gaNkjdz4tRIPeciZYJSn/w2kly+C8qVIffjHikHd60K4fK+anCdJ Xz0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=1adVQGu3EzleOzF5553sjm9Y+OTh0F8rRsMvzXeiYLM=; b=bFFmn/hHS6KrWYjDldwDByuDuoWI+Z4A9jOPJ0kIuFHqclRd2Lxrxaf5ks1ihuKy8M +196/gCW0/02G9kNdulAlhY/DLt0Rj1REVb7wRllEYmYHBr8vrhDEWCg2uGk6jYD3bnr miSKxjn8rKlPn+6Y43zJNGV/zCUyxI8JMp1nZCQ8/YHDrrz3VyKVjJm86XH8tRTT4yk/ OCjxcl8HKrlc9XTf43nWSMdCwYzRd75HTyL77j5cprYEHO440Fto0ABZHMhNnewjybW3 nG9a4bA6tD//95hTGnCbrgEIFpBXDeCTStHn/BHQM2ncGELN5y1SGEUvsgE1BFLQBYfR ov6w== X-Gm-Message-State: AA+aEWY7Bu33R68J+Mly20IhLIiE8P3G24fwHXiWw/i81TlyKKrOxZEG Lbvbs2Skc/rvf9nfLFN1LdUM49Rj X-Google-Smtp-Source: AFSGD/WPHu3XxwqKCQCVYrc4KK2qhasqXmsoOZ75yWO8yH32Oe77m9eFcYIwKyFeh4yW7qvu+37UwA== X-Received: by 2002:aca:a90f:: with SMTP id s15mr4289512oie.137.1543608237537; Fri, 30 Nov 2018 12:03:57 -0800 (PST) Received: from Olgas-MBP-195.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id q10sm2065289otl.15.2018.11.30.12.03.55 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 30 Nov 2018 12:03:56 -0800 (PST) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 03/10] NFSD fill-in netloc4 structure Date: Fri, 30 Nov 2018 15:03:41 -0500 Message-Id: <20181130200348.59524-4-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20181130200348.59524-1-olga.kornievskaia@gmail.com> References: <20181130200348.59524-1-olga.kornievskaia@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP nfs.4 defines nfs42_netaddr structure that represents netloc4. Populate needed fields from the sockaddr structure. This will be used by flexfiles and 4.2 inter copy Signed-off-by: Olga Kornievskaia --- fs/nfsd/nfsd.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 0668999..a8fec63 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -366,6 +367,37 @@ static inline bool nfsd4_spo_must_allow(struct svc_rqst *rqstp) extern const u32 nfsd_suppattrs[3][3]; +static inline u32 nfsd4_set_netaddr(struct sockaddr *addr, + struct nfs42_netaddr *netaddr) +{ + struct sockaddr_in *sin = (struct sockaddr_in *)addr; + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr; + unsigned int port; + size_t ret_addr, ret_port; + + switch (addr->sa_family) { + case AF_INET: + port = ntohs(sin->sin_port); + sprintf(netaddr->netid, "tcp"); + netaddr->netid_len = 3; + break; + case AF_INET6: + port = ntohs(sin6->sin6_port); + sprintf(netaddr->netid, "tcp6"); + netaddr->netid_len = 4; + break; + default: + return nfserr_inval; + } + ret_addr = rpc_ntop(addr, netaddr->addr, sizeof(netaddr->addr)); + ret_port = snprintf(netaddr->addr + ret_addr, + RPCBIND_MAXUADDRLEN + 1 - ret_addr, + ".%u.%u", port >> 8, port & 0xff); + WARN_ON(ret_port >= RPCBIND_MAXUADDRLEN + 1 - ret_addr); + netaddr->addr_len = ret_addr + ret_port; + return 0; +} + static inline bool bmval_is_subset(const u32 *bm1, const u32 *bm2) { return !((bm1[0] & ~bm2[0]) || From patchwork Fri Nov 30 20:03:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 10707113 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2FEE14B7E for ; Fri, 30 Nov 2018 20:04:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 23DC12883D for ; Fri, 30 Nov 2018 20:04:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 17D6A28A68; Fri, 30 Nov 2018 20:04:02 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A96EE2883D for ; Fri, 30 Nov 2018 20:04:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726659AbeLAHOY (ORCPT ); Sat, 1 Dec 2018 02:14:24 -0500 Received: from mail-oi1-f194.google.com ([209.85.167.194]:33231 "EHLO mail-oi1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725790AbeLAHOY (ORCPT ); Sat, 1 Dec 2018 02:14:24 -0500 Received: by mail-oi1-f194.google.com with SMTP id c206so5811549oib.0; Fri, 30 Nov 2018 12:03:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=EIjBAKvsbMeb7MgWFADN1dVY8VW4BHqmrp8gpJd97KM=; b=A8J9a603h7oQeqogg5aS1htMTKzAHVARQuxsHE+so524cOG2x5HLGKyFFdyPwNKW7m Hdmxm5yl3HGPmSafuW+1iG+K3LNflcyrcZ5NZBfA5wanptLOpBnPynfA2NYbNvRtTG0f 3pwhfkM9p8Xq2x76WKD0lScBnDxihsAhcyfODwGsxNbisU+oHAACnfq4HJwiBT8b1NUK Bh3dvz+tb+9DlFeIBfkY8rXVtphn1CX9VrICeEUqSSkZA3hVh6c6q9zgw45V6WyhAeXU 0P/sC/0EPHvKp9YXLYqyySu5pgjq+O5h/bQhcfziFFEtjdOIDUgpFgmYv4uumf4Z2sAH BfkQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=EIjBAKvsbMeb7MgWFADN1dVY8VW4BHqmrp8gpJd97KM=; b=PGS9ksPaUDuqyoyZzBmTqdyXKbjFNbmZZxUD6cgtHF/COAvQHRXo1/ifumhoO4B43r L78YqE2S3z/7MDrtVWCgcWOqAp5AAQBDtmYbVI28ce6vyYSUAH/DBv+5/B/E+ytdGRtk DBapBLpuM+1ldITuaEubrFfcAfDGBIuvPNmq3MSmw27n8O4hxBcfzwoQ/ItL9FPUxAga yy1hvOqJeWshL0b6JD+VefOFIIbj6PZQgHjN2tNx5WblriNRlTyO9IIvCylUUYaCO6VL YtlpYABWXoJeSbnNa4cWPsVuKbJVnE+zdPpd0ds/uKruUDXBMFuv4CsIB5Pa4cIz0GJ6 GrMQ== X-Gm-Message-State: AA+aEWbGR52iXJpFd1aoP5CdSzvBe7chgMnGk/Miy27SGrzPK1pZaI2K fVAPMFLQUrXe007PxTOPTjo= X-Google-Smtp-Source: AFSGD/VaHdWqMdmcREr80qi+2DgThHqBtyz2x/m5/E4yV5sprR4ldWFT2WdVaZYd4fIchQpiRWPiAQ== X-Received: by 2002:aca:7581:: with SMTP id q123mr4345229oic.176.1543608239187; Fri, 30 Nov 2018 12:03:59 -0800 (PST) Received: from Olgas-MBP-195.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id q10sm2065289otl.15.2018.11.30.12.03.57 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 30 Nov 2018 12:03:58 -0800 (PST) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 04/10] NFSD add ca_source_server<> to COPY Date: Fri, 30 Nov 2018 15:03:42 -0500 Message-Id: <20181130200348.59524-5-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20181130200348.59524-1-olga.kornievskaia@gmail.com> References: <20181130200348.59524-1-olga.kornievskaia@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Decode the ca_source_server list that's sent but only use the first one. Presence of non-zero list indicates an "inter" copy. Signed-off-by: Andy Adamson Signed-off-by: Olga Kornievskaia --- fs/nfsd/nfs4xdr.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- fs/nfsd/xdr4.h | 12 ++++++---- 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 3de42a7..879ddc6 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "idmap.h" #include "acl.h" @@ -1743,11 +1744,58 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str DECODE_TAIL; } +static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp, + struct nl4_server *ns) +{ + DECODE_HEAD; + struct nfs42_netaddr *naddr; + + READ_BUF(4); + ns->nl4_type = be32_to_cpup(p++); + + /* currently support for 1 inter-server source server */ + switch (ns->nl4_type) { + case NL4_NAME: + case NL4_URL: + READ_BUF(4); + ns->u.nl4_str_sz = be32_to_cpup(p++); + if (ns->u.nl4_str_sz > NFS4_OPAQUE_LIMIT) + goto xdr_error; + + READ_BUF(ns->u.nl4_str_sz); + COPYMEM(ns->u.nl4_str, + ns->u.nl4_str_sz); + break; + case NL4_NETADDR: + naddr = &ns->u.nl4_addr; + + READ_BUF(4); + naddr->netid_len = be32_to_cpup(p++); + if (naddr->netid_len > RPCBIND_MAXNETIDLEN) + goto xdr_error; + + READ_BUF(naddr->netid_len + 4); /* 4 for uaddr len */ + COPYMEM(naddr->netid, naddr->netid_len); + + naddr->addr_len = be32_to_cpup(p++); + if (naddr->addr_len > RPCBIND_MAXUADDRLEN) + goto xdr_error; + + READ_BUF(naddr->addr_len); + COPYMEM(naddr->addr, naddr->addr_len); + break; + default: + goto xdr_error; + } + DECODE_TAIL; +} + static __be32 nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy) { DECODE_HEAD; - unsigned int tmp; + struct nl4_server ns_dummy; + int i, count; status = nfsd4_decode_stateid(argp, ©->cp_src_stateid); if (status) @@ -1762,8 +1810,25 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str p = xdr_decode_hyper(p, ©->cp_count); p++; /* ca_consecutive: we always do consecutive copies */ copy->cp_synchronous = be32_to_cpup(p++); - tmp = be32_to_cpup(p); /* Source server list not supported */ + count = be32_to_cpup(p++); + copy->cp_intra = false; + if (count == 0) { /* intra-server copy */ + copy->cp_intra = true; + goto intra; + } + + /* decode all the supplied server addresses but use first */ + status = nfsd4_decode_nl4_server(argp, ©->cp_src); + if (status) + return status; + + for (i = 0; i < count - 1; i++) { + status = nfsd4_decode_nl4_server(argp, &ns_dummy); + if (status) + return status; + } +intra: DECODE_TAIL; } diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index feeb6d4..513c9ff 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -516,11 +516,13 @@ struct nfsd42_write_res { struct nfsd4_copy { /* request */ - stateid_t cp_src_stateid; - stateid_t cp_dst_stateid; - u64 cp_src_pos; - u64 cp_dst_pos; - u64 cp_count; + stateid_t cp_src_stateid; + stateid_t cp_dst_stateid; + u64 cp_src_pos; + u64 cp_dst_pos; + u64 cp_count; + struct nl4_server cp_src; + bool cp_intra; /* both */ bool cp_synchronous; From patchwork Fri Nov 30 20:03:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 10707117 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0E57814D6 for ; Fri, 30 Nov 2018 20:04:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F3A142883D for ; Fri, 30 Nov 2018 20:04:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E833828922; Fri, 30 Nov 2018 20:04:03 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 82A102883D for ; Fri, 30 Nov 2018 20:04:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726685AbeLAHO0 (ORCPT ); Sat, 1 Dec 2018 02:14:26 -0500 Received: from mail-oi1-f194.google.com ([209.85.167.194]:45314 "EHLO mail-oi1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725790AbeLAHO0 (ORCPT ); Sat, 1 Dec 2018 02:14:26 -0500 Received: by mail-oi1-f194.google.com with SMTP id b141so5750126oii.12; Fri, 30 Nov 2018 12:04:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=bEIjIY/rDpE2r6ZLK+fnRmNh662BaBr6ZXthexAcb38=; b=H2BqQFLgiDlt9fewMLJ24k/ThSWKt58PK7UebwF0AqxMblhufqUsC/yIanrQ6iQtPv 4qyewIafDDDwu2jLYJLpiE88n1F6ajd3LrqwPgDpH7MKdd0ZpRDuEZWXIcQnl1nksf2C ycT/qj8bMIwVtxKP/3FQc6CLpQ4Yfd4ByNRCSeaIFMtm27DVZlZAxY3+Pj/LrJQxMapR 6gpUXI6Auq9qnlxd6Dg5wldphIHrg+seH3cOv7p7yLZNiHvbWrR8K/+0X+0CcyvPbjgu s9OSukxsHND+jQjzrH5a3EyQQ2YBAQzAjwUZ8R+mvsJwXDL3rIfTQdOi4LO2e0c6L3hU k66Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=bEIjIY/rDpE2r6ZLK+fnRmNh662BaBr6ZXthexAcb38=; b=dMx0Ue4pzGqpMA+CkvVVkyuPI8aS14dHDLj2zoYO4Cpc6+DnOA8ioMI0mfjCYoi7Kd jPm0EB2JC0gGYS+YdmqlE18YwB5CyxoW0P0eecJi+QJt0imK14sihP/b/9aeJoSTGhpx l/etBWQYz8RJNE4aGbAQJXYdLn+Pqch3D8olo8P0gwGDscH1bNCBhQMsDDlqSz2SAv3t b/LH3Sb85BQjdHZaL7urvg+19BJldZTAyOUiVPNGGXn3V1mYUw3GXc9JX72o81QaaKcI cNQll88oUCxOrHJyh0Z6Thubzii4EFcpT1I8b0eoYO86bkchENI17AbTZu0mz9dJ7jlR 2kYg== X-Gm-Message-State: AA+aEWbRSGI22B1Cw/qJMtZ4TBymDEjO7aVb7F8O5aGnC7qXL/upEeiH V3UwCktezQM1N/9G53uKk1kBoLr9 X-Google-Smtp-Source: AFSGD/WzVsqShWBOTgfCMrRRzvxF4d5uUSVr4fIpftuHaElN89K5L78KaWVtMBkEp9QL3UBNvUbsgw== X-Received: by 2002:aca:2ccc:: with SMTP id s195mr4283599ois.282.1543608241033; Fri, 30 Nov 2018 12:04:01 -0800 (PST) Received: from Olgas-MBP-195.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id q10sm2065289otl.15.2018.11.30.12.03.59 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 30 Nov 2018 12:04:00 -0800 (PST) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 05/10] NFSD return nfs4_stid in nfs4_preprocess_stateid_op Date: Fri, 30 Nov 2018 15:03:43 -0500 Message-Id: <20181130200348.59524-6-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20181130200348.59524-1-olga.kornievskaia@gmail.com> References: <20181130200348.59524-1-olga.kornievskaia@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Needed for copy to add nfs4_cp_state to the nfs4_stid. Signed-off-by: Andy Adamson Signed-off-by: Olga Kornievskaia --- fs/nfsd/nfs4proc.c | 17 ++++++++++------- fs/nfsd/nfs4state.c | 8 ++++++-- fs/nfsd/state.h | 3 ++- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index d505990..0152b34 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -781,7 +781,8 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) /* check stateid */ status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &read->rd_stateid, RD_STATE, - &read->rd_filp, &read->rd_tmp_file); + &read->rd_filp, &read->rd_tmp_file, + NULL); if (status) { dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); goto out; @@ -954,7 +955,7 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &setattr->sa_stateid, - WR_STATE, NULL, NULL); + WR_STATE, NULL, NULL, NULL); if (status) { dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n"); return status; @@ -1005,7 +1006,7 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) trace_nfsd_write_start(rqstp, &cstate->current_fh, write->wr_offset, cnt); status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, - stateid, WR_STATE, &filp, NULL); + stateid, WR_STATE, &filp, NULL, NULL); if (status) { dprintk("NFSD: nfsd4_write: couldn't process stateid!\n"); return status; @@ -1042,14 +1043,16 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) return nfserr_nofilehandle; status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->save_fh, - src_stateid, RD_STATE, src, NULL); + src_stateid, RD_STATE, src, NULL, + NULL); if (status) { dprintk("NFSD: %s: couldn't process src stateid!\n", __func__); goto out; } status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, - dst_stateid, WR_STATE, dst, NULL); + dst_stateid, WR_STATE, dst, NULL, + NULL); if (status) { dprintk("NFSD: %s: couldn't process dst stateid!\n", __func__); goto out_put_src; @@ -1353,7 +1356,7 @@ struct nfsd4_copy * status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &fallocate->falloc_stateid, - WR_STATE, &file, NULL); + WR_STATE, &file, NULL, NULL); if (status != nfs_ok) { dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n"); return status; @@ -1412,7 +1415,7 @@ struct nfsd4_copy * status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &seek->seek_stateid, - RD_STATE, &file, NULL); + RD_STATE, &file, NULL, NULL); if (status) { dprintk("NFSD: nfsd4_seek: couldn't process stateid!\n"); return status; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index f093fbe..be3e967 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5158,7 +5158,8 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) __be32 nfs4_preprocess_stateid_op(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct svc_fh *fhp, - stateid_t *stateid, int flags, struct file **filpp, bool *tmp_file) + stateid_t *stateid, int flags, struct file **filpp, + bool *tmp_file, struct nfs4_stid **cstid) { struct inode *ino = d_inode(fhp->fh_dentry); struct net *net = SVC_NET(rqstp); @@ -5209,8 +5210,11 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) if (!status && filpp) status = nfs4_check_file(rqstp, fhp, s, filpp, tmp_file, flags); out: - if (s) + if (s) { + if (!status && cstid) + *cstid = s; nfs4_put_stid(s); + } return status; } diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 6aacb32..304de3b 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -606,7 +606,8 @@ struct nfsd4_blocked_lock { extern __be32 nfs4_preprocess_stateid_op(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct svc_fh *fhp, - stateid_t *stateid, int flags, struct file **filp, bool *tmp_file); + stateid_t *stateid, int flags, struct file **filp, + bool *tmp_file, struct nfs4_stid **cstid); __be32 nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid, unsigned char typemask, struct nfs4_stid **s, struct nfsd_net *nn); From patchwork Fri Nov 30 20:03:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 10707119 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CFB9813B0 for ; Fri, 30 Nov 2018 20:04:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BF4FB2C041 for ; Fri, 30 Nov 2018 20:04:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B162F30121; Fri, 30 Nov 2018 20:04:05 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ACCF62C041 for ; Fri, 30 Nov 2018 20:04:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726712AbeLAHO2 (ORCPT ); Sat, 1 Dec 2018 02:14:28 -0500 Received: from mail-oi1-f196.google.com ([209.85.167.196]:33236 "EHLO mail-oi1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725790AbeLAHO1 (ORCPT ); Sat, 1 Dec 2018 02:14:27 -0500 Received: by mail-oi1-f196.google.com with SMTP id c206so5811679oib.0; Fri, 30 Nov 2018 12:04:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+8IjNlR4m8iNcn92mIpfB3bj3xZ7QGHHKieRRv/s0UY=; b=XwmtCB+sqR2JiSGjrF052Oa36SNhITLdm02m17+VOrLaTWeyO2CJ3vGuy/R5KHkezu ZY/7FeDmPsYU9+pFYAsp7B9u4MSWAW+SB/rDIvNwUuxyStnCbBzvw/TpLVVKJeUNcM0n FAJJaE5oF9WTq5eIBCLzJi3nfAROnYKkn9G3YEqIfqYJ6oH8jtejMVfagSmZ88uyVzdT UWE1lRt64ztxgnD+fL6vaHMMLt62XyAMJfQmatnLY3SD6PWBYWki2EBjZhjYdPh/Zdut FSjkq6m+r7qn7d1WCyCw0GjkHqjZxIgXWxCh/ulNir/V3C2KkCgmIMKGROXbMV6nZrLI C2VA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+8IjNlR4m8iNcn92mIpfB3bj3xZ7QGHHKieRRv/s0UY=; b=ATMQ7dsvKxa8rzJaiZvXzcxe9W5XFLZiyExQd4IzTbJQ8/me2rfO/1P7DjTZBmtaG6 iMFy1Znq7WfO02wnjwJwhpYizhANmtrOQf68u7okWEPvFyLi/d0PX9a78x4+dwZQNaEI p0HOLdQq27cpNFbWuZpQa7wItVrbAmzGqPvKXIlEmS+kVIE8nZ+eIqPxYZ/d7sH4QtYZ f4DfZNawDALuxuHxorWvEcCDBTAhmjFIB36yN9EIG6kWtuAYkFM3GMPDXBTyLiboSYqC lW261iLxNiFQzI+XQEe8Fxvhno7dBzLQYtBCC55FzBSjd5H1wMxC+yU3XbJgfP3dfXCT cMaQ== X-Gm-Message-State: AA+aEWZH21cjK3oiTG60J2WDIhaqU7YIf/ONypMGcTym6vfRZ6dIfIw0 NWpMWz/GJtJFLFmWdH7nOyxbZqFb X-Google-Smtp-Source: AFSGD/WsqXmOLzV3lZ1eE1wACOzSVIVOiwjUZ47AHTJSopTv38gM3RVVwv7K1QxmKL0MovnynrVkHw== X-Received: by 2002:aca:c207:: with SMTP id s7mr4297684oif.1.1543608242311; Fri, 30 Nov 2018 12:04:02 -0800 (PST) Received: from Olgas-MBP-195.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id q10sm2065289otl.15.2018.11.30.12.04.01 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 30 Nov 2018 12:04:01 -0800 (PST) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 06/10] NFSD add COPY_NOTIFY operation Date: Fri, 30 Nov 2018 15:03:44 -0500 Message-Id: <20181130200348.59524-7-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20181130200348.59524-1-olga.kornievskaia@gmail.com> References: <20181130200348.59524-1-olga.kornievskaia@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Introducing the COPY_NOTIFY operation. Create a new unique stateid that will keep track of the copy state and the upcoming READs that will use that stateid. Keep it in the list associated with parent stateid. Return single netaddr to advertise to the copy. Signed-off-by: Andy Adamson Signed-off-by: Olga Kornievskaia --- fs/nfsd/nfs4proc.c | 72 +++++++++++++++++++++++++++++++++++---- fs/nfsd/nfs4state.c | 64 +++++++++++++++++++++++++++++++---- fs/nfsd/nfs4xdr.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++-- fs/nfsd/state.h | 18 ++++++++-- fs/nfsd/xdr4.h | 13 +++++++ 5 files changed, 248 insertions(+), 16 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 0152b34..51fca9e 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "idmap.h" #include "cache.h" @@ -1035,7 +1036,8 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) static __be32 nfsd4_verify_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stateid_t *src_stateid, struct file **src, - stateid_t *dst_stateid, struct file **dst) + stateid_t *dst_stateid, struct file **dst, + struct nfs4_stid **stid) { __be32 status; @@ -1052,7 +1054,7 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, dst_stateid, WR_STATE, dst, NULL, - NULL); + stid); if (status) { dprintk("NFSD: %s: couldn't process dst stateid!\n", __func__); goto out_put_src; @@ -1083,7 +1085,7 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) __be32 status; status = nfsd4_verify_copy(rqstp, cstate, &clone->cl_src_stateid, &src, - &clone->cl_dst_stateid, &dst); + &clone->cl_dst_stateid, &dst, NULL); if (status) goto out; @@ -1230,7 +1232,7 @@ static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst) static void cleanup_async_copy(struct nfsd4_copy *copy) { - nfs4_free_cp_state(copy); + nfs4_free_copy_state(copy); fput(copy->file_dst); fput(copy->file_src); spin_lock(©->cp_clp->async_lock); @@ -1270,7 +1272,7 @@ static int nfsd4_do_async_copy(void *data) status = nfsd4_verify_copy(rqstp, cstate, ©->cp_src_stateid, ©->file_src, ©->cp_dst_stateid, - ©->file_dst); + ©->file_dst, NULL); if (status) goto out; @@ -1284,7 +1286,7 @@ static int nfsd4_do_async_copy(void *data) async_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL); if (!async_copy) goto out; - if (!nfs4_init_cp_state(nn, copy)) { + if (!nfs4_init_copy_state(nn, copy)) { kfree(async_copy); goto out; } @@ -1348,6 +1350,43 @@ struct nfsd4_copy * } static __be32 +nfsd4_copy_notify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) +{ + struct nfsd4_copy_notify *cn = &u->copy_notify; + __be32 status; + struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); + struct nfs4_stid *stid; + struct nfs4_cpntf_state *cps; + + status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, + &cn->cpn_src_stateid, RD_STATE, NULL, + NULL, &stid); + if (status) + return status; + + cn->cpn_sec = nn->nfsd4_lease; + cn->cpn_nsec = 0; + + status = nfserrno(-ENOMEM); + cps = nfs4_alloc_init_cpntf_state(nn, stid); + if (!cps) + return status; + memcpy(&cn->cpn_cnr_stateid, &cps->cp_stateid, sizeof(stateid_t)); + + /** + * For now, only return one server address in cpn_src, the + * address used by the client to connect to this server. + */ + cn->cpn_src.nl4_type = NL4_NETADDR; + status = nfsd4_set_netaddr((struct sockaddr *)&rqstp->rq_daddr, + &cn->cpn_src.u.nl4_addr); + WARN_ON_ONCE(status); + + return status; +} + +static __be32 nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_fallocate *fallocate, int flags) { @@ -2299,6 +2338,21 @@ static inline u32 nfsd4_offload_status_rsize(struct svc_rqst *rqstp, 1 /* osr_complete<1> optional 0 for now */) * sizeof(__be32); } +static inline u32 nfsd4_copy_notify_rsize(struct svc_rqst *rqstp, + struct nfsd4_op *op) +{ + return (op_encode_hdr_size + + 3 /* cnr_lease_time */ + + 1 /* We support one cnr_source_server */ + + 1 /* cnr_stateid seq */ + + op_encode_stateid_maxsz /* cnr_stateid */ + + 1 /* num cnr_source_server*/ + + 1 /* nl4_type */ + + 1 /* nl4 size */ + + XDR_QUADLEN(NFS4_OPAQUE_LIMIT) /*nl4_loc + nl4_loc_sz */) + * sizeof(__be32); +} + #ifdef CONFIG_NFSD_PNFS static inline u32 nfsd4_getdeviceinfo_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) { @@ -2723,6 +2777,12 @@ static inline u32 nfsd4_seek_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) .op_name = "OP_OFFLOAD_CANCEL", .op_rsize_bop = nfsd4_only_status_rsize, }, + [OP_COPY_NOTIFY] = { + .op_func = nfsd4_copy_notify, + .op_flags = OP_MODIFIES_SOMETHING, + .op_name = "OP_COPY_NOTIFY", + .op_rsize_bop = nfsd4_copy_notify_rsize, + }, }; /** diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index be3e967..eaa136f 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -697,6 +697,7 @@ struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *sla /* Will be incremented before return to client: */ refcount_set(&stid->sc_count, 1); spin_lock_init(&stid->sc_lock); + INIT_LIST_HEAD(&stid->sc_cp_list); /* * It shouldn't be a problem to reuse an opaque stateid value. @@ -716,24 +717,53 @@ struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *sla /* * Create a unique stateid_t to represent each COPY. */ -int nfs4_init_cp_state(struct nfsd_net *nn, struct nfsd4_copy *copy) +static int nfs4_init_cp_state(struct nfsd_net *nn, void *ptr, stateid_t *stid) { int new_id; idr_preload(GFP_KERNEL); spin_lock(&nn->s2s_cp_lock); - new_id = idr_alloc_cyclic(&nn->s2s_cp_stateids, copy, 0, 0, GFP_NOWAIT); + new_id = idr_alloc_cyclic(&nn->s2s_cp_stateids, ptr, 0, 0, GFP_NOWAIT); spin_unlock(&nn->s2s_cp_lock); idr_preload_end(); if (new_id < 0) return 0; - copy->cp_stateid.si_opaque.so_id = new_id; - copy->cp_stateid.si_opaque.so_clid.cl_boot = nn->boot_time; - copy->cp_stateid.si_opaque.so_clid.cl_id = nn->s2s_cp_cl_id; + stid->si_opaque.so_id = new_id; + stid->si_opaque.so_clid.cl_boot = nn->boot_time; + stid->si_opaque.so_clid.cl_id = nn->s2s_cp_cl_id; return 1; } -void nfs4_free_cp_state(struct nfsd4_copy *copy) +int nfs4_init_copy_state(struct nfsd_net *nn, struct nfsd4_copy *copy) +{ + return nfs4_init_cp_state(nn, copy, ©->cp_stateid); +} + +struct nfs4_cpntf_state *nfs4_alloc_init_cpntf_state(struct nfsd_net *nn, + struct nfs4_stid *p_stid) +{ + struct nfs4_cpntf_state *cps; + + cps = kzalloc(sizeof(struct nfs4_cpntf_state), GFP_KERNEL); + if (!cps) + return NULL; + if (!nfs4_init_cp_state(nn, cps, &cps->cp_stateid)) + goto out_free; + cps->cp_p_stid = p_stid; + cps->cp_active = false; + cps->cp_timeout = jiffies + (nn->nfsd4_lease * HZ); + INIT_LIST_HEAD(&cps->cp_list); + spin_lock(&nn->s2s_cp_lock); + list_add(&cps->cp_list, &p_stid->sc_cp_list); + spin_unlock(&nn->s2s_cp_lock); + + return cps; +out_free: + kfree(cps); + return NULL; +} + +void nfs4_free_copy_state(struct nfsd4_copy *copy) { struct nfsd_net *nn; @@ -743,6 +773,27 @@ void nfs4_free_cp_state(struct nfsd4_copy *copy) spin_unlock(&nn->s2s_cp_lock); } +static void nfs4_free_cpntf_statelist(struct net *net, struct nfs4_stid *stid) +{ + struct nfs4_cpntf_state *cps; + struct nfsd_net *nn; + + nn = net_generic(net, nfsd_net_id); + + might_sleep(); + + spin_lock(&nn->s2s_cp_lock); + while (!list_empty(&stid->sc_cp_list)) { + cps = list_first_entry(&stid->sc_cp_list, + struct nfs4_cpntf_state, cp_list); + list_del(&cps->cp_list); + idr_remove(&nn->s2s_cp_stateids, + cps->cp_stateid.si_opaque.so_id); + kfree(cps); + } + spin_unlock(&nn->s2s_cp_lock); +} + static struct nfs4_ol_stateid * nfs4_alloc_open_stateid(struct nfs4_client *clp) { struct nfs4_stid *stid; @@ -891,6 +942,7 @@ static void block_delegations(struct knfsd_fh *fh) } idr_remove(&clp->cl_stateids, s->sc_stateid.si_opaque.so_id); spin_unlock(&clp->cl_lock); + nfs4_free_cpntf_statelist(clp->net, s); s->sc_free(s); if (fp) put_nfs4_file(fp); diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 879ddc6..c9fb625 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1840,6 +1840,22 @@ static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp, } static __be32 +nfsd4_decode_copy_notify(struct nfsd4_compoundargs *argp, + struct nfsd4_copy_notify *cn) +{ + int status; + + status = nfsd4_decode_stateid(argp, &cn->cpn_src_stateid); + if (status) + return status; + status = nfsd4_decode_nl4_server(argp, &cn->cpn_dst); + if (status) + return status; + + return status; +} + +static __be32 nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek) { DECODE_HEAD; @@ -1940,7 +1956,7 @@ static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp, /* new operations for NFSv4.2 */ [OP_ALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate, [OP_COPY] = (nfsd4_dec)nfsd4_decode_copy, - [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_notsupp, + [OP_COPY_NOTIFY] = (nfsd4_dec)nfsd4_decode_copy_notify, [OP_DEALLOCATE] = (nfsd4_dec)nfsd4_decode_fallocate, [OP_IO_ADVISE] = (nfsd4_dec)nfsd4_decode_notsupp, [OP_LAYOUTERROR] = (nfsd4_dec)nfsd4_decode_notsupp, @@ -4325,6 +4341,45 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp, } static __be32 +nfsd42_encode_nl4_server(struct nfsd4_compoundres *resp, struct nl4_server *ns) +{ + struct xdr_stream *xdr = &resp->xdr; + struct nfs42_netaddr *addr; + __be32 *p; + + p = xdr_reserve_space(xdr, 4); + *p++ = cpu_to_be32(ns->nl4_type); + + switch (ns->nl4_type) { + case NL4_NETADDR: + addr = &ns->u.nl4_addr; + + /** netid_len, netid, uaddr_len, uaddr (port included + * in RPCBIND_MAXUADDRLEN) + */ + p = xdr_reserve_space(xdr, + 4 /* netid len */ + + (XDR_QUADLEN(addr->netid_len) * 4) + + 4 /* uaddr len */ + + (XDR_QUADLEN(addr->addr_len) * 4)); + if (!p) + return nfserr_resource; + + *p++ = cpu_to_be32(addr->netid_len); + p = xdr_encode_opaque_fixed(p, addr->netid, + addr->netid_len); + *p++ = cpu_to_be32(addr->addr_len); + p = xdr_encode_opaque_fixed(p, addr->addr, + addr->addr_len); + break; + default: + WARN_ON(ns->nl4_type != NL4_NETADDR); + } + + return 0; +} + +static __be32 nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_copy *copy) { @@ -4358,6 +4413,44 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp, } static __be32 +nfsd4_encode_copy_notify(struct nfsd4_compoundres *resp, __be32 nfserr, + struct nfsd4_copy_notify *cn) +{ + struct xdr_stream *xdr = &resp->xdr; + __be32 *p; + + if (nfserr) + return nfserr; + + /* 8 sec, 4 nsec */ + p = xdr_reserve_space(xdr, 12); + if (!p) + return nfserr_resource; + + /* cnr_lease_time */ + p = xdr_encode_hyper(p, cn->cpn_sec); + *p++ = cpu_to_be32(cn->cpn_nsec); + + /* cnr_stateid */ + nfserr = nfsd4_encode_stateid(xdr, &cn->cpn_cnr_stateid); + if (nfserr) + return nfserr; + + /* cnr_src.nl_nsvr */ + p = xdr_reserve_space(xdr, 4); + if (!p) + return nfserr_resource; + + *p++ = cpu_to_be32(1); + + nfserr = nfsd42_encode_nl4_server(resp, &cn->cpn_src); + if (nfserr) + return nfserr; + + return nfserr; +} + +static __be32 nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_seek *seek) { @@ -4454,7 +4547,7 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp, /* NFSv4.2 operations */ [OP_ALLOCATE] = (nfsd4_enc)nfsd4_encode_noop, [OP_COPY] = (nfsd4_enc)nfsd4_encode_copy, - [OP_COPY_NOTIFY] = (nfsd4_enc)nfsd4_encode_noop, + [OP_COPY_NOTIFY] = (nfsd4_enc)nfsd4_encode_copy_notify, [OP_DEALLOCATE] = (nfsd4_enc)nfsd4_encode_noop, [OP_IO_ADVISE] = (nfsd4_enc)nfsd4_encode_noop, [OP_LAYOUTERROR] = (nfsd4_enc)nfsd4_encode_noop, diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 304de3b..31b12b1 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -94,6 +94,7 @@ struct nfs4_stid { #define NFS4_REVOKED_DELEG_STID 16 #define NFS4_CLOSED_DELEG_STID 32 #define NFS4_LAYOUT_STID 64 + struct list_head sc_cp_list; unsigned char sc_type; stateid_t sc_stateid; spinlock_t sc_lock; @@ -102,6 +103,17 @@ struct nfs4_stid { void (*sc_free)(struct nfs4_stid *); }; +/* Keep a list of stateids issued by the COPY_NOTIFY, associate it with the + * parent OPEN/LOCK/DELEG stateid. + */ +struct nfs4_cpntf_state { + stateid_t cp_stateid; + struct list_head cp_list; /* per parent nfs4_stid */ + struct nfs4_stid *cp_p_stid; /* pointer to parent */ + bool cp_active; /* has the copy started */ + unsigned long cp_timeout; /* copy timeout */ +}; + /* * Represents a delegation stateid. The nfs4_client holds references to these * and they are put when it is being destroyed or when the delegation is @@ -613,8 +625,10 @@ __be32 nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate, struct nfs4_stid **s, struct nfsd_net *nn); struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *slab, void (*sc_free)(struct nfs4_stid *)); -int nfs4_init_cp_state(struct nfsd_net *nn, struct nfsd4_copy *copy); -void nfs4_free_cp_state(struct nfsd4_copy *copy); +int nfs4_init_copy_state(struct nfsd_net *nn, struct nfsd4_copy *copy); +void nfs4_free_copy_state(struct nfsd4_copy *copy); +struct nfs4_cpntf_state *nfs4_alloc_init_cpntf_state(struct nfsd_net *nn, + struct nfs4_stid *p_stid); void nfs4_unhash_stid(struct nfs4_stid *s); void nfs4_put_stid(struct nfs4_stid *s); void nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid); diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 513c9ff..bade8e5 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -568,6 +568,18 @@ struct nfsd4_offload_status { u32 status; }; +struct nfsd4_copy_notify { + /* request */ + stateid_t cpn_src_stateid; + struct nl4_server cpn_dst; + + /* response */ + stateid_t cpn_cnr_stateid; + u64 cpn_sec; + u32 cpn_nsec; + struct nl4_server cpn_src; +}; + struct nfsd4_op { int opnum; const struct nfsd4_operation * opdesc; @@ -627,6 +639,7 @@ struct nfsd4_op { struct nfsd4_clone clone; struct nfsd4_copy copy; struct nfsd4_offload_status offload_status; + struct nfsd4_copy_notify copy_notify; struct nfsd4_seek seek; } u; struct nfs4_replay * replay; From patchwork Fri Nov 30 20:03:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 10707125 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 433DA14D6 for ; Fri, 30 Nov 2018 20:04:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3735B2C041 for ; Fri, 30 Nov 2018 20:04:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2B6FE30100; Fri, 30 Nov 2018 20:04:07 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CF9AE2C041 for ; Fri, 30 Nov 2018 20:04:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726766AbeLAHO3 (ORCPT ); Sat, 1 Dec 2018 02:14:29 -0500 Received: from mail-oi1-f194.google.com ([209.85.167.194]:35483 "EHLO mail-oi1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725790AbeLAHO3 (ORCPT ); Sat, 1 Dec 2018 02:14:29 -0500 Received: by mail-oi1-f194.google.com with SMTP id v6so5787844oif.2; Fri, 30 Nov 2018 12:04:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=6zt/YWGQAQJzm1pGDaEw7wvtmJ5ZI+B3uWmI29UKanI=; b=Q3zK/pkwves+5bncZW1fHbihRhBOIextwKpOtvMJFNK603y1TWWNls9pJfOwHKeFH7 c44nVR0n6/0lgGZxs96brWsMZtEkgOE5nxp2A+ZV4egPXqUyMgSwVsSXgJoe5uBxBKFz rma5qpLGNpmEV0isBxIxRwAIw0Ayv4XhiPGTE1kAgqsoSeFaUv9wLkGxdax/PfTeZ8sx jiiTOOZgxmvF9qHGJu1XR7ov003YLREQTpXIQFSzo3JFihO1bv+v7O7DdEt3a6PTM9PB ZcvsWYl1hpkv1ljOZQ5hFZGx0HEqci+nN/2hu5vFADwt2eX2hXHRHTM8C8+HDE6tYonC dVvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=6zt/YWGQAQJzm1pGDaEw7wvtmJ5ZI+B3uWmI29UKanI=; b=pT3r6RGwK4+J6zT325A+xwCE/PTiwKsH4XiqrCpsRuQJfZTJDTO56WGBpe/z/LrDEF tH/CDjqtXEqaQnRMV5njOkMBh8FjhOJK45603YJagXHwukBjFcMOhC2Hz8Vg0a9YON8e g+BqjQN2xYZeGIulaQR3Xwczff0IM4PpgSq9G86+DkRuJIUvDuv4b7ChUJ1tMjr0+Pu3 zZybjvBF4wwsFulSQ2QZ0PeiUqre1i9CDmPpQaWFTt+obPQn0RPB3ntunrqHIXDhPb2Q U/pGoYo+UcVBcmvEACUC97aLY0FPDJ4Ap4aeHXKoWKBEocqYOhAoke1E0FummkVlcyQr +CnA== X-Gm-Message-State: AA+aEWauJjK7MUKGzrUJuR/PRm0g8sHLydZFSQQtbT8Dnrafalit2FET GxfStl1LadvwXORDfrKxcuacmuHA X-Google-Smtp-Source: AFSGD/Xv1gJgMCFKEINJTv08mXr2ySFbmMLA9xymD+/F3o91egsnJEzB9OTBqmplJOijcY52tmuUJA== X-Received: by 2002:aca:3e06:: with SMTP id l6mr4299834oia.299.1543608244342; Fri, 30 Nov 2018 12:04:04 -0800 (PST) Received: from Olgas-MBP-195.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id q10sm2065289otl.15.2018.11.30.12.04.02 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 30 Nov 2018 12:04:02 -0800 (PST) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 07/10] NFSD check stateids against copy stateids Date: Fri, 30 Nov 2018 15:03:45 -0500 Message-Id: <20181130200348.59524-8-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20181130200348.59524-1-olga.kornievskaia@gmail.com> References: <20181130200348.59524-1-olga.kornievskaia@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Incoming stateid (used by a READ) could be a saved copy stateid. On first use make it active and check that the copy has started within the allowable lease time. Signed-off-by: Olga Kornievskaia --- fs/nfsd/nfs4state.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index eaa136f..7b3586ab 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -5203,6 +5203,49 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) return 0; } +/* + * A READ from an inter server to server COPY will have a + * copy stateid. Return the parent nfs4_stid. + */ +static __be32 _find_cpntf_state(struct nfsd_net *nn, stateid_t *st, + struct nfs4_cpntf_state **cps) +{ + struct nfs4_cpntf_state *state = NULL; + + if (st->si_opaque.so_clid.cl_id != nn->s2s_cp_cl_id) + return nfserr_bad_stateid; + spin_lock(&nn->s2s_cp_lock); + state = idr_find(&nn->s2s_cp_stateids, st->si_opaque.so_id); + if (state) + refcount_inc(&state->cp_p_stid->sc_count); + spin_unlock(&nn->s2s_cp_lock); + if (!state) + return nfserr_bad_stateid; + *cps = state; + return 0; +} + +static __be32 find_cpntf_state(struct nfsd_net *nn, stateid_t *st, + struct nfs4_stid **stid) +{ + __be32 status; + struct nfs4_cpntf_state *cps = NULL; + + status = _find_cpntf_state(nn, st, &cps); + if (status) + return status; + + /* Did the inter server to server copy start in time? */ + if (cps->cp_active == false && !time_after(cps->cp_timeout, jiffies)) { + nfs4_put_stid(cps->cp_p_stid); + return nfserr_partner_no_auth; + } else + cps->cp_active = true; + + *stid = cps->cp_p_stid; + + return nfs_ok; +} /* * Checks for stateid operations @@ -5235,6 +5278,8 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid) status = nfsd4_lookup_stateid(cstate, stateid, NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID, &s, nn); + if (status == nfserr_bad_stateid) + status = find_cpntf_state(nn, stateid, &s); if (status) return status; status = nfsd4_stid_check_stateid_generation(stateid, s, From patchwork Fri Nov 30 20:03:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 10707129 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2AFA214D6 for ; Fri, 30 Nov 2018 20:04:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1E4EB2C041 for ; Fri, 30 Nov 2018 20:04:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 12B3330100; Fri, 30 Nov 2018 20:04:09 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AF5842C041 for ; Fri, 30 Nov 2018 20:04:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726773AbeLAHOb (ORCPT ); Sat, 1 Dec 2018 02:14:31 -0500 Received: from mail-oi1-f193.google.com ([209.85.167.193]:39964 "EHLO mail-oi1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725790AbeLAHOb (ORCPT ); Sat, 1 Dec 2018 02:14:31 -0500 Received: by mail-oi1-f193.google.com with SMTP id t204so5772959oie.7; Fri, 30 Nov 2018 12:04:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=QqhAMMIdOepyiUKnkFdrR5tgFJjvwo8ZlYPRjNqTO9k=; b=tFqLWRFTQ6hF5ZIIWn8PRTb2eF3VLspYCJ1hPJ1mcCvjEq7T+yuncCQJRJOhgwaqMO 37296v3UNZejYM5Qzomiq9EYslpVFuqfH7jjcQeAfPjVEUbhkEsfd2odk23zYGz5YBun qy0Z8TgUhh0XS7bc0nVBpWDfm9s0a+1+/pIRuFjOyPBdqBfnbYBbrXYFVsk6Iq2IJbdP rW7KCUbK/psVMf9/LeYiwnBZmXvyBueH6GU2gDgFXHIBbKsI7jE0TUc0PhG8p68zYZvZ YxB5QOKoI6nrqh+a3FlzNcMQH9orPd9YOutsr8TbLrtAgR3avhxsdUCMZjkVauD4rER6 Fxag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=QqhAMMIdOepyiUKnkFdrR5tgFJjvwo8ZlYPRjNqTO9k=; b=sRPb1tuH216Hy2BvT8lH5CIycX3giqlMUHcz/4carVVNLQgr8bZipCylxybFoJyIM2 prCBf2rCfDAPVLQMdMGcW/bWOuCyMU+sJmS5uVM844CK//dxrtDlYKv5SlhOfj7CTKTU PRoBzklb5+SjsLh0sTFrJe3jyKMc7qOhdWqQqyMlfDtB8PWwr1Tl5zhE8VVyWkXX0won IXVoWOoYybpcomZ/LvSHprwpHzN/FGPEQnzM0f9PzFIvWzqCDl7mt3SmrQIoqhOod/0r CIHwbTyu9wNrYQ1g1VSJzdqBh9VCjaj58JGsU+LhyNlSG0cJ9sEhRWymVGDYbg1hUjVd x7XQ== X-Gm-Message-State: AA+aEWZl3JzKq1z4thB0gPa14xKdyeCUbMO0Y6p8B2ZPUhNo3TdqiixI C0GowJ0WLJYNSK0I5l7d6YQ= X-Google-Smtp-Source: AFSGD/Wn1z9UUL44CplTn1Cc7CVUcTI5DrqsxVlcdpCmLKk22ndMeHXcBL0N9O0vitT/hu6vCmzbRg== X-Received: by 2002:a54:488b:: with SMTP id r11mr4316968oic.80.1543608246428; Fri, 30 Nov 2018 12:04:06 -0800 (PST) Received: from Olgas-MBP-195.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id q10sm2065289otl.15.2018.11.30.12.04.04 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 30 Nov 2018 12:04:05 -0800 (PST) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 08/10] NFSD generalize nfsd4_compound_state flag names Date: Fri, 30 Nov 2018 15:03:46 -0500 Message-Id: <20181130200348.59524-9-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20181130200348.59524-1-olga.kornievskaia@gmail.com> References: <20181130200348.59524-1-olga.kornievskaia@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Olga Kornievskaia Allow for sid_flag field non-stateid use. Signed-off-by: Andy Adamson --- fs/nfsd/nfs4proc.c | 8 ++++---- fs/nfsd/nfs4state.c | 7 ++++--- fs/nfsd/xdr4.h | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 51fca9e..70d03e9 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -530,9 +530,9 @@ static __be32 nfsd4_open_omfg(struct svc_rqst *rqstp, struct nfsd4_compound_stat return nfserr_restorefh; fh_dup2(&cstate->current_fh, &cstate->save_fh); - if (HAS_STATE_ID(cstate, SAVED_STATE_ID_FLAG)) { + if (HAS_CSTATE_FLAG(cstate, SAVED_STATE_ID_FLAG)) { memcpy(&cstate->current_stateid, &cstate->save_stateid, sizeof(stateid_t)); - SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG); + SET_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG); } return nfs_ok; } @@ -542,9 +542,9 @@ static __be32 nfsd4_open_omfg(struct svc_rqst *rqstp, struct nfsd4_compound_stat union nfsd4_op_u *u) { fh_dup2(&cstate->save_fh, &cstate->current_fh); - if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG)) { + if (HAS_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG)) { memcpy(&cstate->save_stateid, &cstate->current_stateid, sizeof(stateid_t)); - SET_STATE_ID(cstate, SAVED_STATE_ID_FLAG); + SET_CSTATE_FLAG(cstate, SAVED_STATE_ID_FLAG); } return nfs_ok; } diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 7b3586ab..3f5fb0b 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -7423,7 +7423,8 @@ static int nfs4_state_create_net(struct net *net) static void get_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid) { - if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG) && CURRENT_STATEID(stateid)) + if (HAS_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG) && + CURRENT_STATEID(stateid)) memcpy(stateid, &cstate->current_stateid, sizeof(stateid_t)); } @@ -7432,14 +7433,14 @@ static int nfs4_state_create_net(struct net *net) { if (cstate->minorversion) { memcpy(&cstate->current_stateid, stateid, sizeof(stateid_t)); - SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG); + SET_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG); } } void clear_current_stateid(struct nfsd4_compound_state *cstate) { - CLEAR_STATE_ID(cstate, CURRENT_STATE_ID_FLAG); + CLEAR_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG); } /* diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index bade8e5..9d7318c 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -46,9 +46,9 @@ #define CURRENT_STATE_ID_FLAG (1<<0) #define SAVED_STATE_ID_FLAG (1<<1) -#define SET_STATE_ID(c, f) ((c)->sid_flags |= (f)) -#define HAS_STATE_ID(c, f) ((c)->sid_flags & (f)) -#define CLEAR_STATE_ID(c, f) ((c)->sid_flags &= ~(f)) +#define SET_CSTATE_FLAG(c, f) ((c)->sid_flags |= (f)) +#define HAS_CSTATE_FLAG(c, f) ((c)->sid_flags & (f)) +#define CLEAR_CSTATE_FLAG(c, f) ((c)->sid_flags &= ~(f)) struct nfsd4_compound_state { struct svc_fh current_fh; From patchwork Fri Nov 30 20:03:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 10707133 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A386214D6 for ; Fri, 30 Nov 2018 20:04:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 96E482C041 for ; Fri, 30 Nov 2018 20:04:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8B195300F8; Fri, 30 Nov 2018 20:04:10 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1EC3230121 for ; Fri, 30 Nov 2018 20:04:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726779AbeLAHOc (ORCPT ); Sat, 1 Dec 2018 02:14:32 -0500 Received: from mail-oi1-f196.google.com ([209.85.167.196]:43639 "EHLO mail-oi1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725790AbeLAHOc (ORCPT ); Sat, 1 Dec 2018 02:14:32 -0500 Received: by mail-oi1-f196.google.com with SMTP id u18so5763917oie.10; Fri, 30 Nov 2018 12:04:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=iMCV1jh/pLcsPx1ywGQf3T4aGAZUO1oiUx9bDrugrSE=; b=j/DWnOQ3UrNLG4v11p0rrXaEsWLoDckCk47EC5VI95Xi8qMuihFTUwKb3YR4GLpQ2g zo9Da3uzvG5n+Yri5y+ICtAW3DJq/obnp7PuPvViD1tFI8cHzZMQl7kx1a/3dXYt0wbI 4wPPmqfH31jtmG2IE22pY3cI89lKDsR0kRiKuj4hmByAbNVDqc4+HOB6pk+hwrmZhJgi MPtv+SEkzsxQQvU9/sw9kjv2UUaPgxbWjUnghnialEuYQWkNzRvJVmpXSEvDFVwYkt1t f/mJKQexsLP/KESBP9LSCpuSYMcN/mn85itvwQoufCFy4nenbGRH34Z8SpEncEKj0I3S WxvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=iMCV1jh/pLcsPx1ywGQf3T4aGAZUO1oiUx9bDrugrSE=; b=KQ1WGhm+advNPWFNE1kQZSMFNVOT4/7hEav2IELQA2ERwjAu4uopqYvtUS/PhqVCwO p9FLzPvhJwVSFaPfBdF8RXcHPdjzqm2Bua1h4jufNfFHbkeAeqVn1SPI3OQgZ0krV5P0 ouDtcfrefoeKlG8XodkFb1WmGhOE3E5jv6j9ULLeVZMPil0VUJB5pI4oxcbhHcgoHAWS BY6p8pIlaYC6Lqw0NAGk4dtvAVYkyFRfAAHXIEG7qdWCynDdMHPS01USLbWMkv21zKLJ OiM52WLYzCRZR0fIYRWkWoQvQ4i9LOWSmuQJpTeHrpEg6V6DgFZv0sluWQQO9I/KkOTl oS0g== X-Gm-Message-State: AA+aEWbPnC8F1B1gJACMiWA3rqOXGok7X72tvcS49tbMXVy5qS7ThA7w I+MoWwDHfAoQxbLyL14H0yw= X-Google-Smtp-Source: AFSGD/VTyeecdpTReLmgRyOuO/7HCKDhq7gnuLrQ5P4gq+lZasX0G8twYAF371RARIMJJHuSe/hF9w== X-Received: by 2002:aca:da84:: with SMTP id r126mr4373337oig.219.1543608247872; Fri, 30 Nov 2018 12:04:07 -0800 (PST) Received: from Olgas-MBP-195.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id q10sm2065289otl.15.2018.11.30.12.04.06 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 30 Nov 2018 12:04:06 -0800 (PST) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 09/10] NFSD: allow inter server COPY to have a STALE source server fh Date: Fri, 30 Nov 2018 15:03:47 -0500 Message-Id: <20181130200348.59524-10-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20181130200348.59524-1-olga.kornievskaia@gmail.com> References: <20181130200348.59524-1-olga.kornievskaia@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The inter server to server COPY source server filehandle is a foreign filehandle as the COPY is sent to the destination server. Signed-off-by: Olga Kornievskaia --- fs/nfsd/Kconfig | 10 ++++++++++ fs/nfsd/nfs4proc.c | 41 ++++++++++++++++++++++++++++++++++++----- fs/nfsd/nfsfh.h | 5 ++++- fs/nfsd/xdr4.h | 1 + 4 files changed, 51 insertions(+), 6 deletions(-) diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig index 20b1c17..37ff3d5 100644 --- a/fs/nfsd/Kconfig +++ b/fs/nfsd/Kconfig @@ -131,6 +131,16 @@ config NFSD_FLEXFILELAYOUT If unsure, say N. +config NFSD_V4_2_INTER_SSC + bool "NFSv4.2 inter server to server COPY" + depends on NFSD_V4 && NFS_V4_1 && NFS_V4_2 + help + This option enables support for NFSv4.2 inter server to + server copy where the destination server calls the NFSv4.2 + client to read the data to copy from the source server. + + If unsure, say N. + config NFSD_V4_SECURITY_LABEL bool "Provide Security Label support for NFSv4 server" depends on NFSD_V4 && SECURITY diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 70d03e9..2e28254 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -503,12 +503,20 @@ static __be32 nfsd4_open_omfg(struct svc_rqst *rqstp, struct nfsd4_compound_stat union nfsd4_op_u *u) { struct nfsd4_putfh *putfh = &u->putfh; + __be32 ret; fh_put(&cstate->current_fh); cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen; memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval, putfh->pf_fhlen); - return fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_BYPASS_GSS); + ret = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_BYPASS_GSS); +#ifdef CONFIG_NFSD_V4_2_INTER_SSC + if (ret == nfserr_stale && putfh->no_verify) { + SET_FH_FLAG(&cstate->current_fh, NFSD4_FH_FOREIGN); + ret = 0; + } +#endif + return ret; } static __be32 @@ -1967,11 +1975,12 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp, { struct nfsd4_compoundargs *args = rqstp->rq_argp; struct nfsd4_compoundres *resp = rqstp->rq_resp; - struct nfsd4_op *op; + struct nfsd4_op *op, *current_op, *saved_op; struct nfsd4_compound_state *cstate = &resp->cstate; struct svc_fh *current_fh = &cstate->current_fh; struct svc_fh *save_fh = &cstate->save_fh; __be32 status; + int i; svcxdr_init_encode(rqstp, resp); resp->tagp = resp->xdr.p; @@ -2006,6 +2015,27 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp, resp->opcnt = 1; goto encode_op; } +#ifdef CONFIG_NFSD_V4_2_INTER_SSC + /* traverse all operation and if it's a COPY compound, mark the + * source filehandle to skip verification + */ + for (i = 0; i < args->opcnt; i++) { + op = &args->ops[i]; + if (op->opnum == OP_PUTFH) + current_op = op; + else if (op->opnum == OP_SAVEFH) + saved_op = current_op; + else if (op->opnum == OP_RESTOREFH) + current_op = saved_op; + else if (op->opnum == OP_COPY) { + struct nfsd4_copy *copy = (struct nfsd4_copy *)&op[i].u; + struct nfsd4_putfh *putfh = + (struct nfsd4_putfh *)&saved_op->u; + if (!copy->cp_intra) + putfh->no_verify = true; + } + } +#endif trace_nfsd_compound(rqstp, args->opcnt); while (!status && resp->opcnt < args->opcnt) { @@ -2021,13 +2051,14 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp, op->status = nfsd4_open_omfg(rqstp, cstate, op); goto encode_op; } - - if (!current_fh->fh_dentry) { + if (!current_fh->fh_dentry && + !HAS_FH_FLAG(current_fh, NFSD4_FH_FOREIGN)) { if (!(op->opdesc->op_flags & ALLOWED_WITHOUT_FH)) { op->status = nfserr_nofilehandle; goto encode_op; } - } else if (current_fh->fh_export->ex_fslocs.migrated && + } else if (current_fh->fh_export && + current_fh->fh_export->ex_fslocs.migrated && !(op->opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) { op->status = nfserr_moved; goto encode_op; diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h index 755e256..b9c7568 100644 --- a/fs/nfsd/nfsfh.h +++ b/fs/nfsd/nfsfh.h @@ -35,7 +35,7 @@ static inline ino_t u32_to_ino_t(__u32 uino) bool fh_locked; /* inode locked by us */ bool fh_want_write; /* remount protection taken */ - + int fh_flags; /* FH flags */ #ifdef CONFIG_NFSD_V3 bool fh_post_saved; /* post-op attrs saved */ bool fh_pre_saved; /* pre-op attrs saved */ @@ -56,6 +56,9 @@ static inline ino_t u32_to_ino_t(__u32 uino) #endif /* CONFIG_NFSD_V3 */ } svc_fh; +#define NFSD4_FH_FOREIGN (1<<0) +#define SET_FH_FLAG(c, f) ((c)->fh_flags |= (f)) +#define HAS_FH_FLAG(c, f) ((c)->fh_flags & (f)) enum nfsd_fsid { FSID_DEV = 0, diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 9d7318c..fbd18d6 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -221,6 +221,7 @@ struct nfsd4_lookup { struct nfsd4_putfh { u32 pf_fhlen; /* request */ char *pf_fhval; /* request */ + bool no_verify; /* represents foreigh fh */ }; struct nfsd4_open { From patchwork Fri Nov 30 20:03:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 10707137 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 19C2F13B0 for ; Fri, 30 Nov 2018 20:04:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0D206300F8 for ; Fri, 30 Nov 2018 20:04:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 01695301CC; Fri, 30 Nov 2018 20:04:12 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3B791300F8 for ; Fri, 30 Nov 2018 20:04:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726788AbeLAHOf (ORCPT ); Sat, 1 Dec 2018 02:14:35 -0500 Received: from mail-ot1-f65.google.com ([209.85.210.65]:46412 "EHLO mail-ot1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725790AbeLAHOe (ORCPT ); Sat, 1 Dec 2018 02:14:34 -0500 Received: by mail-ot1-f65.google.com with SMTP id w25so6191239otm.13; Fri, 30 Nov 2018 12:04:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=kxRBQRSAxzCTBzKVVhjEpQCdKjT3iYYyHuoGgGevBJ0=; b=WXhg7pVY2kvl0EM4tB0VbliP7tMdIzptNPPDDVQxz/NAKtdWzaQa/+vonRR2+k2X8A 0EORZJbawKtd1QWV0GnR4CweOe1V3EoYTFGoYyRM/XZibjzCSrPSw768ryWGGAtvxzSh mEJoJHhLMUCmpZafiF8I8NDiM4KkkmXWIiRczW/gNAC+jKhonYwGFlWayVuF755kOReO lu9ZPBPzDmzh85dx1DPc0BHmRprVMp5uAe3mQbrxBDobNwcW+zzim3poc5xH+Nb0UceJ NBhvs1tQaAuJPV2Ec+QQEOiucmof4PmN6X8GCFJlNzOOvVkg5ebj5EhdHsS59Vdj1E89 jXvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=kxRBQRSAxzCTBzKVVhjEpQCdKjT3iYYyHuoGgGevBJ0=; b=YAEocuN5K+/LjL0DrmfFE+34l0MNLRw0uj+zoB3yO9FmOF8q/0ua18qL7IwftLpcAn NM1HpLgEe668pLL9zBKOEpNDRfHKqWN5UFucAfJ5M20j/Yc1WhVn69DrGOxKpf0Nj/yz hg6+0S1DG/nZsFiWBNmtD2CFA7wzFEaiJ8hE4hPcTrv9zntC5F/W1v/MWopdY/JQPGot Ld4kec3/ogx391vdmhHhNU4TqyESFImMFZyc5/LEPddMMj68C0Keit+TzUnvXS0JhthK ecojVHbM7ckarbqUiUDrgD2nijth+ZAT2fhR9RcR9gqUnV8IuGg0JhswPMrGlQEmDJ/v 5a2A== X-Gm-Message-State: AA+aEWbttutp3oXEAR3GtUSzF1rFR+Gv4MNFU00FSr4X4XpHyOsEx3dJ jZKQwgudSFE/C2vG+8O+ZiU= X-Google-Smtp-Source: AFSGD/X+3bl5FzT9dVsAGOOlN3beaNHqil8K7PGJoeX2O7j22ZAoXOLvo1/L8c5Lb9u0moPaqyMuiw== X-Received: by 2002:a9d:7f0d:: with SMTP id j13mr4078139otq.119.1543608249504; Fri, 30 Nov 2018 12:04:09 -0800 (PST) Received: from Olgas-MBP-195.attlocal.net (172-10-226-31.lightspeed.livnmi.sbcglobal.net. [172.10.226.31]) by smtp.gmail.com with ESMTPSA id q10sm2065289otl.15.2018.11.30.12.04.07 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 30 Nov 2018 12:04:08 -0800 (PST) From: Olga Kornievskaia To: bfields@redhat.com Cc: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v2 10/10] NFSD add nfs4 inter ssc to nfsd4_copy Date: Fri, 30 Nov 2018 15:03:48 -0500 Message-Id: <20181130200348.59524-11-olga.kornievskaia@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20181130200348.59524-1-olga.kornievskaia@gmail.com> References: <20181130200348.59524-1-olga.kornievskaia@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Given a universal address, mount the source server from the destination server. Use an internal mount. Call the NFS client nfs42_ssc_open to obtain the NFS struct file suitable for nfsd_copy_range. Ability to do "inter" server-to-server depends on the an nfsd kernel parameter "inter_copy_offload_enabled". Signed-off-by: Olga Kornievskaia Signed-off-by: Andy Adamson --- fs/nfsd/nfs4proc.c | 274 +++++++++++++++++++++++++++++++++++++++++++++++---- fs/nfsd/nfssvc.c | 6 ++ fs/nfsd/xdr4.h | 5 + include/linux/nfs4.h | 1 + 4 files changed, 269 insertions(+), 17 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 2e28254..238c4b7 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1155,6 +1155,209 @@ void nfsd4_shutdown_copy(struct nfs4_client *clp) while ((copy = nfsd4_get_copy(clp)) != NULL) nfsd4_stop_copy(copy); } +#ifdef CONFIG_NFSD_V4_2_INTER_SSC + +extern struct file *nfs42_ssc_open(struct vfsmount *ss_mnt, + struct nfs_fh *src_fh, + nfs4_stateid *stateid); +extern void nfs42_ssc_close(struct file *filep); + +extern void nfs_sb_deactive(struct super_block *sb); + +#define NFSD42_INTERSSC_MOUNTOPS "minorversion=2,vers=4,addr=%s" + +/** + * Support one copy source server for now. + */ +static __be32 +nfsd4_interssc_connect(struct nl4_server *nss, struct svc_rqst *rqstp, + struct vfsmount **mount) +{ + struct file_system_type *type; + struct vfsmount *ss_mnt; + struct nfs42_netaddr *naddr; + struct sockaddr_storage tmp_addr; + size_t tmp_addrlen, match_netid_len = 3; + char *startsep = "", *endsep = "", *match_netid = "tcp"; + char *ipaddr, *dev_name, *raw_data; + int len, raw_len, status = -EINVAL; + + naddr = &nss->u.nl4_addr; + tmp_addrlen = rpc_uaddr2sockaddr(SVC_NET(rqstp), naddr->addr, + naddr->addr_len, + (struct sockaddr *)&tmp_addr, + sizeof(tmp_addr)); + if (tmp_addrlen == 0) + goto out_err; + + if (tmp_addr.ss_family == AF_INET6) { + startsep = "["; + endsep = "]"; + match_netid = "tcp6"; + match_netid_len = 4; + } + + if (naddr->netid_len != match_netid_len || + strncmp(naddr->netid, match_netid, naddr->netid_len)) + goto out_err; + + /* Construct the raw data for the vfs_kern_mount call */ + len = RPC_MAX_ADDRBUFLEN + 1; + ipaddr = kzalloc(len, GFP_KERNEL); + if (!ipaddr) + goto out_err; + + rpc_ntop((struct sockaddr *)&tmp_addr, ipaddr, len); + + /* 2 for ipv6 endsep and startsep. 3 for ":/" and trailing '/0'*/ + + raw_len = strlen(NFSD42_INTERSSC_MOUNTOPS) + strlen(ipaddr); + raw_data = kzalloc(raw_len, GFP_KERNEL); + if (!raw_data) + goto out_free_ipaddr; + + snprintf(raw_data, raw_len, NFSD42_INTERSSC_MOUNTOPS, ipaddr); + + status = -ENODEV; + type = get_fs_type("nfs"); + if (!type) + goto out_free_rawdata; + + /* Set the server: for the vfs_kern_mount call */ + dev_name = kzalloc(len + 5, GFP_KERNEL); + if (!dev_name) + goto out_free_rawdata; + snprintf(dev_name, len + 5, "%s%s%s:/", startsep, ipaddr, endsep); + + /* Use an 'internal' mount: MS_KERNMOUNT -> MNT_INTERNAL */ + ss_mnt = vfs_kern_mount(type, MS_KERNMOUNT, dev_name, raw_data); + module_put(type->owner); + if (IS_ERR(ss_mnt)) + goto out_free_devname; + + status = 0; + *mount = ss_mnt; + +out_free_devname: + kfree(dev_name); +out_free_rawdata: + kfree(raw_data); +out_free_ipaddr: + kfree(ipaddr); +out_err: + return status; +} + +static void +nfsd4_interssc_disconnect(struct vfsmount *ss_mnt) +{ + nfs_sb_deactive(ss_mnt->mnt_sb); + mntput(ss_mnt); +} + +/** + * nfsd4_setup_inter_ssc + * + * Verify COPY destination stateid. + * Connect to the source server with NFSv4.1. + * Create the source struct file for nfsd_copy_range. + * Called with COPY cstate: + * SAVED_FH: source filehandle + * CURRENT_FH: destination filehandle + * + * Returns errno (not nfserrxxx) + */ +static __be32 +nfsd4_setup_inter_ssc(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, + struct nfsd4_copy *copy, struct vfsmount **mount) +{ + struct svc_fh *s_fh = NULL; + stateid_t *s_stid = ©->cp_src_stateid; + __be32 status = -EINVAL; + + /* Verify the destination stateid and set dst struct file*/ + status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, + ©->cp_dst_stateid, + WR_STATE, ©->file_dst, NULL, + NULL); + if (status) + goto out; + + status = nfsd4_interssc_connect(©->cp_src, rqstp, mount); + if (status) + goto out; + + s_fh = &cstate->save_fh; + + copy->c_fh.size = s_fh->fh_handle.fh_size; + memcpy(copy->c_fh.data, &s_fh->fh_handle.fh_base, copy->c_fh.size); + copy->stateid.seqid = s_stid->si_generation; + memcpy(copy->stateid.other, (void *)&s_stid->si_opaque, + sizeof(stateid_opaque_t)); + + status = 0; +out: + return status; +} + +static void +nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct file *src, + struct file *dst) +{ + nfs42_ssc_close(src); + fput(src); + fput(dst); + mntput(ss_mnt); +} + +#else /* CONFIG_NFSD_V4_2_INTER_SSC */ + +static __be32 +nfsd4_setup_inter_ssc(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, + struct nfsd4_copy *copy, + struct vfs_mount **mount) +{ + *mount = NULL; + return -EINVAL; +} + +static void +nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct file *src, + struct file *dst) +{ +} + +static void +nfsd4_interssc_disconnect(struct vfsmount *ss_mnt) +{ +} + +static struct file *nfs42_ssc_open(struct vfsmount *ss_mnt, + struct nfs_fh *src_fh, + nfs4_stateid *stateid) +{ + return NULL; +} +#endif /* CONFIG_NFSD_V4_2_INTER_SSC */ + +static __be32 +nfsd4_setup_intra_ssc(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, + struct nfsd4_copy *copy) +{ + return nfsd4_verify_copy(rqstp, cstate, ©->cp_src_stateid, + ©->file_src, ©->cp_dst_stateid, + ©->file_dst, NULL); +} + +static void +nfsd4_cleanup_intra_ssc(struct file *src, struct file *dst) +{ + fput(src); + fput(dst); +} static void nfsd4_cb_offload_release(struct nfsd4_callback *cb) { @@ -1219,12 +1422,16 @@ static __be32 nfsd4_do_copy(struct nfsd4_copy *copy, bool sync) status = nfs_ok; } - fput(copy->file_src); - fput(copy->file_dst); + if (!copy->cp_intra) /* Inter server SSC */ + nfsd4_cleanup_inter_ssc(copy->ss_mnt, copy->file_src, + copy->file_dst); + else + nfsd4_cleanup_intra_ssc(copy->file_src, copy->file_dst); + return status; } -static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst) +static int dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst) { dst->cp_src_pos = src->cp_src_pos; dst->cp_dst_pos = src->cp_dst_pos; @@ -1234,8 +1441,17 @@ static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst) memcpy(&dst->fh, &src->fh, sizeof(src->fh)); dst->cp_clp = src->cp_clp; dst->file_dst = get_file(src->file_dst); - dst->file_src = get_file(src->file_src); + dst->cp_intra = src->cp_intra; + if (src->cp_intra) /* for inter, file_src doesn't exist yet */ + dst->file_src = get_file(src->file_src); memcpy(&dst->cp_stateid, &src->cp_stateid, sizeof(src->cp_stateid)); + memcpy(&dst->cp_src, &src->cp_src, sizeof(struct nl4_server)); + memcpy(&dst->stateid, &src->stateid, sizeof(src->stateid)); + memcpy(&dst->c_fh, &src->c_fh, sizeof(src->c_fh)); + dst->ss_mnt = src->ss_mnt; + + return 0; + } static void cleanup_async_copy(struct nfsd4_copy *copy) @@ -1254,7 +1470,18 @@ static int nfsd4_do_async_copy(void *data) struct nfsd4_copy *copy = (struct nfsd4_copy *)data; struct nfsd4_copy *cb_copy; + if (!copy->cp_intra) { /* Inter server SSC */ + copy->file_src = nfs42_ssc_open(copy->ss_mnt, ©->c_fh, + ©->stateid); + if (IS_ERR(copy->file_src)) { + copy->nfserr = nfserr_offload_denied; + nfsd4_interssc_disconnect(copy->ss_mnt); + goto do_callback; + } + } + copy->nfserr = nfsd4_do_copy(copy, 0); +do_callback: cb_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL); if (!cb_copy) goto out; @@ -1278,11 +1505,20 @@ static int nfsd4_do_async_copy(void *data) __be32 status; struct nfsd4_copy *async_copy = NULL; - status = nfsd4_verify_copy(rqstp, cstate, ©->cp_src_stateid, - ©->file_src, ©->cp_dst_stateid, - ©->file_dst, NULL); - if (status) - goto out; + if (!copy->cp_intra) { /* Inter server SSC */ + if (!inter_copy_offload_enable || copy->cp_synchronous) { + status = nfserr_notsupp; + goto out; + } + status = nfsd4_setup_inter_ssc(rqstp, cstate, copy, + ©->ss_mnt); + if (status) + return nfserr_offload_denied; + } else { + status = nfsd4_setup_intra_ssc(rqstp, cstate, copy); + if (status) + return status; + } copy->cp_clp = cstate->clp; memcpy(©->fh, &cstate->current_fh.fh_handle, @@ -1293,15 +1529,15 @@ static int nfsd4_do_async_copy(void *data) status = nfserrno(-ENOMEM); async_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL); if (!async_copy) - goto out; - if (!nfs4_init_copy_state(nn, copy)) { - kfree(async_copy); - goto out; - } + goto out_err; + if (!nfs4_init_copy_state(nn, copy)) + goto out_err; refcount_set(&async_copy->refcount, 1); memcpy(©->cp_res.cb_stateid, ©->cp_stateid, sizeof(copy->cp_stateid)); - dup_copy_fields(copy, async_copy); + status = dup_copy_fields(copy, async_copy); + if (status) + goto out_err; async_copy->copy_task = kthread_create(nfsd4_do_async_copy, async_copy, "%s", "copy thread"); if (IS_ERR(async_copy->copy_task)) @@ -1312,13 +1548,17 @@ static int nfsd4_do_async_copy(void *data) spin_unlock(&async_copy->cp_clp->async_lock); wake_up_process(async_copy->copy_task); status = nfs_ok; - } else + } else { status = nfsd4_do_copy(copy, 1); + } out: return status; out_err: cleanup_async_copy(async_copy); - goto out; + status = nfserrno(-ENOMEM); + if (!copy->cp_intra) + nfsd4_interssc_disconnect(copy->ss_mnt); + goto out_err; } struct nfsd4_copy * diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 89cb484..9d254e7 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -30,6 +30,12 @@ #define NFSDDBG_FACILITY NFSDDBG_SVC +bool inter_copy_offload_enable; +EXPORT_SYMBOL_GPL(inter_copy_offload_enable); +module_param(inter_copy_offload_enable, bool, 0644); +MODULE_PARM_DESC(inter_copy_offload_enable, + "Enable inter server to server copy offload. Default: false"); + extern struct svc_program nfsd_program; static int nfsd(void *vrqstp); diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index fbd18d6..bb2f8e5 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -547,7 +547,12 @@ struct nfsd4_copy { struct task_struct *copy_task; refcount_t refcount; bool stopped; + + struct vfsmount *ss_mnt; + struct nfs_fh c_fh; + nfs4_stateid stateid; }; +extern bool inter_copy_offload_enable; struct nfsd4_seek { /* request */ diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 9e49a6c..fa4b411 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -17,6 +17,7 @@ #include #include #include +#include enum nfs4_acl_whotype { NFS4_ACL_WHO_NAMED = 0,