Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

eCryptfs: Invalidate dcache entries when lower i_nlink is zero

Consider eCryptfs dcache entries to be stale when the corresponding
lower inode's i_nlink count is zero. This solves a problem caused by the
lower inode being directly modified, without going through the eCryptfs
mount, leaving stale eCryptfs dentries cached and the eCryptfs inode's
i_nlink count not being cleared.

Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Reported-by: Richard Weinberger <richard@nod.at>
Cc: stable@vger.kernel.org

+9 -9
+9 -9
fs/ecryptfs/dentry.c
··· 45 45 static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags) 46 46 { 47 47 struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); 48 - int rc; 49 - 50 - if (!(lower_dentry->d_flags & DCACHE_OP_REVALIDATE)) 51 - return 1; 48 + int rc = 1; 52 49 53 50 if (flags & LOOKUP_RCU) 54 51 return -ECHILD; 55 52 56 - rc = lower_dentry->d_op->d_revalidate(lower_dentry, flags); 57 - if (d_really_is_positive(dentry)) { 58 - struct inode *lower_inode = 59 - ecryptfs_inode_to_lower(d_inode(dentry)); 53 + if (lower_dentry->d_flags & DCACHE_OP_REVALIDATE) 54 + rc = lower_dentry->d_op->d_revalidate(lower_dentry, flags); 60 55 61 - fsstack_copy_attr_all(d_inode(dentry), lower_inode); 56 + if (d_really_is_positive(dentry)) { 57 + struct inode *inode = d_inode(dentry); 58 + 59 + fsstack_copy_attr_all(inode, ecryptfs_inode_to_lower(inode)); 60 + if (!inode->i_nlink) 61 + return 0; 62 62 } 63 63 return rc; 64 64 }