aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-17 17:56:45 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-17 17:56:45 -0500
commit50652963eae6afe13678dc84d789a174306a4df7 (patch)
tree44d6bc6c2cd938cf59db7ba2b7e514d9b3665f40
parente2b74f232e84dfccd0047eb47545b1d028df8ff1 (diff)
parent87b95ce0964c016ede92763be9c164e49f1019e9 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull misc VFS updates from Al Viro: "This cycle a lot of stuff sits on topical branches, so I'll be sending more or less one pull request per branch. This is the first pile; more to follow in a few. In this one are several misc commits from early in the cycle (before I went for separate branches), plus the rework of mntput/dput ordering on umount, switching to use of fs_pin instead of convoluted games in namespace_unlock()" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: switch the IO-triggering parts of umount to fs_pin new fs_pin killing logics allow attaching fs_pin to a group not associated with some superblock get rid of the second argument of acct_kill() take count and rcu_head out of fs_pin dcache: let the dentry count go down to zero without taking d_lock pull bumping refcount into ->kill() kill pin_put() mode_t whack-a-mole: chelsio file->f_path.dentry is pinned down for as long as the file is open... get rid of lustre_dump_dentry() gut proc_register() a bit kill d_validate() ncpfs: get rid of d_validate() nonsense selinuxfs: don't open-code d_genocide()
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h2
-rw-r--r--drivers/staging/lustre/lustre/llite/dcache.c8
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_internal.h1
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_lib.c42
-rw-r--r--fs/dcache.c149
-rw-r--r--fs/fs_pin.c96
-rw-r--r--fs/internal.h2
-rw-r--r--fs/mount.h4
-rw-r--r--fs/namespace.c44
-rw-r--r--fs/ncpfs/dir.c98
-rw-r--r--fs/ncpfs/ncp_fs_i.h1
-rw-r--r--fs/ncpfs/ncplib_kernel.h30
-rw-r--r--fs/proc/generic.c25
-rw-r--r--fs/super.c4
-rw-r--r--include/linux/dcache.h3
-rw-r--r--include/linux/fs_pin.h25
-rw-r--r--include/linux/lockref.h3
-rw-r--r--include/linux/pid_namespace.h4
-rw-r--r--kernel/acct.c94
-rw-r--r--kernel/auditsc.c5
-rw-r--r--lib/lockref.c36
-rw-r--r--security/commoncap.c6
-rw-r--r--security/selinux/selinuxfs.c52
23 files changed, 356 insertions, 378 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h
index b63cfee2d963..8f418ba868bd 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.h
@@ -55,7 +55,7 @@ static const struct file_operations name##_debugfs_fops = { \
55struct t4_debugfs_entry { 55struct t4_debugfs_entry {
56 const char *name; 56 const char *name;
57 const struct file_operations *ops; 57 const struct file_operations *ops;
58 mode_t mode; 58 umode_t mode;
59 unsigned char data; 59 unsigned char data;
60}; 60};
61 61
diff --git a/drivers/staging/lustre/lustre/llite/dcache.c b/drivers/staging/lustre/lustre/llite/dcache.c
index 5bb9c85cec81..88614b71cf6d 100644
--- a/drivers/staging/lustre/lustre/llite/dcache.c
+++ b/drivers/staging/lustre/lustre/llite/dcache.c
@@ -263,14 +263,6 @@ void ll_invalidate_aliases(struct inode *inode)
263 dentry, dentry, dentry->d_parent, 263 dentry, dentry, dentry->d_parent,
264 dentry->d_inode, dentry->d_flags); 264 dentry->d_inode, dentry->d_flags);
265 265
266 if (unlikely(dentry == dentry->d_sb->s_root)) {
267 CERROR("%s: called on root dentry=%p, fid="DFID"\n",
268 ll_get_fsname(dentry->d_sb, NULL, 0),
269 dentry, PFID(ll_inode2fid(inode)));
270 lustre_dump_dentry(dentry, 1);
271 dump_stack();
272 }
273
274 d_lustre_invalidate(dentry, 0); 266 d_lustre_invalidate(dentry, 0);
275 } 267 }
276 ll_unlock_dcache(inode); 268 ll_unlock_dcache(inode);
diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h
index 37306e0c7aad..d032c2b086cc 100644
--- a/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -816,7 +816,6 @@ int ll_show_options(struct seq_file *seq, struct dentry *dentry);
816void ll_dirty_page_discard_warn(struct page *page, int ioret); 816void ll_dirty_page_discard_warn(struct page *page, int ioret);
817int ll_prep_inode(struct inode **inode, struct ptlrpc_request *req, 817int ll_prep_inode(struct inode **inode, struct ptlrpc_request *req,
818 struct super_block *, struct lookup_intent *); 818 struct super_block *, struct lookup_intent *);
819void lustre_dump_dentry(struct dentry *, int recur);
820int ll_obd_statfs(struct inode *inode, void *arg); 819int ll_obd_statfs(struct inode *inode, void *arg);
821int ll_get_max_mdsize(struct ll_sb_info *sbi, int *max_mdsize); 820int ll_get_max_mdsize(struct ll_sb_info *sbi, int *max_mdsize);
822int ll_get_default_mdsize(struct ll_sb_info *sbi, int *default_mdsize); 821int ll_get_default_mdsize(struct ll_sb_info *sbi, int *default_mdsize);
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index 45aaa1cc56bc..0c1b583a4ea1 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -665,48 +665,6 @@ int ll_get_default_cookiesize(struct ll_sb_info *sbi, int *lmmsize)
665 return rc; 665 return rc;
666} 666}
667 667
668static void ll_dump_inode(struct inode *inode)
669{
670 struct ll_d_hlist_node *tmp;
671 int dentry_count = 0;
672
673 LASSERT(inode != NULL);
674
675 ll_d_hlist_for_each(tmp, &inode->i_dentry)
676 dentry_count++;
677
678 CERROR("inode %p dump: dev=%s ino=%lu mode=%o count=%u, %d dentries\n",
679 inode, ll_i2mdexp(inode)->exp_obd->obd_name, inode->i_ino,
680 inode->i_mode, atomic_read(&inode->i_count), dentry_count);
681}
682
683void lustre_dump_dentry(struct dentry *dentry, int recur)
684{
685 struct list_head *tmp;
686 int subdirs = 0;
687
688 LASSERT(dentry != NULL);
689
690 list_for_each(tmp, &dentry->d_subdirs)
691 subdirs++;
692
693 CERROR("dentry %p dump: name=%pd parent=%pd (%p), inode=%p, count=%u, flags=0x%x, fsdata=%p, %d subdirs\n",
694 dentry, dentry, dentry->d_parent, dentry->d_parent,
695 dentry->d_inode, d_count(dentry),
696 dentry->d_flags, dentry->d_fsdata, subdirs);
697 if (dentry->d_inode != NULL)
698 ll_dump_inode(dentry->d_inode);
699
700 if (recur == 0)
701 return;
702
703 list_for_each(tmp, &dentry->d_subdirs) {
704 struct dentry *d = list_entry(tmp, struct dentry, d_child);
705
706 lustre_dump_dentry(d, recur - 1);
707 }
708}
709
710static void client_common_put_super(struct super_block *sb) 668static void client_common_put_super(struct super_block *sb)
711{ 669{
712 struct ll_sb_info *sbi = ll_s2sbi(sb); 670 struct ll_sb_info *sbi = ll_s2sbi(sb);
diff --git a/fs/dcache.c b/fs/dcache.c
index 7d34f04ec7aa..dc400fd29f4d 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -511,7 +511,7 @@ static void __dentry_kill(struct dentry *dentry)
511 * dentry_iput drops the locks, at which point nobody (except 511 * dentry_iput drops the locks, at which point nobody (except
512 * transient RCU lookups) can reach this dentry. 512 * transient RCU lookups) can reach this dentry.
513 */ 513 */
514 BUG_ON((int)dentry->d_lockref.count > 0); 514 BUG_ON(dentry->d_lockref.count > 0);
515 this_cpu_dec(nr_dentry); 515 this_cpu_dec(nr_dentry);
516 if (dentry->d_op && dentry->d_op->d_release) 516 if (dentry->d_op && dentry->d_op->d_release)
517 dentry->d_op->d_release(dentry); 517 dentry->d_op->d_release(dentry);
@@ -564,7 +564,7 @@ static inline struct dentry *lock_parent(struct dentry *dentry)
564 struct dentry *parent = dentry->d_parent; 564 struct dentry *parent = dentry->d_parent;
565 if (IS_ROOT(dentry)) 565 if (IS_ROOT(dentry))
566 return NULL; 566 return NULL;
567 if (unlikely((int)dentry->d_lockref.count < 0)) 567 if (unlikely(dentry->d_lockref.count < 0))
568 return NULL; 568 return NULL;
569 if (likely(spin_trylock(&parent->d_lock))) 569 if (likely(spin_trylock(&parent->d_lock)))
570 return parent; 570 return parent;
@@ -593,6 +593,110 @@ again:
593 return parent; 593 return parent;
594} 594}
595 595
596/*
597 * Try to do a lockless dput(), and return whether that was successful.
598 *
599 * If unsuccessful, we return false, having already taken the dentry lock.
600 *
601 * The caller needs to hold the RCU read lock, so that the dentry is
602 * guaranteed to stay around even if the refcount goes down to zero!
603 */
604static inline bool fast_dput(struct dentry *dentry)
605{
606 int ret;
607 unsigned int d_flags;
608
609 /*
610 * If we have a d_op->d_delete() operation, we sould not
611 * let the dentry count go to zero, so use "put__or_lock".
612 */
613 if (unlikely(dentry->d_flags & DCACHE_OP_DELETE))
614 return lockref_put_or_lock(&dentry->d_lockref);
615
616 /*
617 * .. otherwise, we can try to just decrement the
618 * lockref optimistically.
619 */
620 ret = lockref_put_return(&dentry->d_lockref);
621
622 /*
623 * If the lockref_put_return() failed due to the lock being held
624 * by somebody else, the fast path has failed. We will need to
625 * get the lock, and then check the count again.
626 */
627 if (unlikely(ret < 0)) {
628 spin_lock(&dentry->d_lock);
629 if (dentry->d_lockref.count > 1) {
630 dentry->d_lockref.count--;
631 spin_unlock(&dentry->d_lock);
632 return 1;
633 }
634 return 0;
635 }
636
637 /*
638 * If we weren't the last ref, we're done.
639 */
640 if (ret)
641 return 1;
642
643 /*
644 * Careful, careful. The reference count went down
645 * to zero, but we don't hold the dentry lock, so
646 * somebody else could get it again, and do another
647 * dput(), and we need to not race with that.
648 *
649 * However, there is a very special and common case
650 * where we don't care, because there is nothing to
651 * do: the dentry is still hashed, it does not have
652 * a 'delete' op, and it's referenced and already on
653 * the LRU list.
654 *
655 * NOTE! Since we aren't locked, these values are
656 * not "stable". However, it is sufficient that at
657 * some point after we dropped the reference the
658 * dentry was hashed and the flags had the proper
659 * value. Other dentry users may have re-gotten
660 * a reference to the dentry and change that, but
661 * our work is done - we can leave the dentry
662 * around with a zero refcount.
663 */
664 smp_rmb();
665 d_flags = ACCESS_ONCE(dentry->d_flags);
666 d_flags &= DCACHE_REFERENCED | DCACHE_LRU_LIST;
667
668 /* Nothing to do? Dropping the reference was all we needed? */
669 if (d_flags == (DCACHE_REFERENCED | DCACHE_LRU_LIST) && !d_unhashed(dentry))
670 return 1;
671
672 /*
673 * Not the fast normal case? Get the lock. We've already decremented
674 * the refcount, but we'll need to re-check the situation after
675 * getting the lock.
676 */
677 spin_lock(&dentry->d_lock);
678
679 /*
680 * Did somebody else grab a reference to it in the meantime, and
681 * we're no longer the last user after all? Alternatively, somebody
682 * else could have killed it and marked it dead. Either way, we
683 * don't need to do anything else.
684 */
685 if (dentry->d_lockref.count) {
686 spin_unlock(&dentry->d_lock);
687 return 1;
688 }
689
690 /*
691 * Re-get the reference we optimistically dropped. We hold the
692 * lock, and we just tested that it was zero, so we can just
693 * set it to 1.
694 */
695 dentry->d_lockref.count = 1;
696 return 0;
697}
698
699
596/* 700/*
597 * This is dput 701 * This is dput
598 * 702 *
@@ -625,8 +729,14 @@ void dput(struct dentry *dentry)
625 return; 729 return;
626 730
627repeat: 731repeat:
628 if (lockref_put_or_lock(&dentry->d_lockref)) 732 rcu_read_lock();
733 if (likely(fast_dput(dentry))) {
734 rcu_read_unlock();
629 return; 735 return;
736 }
737
738 /* Slow case: now with the dentry lock held */
739 rcu_read_unlock();
630 740
631 /* Unreachable? Get rid of it */ 741 /* Unreachable? Get rid of it */
632 if (unlikely(d_unhashed(dentry))) 742 if (unlikely(d_unhashed(dentry)))
@@ -813,7 +923,7 @@ static void shrink_dentry_list(struct list_head *list)
813 * We found an inuse dentry which was not removed from 923 * We found an inuse dentry which was not removed from
814 * the LRU because of laziness during lookup. Do not free it. 924 * the LRU because of laziness during lookup. Do not free it.
815 */ 925 */
816 if ((int)dentry->d_lockref.count > 0) { 926 if (dentry->d_lockref.count > 0) {
817 spin_unlock(&dentry->d_lock); 927 spin_unlock(&dentry->d_lock);
818 if (parent) 928 if (parent)
819 spin_unlock(&parent->d_lock); 929 spin_unlock(&parent->d_lock);
@@ -2191,37 +2301,6 @@ struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name)
2191} 2301}
2192EXPORT_SYMBOL(d_hash_and_lookup); 2302EXPORT_SYMBOL(d_hash_and_lookup);
2193 2303
2194/**
2195 * d_validate - verify dentry provided from insecure source (deprecated)
2196 * @dentry: The dentry alleged to be valid child of @dparent
2197 * @dparent: The parent dentry (known to be valid)
2198 *
2199 * An insecure source has sent us a dentry, here we verify it and dget() it.
2200 * This is used by ncpfs in its readdir implementation.
2201 * Zero is returned in the dentry is invalid.
2202 *
2203 * This function is slow for big directories, and deprecated, do not use it.
2204 */
2205int d_validate(struct dentry *dentry, struct dentry *dparent)
2206{
2207 struct dentry *child;
2208
2209 spin_lock(&dparent->d_lock);
2210 list_for_each_entry(child, &dparent->d_subdirs, d_child) {
2211 if (dentry == child) {
2212 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
2213 __dget_dlock(dentry);
2214 spin_unlock(&dentry->d_lock);
2215 spin_unlock(&dparent->d_lock);
2216 return 1;
2217 }
2218 }
2219 spin_unlock(&dparent->d_lock);
2220
2221 return 0;
2222}
2223EXPORT_SYMBOL(d_validate);
2224
2225/* 2304/*
2226 * When a file is deleted, we have two options: 2305 * When a file is deleted, we have two options:
2227 * - turn this dentry into a negative dentry 2306 * - turn this dentry into a negative dentry
diff --git a/fs/fs_pin.c b/fs/fs_pin.c
index 9368236ca100..b06c98796afb 100644
--- a/fs/fs_pin.c
+++ b/fs/fs_pin.c
@@ -1,78 +1,102 @@
1#include <linux/fs.h> 1#include <linux/fs.h>
2#include <linux/sched.h>
2#include <linux/slab.h> 3#include <linux/slab.h>
3#include <linux/fs_pin.h>
4#include "internal.h" 4#include "internal.h"
5#include "mount.h" 5#include "mount.h"
6 6
7static void pin_free_rcu(struct rcu_head *head)
8{
9 kfree(container_of(head, struct fs_pin, rcu));
10}
11
12static DEFINE_SPINLOCK(pin_lock); 7static DEFINE_SPINLOCK(pin_lock);
13 8
14void pin_put(struct fs_pin *p)
15{
16 if (atomic_long_dec_and_test(&p->count))
17 call_rcu(&p->rcu, pin_free_rcu);
18}
19
20void pin_remove(struct fs_pin *pin) 9void pin_remove(struct fs_pin *pin)
21{ 10{
22 spin_lock(&pin_lock); 11 spin_lock(&pin_lock);
23 hlist_del(&pin->m_list); 12 hlist_del(&pin->m_list);
24 hlist_del(&pin->s_list); 13 hlist_del(&pin->s_list);
25 spin_unlock(&pin_lock); 14 spin_unlock(&pin_lock);
15 spin_lock_irq(&pin->wait.lock);
16 pin->done = 1;
17 wake_up_locked(&pin->wait);
18 spin_unlock_irq(&pin->wait.lock);
26} 19}
27 20
28void pin_insert(struct fs_pin *pin, struct vfsmount *m) 21void pin_insert_group(struct fs_pin *pin, struct vfsmount *m, struct hlist_head *p)
29{ 22{
30 spin_lock(&pin_lock); 23 spin_lock(&pin_lock);
31 hlist_add_head(&pin->s_list, &m->mnt_sb->s_pins); 24 if (p)
25 hlist_add_head(&pin->s_list, p);
32 hlist_add_head(&pin->m_list, &real_mount(m)->mnt_pins); 26 hlist_add_head(&pin->m_list, &real_mount(m)->mnt_pins);
33 spin_unlock(&pin_lock); 27 spin_unlock(&pin_lock);
34} 28}
35 29
30void pin_insert(struct fs_pin *pin, struct vfsmount *m)
31{
32 pin_insert_group(pin, m, &m->mnt_sb->s_pins);
33}
34
35void pin_kill(struct fs_pin *p)
36{
37 wait_queue_t wait;
38
39 if (!p) {
40 rcu_read_unlock();
41 return;
42 }
43 init_wait(&wait);
44 spin_lock_irq(&p->wait.lock);
45 if (likely(!p->done)) {
46 p->done = -1;
47 spin_unlock_irq(&p->wait.lock);
48 rcu_read_unlock();
49 p->kill(p);
50 return;
51 }
52 if (p->done > 0) {
53 spin_unlock_irq(&p->wait.lock);
54 rcu_read_unlock();
55 return;
56 }
57 __add_wait_queue(&p->wait, &wait);
58 while (1) {
59 set_current_state(TASK_UNINTERRUPTIBLE);
60 spin_unlock_irq(&p->wait.lock);
61 rcu_read_unlock();
62 schedule();
63 rcu_read_lock();
64 if (likely(list_empty(&wait.task_list)))
65 break;
66 /* OK, we know p couldn't have been freed yet */
67 spin_lock_irq(&p->wait.lock);
68 if (p->done > 0) {
69 spin_unlock_irq(&p->wait.lock);
70 break;
71 }
72 }
73 rcu_read_unlock();
74}
75
36void mnt_pin_kill(struct mount *m) 76void mnt_pin_kill(struct mount *m)
37{ 77{
38 while (1) { 78 while (1) {
39 struct hlist_node *p; 79 struct hlist_node *p;
40 struct fs_pin *pin;
41 rcu_read_lock(); 80 rcu_read_lock();
42 p = ACCESS_ONCE(m->mnt_pins.first); 81 p = ACCESS_ONCE(m->mnt_pins.first);
43 if (!p) { 82 if (!p) {
44 rcu_read_unlock(); 83 rcu_read_unlock();
45 break; 84 break;
46 } 85 }
47 pin = hlist_entry(p, struct fs_pin, m_list); 86 pin_kill(hlist_entry(p, struct fs_pin, m_list));
48 if (!atomic_long_inc_not_zero(&pin->count)) {
49 rcu_read_unlock();
50 cpu_relax();
51 continue;
52 }
53 rcu_read_unlock();
54 pin->kill(pin);
55 } 87 }
56} 88}
57 89
58void sb_pin_kill(struct super_block *sb) 90void group_pin_kill(struct hlist_head *p)
59{ 91{
60 while (1) { 92 while (1) {
61 struct hlist_node *p; 93 struct hlist_node *q;
62 struct fs_pin *pin;
63 rcu_read_lock(); 94 rcu_read_lock();
64 p = ACCESS_ONCE(sb->s_pins.first); 95 q = ACCESS_ONCE(p->first);
65 if (!p) { 96 if (!q) {
66 rcu_read_unlock(); 97 rcu_read_unlock();
67 break; 98 break;
68 } 99 }
69 pin = hlist_entry(p, struct fs_pin, s_list); 100 pin_kill(hlist_entry(q, struct fs_pin, s_list));
70 if (!atomic_long_inc_not_zero(&pin->count)) {
71 rcu_read_unlock();
72 cpu_relax();
73 continue;
74 }
75 rcu_read_unlock();
76 pin->kill(pin);
77 } 101 }
78} 102}
diff --git a/fs/internal.h b/fs/internal.h
index d92c346a793d..30459dab409d 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -144,7 +144,7 @@ extern const struct file_operations pipefifo_fops;
144/* 144/*
145 * fs_pin.c 145 * fs_pin.c
146 */ 146 */
147extern void sb_pin_kill(struct super_block *sb); 147extern void group_pin_kill(struct hlist_head *p);
148extern void mnt_pin_kill(struct mount *m); 148extern void mnt_pin_kill(struct mount *m);
149 149
150/* 150/*
diff --git a/fs/mount.h b/fs/mount.h
index 0ad6f760ce52..6a61c2b3e385 100644
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -2,6 +2,7 @@
2#include <linux/seq_file.h> 2#include <linux/seq_file.h>
3#include <linux/poll.h> 3#include <linux/poll.h>
4#include <linux/ns_common.h> 4#include <linux/ns_common.h>
5#include <linux/fs_pin.h>
5 6
6struct mnt_namespace { 7struct mnt_namespace {
7 atomic_t count; 8 atomic_t count;
@@ -62,7 +63,8 @@ struct mount {
62 int mnt_group_id; /* peer group identifier */ 63 int mnt_group_id; /* peer group identifier */
63 int mnt_expiry_mark; /* true if marked for expiry */ 64 int mnt_expiry_mark; /* true if marked for expiry */
64 struct hlist_head mnt_pins; 65 struct hlist_head mnt_pins;
65 struct path mnt_ex_mountpoint; 66 struct fs_pin mnt_umount;
67 struct dentry *mnt_ex_mountpoint;
66}; 68};
67 69
68#define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */ 70#define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
diff --git a/fs/namespace.c b/fs/namespace.c
index 6dae553dd69c..72a286e0d33e 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -190,6 +190,14 @@ unsigned int mnt_get_count(struct mount *mnt)
190#endif 190#endif
191} 191}
192 192
193static void drop_mountpoint(struct fs_pin *p)
194{
195 struct mount *m = container_of(p, struct mount, mnt_umount);
196 dput(m->mnt_ex_mountpoint);
197 pin_remove(p);
198 mntput(&m->mnt);
199}
200
193static struct mount *alloc_vfsmnt(const char *name) 201static struct mount *alloc_vfsmnt(const char *name)
194{ 202{
195 struct mount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL); 203 struct mount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL);
@@ -229,6 +237,7 @@ static struct mount *alloc_vfsmnt(const char *name)
229#ifdef CONFIG_FSNOTIFY 237#ifdef CONFIG_FSNOTIFY
230 INIT_HLIST_HEAD(&mnt->mnt_fsnotify_marks); 238 INIT_HLIST_HEAD(&mnt->mnt_fsnotify_marks);
231#endif 239#endif
240 init_fs_pin(&mnt->mnt_umount, drop_mountpoint);
232 } 241 }
233 return mnt; 242 return mnt;
234 243
@@ -1289,7 +1298,6 @@ static HLIST_HEAD(unmounted); /* protected by namespace_sem */
1289 1298
1290static void namespace_unlock(void) 1299static void namespace_unlock(void)
1291{ 1300{
1292 struct mount *mnt;
1293 struct hlist_head head = unmounted; 1301 struct hlist_head head = unmounted;
1294 1302
1295 if (likely(hlist_empty(&head))) { 1303 if (likely(hlist_empty(&head))) {
@@ -1299,23 +1307,11 @@ static void namespace_unlock(void)
1299 1307
1300 head.first->pprev = &head.first; 1308 head.first->pprev = &head.first;
1301 INIT_HLIST_HEAD(&unmounted); 1309 INIT_HLIST_HEAD(&unmounted);
1302
1303 /* undo decrements we'd done in umount_tree() */
1304 hlist_for_each_entry(mnt, &head, mnt_hash)
1305 if (mnt->mnt_ex_mountpoint.mnt)
1306 mntget(mnt->mnt_ex_mountpoint.mnt);
1307
1308 up_write(&namespace_sem); 1310 up_write(&namespace_sem);
1309 1311
1310 synchronize_rcu(); 1312 synchronize_rcu();
1311 1313
1312 while (!hlist_empty(&head)) { 1314 group_pin_kill(&head);
1313 mnt = hlist_entry(head.first, struct mount, mnt_hash);
1314 hlist_del_init(&mnt->mnt_hash);
1315 if (mnt->mnt_ex_mountpoint.mnt)
1316 path_put(&mnt->mnt_ex_mountpoint);
1317 mntput(&mnt->mnt);
1318 }
1319} 1315}
1320 1316
1321static inline void namespace_lock(void) 1317static inline void namespace_lock(void)
@@ -1334,7 +1330,6 @@ void umount_tree(struct mount *mnt, int how)
1334{ 1330{
1335 HLIST_HEAD(tmp_list); 1331 HLIST_HEAD(tmp_list);
1336 struct mount *p; 1332 struct mount *p;
1337 struct mount *last = NULL;
1338 1333
1339 for (p = mnt; p; p = next_mnt(p, mnt)) { 1334 for (p = mnt; p; p = next_mnt(p, mnt)) {
1340 hlist_del_init_rcu(&p->mnt_hash); 1335 hlist_del_init_rcu(&p->mnt_hash);
@@ -1347,33 +1342,28 @@ void umount_tree(struct mount *mnt, int how)
1347 if (how) 1342 if (how)
1348 propagate_umount(&tmp_list); 1343 propagate_umount(&tmp_list);
1349 1344
1350 hlist_for_each_entry(p, &tmp_list, mnt_hash) { 1345 while (!hlist_empty(&tmp_list)) {
1346 p = hlist_entry(tmp_list.first, struct mount, mnt_hash);
1347 hlist_del_init_rcu(&p->mnt_hash);
1351 list_del_init(&p->mnt_expire); 1348 list_del_init(&p->mnt_expire);
1352 list_del_init(&p->mnt_list); 1349 list_del_init(&p->mnt_list);
1353 __touch_mnt_namespace(p->mnt_ns); 1350 __touch_mnt_namespace(p->mnt_ns);
1354 p->mnt_ns = NULL; 1351 p->mnt_ns = NULL;
1355 if (how < 2) 1352 if (how < 2)
1356 p->mnt.mnt_flags |= MNT_SYNC_UMOUNT; 1353 p->mnt.mnt_flags |= MNT_SYNC_UMOUNT;
1354
1355 pin_insert_group(&p->mnt_umount, &p->mnt_parent->mnt, &unmounted);
1357 if (mnt_has_parent(p)) { 1356 if (mnt_has_parent(p)) {
1358 hlist_del_init(&p->mnt_mp_list); 1357 hlist_del_init(&p->mnt_mp_list);
1359 put_mountpoint(p->mnt_mp); 1358 put_mountpoint(p->mnt_mp);
1360 mnt_add_count(p->mnt_parent, -1); 1359 mnt_add_count(p->mnt_parent, -1);
1361 /* move the reference to mountpoint into ->mnt_ex_mountpoint */ 1360 /* old mountpoint will be dropped when we can do that */
1362 p->mnt_ex_mountpoint.dentry = p->mnt_mountpoint; 1361 p->mnt_ex_mountpoint = p->mnt_mountpoint;
1363 p->mnt_ex_mountpoint.mnt = &p->mnt_parent->mnt;
1364 p->mnt_mountpoint = p->mnt.mnt_root; 1362 p->mnt_mountpoint = p->mnt.mnt_root;
1365 p->mnt_parent = p; 1363 p->mnt_parent = p;
1366 p->mnt_mp = NULL; 1364 p->mnt_mp = NULL;
1367 } 1365 }
1368 change_mnt_propagation(p, MS_PRIVATE); 1366 change_mnt_propagation(p, MS_PRIVATE);
1369 last = p;
1370 }
1371 if (last) {
1372 last->mnt_hash.next = unmounted.first;
1373 if (unmounted.first)
1374 unmounted.first->pprev = &last->mnt_hash.next;
1375 unmounted.first = tmp_list.first;
1376 unmounted.first->pprev = &unmounted.first;
1377 } 1367 }
1378} 1368}
1379 1369
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index 008960101520..e7ca827d7694 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -77,6 +77,7 @@ static int ncp_hash_dentry(const struct dentry *, struct qstr *);
77static int ncp_compare_dentry(const struct dentry *, const struct dentry *, 77static int ncp_compare_dentry(const struct dentry *, const struct dentry *,
78 unsigned int, const char *, const struct qstr *); 78 unsigned int, const char *, const struct qstr *);
79static int ncp_delete_dentry(const struct dentry *); 79static int ncp_delete_dentry(const struct dentry *);
80static void ncp_d_prune(struct dentry *dentry);
80 81
81const struct dentry_operations ncp_dentry_operations = 82const struct dentry_operations ncp_dentry_operations =
82{ 83{
@@ -84,6 +85,7 @@ const struct dentry_operations ncp_dentry_operations =
84 .d_hash = ncp_hash_dentry, 85 .d_hash = ncp_hash_dentry,
85 .d_compare = ncp_compare_dentry, 86 .d_compare = ncp_compare_dentry,
86 .d_delete = ncp_delete_dentry, 87 .d_delete = ncp_delete_dentry,
88 .d_prune = ncp_d_prune,
87}; 89};
88 90
89#define ncp_namespace(i) (NCP_SERVER(i)->name_space[NCP_FINFO(i)->volNumber]) 91#define ncp_namespace(i) (NCP_SERVER(i)->name_space[NCP_FINFO(i)->volNumber])
@@ -384,42 +386,6 @@ finished:
384 return val; 386 return val;
385} 387}
386 388
387static struct dentry *
388ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
389{
390 struct dentry *dent = dentry;
391
392 if (d_validate(dent, parent)) {
393 if (dent->d_name.len <= NCP_MAXPATHLEN &&
394 (unsigned long)dent->d_fsdata == fpos) {
395 if (!dent->d_inode) {
396 dput(dent);
397 dent = NULL;
398 }
399 return dent;
400 }
401 dput(dent);
402 }
403
404 /* If a pointer is invalid, we search the dentry. */
405 spin_lock(&parent->d_lock);
406 list_for_each_entry(dent, &parent->d_subdirs, d_child) {
407 if ((unsigned long)dent->d_fsdata == fpos) {
408 if (dent->d_inode)
409 dget(dent);
410 else
411 dent = NULL;
412 spin_unlock(&parent->d_lock);
413 goto out;
414 }
415 }
416 spin_unlock(&parent->d_lock);
417 return NULL;
418
419out:
420 return dent;
421}
422
423static time_t ncp_obtain_mtime(struct dentry *dentry) 389static time_t ncp_obtain_mtime(struct dentry *dentry)
424{ 390{
425 struct inode *inode = dentry->d_inode; 391 struct inode *inode = dentry->d_inode;
@@ -435,6 +401,20 @@ static time_t ncp_obtain_mtime(struct dentry *dentry)
435 return ncp_date_dos2unix(i.modifyTime, i.modifyDate); 401 return ncp_date_dos2unix(i.modifyTime, i.modifyDate);
436} 402}
437 403
404static inline void
405ncp_invalidate_dircache_entries(struct dentry *parent)
406{
407 struct ncp_server *server = NCP_SERVER(parent->d_inode);
408 struct dentry *dentry;
409
410 spin_lock(&parent->d_lock);
411 list_for_each_entry(dentry, &parent->d_subdirs, d_child) {
412 dentry->d_fsdata = NULL;
413 ncp_age_dentry(server, dentry);
414 }
415 spin_unlock(&parent->d_lock);
416}
417
438static int ncp_readdir(struct file *file, struct dir_context *ctx) 418static int ncp_readdir(struct file *file, struct dir_context *ctx)
439{ 419{
440 struct dentry *dentry = file->f_path.dentry; 420 struct dentry *dentry = file->f_path.dentry;
@@ -500,10 +480,21 @@ static int ncp_readdir(struct file *file, struct dir_context *ctx)
500 struct dentry *dent; 480 struct dentry *dent;
501 bool over; 481 bool over;
502 482
503 dent = ncp_dget_fpos(ctl.cache->dentry[ctl.idx], 483 spin_lock(&dentry->d_lock);
504 dentry, ctx->pos); 484 if (!(NCP_FINFO(inode)->flags & NCPI_DIR_CACHE)) {
505 if (!dent) 485 spin_unlock(&dentry->d_lock);
486 goto invalid_cache;
487 }
488 dent = ctl.cache->dentry[ctl.idx];
489 if (unlikely(!lockref_get_not_dead(&dent->d_lockref))) {
490 spin_unlock(&dentry->d_lock);
491 goto invalid_cache;
492 }
493 spin_unlock(&dentry->d_lock);
494 if (!dent->d_inode) {
495 dput(dent);
506 goto invalid_cache; 496 goto invalid_cache;
497 }
507 over = !dir_emit(ctx, dent->d_name.name, 498 over = !dir_emit(ctx, dent->d_name.name,
508 dent->d_name.len, 499 dent->d_name.len,
509 dent->d_inode->i_ino, DT_UNKNOWN); 500 dent->d_inode->i_ino, DT_UNKNOWN);
@@ -548,6 +539,9 @@ init_cache:
548 ctl.filled = 0; 539 ctl.filled = 0;
549 ctl.valid = 1; 540 ctl.valid = 1;
550read_really: 541read_really:
542 spin_lock(&dentry->d_lock);
543 NCP_FINFO(inode)->flags |= NCPI_DIR_CACHE;
544 spin_unlock(&dentry->d_lock);
551 if (ncp_is_server_root(inode)) { 545 if (ncp_is_server_root(inode)) {
552 ncp_read_volume_list(file, ctx, &ctl); 546 ncp_read_volume_list(file, ctx, &ctl);
553 } else { 547 } else {
@@ -573,6 +567,13 @@ out:
573 return result; 567 return result;
574} 568}
575 569
570static void ncp_d_prune(struct dentry *dentry)
571{
572 if (!dentry->d_fsdata) /* not referenced from page cache */
573 return;
574 NCP_FINFO(dentry->d_parent->d_inode)->flags &= ~NCPI_DIR_CACHE;
575}
576
576static int 577static int
577ncp_fill_cache(struct file *file, struct dir_context *ctx, 578ncp_fill_cache(struct file *file, struct dir_context *ctx,
578 struct ncp_cache_control *ctrl, struct ncp_entry_info *entry, 579 struct ncp_cache_control *ctrl, struct ncp_entry_info *entry,
@@ -630,6 +631,10 @@ ncp_fill_cache(struct file *file, struct dir_context *ctx,
630 d_instantiate(newdent, inode); 631 d_instantiate(newdent, inode);
631 if (!hashed) 632 if (!hashed)
632 d_rehash(newdent); 633 d_rehash(newdent);
634 } else {
635 spin_lock(&dentry->d_lock);
636 NCP_FINFO(inode)->flags &= ~NCPI_DIR_CACHE;
637 spin_unlock(&dentry->d_lock);
633 } 638 }
634 } else { 639 } else {
635 struct inode *inode = newdent->d_inode; 640 struct inode *inode = newdent->d_inode;
@@ -639,12 +644,6 @@ ncp_fill_cache(struct file *file, struct dir_context *ctx,
639 mutex_unlock(&inode->i_mutex); 644 mutex_unlock(&inode->i_mutex);
640 } 645 }
641 646
642 if (newdent->d_inode) {
643 ino = newdent->d_inode->i_ino;
644 newdent->d_fsdata = (void *) ctl.fpos;
645 ncp_new_dentry(newdent);
646 }
647
648 if (ctl.idx >= NCP_DIRCACHE_SIZE) { 647 if (ctl.idx >= NCP_DIRCACHE_SIZE) {
649 if (ctl.page) { 648 if (ctl.page) {
650 kunmap(ctl.page); 649 kunmap(ctl.page);
@@ -660,8 +659,13 @@ ncp_fill_cache(struct file *file, struct dir_context *ctx,
660 ctl.cache = kmap(ctl.page); 659 ctl.cache = kmap(ctl.page);
661 } 660 }
662 if (ctl.cache) { 661 if (ctl.cache) {
663 ctl.cache->dentry[ctl.idx] = newdent; 662 if (newdent->d_inode) {
664 valid = 1; 663 newdent->d_fsdata = newdent;
664 ctl.cache->dentry[ctl.idx] = newdent;
665 ino = newdent->d_inode->i_ino;
666 ncp_new_dentry(newdent);
667 }
668 valid = 1;
665 } 669 }
666 dput(newdent); 670 dput(newdent);
667end_advance: 671end_advance:
diff --git a/fs/ncpfs/ncp_fs_i.h b/fs/ncpfs/ncp_fs_i.h
index 4b0bec477846..c4794504f843 100644
--- a/fs/ncpfs/ncp_fs_i.h
+++ b/fs/ncpfs/ncp_fs_i.h
@@ -22,6 +22,7 @@ struct ncp_inode_info {
22 int access; 22 int access;
23 int flags; 23 int flags;
24#define NCPI_KLUDGE_SYMLINK 0x0001 24#define NCPI_KLUDGE_SYMLINK 0x0001
25#define NCPI_DIR_CACHE 0x0002
25 __u8 file_handle[6]; 26 __u8 file_handle[6];
26 struct inode vfs_inode; 27 struct inode vfs_inode;
27}; 28};
diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h
index b785f74bfe3c..250e443a07f3 100644
--- a/fs/ncpfs/ncplib_kernel.h
+++ b/fs/ncpfs/ncplib_kernel.h
@@ -184,36 +184,6 @@ ncp_new_dentry(struct dentry* dentry)
184 dentry->d_time = jiffies; 184 dentry->d_time = jiffies;
185} 185}
186 186
187static inline void
188ncp_renew_dentries(struct dentry *parent)
189{
190 struct ncp_server *server = NCP_SERVER(parent->d_inode);
191 struct dentry *dentry;
192
193 spin_lock(&parent->d_lock);
194 list_for_each_entry(dentry, &parent->d_subdirs, d_child) {
195 if (dentry->d_fsdata == NULL)
196 ncp_age_dentry(server, dentry);
197 else
198 ncp_new_dentry(dentry);
199 }
200 spin_unlock(&parent->d_lock);
201}
202
203static inline void
204ncp_invalidate_dircache_entries(struct dentry *parent)
205{
206 struct ncp_server *server = NCP_SERVER(parent->d_inode);
207 struct dentry *dentry;
208
209 spin_lock(&parent->d_lock);
210 list_for_each_entry(dentry, &parent->d_subdirs, d_child) {
211 dentry->d_fsdata = NULL;
212 ncp_age_dentry(server, dentry);
213 }
214 spin_unlock(&parent->d_lock);
215}
216
217struct ncp_cache_head { 187struct ncp_cache_head {
218 time_t mtime; 188 time_t mtime;
219 unsigned long time; /* cache age */ 189 unsigned long time; /* cache age */
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index de14e46fd807..3309f59d421b 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -350,29 +350,12 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp
350 if (ret) 350 if (ret)
351 return ret; 351 return ret;
352 352
353 if (S_ISDIR(dp->mode)) {
354 dp->proc_fops = &proc_dir_operations;
355 dp->proc_iops = &proc_dir_inode_operations;
356 dir->nlink++;
357 } else if (S_ISLNK(dp->mode)) {
358 dp->proc_iops = &proc_link_inode_operations;
359 } else if (S_ISREG(dp->mode)) {
360 BUG_ON(dp->proc_fops == NULL);
361 dp->proc_iops = &proc_file_inode_operations;
362 } else {
363 WARN_ON(1);
364 proc_free_inum(dp->low_ino);
365 return -EINVAL;
366 }
367
368 spin_lock(&proc_subdir_lock); 353 spin_lock(&proc_subdir_lock);
369 dp->parent = dir; 354 dp->parent = dir;
370 if (pde_subdir_insert(dir, dp) == false) { 355 if (pde_subdir_insert(dir, dp) == false) {
371 WARN(1, "proc_dir_entry '%s/%s' already registered\n", 356 WARN(1, "proc_dir_entry '%s/%s' already registered\n",
372 dir->name, dp->name); 357 dir->name, dp->name);
373 spin_unlock(&proc_subdir_lock); 358 spin_unlock(&proc_subdir_lock);
374 if (S_ISDIR(dp->mode))
375 dir->nlink--;
376 proc_free_inum(dp->low_ino); 359 proc_free_inum(dp->low_ino);
377 return -EEXIST; 360 return -EEXIST;
378 } 361 }
@@ -431,6 +414,7 @@ struct proc_dir_entry *proc_symlink(const char *name,
431 ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL); 414 ent->data = kmalloc((ent->size=strlen(dest))+1, GFP_KERNEL);
432 if (ent->data) { 415 if (ent->data) {
433 strcpy((char*)ent->data,dest); 416 strcpy((char*)ent->data,dest);
417 ent->proc_iops = &proc_link_inode_operations;
434 if (proc_register(parent, ent) < 0) { 418 if (proc_register(parent, ent) < 0) {
435 kfree(ent->data); 419 kfree(ent->data);
436 kfree(ent); 420 kfree(ent);
@@ -456,8 +440,12 @@ struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode,
456 ent = __proc_create(&parent, name, S_IFDIR | mode, 2); 440 ent = __proc_create(&parent, name, S_IFDIR | mode, 2);
457 if (ent) { 441 if (ent) {
458 ent->data = data; 442 ent->data = data;
443 ent->proc_fops = &proc_dir_operations;
444 ent->proc_iops = &proc_dir_inode_operations;
445 parent->nlink++;
459 if (proc_register(parent, ent) < 0) { 446 if (proc_register(parent, ent) < 0) {
460 kfree(ent); 447 kfree(ent);
448 parent->nlink--;
461 ent = NULL; 449 ent = NULL;
462 } 450 }
463 } 451 }
@@ -493,6 +481,8 @@ struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
493 return NULL; 481 return NULL;
494 } 482 }
495 483
484 BUG_ON(proc_fops == NULL);
485
496 if ((mode & S_IALLUGO) == 0) 486 if ((mode & S_IALLUGO) == 0)
497 mode |= S_IRUGO; 487 mode |= S_IRUGO;
498 pde = __proc_create(&parent, name, mode, 1); 488 pde = __proc_create(&parent, name, mode, 1);
@@ -500,6 +490,7 @@ struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
500 goto out; 490 goto out;
501 pde->proc_fops = proc_fops; 491 pde->proc_fops = proc_fops;
502 pde->data = data; 492 pde->data = data;
493 pde->proc_iops = &proc_file_inode_operations;
503 if (proc_register(parent, pde) < 0) 494 if (proc_register(parent, pde) < 0)
504 goto out_free; 495 goto out_free;
505 return pde; 496 return pde;
diff --git a/fs/super.c b/fs/super.c
index 1facd2c282e5..65a53efc1cf4 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -715,9 +715,9 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
715 remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY); 715 remount_ro = (flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY);
716 716
717 if (remount_ro) { 717 if (remount_ro) {
718 if (sb->s_pins.first) { 718 if (!hlist_empty(&sb->s_pins)) {
719 up_write(&sb->s_umount); 719 up_write(&sb->s_umount);
720 sb_pin_kill(sb); 720 group_pin_kill(&sb->s_pins);
721 down_write(&sb->s_umount); 721 down_write(&sb->s_umount);
722 if (!sb->s_root) 722 if (!sb->s_root)
723 return 0; 723 return 0;
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 5a813988e6d4..92c08cf7670e 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -319,9 +319,6 @@ static inline unsigned d_count(const struct dentry *dentry)
319 return dentry->d_lockref.count; 319 return dentry->d_lockref.count;
320} 320}
321 321
322/* validate "insecure" dentry pointer */
323extern int d_validate(struct dentry *, struct dentry *);
324
325/* 322/*
326 * helper function for dentry_operations.d_dname() members 323 * helper function for dentry_operations.d_dname() members
327 */ 324 */
diff --git a/include/linux/fs_pin.h b/include/linux/fs_pin.h
index f66525e72ccf..9dc4e0384bfb 100644
--- a/include/linux/fs_pin.h
+++ b/include/linux/fs_pin.h
@@ -1,17 +1,22 @@
1#include <linux/fs.h> 1#include <linux/wait.h>
2 2
3struct fs_pin { 3struct fs_pin {
4 atomic_long_t count; 4 wait_queue_head_t wait;
5 union { 5 int done;
6 struct { 6 struct hlist_node s_list;
7 struct hlist_node s_list; 7 struct hlist_node m_list;
8 struct hlist_node m_list;
9 };
10 struct rcu_head rcu;
11 };
12 void (*kill)(struct fs_pin *); 8 void (*kill)(struct fs_pin *);
13}; 9};
14 10
15void pin_put(struct fs_pin *); 11struct vfsmount;
12
13static inline void init_fs_pin(struct fs_pin *p, void (*kill)(struct fs_pin *))
14{
15 init_waitqueue_head(&p->wait);
16 p->kill = kill;
17}
18
16void pin_remove(struct fs_pin *); 19void pin_remove(struct fs_pin *);
20void pin_insert_group(struct fs_pin *, struct vfsmount *, struct hlist_head *);
17void pin_insert(struct fs_pin *, struct vfsmount *); 21void pin_insert(struct fs_pin *, struct vfsmount *);
22void pin_kill(struct fs_pin *);
diff --git a/include/linux/lockref.h b/include/linux/lockref.h
index 4bfde0e99ed5..b10b122dd099 100644
--- a/include/linux/lockref.h
+++ b/include/linux/lockref.h
@@ -28,12 +28,13 @@ struct lockref {
28#endif 28#endif
29 struct { 29 struct {
30 spinlock_t lock; 30 spinlock_t lock;
31 unsigned int count; 31 int count;
32 }; 32 };
33 }; 33 };
34}; 34};
35 35
36extern void lockref_get(struct lockref *); 36extern void lockref_get(struct lockref *);
37extern int lockref_put_return(struct lockref *);
37extern int lockref_get_not_zero(struct lockref *); 38extern int lockref_get_not_zero(struct lockref *);
38extern int lockref_get_or_lock(struct lockref *); 39extern int lockref_get_or_lock(struct lockref *);
39extern int lockref_put_or_lock(struct lockref *); 40extern int lockref_put_or_lock(struct lockref *);
diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h
index b9cf6c51b181..918b117a7cd3 100644
--- a/include/linux/pid_namespace.h
+++ b/include/linux/pid_namespace.h
@@ -19,7 +19,7 @@ struct pidmap {
19#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1) 19#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1)
20#define PIDMAP_ENTRIES ((PID_MAX_LIMIT+BITS_PER_PAGE-1)/BITS_PER_PAGE) 20#define PIDMAP_ENTRIES ((PID_MAX_LIMIT+BITS_PER_PAGE-1)/BITS_PER_PAGE)
21 21
22struct bsd_acct_struct; 22struct fs_pin;
23 23
24struct pid_namespace { 24struct pid_namespace {
25 struct kref kref; 25 struct kref kref;
@@ -37,7 +37,7 @@ struct pid_namespace {
37 struct dentry *proc_thread_self; 37 struct dentry *proc_thread_self;
38#endif 38#endif
39#ifdef CONFIG_BSD_PROCESS_ACCT 39#ifdef CONFIG_BSD_PROCESS_ACCT
40 struct bsd_acct_struct *bacct; 40 struct fs_pin *bacct;
41#endif 41#endif
42 struct user_namespace *user_ns; 42 struct user_namespace *user_ns;
43 struct work_struct proc_work; 43 struct work_struct proc_work;
diff --git a/kernel/acct.c b/kernel/acct.c
index 33738ef972f3..e6c10d1a4058 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -76,10 +76,11 @@ int acct_parm[3] = {4, 2, 30};
76/* 76/*
77 * External references and all of the globals. 77 * External references and all of the globals.
78 */ 78 */
79static void do_acct_process(struct bsd_acct_struct *acct);
80 79
81struct bsd_acct_struct { 80struct bsd_acct_struct {
82 struct fs_pin pin; 81 struct fs_pin pin;
82 atomic_long_t count;
83 struct rcu_head rcu;
83 struct mutex lock; 84 struct mutex lock;
84 int active; 85 int active;
85 unsigned long needcheck; 86 unsigned long needcheck;
@@ -89,6 +90,8 @@ struct bsd_acct_struct {
89 struct completion done; 90 struct completion done;
90}; 91};
91 92
93static void do_acct_process(struct bsd_acct_struct *acct);
94
92/* 95/*
93 * Check the amount of free space and suspend/resume accordingly. 96 * Check the amount of free space and suspend/resume accordingly.
94 */ 97 */
@@ -124,32 +127,56 @@ out:
124 return acct->active; 127 return acct->active;
125} 128}
126 129
130static void acct_put(struct bsd_acct_struct *p)
131{
132 if (atomic_long_dec_and_test(&p->count))
133 kfree_rcu(p, rcu);
134}
135
136static inline struct bsd_acct_struct *to_acct(struct fs_pin *p)
137{
138 return p ? container_of(p, struct bsd_acct_struct, pin) : NULL;
139}
140
127static struct bsd_acct_struct *acct_get(struct pid_namespace *ns) 141static struct bsd_acct_struct *acct_get(struct pid_namespace *ns)
128{ 142{
129 struct bsd_acct_struct *res; 143 struct bsd_acct_struct *res;
130again: 144again:
131 smp_rmb(); 145 smp_rmb();
132 rcu_read_lock(); 146 rcu_read_lock();
133 res = ACCESS_ONCE(ns->bacct); 147 res = to_acct(ACCESS_ONCE(ns->bacct));
134 if (!res) { 148 if (!res) {
135 rcu_read_unlock(); 149 rcu_read_unlock();
136 return NULL; 150 return NULL;
137 } 151 }
138 if (!atomic_long_inc_not_zero(&res->pin.count)) { 152 if (!atomic_long_inc_not_zero(&res->count)) {
139 rcu_read_unlock(); 153 rcu_read_unlock();
140 cpu_relax(); 154 cpu_relax();
141 goto again; 155 goto again;
142 } 156 }
143 rcu_read_unlock(); 157 rcu_read_unlock();
144 mutex_lock(&res->lock); 158 mutex_lock(&res->lock);
145 if (!res->ns) { 159 if (res != to_acct(ACCESS_ONCE(ns->bacct))) {
146 mutex_unlock(&res->lock); 160 mutex_unlock(&res->lock);
147 pin_put(&res->pin); 161 acct_put(res);
148 goto again; 162 goto again;
149 } 163 }
150 return res; 164 return res;
151} 165}
152 166
167static void acct_pin_kill(struct fs_pin *pin)
168{
169 struct bsd_acct_struct *acct = to_acct(pin);
170 mutex_lock(&acct->lock);
171 do_acct_process(acct);
172 schedule_work(&acct->work);
173 wait_for_completion(&acct->done);
174 cmpxchg(&acct->ns->bacct, pin, NULL);
175 mutex_unlock(&acct->lock);
176 pin_remove(pin);
177 acct_put(acct);
178}
179
153static void close_work(struct work_struct *work) 180static void close_work(struct work_struct *work)
154{ 181{
155 struct bsd_acct_struct *acct = container_of(work, struct bsd_acct_struct, work); 182 struct bsd_acct_struct *acct = container_of(work, struct bsd_acct_struct, work);
@@ -160,44 +187,13 @@ static void close_work(struct work_struct *work)
160 complete(&acct->done); 187 complete(&acct->done);
161} 188}
162 189
163static void acct_kill(struct bsd_acct_struct *acct,
164 struct bsd_acct_struct *new)
165{
166 if (acct) {
167 struct pid_namespace *ns = acct->ns;
168 do_acct_process(acct);
169 INIT_WORK(&acct->work, close_work);
170 init_completion(&acct->done);
171 schedule_work(&acct->work);
172 wait_for_completion(&acct->done);
173 pin_remove(&acct->pin);
174 ns->bacct = new;
175 acct->ns = NULL;
176 atomic_long_dec(&acct->pin.count);
177 mutex_unlock(&acct->lock);
178 pin_put(&acct->pin);
179 }
180}
181
182static void acct_pin_kill(struct fs_pin *pin)
183{
184 struct bsd_acct_struct *acct;
185 acct = container_of(pin, struct bsd_acct_struct, pin);
186 mutex_lock(&acct->lock);
187 if (!acct->ns) {
188 mutex_unlock(&acct->lock);
189 pin_put(pin);
190 acct = NULL;
191 }
192 acct_kill(acct, NULL);
193}
194
195static int acct_on(struct filename *pathname) 190static int acct_on(struct filename *pathname)
196{ 191{
197 struct file *file; 192 struct file *file;
198 struct vfsmount *mnt, *internal; 193 struct vfsmount *mnt, *internal;
199 struct pid_namespace *ns = task_active_pid_ns(current); 194 struct pid_namespace *ns = task_active_pid_ns(current);
200 struct bsd_acct_struct *acct, *old; 195 struct bsd_acct_struct *acct;
196 struct fs_pin *old;
201 int err; 197 int err;
202 198
203 acct = kzalloc(sizeof(struct bsd_acct_struct), GFP_KERNEL); 199 acct = kzalloc(sizeof(struct bsd_acct_struct), GFP_KERNEL);
@@ -238,21 +234,21 @@ static int acct_on(struct filename *pathname)
238 mnt = file->f_path.mnt; 234 mnt = file->f_path.mnt;
239 file->f_path.mnt = internal; 235 file->f_path.mnt = internal;
240 236
241 atomic_long_set(&acct->pin.count, 1); 237 atomic_long_set(&acct->count, 1);
242 acct->pin.kill = acct_pin_kill; 238 init_fs_pin(&acct->pin, acct_pin_kill);
243 acct->file = file; 239 acct->file = file;
244 acct->needcheck = jiffies; 240 acct->needcheck = jiffies;
245 acct->ns = ns; 241 acct->ns = ns;
246 mutex_init(&acct->lock); 242 mutex_init(&acct->lock);
243 INIT_WORK(&acct->work, close_work);
244 init_completion(&acct->done);
247 mutex_lock_nested(&acct->lock, 1); /* nobody has seen it yet */ 245 mutex_lock_nested(&acct->lock, 1); /* nobody has seen it yet */
248 pin_insert(&acct->pin, mnt); 246 pin_insert(&acct->pin, mnt);
249 247
250 old = acct_get(ns); 248 rcu_read_lock();
251 if (old) 249 old = xchg(&ns->bacct, &acct->pin);
252 acct_kill(old, acct);
253 else
254 ns->bacct = acct;
255 mutex_unlock(&acct->lock); 250 mutex_unlock(&acct->lock);
251 pin_kill(old);
256 mnt_drop_write(mnt); 252 mnt_drop_write(mnt);
257 mntput(mnt); 253 mntput(mnt);
258 return 0; 254 return 0;
@@ -288,7 +284,8 @@ SYSCALL_DEFINE1(acct, const char __user *, name)
288 mutex_unlock(&acct_on_mutex); 284 mutex_unlock(&acct_on_mutex);
289 putname(tmp); 285 putname(tmp);
290 } else { 286 } else {
291 acct_kill(acct_get(task_active_pid_ns(current)), NULL); 287 rcu_read_lock();
288 pin_kill(task_active_pid_ns(current)->bacct);
292 } 289 }
293 290
294 return error; 291 return error;
@@ -296,7 +293,8 @@ SYSCALL_DEFINE1(acct, const char __user *, name)
296 293
297void acct_exit_ns(struct pid_namespace *ns) 294void acct_exit_ns(struct pid_namespace *ns)
298{ 295{
299 acct_kill(acct_get(ns), NULL); 296 rcu_read_lock();
297 pin_kill(ns->bacct);
300} 298}
301 299
302/* 300/*
@@ -576,7 +574,7 @@ static void slow_acct_process(struct pid_namespace *ns)
576 if (acct) { 574 if (acct) {
577 do_acct_process(acct); 575 do_acct_process(acct);
578 mutex_unlock(&acct->lock); 576 mutex_unlock(&acct->lock);
579 pin_put(&acct->pin); 577 acct_put(acct);
580 } 578 }
581 } 579 }
582} 580}
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 072566dd0caf..55f82fce2526 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -2405,7 +2405,6 @@ int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
2405 struct audit_aux_data_bprm_fcaps *ax; 2405 struct audit_aux_data_bprm_fcaps *ax;
2406 struct audit_context *context = current->audit_context; 2406 struct audit_context *context = current->audit_context;
2407 struct cpu_vfs_cap_data vcaps; 2407 struct cpu_vfs_cap_data vcaps;
2408 struct dentry *dentry;
2409 2408
2410 ax = kmalloc(sizeof(*ax), GFP_KERNEL); 2409 ax = kmalloc(sizeof(*ax), GFP_KERNEL);
2411 if (!ax) 2410 if (!ax)
@@ -2415,9 +2414,7 @@ int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
2415 ax->d.next = context->aux; 2414 ax->d.next = context->aux;
2416 context->aux = (void *)ax; 2415 context->aux = (void *)ax;
2417 2416
2418 dentry = dget(bprm->file->f_path.dentry); 2417 get_vfs_caps_from_disk(bprm->file->f_path.dentry, &vcaps);
2419 get_vfs_caps_from_disk(dentry, &vcaps);
2420 dput(dentry);
2421 2418
2422 ax->fcap.permitted = vcaps.permitted; 2419 ax->fcap.permitted = vcaps.permitted;
2423 ax->fcap.inheritable = vcaps.inheritable; 2420 ax->fcap.inheritable = vcaps.inheritable;
diff --git a/lib/lockref.c b/lib/lockref.c
index d2233de9a86e..ecb9a665ec19 100644
--- a/lib/lockref.c
+++ b/lib/lockref.c
@@ -60,7 +60,7 @@ void lockref_get(struct lockref *lockref)
60EXPORT_SYMBOL(lockref_get); 60EXPORT_SYMBOL(lockref_get);
61 61
62/** 62/**
63 * lockref_get_not_zero - Increments count unless the count is 0 63 * lockref_get_not_zero - Increments count unless the count is 0 or dead
64 * @lockref: pointer to lockref structure 64 * @lockref: pointer to lockref structure
65 * Return: 1 if count updated successfully or 0 if count was zero 65 * Return: 1 if count updated successfully or 0 if count was zero
66 */ 66 */
@@ -70,7 +70,7 @@ int lockref_get_not_zero(struct lockref *lockref)
70 70
71 CMPXCHG_LOOP( 71 CMPXCHG_LOOP(
72 new.count++; 72 new.count++;
73 if (!old.count) 73 if (old.count <= 0)
74 return 0; 74 return 0;
75 , 75 ,
76 return 1; 76 return 1;
@@ -78,7 +78,7 @@ int lockref_get_not_zero(struct lockref *lockref)
78 78
79 spin_lock(&lockref->lock); 79 spin_lock(&lockref->lock);
80 retval = 0; 80 retval = 0;
81 if (lockref->count) { 81 if (lockref->count > 0) {
82 lockref->count++; 82 lockref->count++;
83 retval = 1; 83 retval = 1;
84 } 84 }
@@ -88,7 +88,7 @@ int lockref_get_not_zero(struct lockref *lockref)
88EXPORT_SYMBOL(lockref_get_not_zero); 88EXPORT_SYMBOL(lockref_get_not_zero);
89 89
90/** 90/**
91 * lockref_get_or_lock - Increments count unless the count is 0 91 * lockref_get_or_lock - Increments count unless the count is 0 or dead
92 * @lockref: pointer to lockref structure 92 * @lockref: pointer to lockref structure
93 * Return: 1 if count updated successfully or 0 if count was zero 93 * Return: 1 if count updated successfully or 0 if count was zero
94 * and we got the lock instead. 94 * and we got the lock instead.
@@ -97,14 +97,14 @@ int lockref_get_or_lock(struct lockref *lockref)
97{ 97{
98 CMPXCHG_LOOP( 98 CMPXCHG_LOOP(
99 new.count++; 99 new.count++;
100 if (!old.count) 100 if (old.count <= 0)
101 break; 101 break;
102 , 102 ,
103 return 1; 103 return 1;
104 ); 104 );
105 105
106 spin_lock(&lockref->lock); 106 spin_lock(&lockref->lock);
107 if (!lockref->count) 107 if (lockref->count <= 0)
108 return 0; 108 return 0;
109 lockref->count++; 109 lockref->count++;
110 spin_unlock(&lockref->lock); 110 spin_unlock(&lockref->lock);
@@ -113,6 +113,26 @@ int lockref_get_or_lock(struct lockref *lockref)
113EXPORT_SYMBOL(lockref_get_or_lock); 113EXPORT_SYMBOL(lockref_get_or_lock);
114 114
115/** 115/**
116 * lockref_put_return - Decrement reference count if possible
117 * @lockref: pointer to lockref structure
118 *
119 * Decrement the reference count and return the new value.
120 * If the lockref was dead or locked, return an error.
121 */
122int lockref_put_return(struct lockref *lockref)
123{
124 CMPXCHG_LOOP(
125 new.count--;
126 if (old.count <= 0)
127 return -1;
128 ,
129 return new.count;
130 );
131 return -1;
132}
133EXPORT_SYMBOL(lockref_put_return);
134
135/**
116 * lockref_put_or_lock - decrements count unless count <= 1 before decrement 136 * lockref_put_or_lock - decrements count unless count <= 1 before decrement
117 * @lockref: pointer to lockref structure 137 * @lockref: pointer to lockref structure
118 * Return: 1 if count updated successfully or 0 if count <= 1 and lock taken 138 * Return: 1 if count updated successfully or 0 if count <= 1 and lock taken
@@ -158,7 +178,7 @@ int lockref_get_not_dead(struct lockref *lockref)
158 178
159 CMPXCHG_LOOP( 179 CMPXCHG_LOOP(
160 new.count++; 180 new.count++;
161 if ((int)old.count < 0) 181 if (old.count < 0)
162 return 0; 182 return 0;
163 , 183 ,
164 return 1; 184 return 1;
@@ -166,7 +186,7 @@ int lockref_get_not_dead(struct lockref *lockref)
166 186
167 spin_lock(&lockref->lock); 187 spin_lock(&lockref->lock);
168 retval = 0; 188 retval = 0;
169 if ((int) lockref->count >= 0) { 189 if (lockref->count >= 0) {
170 lockref->count++; 190 lockref->count++;
171 retval = 1; 191 retval = 1;
172 } 192 }
diff --git a/security/commoncap.c b/security/commoncap.c
index 2915d8503054..f66713bd7450 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -434,7 +434,6 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data
434 */ 434 */
435static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_cap) 435static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_cap)
436{ 436{
437 struct dentry *dentry;
438 int rc = 0; 437 int rc = 0;
439 struct cpu_vfs_cap_data vcaps; 438 struct cpu_vfs_cap_data vcaps;
440 439
@@ -446,9 +445,7 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_c
446 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) 445 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
447 return 0; 446 return 0;
448 447
449 dentry = dget(bprm->file->f_path.dentry); 448 rc = get_vfs_caps_from_disk(bprm->file->f_path.dentry, &vcaps);
450
451 rc = get_vfs_caps_from_disk(dentry, &vcaps);
452 if (rc < 0) { 449 if (rc < 0) {
453 if (rc == -EINVAL) 450 if (rc == -EINVAL)
454 printk(KERN_NOTICE "%s: get_vfs_caps_from_disk returned %d for %s\n", 451 printk(KERN_NOTICE "%s: get_vfs_caps_from_disk returned %d for %s\n",
@@ -464,7 +461,6 @@ static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_c
464 __func__, rc, bprm->filename); 461 __func__, rc, bprm->filename);
465 462
466out: 463out:
467 dput(dentry);
468 if (rc) 464 if (rc)
469 bprm_clear_caps(bprm); 465 bprm_clear_caps(bprm);
470 466
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 33db1ad4fd10..1684bcc78b34 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -1195,30 +1195,8 @@ static const struct file_operations sel_commit_bools_ops = {
1195 1195
1196static void sel_remove_entries(struct dentry *de) 1196static void sel_remove_entries(struct dentry *de)
1197{ 1197{
1198 struct list_head *node; 1198 d_genocide(de);
1199 1199 shrink_dcache_parent(de);
1200 spin_lock(&de->d_lock);
1201 node = de->d_subdirs.next;
1202 while (node != &de->d_subdirs) {
1203 struct dentry *d = list_entry(node, struct dentry, d_child);
1204
1205 spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
1206 list_del_init(node);
1207
1208 if (d->d_inode) {
1209 dget_dlock(d);
1210 spin_unlock(&de->d_lock);
1211 spin_unlock(&d->d_lock);
1212 d_delete(d);
1213 simple_unlink(de->d_inode, d);
1214 dput(d);
1215 spin_lock(&de->d_lock);
1216 } else
1217 spin_unlock(&d->d_lock);
1218 node = de->d_subdirs.next;
1219 }
1220
1221 spin_unlock(&de->d_lock);
1222} 1200}
1223 1201
1224#define BOOL_DIR_NAME "booleans" 1202#define BOOL_DIR_NAME "booleans"
@@ -1668,37 +1646,13 @@ static int sel_make_class_dir_entries(char *classname, int index,
1668 return rc; 1646 return rc;
1669} 1647}
1670 1648
1671static void sel_remove_classes(void)
1672{
1673 struct list_head *class_node;
1674
1675 list_for_each(class_node, &class_dir->d_subdirs) {
1676 struct dentry *class_subdir = list_entry(class_node,
1677 struct dentry, d_child);
1678 struct list_head *class_subdir_node;
1679
1680 list_for_each(class_subdir_node, &class_subdir->d_subdirs) {
1681 struct dentry *d = list_entry(class_subdir_node,
1682 struct dentry, d_child);
1683
1684 if (d->d_inode)
1685 if (d->d_inode->i_mode & S_IFDIR)
1686 sel_remove_entries(d);
1687 }
1688
1689 sel_remove_entries(class_subdir);
1690 }
1691
1692 sel_remove_entries(class_dir);
1693}
1694
1695static int sel_make_classes(void) 1649static int sel_make_classes(void)
1696{ 1650{
1697 int rc, nclasses, i; 1651 int rc, nclasses, i;
1698 char **classes; 1652 char **classes;
1699 1653
1700 /* delete any existing entries */ 1654 /* delete any existing entries */
1701 sel_remove_classes(); 1655 sel_remove_entries(class_dir);
1702 1656
1703 rc = security_get_classes(&classes, &nclasses); 1657 rc = security_get_classes(&classes, &nclasses);
1704 if (rc) 1658 if (rc)