diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-12-03 19:15:36 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-12-03 19:15:36 +0300 |
commit | 8002cedc1adbf51e2d56091534ef7551b88329b4 (patch) | |
tree | 2c65c82b2b5300eac581a0ee794d98f0b61593b6 /fs/proc | |
parent | e87cb5db0dc357473ac71801051954ddd6ff604f (diff) | |
parent | d523a328fb0271e1a763e985a21f2488fd816e7e (diff) | |
download | linux-8002cedc1adbf51e2d56091534ef7551b88329b4.tar.xz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/net-2.6: (27 commits)
[INET]: Fix inet_diag dead-lock regression
[NETNS]: Fix /proc/net breakage
[TEXTSEARCH]: Do not allow zero length patterns in the textsearch infrastructure
[NETFILTER]: fix forgotten module release in xt_CONNMARK and xt_CONNSECMARK
[NETFILTER]: xt_TCPMSS: remove network triggerable WARN_ON
[DECNET]: dn_nl_deladdr() almost always returns no error
[IPV6]: Restore IPv6 when MTU is big enough
[RXRPC]: Add missing select on CRYPTO
mac80211: rate limit wep decrypt failed messages
rfkill: fix double-mutex-locking
mac80211: drop unencrypted frames if encryption is expected
mac80211: Fix behavior of ieee80211_open and ieee80211_close
ieee80211: fix unaligned access in ieee80211_copy_snap
mac80211: free ifsta->extra_ie and clear IEEE80211_STA_PRIVACY_INVOKED
SCTP: Fix build issues with SCTP AUTH.
SCTP: Fix chunk acceptance when no authenticated chunks were listed.
SCTP: Fix the supported extensions paramter
SCTP: Fix SCTP-AUTH to correctly add HMACS paramter.
SCTP: Fix the number of HB transmissions.
[TCP] illinois: Incorrect beta usage
...
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/generic.c | 12 | ||||
-rw-r--r-- | fs/proc/proc_net.c | 86 |
2 files changed, 16 insertions, 82 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 39f3d6519035..5fccfe222a63 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -374,9 +374,16 @@ static int proc_delete_dentry(struct dentry * dentry) return 1; } +static int proc_revalidate_dentry(struct dentry *dentry, struct nameidata *nd) +{ + d_drop(dentry); + return 0; +} + static struct dentry_operations proc_dentry_operations = { .d_delete = proc_delete_dentry, + .d_revalidate = proc_revalidate_dentry, }; /* @@ -397,8 +404,11 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nam if (de->namelen != dentry->d_name.len) continue; if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { - unsigned int ino = de->low_ino; + unsigned int ino; + if (de->shadow_proc) + de = de->shadow_proc(current, de); + ino = de->low_ino; de_get(de); spin_unlock(&proc_subdir_lock); error = -EINVAL; diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index 131f9c68be5f..0afe21ee0607 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -50,89 +50,14 @@ struct net *get_proc_net(const struct inode *inode) } EXPORT_SYMBOL_GPL(get_proc_net); -static struct proc_dir_entry *proc_net_shadow; +static struct proc_dir_entry *shadow_pde; -static struct dentry *proc_net_shadow_dentry(struct dentry *parent, +static struct proc_dir_entry *proc_net_shadow(struct task_struct *task, struct proc_dir_entry *de) { - struct dentry *shadow = NULL; - struct inode *inode; - if (!de) - goto out; - de_get(de); - inode = proc_get_inode(parent->d_inode->i_sb, de->low_ino, de); - if (!inode) - goto out_de_put; - shadow = d_alloc_name(parent, de->name); - if (!shadow) - goto out_iput; - shadow->d_op = parent->d_op; /* proc_dentry_operations */ - d_instantiate(shadow, inode); -out: - return shadow; -out_iput: - iput(inode); -out_de_put: - de_put(de); - goto out; -} - -static void *proc_net_follow_link(struct dentry *parent, struct nameidata *nd) -{ - struct net *net = current->nsproxy->net_ns; - struct dentry *shadow; - shadow = proc_net_shadow_dentry(parent, net->proc_net); - if (!shadow) - return ERR_PTR(-ENOENT); - - dput(nd->dentry); - /* My dentry count is 1 and that should be enough as the - * shadow dentry is thrown away immediately. - */ - nd->dentry = shadow; - return NULL; + return task->nsproxy->net_ns->proc_net; } -static struct dentry *proc_net_lookup(struct inode *dir, struct dentry *dentry, - struct nameidata *nd) -{ - struct net *net = current->nsproxy->net_ns; - struct dentry *shadow; - - shadow = proc_net_shadow_dentry(nd->dentry, net->proc_net); - if (!shadow) - return ERR_PTR(-ENOENT); - - dput(nd->dentry); - nd->dentry = shadow; - - return shadow->d_inode->i_op->lookup(shadow->d_inode, dentry, nd); -} - -static int proc_net_setattr(struct dentry *dentry, struct iattr *iattr) -{ - struct net *net = current->nsproxy->net_ns; - struct dentry *shadow; - int ret; - - shadow = proc_net_shadow_dentry(dentry->d_parent, net->proc_net); - if (!shadow) - return -ENOENT; - ret = shadow->d_inode->i_op->setattr(shadow, iattr); - dput(shadow); - return ret; -} - -static const struct file_operations proc_net_dir_operations = { - .read = generic_read_dir, -}; - -static struct inode_operations proc_net_dir_inode_operations = { - .follow_link = proc_net_follow_link, - .lookup = proc_net_lookup, - .setattr = proc_net_setattr, -}; - static __net_init int proc_net_ns_init(struct net *net) { struct proc_dir_entry *root, *netd, *net_statd; @@ -185,9 +110,8 @@ static struct pernet_operations __net_initdata proc_net_ns_ops = { int __init proc_net_init(void) { - proc_net_shadow = proc_mkdir("net", NULL); - proc_net_shadow->proc_iops = &proc_net_dir_inode_operations; - proc_net_shadow->proc_fops = &proc_net_dir_operations; + shadow_pde = proc_mkdir("net", NULL); + shadow_pde->shadow_proc = proc_net_shadow; return register_pernet_subsys(&proc_net_ns_ops); } |