Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp6904591ybi; Mon, 8 Jul 2019 10:34:05 -0700 (PDT) X-Google-Smtp-Source: APXvYqwbf85QqHn4PSlNaoxlpiAWL4nXGqx+QBw7f/NekU6GDVged7QxF1v2BzHkSBUJ19ZL/0Mj X-Received: by 2002:a17:902:4201:: with SMTP id g1mr26616428pld.300.1562607245089; Mon, 08 Jul 2019 10:34:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1562607245; cv=none; d=google.com; s=arc-20160816; b=g8k/cGlrsuNXlX/nBdl55rxYWdmW9gBCu8aeOeDzE4MWg0DEHpWpVO61OSNv45HoW6 Ai1U89zHGHLVDUR6s+9AnhdPA/j/Jn6WUmfW/NwFhsXGYLlcMKFT4rqhh8jFYedPqV0B MunwhX1vMY9ju7W1NcV6Y4mQYjOu0xLdQczZe03x39ufJ1EqgiyxbkkcMtd0L7nkOOEh EVrGm/ikCzb1OTiFwZyyGUzCfOf8H7MtEJubBhQxNYPgvITi9Yao2bj7bYQCYBF68CJX WB9oqSpEDXJR21Op5Pg2dM1hwjH/W4BYZqxJ26W32YvYgQe9XIAKzIXNYkQ/byBZd92Y FYiQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=T9dRuHk4Gznnu6vlpaTVC8HIA37QFognsB7tNqSFDKY=; b=0mr+6Sf8NP+gHvygQB3eYbTnn3WmPdEOGkeKPIu2HV4dzlzQMaUkCsjU5QP3Zjp+L3 5UOo9NwzRl4mF8EQef91vIZ8EnHLLO1eAlygtRfHCBJzqxrCkEKuYkhPqGroMdGsdYVn RnvW2Q7T0S+vM9RKsnG0ThRkU9geHAl6h2THREvGxAEuE8uZoiA60IotRk5P3AD+Euch Eck2tMoIHdADaj55xQWt8N+dGVKy1iG166fCbmAA9outvtbOcjlOwk4LevIiwc39DgPW b0E+Uqq0VdC9ym2AyZ9xBwZR0NTe/m6Ef32vllkOCRJbSoWuOXGXPPRWdnzL7vuXwr55 Ye6A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q195si18825855pgq.119.2019.07.08.10.33.49; Mon, 08 Jul 2019 10:34:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730680AbfGHMpL (ORCPT + 99 others); Mon, 8 Jul 2019 08:45:11 -0400 Received: from fieldses.org ([173.255.197.46]:37704 "EHLO fieldses.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727052AbfGHMpL (ORCPT ); Mon, 8 Jul 2019 08:45:11 -0400 Received: by fieldses.org (Postfix, from userid 2815) id 18F757CB; Mon, 8 Jul 2019 08:45:10 -0400 (EDT) Date: Mon, 8 Jul 2019 08:45:10 -0400 From: "J. Bruce Fields" To: Stephen Rothwell Cc: Al Viro , Linux Next Mailing List , Linux Kernel Mailing List , David Howells Subject: Re: linux-next: manual merge of the vfs tree with the nfsd tree Message-ID: <20190708124510.GB7625@fieldses.org> References: <20190708110633.6e491989@canb.auug.org.au> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20190708110633.6e491989@canb.auug.org.au> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Jul 08, 2019 at 11:06:33AM +1000, Stephen Rothwell wrote: > Today's linux-next merge of the vfs tree got a conflict in: > > fs/nfsd/nfsctl.c > > between commits: > > e8a79fb14f6b ("nfsd: add nfsd/clients directory") > > from the nfsd tree and commit: > > 96a374a35f82 ("vfs: Convert nfsctl to use the new mount API") I did a fetch of git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git and looked at the "master" branch and couldn't find that vfs commit. Am I looking in the wrong place? (I'm sure your resolution is fine, I just thought to be careful it might be nice to run some tests on the merge.) --b. > > from the vfs tree. > > I fixed it up (Maybe? see below) and can carry the fix as necessary. > This is now fixed as far as linux-next is concerned, but any non trivial > conflicts should be mentioned to your upstream maintainer when your tree > is submitted for merging. You may also want to consider cooperating > with the maintainer of the conflicting tree to minimise any particularly > complex conflicts. > > -- > Cheers, > Stephen Rothwell > > diff --cc fs/nfsd/nfsctl.c > index 4683ba5c69c7,bbff9c4ac49f..000000000000 > --- a/fs/nfsd/nfsctl.c > +++ b/fs/nfsd/nfsctl.c > @@@ -1149,201 -1148,8 +1150,201 @@@ static ssize_t write_v4_end_grace(struc > * populating the filesystem. > */ > > +/* Basically copying rpc_get_inode. */ > +static struct inode *nfsd_get_inode(struct super_block *sb, umode_t mode) > +{ > + struct inode *inode = new_inode(sb); > + if (!inode) > + return NULL; > + /* Following advice from simple_fill_super documentation: */ > + inode->i_ino = iunique(sb, NFSD_MaxReserved); > + inode->i_mode = mode; > + inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); > + switch (mode & S_IFMT) { > + case S_IFDIR: > + inode->i_fop = &simple_dir_operations; > + inode->i_op = &simple_dir_inode_operations; > + inc_nlink(inode); > + default: > + break; > + } > + return inode; > +} > + > +static int __nfsd_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) > +{ > + struct inode *inode; > + > + inode = nfsd_get_inode(dir->i_sb, mode); > + if (!inode) > + return -ENOMEM; > + d_add(dentry, inode); > + inc_nlink(dir); > + fsnotify_mkdir(dir, dentry); > + return 0; > +} > + > +static struct dentry *nfsd_mkdir(struct dentry *parent, struct nfsdfs_client *ncl, char *name) > +{ > + struct inode *dir = parent->d_inode; > + struct dentry *dentry; > + int ret = -ENOMEM; > + > + inode_lock(dir); > + dentry = d_alloc_name(parent, name); > + if (!dentry) > + goto out_err; > + ret = __nfsd_mkdir(d_inode(parent), dentry, S_IFDIR | 0600); > + if (ret) > + goto out_err; > + if (ncl) { > + d_inode(dentry)->i_private = ncl; > + kref_get(&ncl->cl_ref); > + } > +out: > + inode_unlock(dir); > + return dentry; > +out_err: > + dentry = ERR_PTR(ret); > + goto out; > +} > + > +static void clear_ncl(struct inode *inode) > +{ > + struct nfsdfs_client *ncl = inode->i_private; > + > + inode->i_private = NULL; > + synchronize_rcu(); > + kref_put(&ncl->cl_ref, ncl->cl_release); > +} > + > + > +struct nfsdfs_client *__get_nfsdfs_client(struct inode *inode) > +{ > + struct nfsdfs_client *nc = inode->i_private; > + > + if (nc) > + kref_get(&nc->cl_ref); > + return nc; > +} > + > +struct nfsdfs_client *get_nfsdfs_client(struct inode *inode) > +{ > + struct nfsdfs_client *nc; > + > + rcu_read_lock(); > + nc = __get_nfsdfs_client(inode); > + rcu_read_unlock(); > + return nc; > +} > +/* from __rpc_unlink */ > +static void nfsdfs_remove_file(struct inode *dir, struct dentry *dentry) > +{ > + int ret; > + > + clear_ncl(d_inode(dentry)); > + dget(dentry); > + ret = simple_unlink(dir, dentry); > + d_delete(dentry); > + dput(dentry); > + WARN_ON_ONCE(ret); > +} > + > +static void nfsdfs_remove_files(struct dentry *root) > +{ > + struct dentry *dentry, *tmp; > + > + list_for_each_entry_safe(dentry, tmp, &root->d_subdirs, d_child) { > + if (!simple_positive(dentry)) { > + WARN_ON_ONCE(1); /* I think this can't happen? */ > + continue; > + } > + nfsdfs_remove_file(d_inode(root), dentry); > + } > +} > + > +/* XXX: cut'n'paste from simple_fill_super; figure out if we could share > + * code instead. */ > +static int nfsdfs_create_files(struct dentry *root, > + const struct tree_descr *files) > +{ > + struct inode *dir = d_inode(root); > + struct inode *inode; > + struct dentry *dentry; > + int i; > + > + inode_lock(dir); > + for (i = 0; files->name && files->name[0]; i++, files++) { > + if (!files->name) > + continue; > + dentry = d_alloc_name(root, files->name); > + if (!dentry) > + goto out; > + inode = nfsd_get_inode(d_inode(root)->i_sb, > + S_IFREG | files->mode); > + if (!inode) { > + dput(dentry); > + goto out; > + } > + inode->i_fop = files->ops; > + inode->i_private = __get_nfsdfs_client(dir); > + d_add(dentry, inode); > + fsnotify_create(dir, dentry); > + } > + inode_unlock(dir); > + return 0; > +out: > + nfsdfs_remove_files(root); > + inode_unlock(dir); > + return -ENOMEM; > +} > + > +/* on success, returns positive number unique to that client. */ > +struct dentry *nfsd_client_mkdir(struct nfsd_net *nn, > + struct nfsdfs_client *ncl, u32 id, > + const struct tree_descr *files) > +{ > + struct dentry *dentry; > + char name[11]; > + int ret; > + > + sprintf(name, "%u", id); > + > + dentry = nfsd_mkdir(nn->nfsd_client_dir, ncl, name); > + if (IS_ERR(dentry)) /* XXX: tossing errors? */ > + return NULL; > + ret = nfsdfs_create_files(dentry, files); > + if (ret) { > + nfsd_client_rmdir(dentry); > + return NULL; > + } > + return dentry; > +} > + > +/* Taken from __rpc_rmdir: */ > +void nfsd_client_rmdir(struct dentry *dentry) > +{ > + struct inode *dir = d_inode(dentry->d_parent); > + struct inode *inode = d_inode(dentry); > + int ret; > + > + inode_lock(dir); > + nfsdfs_remove_files(dentry); > + clear_ncl(inode); > + dget(dentry); > + ret = simple_rmdir(dir, dentry); > + WARN_ON_ONCE(ret); > + d_delete(dentry); > + inode_unlock(dir); > +} > + > - static int nfsd_fill_super(struct super_block * sb, void * data, int silent) > + static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc) > { > + struct nfsd_net *nn = net_generic(current->nsproxy->net_ns, > + nfsd_net_id); > + struct dentry *dentry; > + int ret; > + > static const struct tree_descr nfsd_files[] = { > [NFSD_List] = {"exports", &exports_nfsd_operations, S_IRUGO}, > [NFSD_Export_features] = {"export_features", > @@@ -1372,23 -1178,33 +1373,39 @@@ > #endif > /* last one */ {""} > }; > - get_net(sb->s_fs_info); > - > - return simple_fill_super(sb, 0x6e667364, nfsd_files); > + ret = simple_fill_super(sb, 0x6e667364, nfsd_files); > + if (ret) > + return ret; > + dentry = nfsd_mkdir(sb->s_root, NULL, "clients"); > + if (IS_ERR(dentry)) > + return PTR_ERR(dentry); > + nn->nfsd_client_dir = dentry; > + return 0; > + } > + > + static int nfsd_fs_get_tree(struct fs_context *fc) > + { > + fc->s_fs_info = get_net(fc->net_ns); > + return vfs_get_super(fc, vfs_get_keyed_super, nfsd_fill_super); > + } > > + static void nfsd_fs_free_fc(struct fs_context *fc) > + { > + if (fc->s_fs_info) > + put_net(fc->s_fs_info); > } > > - static struct dentry *nfsd_mount(struct file_system_type *fs_type, > - int flags, const char *dev_name, void *data) > + static const struct fs_context_operations nfsd_fs_context_ops = { > + .free = nfsd_fs_free_fc, > + .get_tree = nfsd_fs_get_tree, > + }; > + > + static int nfsd_init_fs_context(struct fs_context *fc) > { > - struct net *net = current->nsproxy->net_ns; > - return mount_ns(fs_type, flags, data, net, net->user_ns, nfsd_fill_super); > + put_user_ns(fc->user_ns); > + fc->user_ns = get_user_ns(fc->net_ns->user_ns); > + fc->ops = &nfsd_fs_context_ops; > + return 0; > } > > static void nfsd_umount(struct super_block *sb)