From patchwork Wed Aug 26 08:16:45 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Tao X-Patchwork-Id: 7075331 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 879159F305 for ; Wed, 26 Aug 2015 08:20:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A61EB208E8 for ; Wed, 26 Aug 2015 08:20:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 969B7205C4 for ; Wed, 26 Aug 2015 08:20:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756540AbbHZITF (ORCPT ); Wed, 26 Aug 2015 04:19:05 -0400 Received: from mail-pa0-f54.google.com ([209.85.220.54]:34998 "EHLO mail-pa0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756399AbbHZITB (ORCPT ); Wed, 26 Aug 2015 04:19:01 -0400 Received: by pacdd16 with SMTP id dd16so153139236pac.2 for ; Wed, 26 Aug 2015 01:18:59 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ASPPxdmP9I0q+nRYTU4Nj9sRQJbFlwBzpNEEMD3A9HA=; b=R0jUVz4iFn03noqJtjF1+bSDAQqPGDP1kNbEe5DHDLlzwqMRiDAnDKcCp6uyfqzcou Gwuf74gsJEwcQ+5K5RUKWhIqinxxk0lYkxthnmPT9fDc/M6gSSlgm06qvkcwRj9Y5mZ5 aL0jsaqMadZ8Hv8CcIBH6QX3GfzCjINvfn5WdzKkpu9h/ceNKDfhsNsIdusstG7MTS+a nVd1IHaJqKLElozS39ugps4r1Wxm0TUFHFbaOcL5eDwtA38mgk8UH33ynQuJZJzlQd0L oj3i9jdpEesAJLk+JNRXGWDbK921BSxpgK0KQIwkWoOG9gLgUr18NVbXg5wqxSxkAe7l bkpg== X-Gm-Message-State: ALoCoQmAvw0jwZb2ZIiwQBJq2Th6hE/sv0yte14PM/qlgmBEn5MzAkUkL13+G8Xa2+UWFwyZ8x45 X-Received: by 10.68.136.234 with SMTP id qd10mr67444229pbb.162.1440577139770; Wed, 26 Aug 2015 01:18:59 -0700 (PDT) Received: from lear.localdomain (ec2-54-65-164-9.ap-northeast-1.compute.amazonaws.com. [54.65.164.9]) by smtp.gmail.com with ESMTPSA id a2sm23689455pbu.41.2015.08.26.01.18.55 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 26 Aug 2015 01:18:59 -0700 (PDT) From: Peng Tao To: linux-fsdevel@vger.kernel.org Cc: Trond Myklebust , Anna Schumaker , Christoph Hellwig , Zach Brown , Darren Hart , bfields@fieldses.org, Jeff Layton , linux-nfs@vger.kernel.org, "Darrick J. Wong" , linux-btrfs@vger.kernel.org, Peng Tao Subject: [PATCH-RFC-RESEND 4/9] nfs42: add CLONE proc functions Date: Wed, 26 Aug 2015 16:16:45 +0800 Message-Id: <1440577010-122867-5-git-send-email-tao.peng@primarydata.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1440577010-122867-1-git-send-email-tao.peng@primarydata.com> References: <1440577010-122867-1-git-send-email-tao.peng@primarydata.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-8.3 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Peng Tao --- fs/nfs/nfs42.h | 1 + fs/nfs/nfs42proc.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++ fs/nfs/nfs4proc.c | 3 +- include/linux/nfs_fs_sb.h | 1 + 4 files changed, 75 insertions(+), 1 deletion(-) diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h index ff66ae7..3585f3c 100644 --- a/fs/nfs/nfs42.h +++ b/fs/nfs/nfs42.h @@ -17,6 +17,7 @@ int nfs42_proc_deallocate(struct file *, loff_t, loff_t); loff_t nfs42_proc_llseek(struct file *, loff_t, int); int nfs42_proc_layoutstats_generic(struct nfs_server *, struct nfs42_layoutstat_data *); +int nfs42_proc_clone(struct file *, struct file *, loff_t, loff_t, loff_t); /* nfs4.2xdr.h */ extern struct rpc_procinfo nfs4_2_procedures[]; diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index d731bbf..baa3141 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -269,3 +269,74 @@ int nfs42_proc_layoutstats_generic(struct nfs_server *server, return PTR_ERR(task); return 0; } + +static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f, + struct file *dst_f, loff_t src_offset, + loff_t dst_offset, loff_t count) +{ + struct inode *src_inode = file_inode(src_f); + struct inode *dst_inode = file_inode(dst_f); + struct nfs_server *server = NFS_SERVER(dst_inode); + struct nfs42_clone_args args = { + .src_fh = NFS_FH(src_inode), + .dst_fh = NFS_FH(dst_inode), + .src_offset = src_offset, + .dst_offset = dst_offset, + .dst_bitmask = server->cache_consistency_bitmask, + }; + struct nfs42_clone_res res = { + .server = server, + }; + int status; + + msg->rpc_argp = &args; + msg->rpc_resp = &res; + + status = nfs42_set_rw_stateid(&args.src_stateid, src_f, FMODE_READ); + if (status) + return status; + + status = nfs42_set_rw_stateid(&args.dst_stateid, dst_f, FMODE_WRITE); + if (status) + return status; + + res.dst_fattr = nfs_alloc_fattr(); + if (!res.dst_fattr) + return -ENOMEM; + + status = nfs4_call_sync(server->client, server, msg, + &args.seq_args, &res.seq_res, 0); + if (status == 0) + status = nfs_post_op_update_inode(dst_inode, res.dst_fattr); + + kfree(res.dst_fattr); + return status; +} + +int nfs42_proc_clone(struct file *src_f, struct file *dst_f, + loff_t src_offset, loff_t dst_offset, loff_t count) +{ + struct rpc_message msg = { + .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLONE], + }; + struct inode *inode = file_inode(src_f); + struct nfs_server *server = NFS_SERVER(file_inode(src_f)); + struct nfs4_exception exception = { }; + int err; + + if (!nfs_server_capable(inode, NFS_CAP_CLONE)) + return -EOPNOTSUPP; + + do { + err = _nfs42_proc_clone(&msg, src_f, dst_f, src_offset, + dst_offset, count); + if (err == -ENOTSUPP || err == -EOPNOTSUPP) { + NFS_SERVER(inode)->caps &= ~NFS_CAP_CLONE; + return -EOPNOTSUPP; + } + err = nfs4_handle_exception(server, err, &exception); + } while (exception.retry); + + return err; + +} diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 6e988fd..fb51b75 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -8659,7 +8659,8 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = { | NFS_CAP_ALLOCATE | NFS_CAP_DEALLOCATE | NFS_CAP_SEEK - | NFS_CAP_LAYOUTSTATS, + | NFS_CAP_LAYOUTSTATS + | NFS_CAP_CLONE, .init_client = nfs41_init_client, .shutdown_client = nfs41_shutdown_client, .match_stateid = nfs41_match_stateid, diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 20bc8e5..2fb163a 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -238,5 +238,6 @@ struct nfs_server { #define NFS_CAP_ALLOCATE (1U << 20) #define NFS_CAP_DEALLOCATE (1U << 21) #define NFS_CAP_LAYOUTSTATS (1U << 22) +#define NFS_CAP_CLONE (1U << 23) #endif