From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from zeniv.linux.org.uk ([195.92.253.2]:53120 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753583AbcCJT76 (ORCPT ); Thu, 10 Mar 2016 14:59:58 -0500 Date: Thu, 10 Mar 2016 19:59:51 +0000 From: Al Viro To: "Drokin, Oleg" Cc: "Dilger, Andreas" , Linus Torvalds , "" , Theodore Ts'o , Mark Fasheh Subject: Re: races in ll_splice_alias() and elsewhere (ext4, ocfs2) Message-ID: <20160310195951.GL17997@ZenIV.linux.org.uk> References: <20160308160537.GV17997@ZenIV.linux.org.uk> <498D5A19-9E55-48D7-B5CF-34CA5769FF7F@intel.com> <20160308211148.GX17997@ZenIV.linux.org.uk> <20160309003416.GY17997@ZenIV.linux.org.uk> <7C3EBB6F-54AC-4744-BEC1-33EA82216F85@intel.com> <20160309012658.GZ17997@ZenIV.linux.org.uk> <34C2B1C3-2B7F-490B-A03A-3BCDDFC8BE48@intel.com> <20160310022041.GF17997@ZenIV.linux.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20160310022041.GF17997@ZenIV.linux.org.uk> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: On Thu, Mar 10, 2016 at 02:20:42AM +0000, Al Viro wrote: > I'll pick it. Mind if I fold it into the one I'd posted (with credits, > obviously)? Actually, it's still racy - there's a window between d_obtain_alias() and ll_d_init() where it can be picked by d_splice_alias(). Sigh... I'm really tempted to just add ->d_init() and let d_alloc() call it if non-NULL. The question is what should it get and what should it be the method of... How about int (*d_init)(struct dentry *); in dentry_operations, with __d_alloc() ending with d_set_d_op(dentry, dentry->d_sb->s_d_op); if (unlikely(dentry->d_op && dentry->d_op->d_init)) { int err = dentry->d_op->d_init(dentry); if (unlikely(err)) { dentry_free(dentry); return ERR_PTR(err); } } this_cpu_inc(nr_dentry); return dentry; } Then lustre would simply have int ll_d_init(struct dentry *de) { struct ll_dentry_data *lld = kzalloc(sizeof(*lld), GFP_NOFS); if (unlikely(!lld)) return -ENOMEM; lld->lld_invalid = 1; smp_wmb(); /* read barrier in whatever will find us */ de->d_fsdata = lld; return 0; } as its ->d_init() and forget about all that mess. Objections, better ideas?