From patchwork Mon May 15 14:39:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Weinberger X-Patchwork-Id: 9727123 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A80C96028A for ; Mon, 15 May 2017 14:39:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 99B4D28952 for ; Mon, 15 May 2017 14:39:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8E23928968; Mon, 15 May 2017 14:39:29 +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=-6.9 required=2.0 tests=BAYES_00,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 D92AE28952 for ; Mon, 15 May 2017 14:39:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964971AbdEOOj2 (ORCPT ); Mon, 15 May 2017 10:39:28 -0400 Received: from b.ns.miles-group.at ([95.130.255.144]:44725 "EHLO radon.swed.at" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S933464AbdEOOj0 (ORCPT ); Mon, 15 May 2017 10:39:26 -0400 Received: (qmail 26781 invoked by uid 89); 15 May 2017 14:39:24 -0000 Received: by simscan 1.3.1 ppid: 26776, pid: 26779, t: 0.0389s scanners: attach: 1.3.1 Received: from unknown (HELO ?10.1.1.177?) (richard@nod.at@82.150.214.13) by radon.swed.at with ESMTPA; 15 May 2017 14:39:24 -0000 From: Richard Weinberger To: linux-fscrypt@vger.kernel.org Cc: linux-fsdevel , Eric Biggers , Theodore Ts'o , Al Viro , David Gstir , David Oberhollenzer , "linux-kernel@vger.kernel.org" , "linux-mtd@lists.infradead.org" , Artem Bityutskiy , Adrian Hunter Subject: Question on fscrypt_d_revalidate() and fstest generic/429 Message-ID: Date: Mon, 15 May 2017 16:39:23 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.7.1 MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Hi! on UBIFS, fstest generic/429 fails due to -ENFILE because the internal orphan list reaches the maximum size. When you unlink a file, the inode goes into the orphan list, in UBIFS' evict() function it is being removed later. So, only unlinked but used inodes should stay in that list. If a directory is encrypted, evict() is not being called although the inode has no users anymore. It turned out evict() is not being called because fscrypt's fscrypt_d_revalidate() function. When I omit fscrypt_set_d_op() in UBIFS code, the test works just fine. Can it be that fscrypt_d_revalidate() misses the case of i_nlink being 0? It seem to treat unlinked inodes as already gone and they stay. The following change makes the problem go away here: Does this change make sense? TBH, I'm not really an expert in this area and it is also not clear to me why you don't see these issue on ext4 or f2fs. Maybe UBIFS' limitations kick in much earlier. ;-) Thanks, //richard --- To unsubscribe from this list: send the line "unsubscribe linux-fscrypt" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 6d6eca394d4d..d0c19838e513 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -327,6 +327,7 @@ EXPORT_SYMBOL(fscrypt_decrypt_page); static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags) { struct dentry *dir; + struct inode *inode = d_inode(dentry); int dir_has_key, cached_with_key; if (flags & LOOKUP_RCU) @@ -359,6 +360,10 @@ static int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags) (!cached_with_key && dir_has_key) || (cached_with_key && !dir_has_key)) return 0; + + if (!inode || inode->i_nlink == 0) + return 0; + return 1; }