The patch titled proc: Factor out an instantiate method from every lookup method has been added to the -mm tree. Its filename is proc-factor-out-an-instantiate-method-from-every-lookup-method.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: proc: Factor out an instantiate method from every lookup method From: Eric W. Biederman <ebiederm@xxxxxxxxxxxx> To remove the hard coded proc inode numbers it is necessary to be able to create the proc inodes during readdir. The instantiate methods are the subset of lookup that is needed to accomplish that. This first step just splits the lookup methods into 2 functions. Signed-off-by: Eric W. Biederman <ebiederm@xxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- fs/proc/base.c | 269 +++++++++++++++++++++++++++-------------------- 1 files changed, 158 insertions(+), 111 deletions(-) diff -puN fs/proc/base.c~proc-factor-out-an-instantiate-method-from-every-lookup-method fs/proc/base.c --- a/fs/proc/base.c~proc-factor-out-an-instantiate-method-from-every-lookup-method +++ a/fs/proc/base.c @@ -1254,21 +1254,15 @@ static struct dentry_operations tid_fd_d .d_delete = pid_delete_dentry, }; -/* SMP-safe */ -static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd) +static struct dentry *proc_fd_instantiate(struct inode *dir, + struct dentry *dentry, struct task_struct *task, void *ptr) { - struct task_struct *task = get_proc_task(dir); - unsigned fd = name_to_int(dentry); - struct dentry *result = ERR_PTR(-ENOENT); - struct file * file; - struct files_struct * files; - struct inode *inode; - struct proc_inode *ei; - - if (!task) - goto out_no_task; - if (fd == ~0U) - goto out; + unsigned fd = *(unsigned *)ptr; + struct file *file; + struct files_struct *files; + struct inode *inode; + struct proc_inode *ei; + struct dentry *error = ERR_PTR(-ENOENT); inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_FD_DIR+fd); if (!inode) @@ -1277,7 +1271,7 @@ static struct dentry *proc_lookupfd(stru ei->fd = fd; files = get_files_struct(task); if (!files) - goto out_unlock; + goto out_iput; inode->i_mode = S_IFLNK; /* @@ -1287,13 +1281,14 @@ static struct dentry *proc_lookupfd(stru spin_lock(&files->file_lock); file = fcheck_files(files, fd); if (!file) - goto out_unlock2; + goto out_unlock; if (file->f_mode & 1) inode->i_mode |= S_IRUSR | S_IXUSR; if (file->f_mode & 2) inode->i_mode |= S_IWUSR | S_IXUSR; spin_unlock(&files->file_lock); put_files_struct(files); + inode->i_op = &proc_pid_link_inode_operations; inode->i_size = 64; ei->op.proc_get_link = proc_fd_link; @@ -1301,20 +1296,37 @@ static struct dentry *proc_lookupfd(stru d_add(dentry, inode); /* Close the race of the process dying before we return the dentry */ if (tid_fd_revalidate(dentry, NULL)) - result = NULL; -out: - put_task_struct(task); -out_no_task: - return result; + error = NULL; -out_unlock2: + out: + return error; +out_unlock: spin_unlock(&files->file_lock); put_files_struct(files); -out_unlock: +out_iput: iput(inode); goto out; } +/* SMP-safe */ +static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, struct nameidata *nd) +{ + struct task_struct *task = get_proc_task(dir); + unsigned fd = name_to_int(dentry); + struct dentry *result = ERR_PTR(-ENOENT); + + if (!task) + goto out_no_task; + if (fd == ~0U) + goto out; + + result = proc_fd_instantiate(dir, dentry, task, &fd); +out: + put_task_struct(task); +out_no_task: + return result; +} + static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) { struct dentry *dentry = filp->f_dentry; @@ -1395,6 +1407,36 @@ static struct inode_operations proc_fd_i .setattr = proc_setattr, }; +static struct dentry *proc_pident_instantiate(struct inode *dir, + struct dentry *dentry, struct task_struct *task, void *ptr) +{ + struct pid_entry *p = ptr; + struct inode *inode; + struct proc_inode *ei; + struct dentry *error = ERR_PTR(-EINVAL); + + inode = proc_pid_make_inode(dir->i_sb, task, p->type); + if (!inode) + goto out; + + ei = PROC_I(inode); + inode->i_mode = p->mode; + if (S_ISDIR(inode->i_mode)) + inode->i_nlink = 2; /* Use getattr to fix if necessary */ + if (p->iop) + inode->i_op = p->iop; + if (p->fop) + inode->i_fop = p->fop; + ei->op = p->op; + dentry->d_op = &pid_dentry_operations; + d_add(dentry, inode); + /* Close the race of the process dying before we return the dentry */ + if (pid_revalidate(dentry, NULL)) + error = NULL; +out: + return error; +} + /* SMP-safe */ static struct dentry *proc_pident_lookup(struct inode *dir, struct dentry *dentry, @@ -1404,7 +1446,6 @@ static struct dentry *proc_pident_lookup struct dentry *error; struct task_struct *task = get_proc_task(dir); struct pid_entry *p; - struct proc_inode *ei; error = ERR_PTR(-ENOENT); inode = NULL; @@ -1425,25 +1466,7 @@ static struct dentry *proc_pident_lookup if (!p->name) goto out; - error = ERR_PTR(-EINVAL); - inode = proc_pid_make_inode(dir->i_sb, task, p->type); - if (!inode) - goto out; - - ei = PROC_I(inode); - inode->i_mode = p->mode; - if (S_ISDIR(inode->i_mode)) - inode->i_nlink = 2; /* Use getattr to fix if necessary */ - if (p->iop) - inode->i_op = p->iop; - if (p->fop) - inode->i_fop = p->fop; - ei->op = p->op; - dentry->d_op = &pid_dentry_operations; - d_add(dentry, inode); - /* Close the race of the process dying before we return the dentry */ - if (pid_revalidate(dentry, NULL)) - error = NULL; + error = proc_pident_instantiate(dir, dentry, task, p); out: put_task_struct(task); out_no_task: @@ -1709,29 +1732,13 @@ static struct dentry_operations proc_bas .d_delete = pid_delete_dentry, }; -static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) +static struct dentry *proc_base_instantiate(struct inode *dir, + struct dentry *dentry, struct task_struct *task, void *ptr) { + struct pid_entry *p = ptr; struct inode *inode; - struct dentry *error; - struct task_struct *task = get_proc_task(dir); - struct pid_entry *p; struct proc_inode *ei; - - error = ERR_PTR(-ENOENT); - inode = NULL; - - if (!task) - goto out_no_task; - - /* Lookup the directory entry */ - for (p = proc_base_stuff; p->name; p++) { - if (p->len != dentry->d_name.len) - continue; - if (!memcmp(dentry->d_name.name, p->name, p->len)) - break; - } - if (!p->name) - goto out; + struct dentry *error = ERR_PTR(-EINVAL); /* Allocate the inode */ error = ERR_PTR(-ENOMEM); @@ -1767,14 +1774,41 @@ static struct dentry *proc_base_lookup(s d_add(dentry, inode); error = NULL; out: - put_task_struct(task); -out_no_task: return error; out_iput: iput(inode); goto out; } +static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) +{ + struct dentry *error; + struct task_struct *task = get_proc_task(dir); + struct pid_entry *p; + + error = ERR_PTR(-ENOENT); + + if (!task) + goto out_no_task; + + /* Lookup the directory entry */ + for (p = proc_base_stuff; p->name; p++) { + if (p->len != dentry->d_name.len) + continue; + if (!memcmp(dentry->d_name.name, p->name, p->len)) + break; + } + if (!p->name) + goto out; + + error = proc_base_instantiate(dir, dentry, task, p); + +out: + put_task_struct(task); +out_no_task: + return error; +} + /* * Thread groups */ @@ -1915,12 +1949,40 @@ out: return; } +struct dentry *proc_pid_instantiate(struct inode *dir, + struct dentry * dentry, struct task_struct *task, void *ptr) +{ + struct dentry *error = ERR_PTR(-ENOENT); + struct inode *inode; + + inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO); + if (!inode) + goto out; + + inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; + inode->i_op = &proc_tgid_base_inode_operations; + inode->i_fop = &proc_tgid_base_operations; + inode->i_flags|=S_IMMUTABLE; + inode->i_nlink = 4; +#ifdef CONFIG_SECURITY + inode->i_nlink += 1; +#endif + + dentry->d_op = &pid_dentry_operations; + + d_add(dentry, inode); + /* Close the race of the process dying before we return the dentry */ + if (pid_revalidate(dentry, NULL)) + error = NULL; +out: + return error; +} + /* SMP-safe */ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) { struct dentry *result = ERR_PTR(-ENOENT); struct task_struct *task; - struct inode *inode; unsigned tgid; result = proc_base_lookup(dir, dentry); @@ -1939,28 +2001,7 @@ struct dentry *proc_pid_lookup(struct in if (!task) goto out; - inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO); - if (!inode) - goto out_put_task; - - inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; - inode->i_op = &proc_tgid_base_inode_operations; - inode->i_fop = &proc_tgid_base_operations; - inode->i_flags|=S_IMMUTABLE; -#ifdef CONFIG_SECURITY - inode->i_nlink = 5; -#else - inode->i_nlink = 4; -#endif - - dentry->d_op = &pid_dentry_operations; - - d_add(dentry, inode); - /* Close the race of the process dying before we return the dentry */ - if (pid_revalidate(dentry, NULL)) - result = NULL; - -out_put_task: + result = proc_pid_instantiate(dir, dentry, task, NULL); put_task_struct(task); out: return result; @@ -2107,13 +2148,40 @@ static struct inode_operations proc_tid_ .setattr = proc_setattr, }; +static struct dentry *proc_task_instantiate(struct inode *dir, + struct dentry *dentry, struct task_struct *task, void *ptr) +{ + struct dentry *error = ERR_PTR(-ENOENT); + struct inode *inode; + inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO); + + if (!inode) + goto out; + inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; + inode->i_op = &proc_tid_base_inode_operations; + inode->i_fop = &proc_tid_base_operations; + inode->i_flags|=S_IMMUTABLE; + inode->i_nlink = 3; +#ifdef CONFIG_SECURITY + inode->i_nlink += 1; +#endif + + dentry->d_op = &pid_dentry_operations; + + d_add(dentry, inode); + /* Close the race of the process dying before we return the dentry */ + if (pid_revalidate(dentry, NULL)) + error = NULL; +out: + return error; +} + /* SMP-safe */ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) { struct dentry *result = ERR_PTR(-ENOENT); struct task_struct *task; struct task_struct *leader = get_proc_task(dir); - struct inode *inode; unsigned tid; if (!leader) @@ -2133,28 +2201,7 @@ static struct dentry *proc_task_lookup(s if (leader->tgid != task->tgid) goto out_drop_task; - inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO); - - - if (!inode) - goto out_drop_task; - inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; - inode->i_op = &proc_tid_base_inode_operations; - inode->i_fop = &proc_tid_base_operations; - inode->i_flags|=S_IMMUTABLE; -#ifdef CONFIG_SECURITY - inode->i_nlink = 4; -#else - inode->i_nlink = 3; -#endif - - dentry->d_op = &pid_dentry_operations; - - d_add(dentry, inode); - /* Close the race of the process dying before we return the dentry */ - if (pid_revalidate(dentry, NULL)) - result = NULL; - + result = proc_task_instantiate(dir, dentry, task, NULL); out_drop_task: put_task_struct(task); out: _ Patches currently in -mm which might be from ebiederm@xxxxxxxxxxxx are megaraid-use-the-proper-type-to-hold-the-irq-number.patch x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch msi-use-kmem_cache_zalloc.patch sysctl-allow-proc-sys-without-sys_sysctl.patch sysctl-allow-proc-sys-without-sys_sysctl-fix.patch sysctl-document-that-sys_sysctl-will-be-removed.patch pid-implement-transfer_pid-and-use-it-to-simplify-de_thread.patch pid-remove-temporary-debug-code-in-attach_pid.patch de_thread-use-tsk-not-current.patch fix-conflict-with-the-is_init-identifier-on-parisc.patch pidspace-is_init.patch simplify-update_times-avoid-jiffies-jiffies_64-aliasing-problem-2.patch kexec-warning-fix.patch kill-extraneous-printk-in-kernel_restart.patch fix-mem_write-return-value.patch kcore-elf-note-namesz-field-fix.patch stack-overflow-safe-kdump-safe_smp_processor_id.patch stack-overflow-safe-kdump-safe_smp_processor_id_voyager.patch stack-overflow-safe-kdump-crash_use_safe_smp_processor_id.patch stack-overflow-safe-kdump-crash_use_safe_smp_processor_id-fix.patch stack-overflow-safe-kdump-safe_smp_send_nmi_allbutself.patch proc-readdir-race-fix-take-3.patch proc-reorder-the-functions-in-basec.patch proc-modify-proc_pident_lookup-to-be-completely-table-driven.patch proc-give-the-root-directory-a-task.patch pid-implement-access-helpers-for-a-tacks-various-process-groups.patch pid-add-do_each_pid_task.patch pid-implement-signal-functions-that-take-a-struct-pid.patch pid-export-the-symbols-needed-to-use-struct-pid.patch pid-implement-pid_nr.patch vt-update-spawnpid-to-be-a-struct-pid_t.patch vt-update-spawnpid-to-be-a-struct-pid_t-tidy.patch file-modify-struct-fown_struct-to-use-a-struct-pid.patch file-modify-struct-fown_struct-to-use-a-struct-pid-fix.patch pids-coding-style-use-struct-pidmap.patch proc-readdir-race-fix-take-3-fix-1.patch simplify-pid-iterators.patch move-pidmap-to-pspaceh.patch move-pidmap-to-pspaceh-fix.patch define-struct-pspace.patch proc-readdir-race-fix-take-3-fix-2.patch proc-sysctl-add-_proc_do_string-helper.patch namespaces-add-nsproxy.patch namespaces-add-nsproxy-move-init_nsproxy-into-kernel-nsproxyc.patch namespaces-incorporate-fs-namespace-into-nsproxy.patch namespaces-incorporate-fs-namespace-into-nsproxy-whitespace.patch namespaces-utsname-introduce-temporary-helpers.patch namespaces-utsname-switch-to-using-uts-namespaces.patch namespaces-utsname-use-init_utsname-when-appropriate.patch namespaces-utsname-implement-utsname-namespaces.patch namespaces-utsname-sysctl-hack.patch namespaces-utsname-remove-system_utsname.patch namespaces-utsname-implement-clone_newuts-flag.patch uts-copy-nsproxy-only-when-needed.patch namespaces-utsname-switch-to-using-uts-namespaces-klibc-bit.patch namespaces-utsname-use-init_utsname-when-appropriate-klibc-bit.patch namespaces-utsname-switch-to-using-uts-namespaces-klibc-bit-2.patch ipc-namespace-core.patch ipc-namespace-utils.patch proc-make-the-generation-of-the-self-symlink-table-driven.patch proc-factor-out-an-instantiate-method-from-every-lookup-method.patch proc-remove-the-hard-coded-inode-numbers.patch proc-merge-proc_tid_attr-and-proc_tgid_attr.patch proc-use-pid_task-instead-of-open-coding-it.patch genirq-irq-convert-the-move_irq-flag-from-a-32bit-word-to-a-single-bit.patch genirq-irq-add-moved_masked_irq.patch genirq-x86_64-irq-reenable-migrating-irqs-to-other-cpus.patch genirq-msi-simplify-msi-enable-and-disable.patch genirq-msi-make-the-msi-boolean-tests-return-either-0-or-1.patch genirq-msi-implement-helper-functions-read_msi_msg-and-write_msi_msg.patch genirq-msi-refactor-the-msi_ops.patch genirq-msi-simplify-the-msi-irq-limit-policy.patch genirq-irq-add-a-dynamic-irq-creation-api.patch genirq-ia64-irq-dynamic-irq-support.patch genirq-i386-irq-dynamic-irq-support.patch genirq-x86_64-irq-dynamic-irq-support.patch genirq-msi-make-the-msi-code-irq-based-and-not-vector-based.patch genirq-x86_64-irq-move-msi-message-composition-into-io_apicc.patch genirq-i386-irq-move-msi-message-composition-into-io_apicc.patch genirq-msi-only-build-msi-apicc-on-ia64.patch genirq-msi-only-build-msi-apicc-on-ia64-fix.patch genirq-x86_64-irq-remove-the-msi-assumption-that-irq-==-vector.patch genirq-i386-irq-remove-the-msi-assumption-that-irq-==-vector.patch genirq-irq-remove-msi-hacks.patch genirq-irq-generalize-the-check-for-hardirq_bits.patch genirq-x86_64-irq-make-the-external-irq-handlers-report-their-vector-not-the-irq-number.patch genirq-x86_64-irq-make-vector_irq-per-cpu.patch genirq-x86_64-irq-make-vector_irq-per-cpu-fix.patch genirq-x86_64-irq-make-vector_irq-per-cpu-warning-fix.patch genirq-x86_64-irq-kill-gsi_irq_sharing.patch genirq-x86_64-irq-kill-irq-compression.patch add-hypertransport-capability-defines.patch add-hypertransport-capability-defines-fix.patch initial-generic-hypertransport-interrupt-support.patch initial-generic-hypertransport-interrupt-support-Kconfig-fix.patch pidhash-temporary-debug-checks.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