This will allow us to move the generic readlink logic into the VFS and get rid of the readlink method. Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxxxxx> --- fs/proc/namespaces.c | 56 +++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c index 51b8b0a8ad91..9c9a1683791a 100644 --- a/fs/proc/namespaces.c +++ b/fs/proc/namespaces.c @@ -33,6 +33,8 @@ static const struct proc_ns_operations *ns_entries[] = { #endif }; +#define PROC_NS_LINK_MAX 50 + static const char *proc_ns_get_link(struct dentry *dentry, struct inode *inode, struct delayed_call *done) @@ -40,47 +42,47 @@ static const char *proc_ns_get_link(struct dentry *dentry, const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops; struct task_struct *task; struct path ns_path; - void *error = ERR_PTR(-EACCES); + char *res = ERR_PTR(-EACCES); if (!dentry) return ERR_PTR(-ECHILD); task = get_proc_task(inode); if (!task) - return error; - - if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) { - error = ns_get_path(&ns_path, task, ns_ops); - if (!error) - nd_jump_link(&ns_path); - } - put_task_struct(task); - return error; -} - -static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int buflen) -{ - struct inode *inode = d_inode(dentry); - const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops; - struct task_struct *task; - char name[50]; - int res = -EACCES; + goto out; - task = get_proc_task(inode); - if (!task) - return res; + if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) + goto out_put; - if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) { - res = ns_get_name(name, sizeof(name), task, ns_ops); - if (res >= 0) - res = readlink_copy(buffer, buflen, name); + if (is_following_link()) { + res = ns_get_path(&ns_path, task, ns_ops); + if (!res) + nd_jump_link(&ns_path); + } else { + char *name = kmalloc(PROC_NS_LINK_MAX, GFP_KERNEL); + int err; + + res = ERR_PTR(-ENOMEM); + if (!name) + goto out_put; + + err = ns_get_name(name, PROC_NS_LINK_MAX, task, ns_ops); + if (err < 0) { + kfree(name); + res = ERR_PTR(err); + goto out_put; + } + set_delayed_call(done, kfree_link, name); + res = name; } +out_put: put_task_struct(task); +out: return res; } static const struct inode_operations proc_ns_link_inode_operations = { - .readlink = proc_ns_readlink, + .readlink = generic_readlink, .get_link = proc_ns_get_link, .setattr = proc_setattr, }; -- 2.5.5 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html