aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/mount.h3
-rw-r--r--fs/namespace.c32
-rw-r--r--fs/pnode.c2
3 files changed, 21 insertions, 16 deletions
diff --git a/fs/mount.h b/fs/mount.h
index c7bd401960ea..9217e03ba5e7 100644
--- a/fs/mount.h
+++ b/fs/mount.h
@@ -28,6 +28,9 @@ struct mount {
28 struct mnt_namespace *mnt_ns; /* containing namespace */ 28 struct mnt_namespace *mnt_ns; /* containing namespace */
29 int mnt_id; /* mount identifier */ 29 int mnt_id; /* mount identifier */
30 int mnt_group_id; /* peer group identifier */ 30 int mnt_group_id; /* peer group identifier */
31 int mnt_expiry_mark; /* true if marked for expiry */
32 int mnt_pinned;
33 int mnt_ghosts;
31}; 34};
32 35
33static inline struct mount *real_mount(struct vfsmount *mnt) 36static inline struct mount *real_mount(struct vfsmount *mnt)
diff --git a/fs/namespace.c b/fs/namespace.c
index dfed9a25f204..c7b8dbc88fe5 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -787,9 +787,9 @@ put_again:
787 return; 787 return;
788 br_write_lock(vfsmount_lock); 788 br_write_lock(vfsmount_lock);
789#endif 789#endif
790 if (unlikely(mnt->mnt.mnt_pinned)) { 790 if (unlikely(mnt->mnt_pinned)) {
791 mnt_add_count(mnt, mnt->mnt.mnt_pinned + 1); 791 mnt_add_count(mnt, mnt->mnt_pinned + 1);
792 mnt->mnt.mnt_pinned = 0; 792 mnt->mnt_pinned = 0;
793 br_write_unlock(vfsmount_lock); 793 br_write_unlock(vfsmount_lock);
794 acct_auto_close_mnt(&mnt->mnt); 794 acct_auto_close_mnt(&mnt->mnt);
795 goto put_again; 795 goto put_again;
@@ -801,10 +801,11 @@ put_again:
801void mntput(struct vfsmount *mnt) 801void mntput(struct vfsmount *mnt)
802{ 802{
803 if (mnt) { 803 if (mnt) {
804 struct mount *m = real_mount(mnt);
804 /* avoid cacheline pingpong, hope gcc doesn't get "smart" */ 805 /* avoid cacheline pingpong, hope gcc doesn't get "smart" */
805 if (unlikely(mnt->mnt_expiry_mark)) 806 if (unlikely(m->mnt_expiry_mark))
806 mnt->mnt_expiry_mark = 0; 807 m->mnt_expiry_mark = 0;
807 mntput_no_expire(real_mount(mnt)); 808 mntput_no_expire(m);
808 } 809 }
809} 810}
810EXPORT_SYMBOL(mntput); 811EXPORT_SYMBOL(mntput);
@@ -820,16 +821,17 @@ EXPORT_SYMBOL(mntget);
820void mnt_pin(struct vfsmount *mnt) 821void mnt_pin(struct vfsmount *mnt)
821{ 822{
822 br_write_lock(vfsmount_lock); 823 br_write_lock(vfsmount_lock);
823 mnt->mnt_pinned++; 824 real_mount(mnt)->mnt_pinned++;
824 br_write_unlock(vfsmount_lock); 825 br_write_unlock(vfsmount_lock);
825} 826}
826EXPORT_SYMBOL(mnt_pin); 827EXPORT_SYMBOL(mnt_pin);
827 828
828void mnt_unpin(struct vfsmount *mnt) 829void mnt_unpin(struct vfsmount *m)
829{ 830{
831 struct mount *mnt = real_mount(m);
830 br_write_lock(vfsmount_lock); 832 br_write_lock(vfsmount_lock);
831 if (mnt->mnt_pinned) { 833 if (mnt->mnt_pinned) {
832 mnt_add_count(real_mount(mnt), 1); 834 mnt_add_count(mnt, 1);
833 mnt->mnt_pinned--; 835 mnt->mnt_pinned--;
834 } 836 }
835 br_write_unlock(vfsmount_lock); 837 br_write_unlock(vfsmount_lock);
@@ -1200,17 +1202,17 @@ void release_mounts(struct list_head *head)
1200 list_del_init(&mnt->mnt_hash); 1202 list_del_init(&mnt->mnt_hash);
1201 if (mnt_has_parent(mnt)) { 1203 if (mnt_has_parent(mnt)) {
1202 struct dentry *dentry; 1204 struct dentry *dentry;
1203 struct vfsmount *m; 1205 struct mount *m;
1204 1206
1205 br_write_lock(vfsmount_lock); 1207 br_write_lock(vfsmount_lock);
1206 dentry = mnt->mnt_mountpoint; 1208 dentry = mnt->mnt_mountpoint;
1207 m = &mnt->mnt_parent->mnt; 1209 m = mnt->mnt_parent;
1208 mnt->mnt_mountpoint = mnt->mnt.mnt_root; 1210 mnt->mnt_mountpoint = mnt->mnt.mnt_root;
1209 mnt->mnt_parent = mnt; 1211 mnt->mnt_parent = mnt;
1210 m->mnt_ghosts--; 1212 m->mnt_ghosts--;
1211 br_write_unlock(vfsmount_lock); 1213 br_write_unlock(vfsmount_lock);
1212 dput(dentry); 1214 dput(dentry);
1213 mntput(m); 1215 mntput(&m->mnt);
1214 } 1216 }
1215 mntput(&mnt->mnt); 1217 mntput(&mnt->mnt);
1216 } 1218 }
@@ -1239,7 +1241,7 @@ void umount_tree(struct mount *mnt, int propagate, struct list_head *kill)
1239 __mnt_make_shortterm(p); 1241 __mnt_make_shortterm(p);
1240 list_del_init(&p->mnt_child); 1242 list_del_init(&p->mnt_child);
1241 if (mnt_has_parent(p)) { 1243 if (mnt_has_parent(p)) {
1242 p->mnt_parent->mnt.mnt_ghosts++; 1244 p->mnt_parent->mnt_ghosts++;
1243 dentry_reset_mounted(p->mnt_mountpoint); 1245 dentry_reset_mounted(p->mnt_mountpoint);
1244 } 1246 }
1245 change_mnt_propagation(p, MS_PRIVATE); 1247 change_mnt_propagation(p, MS_PRIVATE);
@@ -1281,7 +1283,7 @@ static int do_umount(struct mount *mnt, int flags)
1281 } 1283 }
1282 br_write_unlock(vfsmount_lock); 1284 br_write_unlock(vfsmount_lock);
1283 1285
1284 if (!xchg(&mnt->mnt.mnt_expiry_mark, 1)) 1286 if (!xchg(&mnt->mnt_expiry_mark, 1))
1285 return -EAGAIN; 1287 return -EAGAIN;
1286 } 1288 }
1287 1289
@@ -2106,7 +2108,7 @@ void mark_mounts_for_expiry(struct list_head *mounts)
2106 * cleared by mntput()) 2108 * cleared by mntput())
2107 */ 2109 */
2108 list_for_each_entry_safe(mnt, next, mounts, mnt_expire) { 2110 list_for_each_entry_safe(mnt, next, mounts, mnt_expire) {
2109 if (!xchg(&mnt->mnt.mnt_expiry_mark, 1) || 2111 if (!xchg(&mnt->mnt_expiry_mark, 1) ||
2110 propagate_mount_busy(mnt, 1)) 2112 propagate_mount_busy(mnt, 1))
2111 continue; 2113 continue;
2112 list_move(&mnt->mnt_expire, &graveyard); 2114 list_move(&mnt->mnt_expire, &graveyard);
diff --git a/fs/pnode.c b/fs/pnode.c
index 001c8b0df379..a40abf20f35e 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -272,7 +272,7 @@ out:
272 */ 272 */
273static inline int do_refcount_check(struct mount *mnt, int count) 273static inline int do_refcount_check(struct mount *mnt, int count)
274{ 274{
275 int mycount = mnt_get_count(mnt) - mnt->mnt.mnt_ghosts; 275 int mycount = mnt_get_count(mnt) - mnt->mnt_ghosts;
276 return (mycount > count); 276 return (mycount > count);
277} 277}
278 278