diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/mount.h | 3 | ||||
-rw-r--r-- | fs/namespace.c | 32 | ||||
-rw-r--r-- | fs/pnode.c | 2 |
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 | ||
33 | static inline struct mount *real_mount(struct vfsmount *mnt) | 36 | static 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: | |||
801 | void mntput(struct vfsmount *mnt) | 801 | void 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 | } |
810 | EXPORT_SYMBOL(mntput); | 811 | EXPORT_SYMBOL(mntput); |
@@ -820,16 +821,17 @@ EXPORT_SYMBOL(mntget); | |||
820 | void mnt_pin(struct vfsmount *mnt) | 821 | void 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 | } |
826 | EXPORT_SYMBOL(mnt_pin); | 827 | EXPORT_SYMBOL(mnt_pin); |
827 | 828 | ||
828 | void mnt_unpin(struct vfsmount *mnt) | 829 | void 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 | */ |
273 | static inline int do_refcount_check(struct mount *mnt, int count) | 273 | static 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 | ||