The patch titled NFS: Replace null dentries that appear in readdir's list has been removed from the -mm tree. Its filename is nfs-replace-null-dentries-that-appear-in-readdirs-list-2.patch This patch was dropped because it is obsolete ------------------------------------------------------ Subject: NFS: Replace null dentries that appear in readdir's list From: David Howells <dhowells@xxxxxxxxxx> (Previously nacked by Trond. I retained it because the cachefiles code might need it. Help.) Have nfs_readdir_lookup() drop and replace any null dentry when it that gets listed by a READDIR RPC call. This can be caused by an optimisation in nfs_lookup() that causes a dentry to be incorrectly left as negative when mkdir() or similar is aborted by SELinux mid-procedure. This can be triggered by mounting through autofs4 a server:/ NFS share for which there are other exports available on that server. SELinux also has to be turned on in enforcing mode to abort mid-flow the mkdir operation performed by autofs4. The problematic sequence of events is this: (1) nfs_lookup() is called by sys_mkdirat() -> lookup_create() -> __lookup_hash() with intent to create exclusively set in the nameidata: nd->flags == LOOKUP_CREATE nd->intent.open.flags == O_EXCL (2) nfs_lookup() has an optimisation to avoid going to the server in this case, presumably since the nfs_mkdir() op or whatever will deal with the conflict. (3) nfs_lookup() returns successfully, leaving the dentry in a negative state, but attached to the parent directory. (4) sys_mkdirat() calls vfs_mkdir() which calls may_create(). may_create() checks that the directory has MAY_WRITE and MAY_EXEC permissions. (5) may_create() calls nfs_permission(), which grants permission. (6) may_create() calls security_inode_permission(), which calls SELinux, which then _DENIES_ permission. (7) may_create() fails, and vfs_mkdir() then fails and sys_mkdirat() then fails (as does sys_mkdir). _However_, the new dentry is left in the negative state, with no consultation of the server. (8) The parent directory is listed, and the name of the new dentry is returned. (9) stat on the new dentry fails (because it's negative), and "ls -l" returns "?---------" as the file type and mode. This fix makes step (8) replace the dentry looked up in steps (1) - (3). Signed-off-by: David Howells <dhowells@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- fs/nfs/dir.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff -puN fs/nfs/dir.c~nfs-replace-null-dentries-that-appear-in-readdirs-list-2 fs/nfs/dir.c --- a/fs/nfs/dir.c~nfs-replace-null-dentries-that-appear-in-readdirs-list-2 +++ a/fs/nfs/dir.c @@ -1112,14 +1112,27 @@ static struct dentry *nfs_readdir_lookup } name.hash = full_name_hash(name.name, name.len); dentry = d_lookup(parent, &name); - if (dentry != NULL) - return dentry; - if (!desc->plus || !(entry->fattr->valid & NFS_ATTR_FATTR)) - return NULL; - /* Note: caller is already holding the dir->i_mutex! */ - dentry = d_alloc(parent, &name); - if (dentry == NULL) + if (dentry != NULL) { + if (IS_ERR(dentry) || dentry->d_inode) + return dentry; + + /* this negative dentry matched a dirent obtained from readdir + * and so needs reconsideration */ + d_drop(dentry); + + if (!desc->plus || !(entry->fattr->valid & NFS_ATTR_FATTR)) { + dput(dentry); + return NULL; + } + } else if (!desc->plus || !(entry->fattr->valid & NFS_ATTR_FATTR)) { return NULL; + } else { + /* Note: caller is already holding the dir->i_mutex! */ + dentry = d_alloc(parent, &name); + if (dentry == NULL) + return NULL; + } + dentry->d_op = NFS_PROTO(dir)->dentry_ops; inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr); if (IS_ERR(inode)) { _ Patches currently in -mm which might be from dhowells@xxxxxxxxxx are origin.patch git-block.patch git-block-hack.patch git-gfs2.patch nfs-replace-null-dentries-that-appear-in-readdirs-list-2.patch git-serial.patch mm-tracking-shared-dirty-pages-nommu-fix-2.patch binfmt_elf-consistently-use-loff_t.patch frv-use-the-generic-irq-stuff.patch frv-improve-frvs-use-of-generic-irq-handling.patch frv-permit-__do_irq-to-be-dispensed-with.patch frv-fix-fls-to-handle-bit-31-being-set-correctly.patch frv-implement-fls64.patch frv-optimise-ffs.patch alchemy-delete-unused-pt_regs-argument-from-au1xxx_dbdma_chan_alloc.patch nommu-check-that-access_process_vm-has-a-valid-target.patch nommu-set-bdi-capabilities-for-dev-mem-and-dev-kmem.patch nommu-set-bdi-capabilities-for-dev-mem-and-dev-kmem-tidy.patch nommu-use-find_vma-rather-than-reimplementing-a-vma-search.patch check-if-start-address-is-in-vma-region-in-nommu-function-get_user_pages.patch nommu-check-vma-protections.patch nommu-permit-ptrace-to-ignore-non-prot_write-vmas-in-nommu-mode.patch nommu-implement-proc-pid-maps-for-nommu.patch nommu-order-the-per-mm_struct-vma-list.patch nommu-make-mremap-partially-work-for-nommu-kernels.patch nommu-add-docs-about-shared-memory.patch nommu-make-futexes-work-under-nommu-conditions.patch nommu-make-futexes-work-under-nommu-conditions-doc.patch nommu-move-the-fallback-arch_vma_name-to-a-sensible-place.patch nommu-move-the-fallback-arch_vma_name-to-a-sensible-place-fix.patch afs-add-lock-annotations-to-afs_proc_cell_servers_startstop.patch elf_fdpic_core_dump-dont-take-tasklist_lock.patch simplify-update_times-avoid-jiffies-jiffies_64-aliasing-problem-2.patch lib-rwsemc-un-inline-rwsem_down_failed_common.patch kill-wall_jiffies.patch reiserfs-make-sure-all-dentries-refs-are-released-before-calling-kill_block_super-try-2.patch fs-cache-provide-a-filesystem-specific-syncable-page-bit.patch fs-cache-generic-filesystem-caching-facility.patch fs-cache-release-page-private-in-failed-readahead.patch fs-cache-release-page-private-after-failed-readahead-12.patch fs-cache-make-kafs-use-fs-cache.patch fs-cache-make-kafs-use-fs-cache-fix.patch fs-cache-make-kafs-use-fs-cache-12.patch fs-cache-make-kafs-use-fs-cache-12-fix.patch fs-cache-make-kafs-use-fs-cache-kconfig-fix.patch fs-cache-make-kafs-use-fs-cache-vs-streamline-generic_file_-interfaces-and-filemap.patch nfs-use-local-caching.patch nfs-use-local-caching-12.patch nfs-use-local-caching-12-fix.patch nfs-use-local-caching-kconfig-fix.patch add-missing-page_copy-export-for-ppc-and-powerpc.patch fs-cache-cachefiles-ia64-missing-copy_page-export.patch fs-cache-cachefiles-a-cache-that-backs-onto-a-mounted-filesystem.patch fs-cache-cachefiles-a-cache-that-backs-onto-a-mounted-filesystem-cachefiles-printk-format-warning.patch fs-cache-cachefiles-a-cache-that-backs-onto-a-mounted-filesystem-warning-fixes.patch fs-cache-cachefiles-a-cache-that-backs-onto-a-mounted-filesystem-cachefiles-cachefiles_write_page-shouldnt-indicate-error-twice.patch fs-cache-cachefiles-a-cache-that-backs-onto-a-mounted-filesystem-cachefiles-handle-enospc-on-create-mkdir-better.patch fs-cache-cachefiles-a-cache-that-backs-onto-a-mounted-filesystem-inode-count-maintenance.patch autofs-make-sure-all-dentries-refs-are-released-before-calling-kill_anon_super.patch vfs-destroy-the-dentries-contributed-by-a-superblock-on-unmounting.patch afs-amend-the-afs-configuration-options.patch generic-ioremap_page_range-implementation-nommu-fix.patch vfs-make-filldir_t-and-struct-kstat-deal-in-64-bit-inode-numbers.patch vfs-make-filldir_t-and-struct-kstat-deal-in-64-bit-inode-numbers-alpha-fix.patch nfs-represent-64-bit-fileids-as-64-bit-inode-numbers-on-32-bit-systems.patch ecryptfs-get_sb_dev-fix.patch ecryptfs-inode-numbering-fixes.patch introduce-kernel_execve.patch rename-the-provided-execve-functions-to-kernel_execve.patch provide-kernel_execve-on-all-architectures.patch provide-kernel_execve-on-all-architectures-fix.patch remove-the-use-of-_syscallx-macros-in-uml.patch sh64-remove-the-use-of-kernel-syscalls.patch remove-remaining-errno-and-__kernel_syscalls__-references.patch reiser4-get_sb_dev-fix.patch mutex-subsystem-synchro-test-module.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html