Blame view

fs/namespace.c 98.5 KB
59bd9ded4   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
  /*
   *  linux/fs/namespace.c
   *
   * (C) Copyright Al Viro 2000, 2001
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
7
8
9
   *
   * Based on code from fs/super.c, copyright Linus Torvalds and others.
   * Heavily rewritten.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
  #include <linux/syscalls.h>
d10577a8d   Al Viro   vfs: trim include...
11
  #include <linux/export.h>
16f7e0fe2   Randy Dunlap   [PATCH] capable/c...
12
  #include <linux/capability.h>
6b3286ed1   Kirill Korotaev   [PATCH] rename st...
13
  #include <linux/mnt_namespace.h>
771b13716   Eric W. Biederman   vfs: Add a user n...
14
  #include <linux/user_namespace.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
16
  #include <linux/namei.h>
  #include <linux/security.h>
5b825c3af   Ingo Molnar   sched/headers: Pr...
17
  #include <linux/cred.h>
73cd49ecd   Miklos Szeredi   [patch 3/7] vfs: ...
18
  #include <linux/idr.h>
57f150a58   Rob Landley   initmpfs: move ro...
19
  #include <linux/init.h>		/* init_rootfs */
d10577a8d   Al Viro   vfs: trim include...
20
21
  #include <linux/fs_struct.h>	/* get_fs_root et.al. */
  #include <linux/fsnotify.h>	/* fsnotify_vfsmount_delete */
a07b20004   Al Viro   vfs: syscall: Add...
22
  #include <linux/file.h>
d10577a8d   Al Viro   vfs: trim include...
23
  #include <linux/uaccess.h>
0bb80f240   David Howells   proc: Split the n...
24
  #include <linux/proc_ns.h>
20b4fb485   Linus Torvalds   Merge branch 'for...
25
  #include <linux/magic.h>
57c8a661d   Mike Rapoport   mm: remove includ...
26
  #include <linux/memblock.h>
9ea459e11   Al Viro   delayed mntput
27
  #include <linux/task_work.h>
9164bb4a1   Ingo Molnar   sched/headers: Pr...
28
  #include <linux/sched/task.h>
e262e32d6   David Howells   vfs: Suppress MS_...
29
  #include <uapi/linux/mount.h>
9bc61ab18   David Howells   vfs: Introduce fs...
30
  #include <linux/fs_context.h>
037f11b47   Al Viro   mnt_init(): call ...
31
  #include <linux/shmem_fs.h>
9164bb4a1   Ingo Molnar   sched/headers: Pr...
32

07b20889e   Ram Pai   [PATCH] beginning...
33
  #include "pnode.h"
948730b0e   Adrian Bunk   fs/namespace.c sh...
34
  #include "internal.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35

d29216842   Eric W. Biederman   mnt: Add a per mo...
36
37
  /* Maximum number of mounts in a mount namespace */
  unsigned int sysctl_mount_max __read_mostly = 100000;
0818bf27c   Al Viro   resizable namespa...
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
  static unsigned int m_hash_mask __read_mostly;
  static unsigned int m_hash_shift __read_mostly;
  static unsigned int mp_hash_mask __read_mostly;
  static unsigned int mp_hash_shift __read_mostly;
  
  static __initdata unsigned long mhash_entries;
  static int __init set_mhash_entries(char *str)
  {
  	if (!str)
  		return 0;
  	mhash_entries = simple_strtoul(str, &str, 0);
  	return 1;
  }
  __setup("mhash_entries=", set_mhash_entries);
  
  static __initdata unsigned long mphash_entries;
  static int __init set_mphash_entries(char *str)
  {
  	if (!str)
  		return 0;
  	mphash_entries = simple_strtoul(str, &str, 0);
  	return 1;
  }
  __setup("mphash_entries=", set_mphash_entries);
13f14b4d8   Eric Dumazet   Use ilog2() in fs...
62

c7999c362   Al Viro   reduce m_start() ...
63
  static u64 event;
73cd49ecd   Miklos Szeredi   [patch 3/7] vfs: ...
64
  static DEFINE_IDA(mnt_id_ida);
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
65
  static DEFINE_IDA(mnt_group_ida);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66

38129a13e   Al Viro   switch mnt_hash t...
67
  static struct hlist_head *mount_hashtable __read_mostly;
0818bf27c   Al Viro   resizable namespa...
68
  static struct hlist_head *mountpoint_hashtable __read_mostly;
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
69
  static struct kmem_cache *mnt_cache __read_mostly;
59aa0da8e   Al Viro   initialize namesp...
70
  static DECLARE_RWSEM(namespace_sem);
4edbe133f   Al Viro   make struct mount...
71
72
  static HLIST_HEAD(unmounted);	/* protected by namespace_sem */
  static LIST_HEAD(ex_mountpoints); /* protected by namespace_sem */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73

f87fd4c2a   Miklos Szeredi   [PATCH] add /sys/fs
74
  /* /sys/fs */
00d266662   Greg Kroah-Hartman   kobject: convert ...
75
76
  struct kobject *fs_kobj;
  EXPORT_SYMBOL_GPL(fs_kobj);
f87fd4c2a   Miklos Szeredi   [PATCH] add /sys/fs
77

99b7db7b8   Nick Piggin   fs: brlock vfsmou...
78
79
80
81
82
83
84
85
  /*
   * vfsmount lock may be taken for read to prevent changes to the
   * vfsmount hash, ie. during mountpoint lookups or walking back
   * up the tree.
   *
   * It should be taken for write in all cases where the vfsmount
   * tree or hash is modified or when a vfsmount structure is modified.
   */
48a066e72   Al Viro   RCU'd vfsmounts
86
  __cacheline_aligned_in_smp DEFINE_SEQLOCK(mount_lock);
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
87

38129a13e   Al Viro   switch mnt_hash t...
88
  static inline struct hlist_head *m_hash(struct vfsmount *mnt, struct dentry *dentry)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
  {
b58fed8b1   Ram Pai   [PATCH] lindent f...
90
91
  	unsigned long tmp = ((unsigned long)mnt / L1_CACHE_BYTES);
  	tmp += ((unsigned long)dentry / L1_CACHE_BYTES);
0818bf27c   Al Viro   resizable namespa...
92
93
94
95
96
97
98
99
100
  	tmp = tmp + (tmp >> m_hash_shift);
  	return &mount_hashtable[tmp & m_hash_mask];
  }
  
  static inline struct hlist_head *mp_hash(struct dentry *dentry)
  {
  	unsigned long tmp = ((unsigned long)dentry / L1_CACHE_BYTES);
  	tmp = tmp + (tmp >> mp_hash_shift);
  	return &mountpoint_hashtable[tmp & mp_hash_mask];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
  }
b105e270b   Al Viro   vfs: spread struc...
102
  static int mnt_alloc_id(struct mount *mnt)
73cd49ecd   Miklos Szeredi   [patch 3/7] vfs: ...
103
  {
169b480e4   Matthew Wilcox   fs: Convert names...
104
105
106
107
108
109
  	int res = ida_alloc(&mnt_id_ida, GFP_KERNEL);
  
  	if (res < 0)
  		return res;
  	mnt->mnt_id = res;
  	return 0;
73cd49ecd   Miklos Szeredi   [patch 3/7] vfs: ...
110
  }
b105e270b   Al Viro   vfs: spread struc...
111
  static void mnt_free_id(struct mount *mnt)
73cd49ecd   Miklos Szeredi   [patch 3/7] vfs: ...
112
  {
169b480e4   Matthew Wilcox   fs: Convert names...
113
  	ida_free(&mnt_id_ida, mnt->mnt_id);
73cd49ecd   Miklos Szeredi   [patch 3/7] vfs: ...
114
  }
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
115
116
  /*
   * Allocate a new peer group ID
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
117
   */
4b8b21f4f   Al Viro   vfs: spread struc...
118
  static int mnt_alloc_group_id(struct mount *mnt)
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
119
  {
169b480e4   Matthew Wilcox   fs: Convert names...
120
  	int res = ida_alloc_min(&mnt_group_ida, 1, GFP_KERNEL);
f21f62208   Al Viro   ... and the same ...
121

169b480e4   Matthew Wilcox   fs: Convert names...
122
123
124
125
  	if (res < 0)
  		return res;
  	mnt->mnt_group_id = res;
  	return 0;
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
126
127
128
129
130
  }
  
  /*
   * Release a peer group ID
   */
4b8b21f4f   Al Viro   vfs: spread struc...
131
  void mnt_release_group_id(struct mount *mnt)
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
132
  {
169b480e4   Matthew Wilcox   fs: Convert names...
133
  	ida_free(&mnt_group_ida, mnt->mnt_group_id);
15169fe78   Al Viro   vfs: mnt_id/mnt_g...
134
  	mnt->mnt_group_id = 0;
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
135
  }
b3e19d924   Nick Piggin   fs: scale mntget/...
136
137
138
  /*
   * vfsmount lock must be held for read
   */
83adc7532   Al Viro   vfs: spread struc...
139
  static inline void mnt_add_count(struct mount *mnt, int n)
b3e19d924   Nick Piggin   fs: scale mntget/...
140
141
  {
  #ifdef CONFIG_SMP
68e8a9fea   Al Viro   vfs: all counters...
142
  	this_cpu_add(mnt->mnt_pcp->mnt_count, n);
b3e19d924   Nick Piggin   fs: scale mntget/...
143
144
  #else
  	preempt_disable();
68e8a9fea   Al Viro   vfs: all counters...
145
  	mnt->mnt_count += n;
b3e19d924   Nick Piggin   fs: scale mntget/...
146
147
148
  	preempt_enable();
  #endif
  }
b3e19d924   Nick Piggin   fs: scale mntget/...
149
150
151
  /*
   * vfsmount lock must be held for write
   */
eae1fb3bc   Eric Biggers   fs/namespace.c: W...
152
  int mnt_get_count(struct mount *mnt)
b3e19d924   Nick Piggin   fs: scale mntget/...
153
154
  {
  #ifdef CONFIG_SMP
eae1fb3bc   Eric Biggers   fs/namespace.c: W...
155
  	int count = 0;
b3e19d924   Nick Piggin   fs: scale mntget/...
156
157
158
  	int cpu;
  
  	for_each_possible_cpu(cpu) {
68e8a9fea   Al Viro   vfs: all counters...
159
  		count += per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_count;
b3e19d924   Nick Piggin   fs: scale mntget/...
160
161
162
163
  	}
  
  	return count;
  #else
68e8a9fea   Al Viro   vfs: all counters...
164
  	return mnt->mnt_count;
b3e19d924   Nick Piggin   fs: scale mntget/...
165
166
  #endif
  }
b105e270b   Al Viro   vfs: spread struc...
167
  static struct mount *alloc_vfsmnt(const char *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
  {
c63181e6b   Al Viro   vfs: move fsnotif...
169
170
  	struct mount *mnt = kmem_cache_zalloc(mnt_cache, GFP_KERNEL);
  	if (mnt) {
73cd49ecd   Miklos Szeredi   [patch 3/7] vfs: ...
171
  		int err;
c63181e6b   Al Viro   vfs: move fsnotif...
172
  		err = mnt_alloc_id(mnt);
88b387824   Li Zefan   [PATCH] vfs: use ...
173
174
175
176
  		if (err)
  			goto out_free_cache;
  
  		if (name) {
fcc139ae2   Andrzej Hajda   fs/namespace: con...
177
  			mnt->mnt_devname = kstrdup_const(name, GFP_KERNEL);
c63181e6b   Al Viro   vfs: move fsnotif...
178
  			if (!mnt->mnt_devname)
88b387824   Li Zefan   [PATCH] vfs: use ...
179
  				goto out_free_id;
73cd49ecd   Miklos Szeredi   [patch 3/7] vfs: ...
180
  		}
b3e19d924   Nick Piggin   fs: scale mntget/...
181
  #ifdef CONFIG_SMP
c63181e6b   Al Viro   vfs: move fsnotif...
182
183
  		mnt->mnt_pcp = alloc_percpu(struct mnt_pcp);
  		if (!mnt->mnt_pcp)
b3e19d924   Nick Piggin   fs: scale mntget/...
184
  			goto out_free_devname;
c63181e6b   Al Viro   vfs: move fsnotif...
185
  		this_cpu_add(mnt->mnt_pcp->mnt_count, 1);
b3e19d924   Nick Piggin   fs: scale mntget/...
186
  #else
c63181e6b   Al Viro   vfs: move fsnotif...
187
188
  		mnt->mnt_count = 1;
  		mnt->mnt_writers = 0;
b3e19d924   Nick Piggin   fs: scale mntget/...
189
  #endif
38129a13e   Al Viro   switch mnt_hash t...
190
  		INIT_HLIST_NODE(&mnt->mnt_hash);
c63181e6b   Al Viro   vfs: move fsnotif...
191
192
193
194
195
196
197
  		INIT_LIST_HEAD(&mnt->mnt_child);
  		INIT_LIST_HEAD(&mnt->mnt_mounts);
  		INIT_LIST_HEAD(&mnt->mnt_list);
  		INIT_LIST_HEAD(&mnt->mnt_expire);
  		INIT_LIST_HEAD(&mnt->mnt_share);
  		INIT_LIST_HEAD(&mnt->mnt_slave_list);
  		INIT_LIST_HEAD(&mnt->mnt_slave);
0a5eb7c81   Eric W. Biederman   vfs: Keep a list ...
198
  		INIT_HLIST_NODE(&mnt->mnt_mp_list);
99b19d164   Eric W. Biederman   mnt: In propgate_...
199
  		INIT_LIST_HEAD(&mnt->mnt_umounting);
56cbb429d   Al Viro   switch the remnan...
200
  		INIT_HLIST_HEAD(&mnt->mnt_stuck_children);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
  	}
c63181e6b   Al Viro   vfs: move fsnotif...
202
  	return mnt;
88b387824   Li Zefan   [PATCH] vfs: use ...
203

d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
204
205
  #ifdef CONFIG_SMP
  out_free_devname:
fcc139ae2   Andrzej Hajda   fs/namespace: con...
206
  	kfree_const(mnt->mnt_devname);
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
207
  #endif
88b387824   Li Zefan   [PATCH] vfs: use ...
208
  out_free_id:
c63181e6b   Al Viro   vfs: move fsnotif...
209
  	mnt_free_id(mnt);
88b387824   Li Zefan   [PATCH] vfs: use ...
210
  out_free_cache:
c63181e6b   Al Viro   vfs: move fsnotif...
211
  	kmem_cache_free(mnt_cache, mnt);
88b387824   Li Zefan   [PATCH] vfs: use ...
212
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213
  }
8366025eb   Dave Hansen   [PATCH] r/o bind ...
214
215
216
217
218
219
220
221
  /*
   * Most r/o checks on a fs are for operations that take
   * discrete amounts of time, like a write() or unlink().
   * We must keep track of when those operations start
   * (for permission checks) and when they end, so that
   * we can determine when writes are able to occur to
   * a filesystem.
   */
3d733633a   Dave Hansen   [PATCH] r/o bind ...
222
223
224
225
226
227
228
229
230
231
232
  /*
   * __mnt_is_readonly: check whether a mount is read-only
   * @mnt: the mount to check for its write status
   *
   * This shouldn't be used directly ouside of the VFS.
   * It does not guarantee that the filesystem will stay
   * r/w, just that it is right *now*.  This can not and
   * should not be used in place of IS_RDONLY(inode).
   * mnt_want/drop_write() will _keep_ the filesystem
   * r/w.
   */
43f5e655e   David Howells   vfs: Separate cha...
233
  bool __mnt_is_readonly(struct vfsmount *mnt)
3d733633a   Dave Hansen   [PATCH] r/o bind ...
234
  {
43f5e655e   David Howells   vfs: Separate cha...
235
  	return (mnt->mnt_flags & MNT_READONLY) || sb_rdonly(mnt->mnt_sb);
3d733633a   Dave Hansen   [PATCH] r/o bind ...
236
237
  }
  EXPORT_SYMBOL_GPL(__mnt_is_readonly);
83adc7532   Al Viro   vfs: spread struc...
238
  static inline void mnt_inc_writers(struct mount *mnt)
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
239
240
  {
  #ifdef CONFIG_SMP
68e8a9fea   Al Viro   vfs: all counters...
241
  	this_cpu_inc(mnt->mnt_pcp->mnt_writers);
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
242
  #else
68e8a9fea   Al Viro   vfs: all counters...
243
  	mnt->mnt_writers++;
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
244
245
  #endif
  }
3d733633a   Dave Hansen   [PATCH] r/o bind ...
246

83adc7532   Al Viro   vfs: spread struc...
247
  static inline void mnt_dec_writers(struct mount *mnt)
3d733633a   Dave Hansen   [PATCH] r/o bind ...
248
  {
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
249
  #ifdef CONFIG_SMP
68e8a9fea   Al Viro   vfs: all counters...
250
  	this_cpu_dec(mnt->mnt_pcp->mnt_writers);
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
251
  #else
68e8a9fea   Al Viro   vfs: all counters...
252
  	mnt->mnt_writers--;
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
253
  #endif
3d733633a   Dave Hansen   [PATCH] r/o bind ...
254
  }
3d733633a   Dave Hansen   [PATCH] r/o bind ...
255

83adc7532   Al Viro   vfs: spread struc...
256
  static unsigned int mnt_get_writers(struct mount *mnt)
3d733633a   Dave Hansen   [PATCH] r/o bind ...
257
  {
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
258
259
  #ifdef CONFIG_SMP
  	unsigned int count = 0;
3d733633a   Dave Hansen   [PATCH] r/o bind ...
260
  	int cpu;
3d733633a   Dave Hansen   [PATCH] r/o bind ...
261
262
  
  	for_each_possible_cpu(cpu) {
68e8a9fea   Al Viro   vfs: all counters...
263
  		count += per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_writers;
3d733633a   Dave Hansen   [PATCH] r/o bind ...
264
  	}
3d733633a   Dave Hansen   [PATCH] r/o bind ...
265

d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
266
267
268
269
  	return count;
  #else
  	return mnt->mnt_writers;
  #endif
3d733633a   Dave Hansen   [PATCH] r/o bind ...
270
  }
4ed5e82fe   Miklos Szeredi   vfs: protect remo...
271
272
273
274
275
276
277
278
  static int mnt_is_readonly(struct vfsmount *mnt)
  {
  	if (mnt->mnt_sb->s_readonly_remount)
  		return 1;
  	/* Order wrt setting s_flags/s_readonly_remount in do_remount() */
  	smp_rmb();
  	return __mnt_is_readonly(mnt);
  }
3d733633a   Dave Hansen   [PATCH] r/o bind ...
279
  /*
eb04c2828   Jan Kara   fs: Add freezing ...
280
281
282
283
   * Most r/o & frozen checks on a fs are for operations that take discrete
   * amounts of time, like a write() or unlink().  We must keep track of when
   * those operations start (for permission checks) and when they end, so that we
   * can determine when writes are able to occur to a filesystem.
3d733633a   Dave Hansen   [PATCH] r/o bind ...
284
   */
8366025eb   Dave Hansen   [PATCH] r/o bind ...
285
  /**
eb04c2828   Jan Kara   fs: Add freezing ...
286
   * __mnt_want_write - get write access to a mount without freeze protection
83adc7532   Al Viro   vfs: spread struc...
287
   * @m: the mount on which to take a write
8366025eb   Dave Hansen   [PATCH] r/o bind ...
288
   *
eb04c2828   Jan Kara   fs: Add freezing ...
289
290
291
292
293
   * This tells the low-level filesystem that a write is about to be performed to
   * it, and makes sure that writes are allowed (mnt it read-write) before
   * returning success. This operation does not protect against filesystem being
   * frozen. When the write operation is finished, __mnt_drop_write() must be
   * called. This is effectively a refcount.
8366025eb   Dave Hansen   [PATCH] r/o bind ...
294
   */
eb04c2828   Jan Kara   fs: Add freezing ...
295
  int __mnt_want_write(struct vfsmount *m)
8366025eb   Dave Hansen   [PATCH] r/o bind ...
296
  {
83adc7532   Al Viro   vfs: spread struc...
297
  	struct mount *mnt = real_mount(m);
3d733633a   Dave Hansen   [PATCH] r/o bind ...
298
  	int ret = 0;
3d733633a   Dave Hansen   [PATCH] r/o bind ...
299

d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
300
  	preempt_disable();
c6653a838   Nick Piggin   fs: rename vfsmou...
301
  	mnt_inc_writers(mnt);
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
302
  	/*
c6653a838   Nick Piggin   fs: rename vfsmou...
303
  	 * The store to mnt_inc_writers must be visible before we pass
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
304
305
306
307
  	 * MNT_WRITE_HOLD loop below, so that the slowpath can see our
  	 * incremented count after it has set MNT_WRITE_HOLD.
  	 */
  	smp_mb();
6aa7de059   Mark Rutland   locking/atomics: ...
308
  	while (READ_ONCE(mnt->mnt.mnt_flags) & MNT_WRITE_HOLD)
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
309
310
311
312
313
314
315
  		cpu_relax();
  	/*
  	 * After the slowpath clears MNT_WRITE_HOLD, mnt_is_readonly will
  	 * be set to match its requirements. So we must not load that until
  	 * MNT_WRITE_HOLD is cleared.
  	 */
  	smp_rmb();
4ed5e82fe   Miklos Szeredi   vfs: protect remo...
316
  	if (mnt_is_readonly(m)) {
c6653a838   Nick Piggin   fs: rename vfsmou...
317
  		mnt_dec_writers(mnt);
3d733633a   Dave Hansen   [PATCH] r/o bind ...
318
  		ret = -EROFS;
3d733633a   Dave Hansen   [PATCH] r/o bind ...
319
  	}
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
320
  	preempt_enable();
eb04c2828   Jan Kara   fs: Add freezing ...
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
  
  	return ret;
  }
  
  /**
   * mnt_want_write - get write access to a mount
   * @m: the mount on which to take a write
   *
   * This tells the low-level filesystem that a write is about to be performed to
   * it, and makes sure that writes are allowed (mount is read-write, filesystem
   * is not frozen) before returning success.  When the write operation is
   * finished, mnt_drop_write() must be called.  This is effectively a refcount.
   */
  int mnt_want_write(struct vfsmount *m)
  {
  	int ret;
  
  	sb_start_write(m->mnt_sb);
  	ret = __mnt_want_write(m);
  	if (ret)
  		sb_end_write(m->mnt_sb);
3d733633a   Dave Hansen   [PATCH] r/o bind ...
342
  	return ret;
8366025eb   Dave Hansen   [PATCH] r/o bind ...
343
344
345
346
  }
  EXPORT_SYMBOL_GPL(mnt_want_write);
  
  /**
96029c4e0   npiggin@suse.de   fs: introduce mnt...
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
   * mnt_clone_write - get write access to a mount
   * @mnt: the mount on which to take a write
   *
   * This is effectively like mnt_want_write, except
   * it must only be used to take an extra write reference
   * on a mountpoint that we already know has a write reference
   * on it. This allows some optimisation.
   *
   * After finished, mnt_drop_write must be called as usual to
   * drop the reference.
   */
  int mnt_clone_write(struct vfsmount *mnt)
  {
  	/* superblock may be r/o */
  	if (__mnt_is_readonly(mnt))
  		return -EROFS;
  	preempt_disable();
83adc7532   Al Viro   vfs: spread struc...
364
  	mnt_inc_writers(real_mount(mnt));
96029c4e0   npiggin@suse.de   fs: introduce mnt...
365
366
367
368
369
370
  	preempt_enable();
  	return 0;
  }
  EXPORT_SYMBOL_GPL(mnt_clone_write);
  
  /**
eb04c2828   Jan Kara   fs: Add freezing ...
371
   * __mnt_want_write_file - get write access to a file's mount
96029c4e0   npiggin@suse.de   fs: introduce mnt...
372
373
   * @file: the file who's mount on which to take a write
   *
eb04c2828   Jan Kara   fs: Add freezing ...
374
   * This is like __mnt_want_write, but it takes a file and can
96029c4e0   npiggin@suse.de   fs: introduce mnt...
375
376
   * do some optimisations if the file is open for write already
   */
eb04c2828   Jan Kara   fs: Add freezing ...
377
  int __mnt_want_write_file(struct file *file)
96029c4e0   npiggin@suse.de   fs: introduce mnt...
378
  {
83f936c75   Al Viro   mark struct file ...
379
  	if (!(file->f_mode & FMODE_WRITER))
eb04c2828   Jan Kara   fs: Add freezing ...
380
  		return __mnt_want_write(file->f_path.mnt);
96029c4e0   npiggin@suse.de   fs: introduce mnt...
381
382
383
  	else
  		return mnt_clone_write(file->f_path.mnt);
  }
eb04c2828   Jan Kara   fs: Add freezing ...
384
385
  
  /**
7c6893e3c   Miklos Szeredi   ovl: don't allow ...
386
387
388
389
390
   * mnt_want_write_file - get write access to a file's mount
   * @file: the file who's mount on which to take a write
   *
   * This is like mnt_want_write, but it takes a file and can
   * do some optimisations if the file is open for write already
7c6893e3c   Miklos Szeredi   ovl: don't allow ...
391
392
393
394
   */
  int mnt_want_write_file(struct file *file)
  {
  	int ret;
a6795a585   Miklos Szeredi   vfs: fix freeze p...
395
  	sb_start_write(file_inode(file)->i_sb);
eb04c2828   Jan Kara   fs: Add freezing ...
396
397
  	ret = __mnt_want_write_file(file);
  	if (ret)
a6795a585   Miklos Szeredi   vfs: fix freeze p...
398
  		sb_end_write(file_inode(file)->i_sb);
7c6893e3c   Miklos Szeredi   ovl: don't allow ...
399
400
  	return ret;
  }
96029c4e0   npiggin@suse.de   fs: introduce mnt...
401
402
403
  EXPORT_SYMBOL_GPL(mnt_want_write_file);
  
  /**
eb04c2828   Jan Kara   fs: Add freezing ...
404
   * __mnt_drop_write - give up write access to a mount
8366025eb   Dave Hansen   [PATCH] r/o bind ...
405
406
407
408
   * @mnt: the mount on which to give up write access
   *
   * Tells the low-level filesystem that we are done
   * performing writes to it.  Must be matched with
eb04c2828   Jan Kara   fs: Add freezing ...
409
   * __mnt_want_write() call above.
8366025eb   Dave Hansen   [PATCH] r/o bind ...
410
   */
eb04c2828   Jan Kara   fs: Add freezing ...
411
  void __mnt_drop_write(struct vfsmount *mnt)
8366025eb   Dave Hansen   [PATCH] r/o bind ...
412
  {
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
413
  	preempt_disable();
83adc7532   Al Viro   vfs: spread struc...
414
  	mnt_dec_writers(real_mount(mnt));
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
415
  	preempt_enable();
8366025eb   Dave Hansen   [PATCH] r/o bind ...
416
  }
eb04c2828   Jan Kara   fs: Add freezing ...
417
418
419
420
421
422
423
424
425
426
427
428
429
430
  
  /**
   * mnt_drop_write - give up write access to a mount
   * @mnt: the mount on which to give up write access
   *
   * Tells the low-level filesystem that we are done performing writes to it and
   * also allows filesystem to be frozen again.  Must be matched with
   * mnt_want_write() call above.
   */
  void mnt_drop_write(struct vfsmount *mnt)
  {
  	__mnt_drop_write(mnt);
  	sb_end_write(mnt->mnt_sb);
  }
8366025eb   Dave Hansen   [PATCH] r/o bind ...
431
  EXPORT_SYMBOL_GPL(mnt_drop_write);
eb04c2828   Jan Kara   fs: Add freezing ...
432
433
434
435
  void __mnt_drop_write_file(struct file *file)
  {
  	__mnt_drop_write(file->f_path.mnt);
  }
7c6893e3c   Miklos Szeredi   ovl: don't allow ...
436
437
  void mnt_drop_write_file(struct file *file)
  {
a6795a585   Miklos Szeredi   vfs: fix freeze p...
438
  	__mnt_drop_write_file(file);
7c6893e3c   Miklos Szeredi   ovl: don't allow ...
439
440
  	sb_end_write(file_inode(file)->i_sb);
  }
2a79f17e4   Al Viro   vfs: mnt_drop_wri...
441
  EXPORT_SYMBOL(mnt_drop_write_file);
83adc7532   Al Viro   vfs: spread struc...
442
  static int mnt_make_readonly(struct mount *mnt)
8366025eb   Dave Hansen   [PATCH] r/o bind ...
443
  {
3d733633a   Dave Hansen   [PATCH] r/o bind ...
444
  	int ret = 0;
719ea2fbb   Al Viro   new helpers: lock...
445
  	lock_mount_hash();
83adc7532   Al Viro   vfs: spread struc...
446
  	mnt->mnt.mnt_flags |= MNT_WRITE_HOLD;
3d733633a   Dave Hansen   [PATCH] r/o bind ...
447
  	/*
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
448
449
  	 * After storing MNT_WRITE_HOLD, we'll read the counters. This store
  	 * should be visible before we do.
3d733633a   Dave Hansen   [PATCH] r/o bind ...
450
  	 */
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
451
  	smp_mb();
3d733633a   Dave Hansen   [PATCH] r/o bind ...
452
  	/*
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
453
454
455
456
457
458
459
460
461
462
463
464
465
466
  	 * With writers on hold, if this value is zero, then there are
  	 * definitely no active writers (although held writers may subsequently
  	 * increment the count, they'll have to wait, and decrement it after
  	 * seeing MNT_READONLY).
  	 *
  	 * It is OK to have counter incremented on one CPU and decremented on
  	 * another: the sum will add up correctly. The danger would be when we
  	 * sum up each counter, if we read a counter before it is incremented,
  	 * but then read another CPU's count which it has been subsequently
  	 * decremented from -- we would see more decrements than we should.
  	 * MNT_WRITE_HOLD protects against this scenario, because
  	 * mnt_want_write first increments count, then smp_mb, then spins on
  	 * MNT_WRITE_HOLD, so it can't be decremented by another CPU while
  	 * we're counting up here.
3d733633a   Dave Hansen   [PATCH] r/o bind ...
467
  	 */
c6653a838   Nick Piggin   fs: rename vfsmou...
468
  	if (mnt_get_writers(mnt) > 0)
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
469
470
  		ret = -EBUSY;
  	else
83adc7532   Al Viro   vfs: spread struc...
471
  		mnt->mnt.mnt_flags |= MNT_READONLY;
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
472
473
474
475
476
  	/*
  	 * MNT_READONLY must become visible before ~MNT_WRITE_HOLD, so writers
  	 * that become unheld will see MNT_READONLY.
  	 */
  	smp_wmb();
83adc7532   Al Viro   vfs: spread struc...
477
  	mnt->mnt.mnt_flags &= ~MNT_WRITE_HOLD;
719ea2fbb   Al Viro   new helpers: lock...
478
  	unlock_mount_hash();
3d733633a   Dave Hansen   [PATCH] r/o bind ...
479
  	return ret;
8366025eb   Dave Hansen   [PATCH] r/o bind ...
480
  }
8366025eb   Dave Hansen   [PATCH] r/o bind ...
481

43f5e655e   David Howells   vfs: Separate cha...
482
  static int __mnt_unmake_readonly(struct mount *mnt)
2e4b7fcd9   Dave Hansen   [PATCH] r/o bind ...
483
  {
719ea2fbb   Al Viro   new helpers: lock...
484
  	lock_mount_hash();
83adc7532   Al Viro   vfs: spread struc...
485
  	mnt->mnt.mnt_flags &= ~MNT_READONLY;
719ea2fbb   Al Viro   new helpers: lock...
486
  	unlock_mount_hash();
43f5e655e   David Howells   vfs: Separate cha...
487
  	return 0;
2e4b7fcd9   Dave Hansen   [PATCH] r/o bind ...
488
  }
4ed5e82fe   Miklos Szeredi   vfs: protect remo...
489
490
491
492
  int sb_prepare_remount_readonly(struct super_block *sb)
  {
  	struct mount *mnt;
  	int err = 0;
8e8b87964   Miklos Szeredi   vfs: prevent remo...
493
494
495
  	/* Racy optimization.  Recheck the counter under MNT_WRITE_HOLD */
  	if (atomic_long_read(&sb->s_remove_count))
  		return -EBUSY;
719ea2fbb   Al Viro   new helpers: lock...
496
  	lock_mount_hash();
4ed5e82fe   Miklos Szeredi   vfs: protect remo...
497
498
499
500
501
502
503
504
505
506
  	list_for_each_entry(mnt, &sb->s_mounts, mnt_instance) {
  		if (!(mnt->mnt.mnt_flags & MNT_READONLY)) {
  			mnt->mnt.mnt_flags |= MNT_WRITE_HOLD;
  			smp_mb();
  			if (mnt_get_writers(mnt) > 0) {
  				err = -EBUSY;
  				break;
  			}
  		}
  	}
8e8b87964   Miklos Szeredi   vfs: prevent remo...
507
508
  	if (!err && atomic_long_read(&sb->s_remove_count))
  		err = -EBUSY;
4ed5e82fe   Miklos Szeredi   vfs: protect remo...
509
510
511
512
513
514
515
516
  	if (!err) {
  		sb->s_readonly_remount = 1;
  		smp_wmb();
  	}
  	list_for_each_entry(mnt, &sb->s_mounts, mnt_instance) {
  		if (mnt->mnt.mnt_flags & MNT_WRITE_HOLD)
  			mnt->mnt.mnt_flags &= ~MNT_WRITE_HOLD;
  	}
719ea2fbb   Al Viro   new helpers: lock...
517
  	unlock_mount_hash();
4ed5e82fe   Miklos Szeredi   vfs: protect remo...
518
519
520
  
  	return err;
  }
b105e270b   Al Viro   vfs: spread struc...
521
  static void free_vfsmnt(struct mount *mnt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
522
  {
fcc139ae2   Andrzej Hajda   fs/namespace: con...
523
  	kfree_const(mnt->mnt_devname);
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
524
  #ifdef CONFIG_SMP
68e8a9fea   Al Viro   vfs: all counters...
525
  	free_percpu(mnt->mnt_pcp);
d3ef3d735   npiggin@suse.de   fs: mnt_want_writ...
526
  #endif
b105e270b   Al Viro   vfs: spread struc...
527
  	kmem_cache_free(mnt_cache, mnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528
  }
8ffcb32e0   David Howells   VFS: Make delayed...
529
530
531
532
  static void delayed_free_vfsmnt(struct rcu_head *head)
  {
  	free_vfsmnt(container_of(head, struct mount, mnt_rcu));
  }
48a066e72   Al Viro   RCU'd vfsmounts
533
  /* call under rcu_read_lock */
294d71ff2   Al Viro   new helper: __leg...
534
  int __legitimize_mnt(struct vfsmount *bastard, unsigned seq)
48a066e72   Al Viro   RCU'd vfsmounts
535
536
537
  {
  	struct mount *mnt;
  	if (read_seqretry(&mount_lock, seq))
294d71ff2   Al Viro   new helper: __leg...
538
  		return 1;
48a066e72   Al Viro   RCU'd vfsmounts
539
  	if (bastard == NULL)
294d71ff2   Al Viro   new helper: __leg...
540
  		return 0;
48a066e72   Al Viro   RCU'd vfsmounts
541
542
  	mnt = real_mount(bastard);
  	mnt_add_count(mnt, 1);
119e1ef80   Al Viro   fix __legitimize_...
543
  	smp_mb();			// see mntput_no_expire()
48a066e72   Al Viro   RCU'd vfsmounts
544
  	if (likely(!read_seqretry(&mount_lock, seq)))
294d71ff2   Al Viro   new helper: __leg...
545
  		return 0;
48a066e72   Al Viro   RCU'd vfsmounts
546
547
  	if (bastard->mnt_flags & MNT_SYNC_UMOUNT) {
  		mnt_add_count(mnt, -1);
294d71ff2   Al Viro   new helper: __leg...
548
549
  		return 1;
  	}
119e1ef80   Al Viro   fix __legitimize_...
550
551
552
553
554
555
556
557
  	lock_mount_hash();
  	if (unlikely(bastard->mnt_flags & MNT_DOOMED)) {
  		mnt_add_count(mnt, -1);
  		unlock_mount_hash();
  		return 1;
  	}
  	unlock_mount_hash();
  	/* caller will mntput() */
294d71ff2   Al Viro   new helper: __leg...
558
559
560
561
562
563
564
565
566
567
568
569
570
  	return -1;
  }
  
  /* call under rcu_read_lock */
  bool legitimize_mnt(struct vfsmount *bastard, unsigned seq)
  {
  	int res = __legitimize_mnt(bastard, seq);
  	if (likely(!res))
  		return true;
  	if (unlikely(res < 0)) {
  		rcu_read_unlock();
  		mntput(bastard);
  		rcu_read_lock();
48a066e72   Al Viro   RCU'd vfsmounts
571
  	}
48a066e72   Al Viro   RCU'd vfsmounts
572
573
  	return false;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
574
  /*
474279dc0   Al Viro   split __lookup_mn...
575
   * find the first mount at @dentry on vfsmount @mnt.
48a066e72   Al Viro   RCU'd vfsmounts
576
   * call under rcu_read_lock()
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
577
   */
474279dc0   Al Viro   split __lookup_mn...
578
  struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
579
  {
38129a13e   Al Viro   switch mnt_hash t...
580
  	struct hlist_head *head = m_hash(mnt, dentry);
474279dc0   Al Viro   split __lookup_mn...
581
  	struct mount *p;
38129a13e   Al Viro   switch mnt_hash t...
582
  	hlist_for_each_entry_rcu(p, head, mnt_hash)
474279dc0   Al Viro   split __lookup_mn...
583
584
585
586
587
588
  		if (&p->mnt_parent->mnt == mnt && p->mnt_mountpoint == dentry)
  			return p;
  	return NULL;
  }
  
  /*
f015f1267   David Howells   VFS: Comment moun...
589
590
591
592
593
594
595
596
597
598
599
600
601
602
   * lookup_mnt - Return the first child mount mounted at path
   *
   * "First" means first mounted chronologically.  If you create the
   * following mounts:
   *
   * mount /dev/sda1 /mnt
   * mount /dev/sda2 /mnt
   * mount /dev/sda3 /mnt
   *
   * Then lookup_mnt() on the base /mnt dentry in the root mount will
   * return successively the root dentry and vfsmount of /dev/sda1, then
   * /dev/sda2, then /dev/sda3, then NULL.
   *
   * lookup_mnt takes a reference to the found vfsmount.
a05964f39   Ram Pai   [PATCH] shared mo...
603
   */
ca71cf71e   Al Viro   namespace.c: cons...
604
  struct vfsmount *lookup_mnt(const struct path *path)
a05964f39   Ram Pai   [PATCH] shared mo...
605
  {
c71053659   Al Viro   vfs: spread struc...
606
  	struct mount *child_mnt;
48a066e72   Al Viro   RCU'd vfsmounts
607
608
  	struct vfsmount *m;
  	unsigned seq;
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
609

48a066e72   Al Viro   RCU'd vfsmounts
610
611
612
613
614
615
616
617
  	rcu_read_lock();
  	do {
  		seq = read_seqbegin(&mount_lock);
  		child_mnt = __lookup_mnt(path->mnt, path->dentry);
  		m = child_mnt ? &child_mnt->mnt : NULL;
  	} while (!legitimize_mnt(m, seq));
  	rcu_read_unlock();
  	return m;
a05964f39   Ram Pai   [PATCH] shared mo...
618
  }
9f6c61f96   Miklos Szeredi   proc/mounts: add ...
619
620
621
622
623
624
625
626
627
628
629
630
631
632
  static inline void lock_ns_list(struct mnt_namespace *ns)
  {
  	spin_lock(&ns->ns_lock);
  }
  
  static inline void unlock_ns_list(struct mnt_namespace *ns)
  {
  	spin_unlock(&ns->ns_lock);
  }
  
  static inline bool mnt_is_cursor(struct mount *mnt)
  {
  	return mnt->mnt.mnt_flags & MNT_CURSOR;
  }
7af1364ff   Eric W. Biederman   vfs: Don't allow ...
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
  /*
   * __is_local_mountpoint - Test to see if dentry is a mountpoint in the
   *                         current mount namespace.
   *
   * The common case is dentries are not mountpoints at all and that
   * test is handled inline.  For the slow case when we are actually
   * dealing with a mountpoint of some kind, walk through all of the
   * mounts in the current mount namespace and test to see if the dentry
   * is a mountpoint.
   *
   * The mount_hashtable is not usable in the context because we
   * need to identify all mounts that may be in the current mount
   * namespace not just a mount that happens to have some specified
   * parent mount.
   */
  bool __is_local_mountpoint(struct dentry *dentry)
  {
  	struct mnt_namespace *ns = current->nsproxy->mnt_ns;
  	struct mount *mnt;
  	bool is_covered = false;
7af1364ff   Eric W. Biederman   vfs: Don't allow ...
653
  	down_read(&namespace_sem);
9f6c61f96   Miklos Szeredi   proc/mounts: add ...
654
  	lock_ns_list(ns);
7af1364ff   Eric W. Biederman   vfs: Don't allow ...
655
  	list_for_each_entry(mnt, &ns->list, mnt_list) {
9f6c61f96   Miklos Szeredi   proc/mounts: add ...
656
657
  		if (mnt_is_cursor(mnt))
  			continue;
7af1364ff   Eric W. Biederman   vfs: Don't allow ...
658
659
660
661
  		is_covered = (mnt->mnt_mountpoint == dentry);
  		if (is_covered)
  			break;
  	}
9f6c61f96   Miklos Szeredi   proc/mounts: add ...
662
  	unlock_ns_list(ns);
7af1364ff   Eric W. Biederman   vfs: Don't allow ...
663
  	up_read(&namespace_sem);
5ad05cc8e   Nikolay Borisov   vfs: Remove dupli...
664

7af1364ff   Eric W. Biederman   vfs: Don't allow ...
665
666
  	return is_covered;
  }
e2dfa9354   Eric W. Biederman   vfs: factor out l...
667
  static struct mountpoint *lookup_mountpoint(struct dentry *dentry)
84d17192d   Al Viro   get rid of full-h...
668
  {
0818bf27c   Al Viro   resizable namespa...
669
  	struct hlist_head *chain = mp_hash(dentry);
84d17192d   Al Viro   get rid of full-h...
670
  	struct mountpoint *mp;
0818bf27c   Al Viro   resizable namespa...
671
  	hlist_for_each_entry(mp, chain, m_hash) {
84d17192d   Al Viro   get rid of full-h...
672
  		if (mp->m_dentry == dentry) {
84d17192d   Al Viro   get rid of full-h...
673
674
675
676
  			mp->m_count++;
  			return mp;
  		}
  	}
e2dfa9354   Eric W. Biederman   vfs: factor out l...
677
678
  	return NULL;
  }
3895dbf89   Eric W. Biederman   mnt: Protect the ...
679
  static struct mountpoint *get_mountpoint(struct dentry *dentry)
e2dfa9354   Eric W. Biederman   vfs: factor out l...
680
  {
3895dbf89   Eric W. Biederman   mnt: Protect the ...
681
  	struct mountpoint *mp, *new = NULL;
e2dfa9354   Eric W. Biederman   vfs: factor out l...
682
  	int ret;
84d17192d   Al Viro   get rid of full-h...
683

3895dbf89   Eric W. Biederman   mnt: Protect the ...
684
  	if (d_mountpoint(dentry)) {
1e9c75fb9   Benjamin Coddington   mnt: fix __detach...
685
686
687
  		/* might be worth a WARN_ON() */
  		if (d_unlinked(dentry))
  			return ERR_PTR(-ENOENT);
3895dbf89   Eric W. Biederman   mnt: Protect the ...
688
689
690
691
692
693
694
695
696
697
698
  mountpoint:
  		read_seqlock_excl(&mount_lock);
  		mp = lookup_mountpoint(dentry);
  		read_sequnlock_excl(&mount_lock);
  		if (mp)
  			goto done;
  	}
  
  	if (!new)
  		new = kmalloc(sizeof(struct mountpoint), GFP_KERNEL);
  	if (!new)
84d17192d   Al Viro   get rid of full-h...
699
  		return ERR_PTR(-ENOMEM);
3895dbf89   Eric W. Biederman   mnt: Protect the ...
700
701
  
  	/* Exactly one processes may set d_mounted */
eed810076   Miklos Szeredi   vfs: check unlink...
702
  	ret = d_set_mounted(dentry);
eed810076   Miklos Szeredi   vfs: check unlink...
703

3895dbf89   Eric W. Biederman   mnt: Protect the ...
704
705
706
707
708
709
710
711
712
713
714
  	/* Someone else set d_mounted? */
  	if (ret == -EBUSY)
  		goto mountpoint;
  
  	/* The dentry is not available as a mountpoint? */
  	mp = ERR_PTR(ret);
  	if (ret)
  		goto done;
  
  	/* Add the new mountpoint to the hash table */
  	read_seqlock_excl(&mount_lock);
4edbe133f   Al Viro   make struct mount...
715
  	new->m_dentry = dget(dentry);
3895dbf89   Eric W. Biederman   mnt: Protect the ...
716
717
718
719
720
721
722
723
724
  	new->m_count = 1;
  	hlist_add_head(&new->m_hash, mp_hash(dentry));
  	INIT_HLIST_HEAD(&new->m_list);
  	read_sequnlock_excl(&mount_lock);
  
  	mp = new;
  	new = NULL;
  done:
  	kfree(new);
84d17192d   Al Viro   get rid of full-h...
725
726
  	return mp;
  }
4edbe133f   Al Viro   make struct mount...
727
728
729
730
731
  /*
   * vfsmount lock must be held.  Additionally, the caller is responsible
   * for serializing calls for given disposal list.
   */
  static void __put_mountpoint(struct mountpoint *mp, struct list_head *list)
84d17192d   Al Viro   get rid of full-h...
732
733
734
  {
  	if (!--mp->m_count) {
  		struct dentry *dentry = mp->m_dentry;
0a5eb7c81   Eric W. Biederman   vfs: Keep a list ...
735
  		BUG_ON(!hlist_empty(&mp->m_list));
84d17192d   Al Viro   get rid of full-h...
736
737
738
  		spin_lock(&dentry->d_lock);
  		dentry->d_flags &= ~DCACHE_MOUNTED;
  		spin_unlock(&dentry->d_lock);
4edbe133f   Al Viro   make struct mount...
739
  		dput_to_list(dentry, list);
0818bf27c   Al Viro   resizable namespa...
740
  		hlist_del(&mp->m_hash);
84d17192d   Al Viro   get rid of full-h...
741
742
743
  		kfree(mp);
  	}
  }
4edbe133f   Al Viro   make struct mount...
744
745
746
747
748
  /* called with namespace_lock and vfsmount lock */
  static void put_mountpoint(struct mountpoint *mp)
  {
  	__put_mountpoint(mp, &ex_mountpoints);
  }
143c8c91c   Al Viro   vfs: mnt_ns moved...
749
  static inline int check_mnt(struct mount *mnt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
750
  {
6b3286ed1   Kirill Korotaev   [PATCH] rename st...
751
  	return mnt->mnt_ns == current->nsproxy->mnt_ns;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
752
  }
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
753
754
755
  /*
   * vfsmount lock must be held for write
   */
6b3286ed1   Kirill Korotaev   [PATCH] rename st...
756
  static void touch_mnt_namespace(struct mnt_namespace *ns)
5addc5dd8   Al Viro   [PATCH] make /pro...
757
758
759
760
761
762
  {
  	if (ns) {
  		ns->event = ++event;
  		wake_up_interruptible(&ns->poll);
  	}
  }
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
763
764
765
  /*
   * vfsmount lock must be held for write
   */
6b3286ed1   Kirill Korotaev   [PATCH] rename st...
766
  static void __touch_mnt_namespace(struct mnt_namespace *ns)
5addc5dd8   Al Viro   [PATCH] make /pro...
767
768
769
770
771
772
  {
  	if (ns && ns->event != event) {
  		ns->event = event;
  		wake_up_interruptible(&ns->poll);
  	}
  }
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
773
774
775
  /*
   * vfsmount lock must be held for write
   */
e4e59906c   Al Viro   fs/namespace.c: s...
776
  static struct mountpoint *unhash_mnt(struct mount *mnt)
419148da6   Al Viro   vfs: spread struc...
777
  {
e4e59906c   Al Viro   fs/namespace.c: s...
778
  	struct mountpoint *mp;
0714a5338   Al Viro   vfs: now it can b...
779
  	mnt->mnt_parent = mnt;
a73324da7   Al Viro   vfs: move mnt_mou...
780
  	mnt->mnt_mountpoint = mnt->mnt.mnt_root;
6b41d536f   Al Viro   vfs: take mnt_chi...
781
  	list_del_init(&mnt->mnt_child);
38129a13e   Al Viro   switch mnt_hash t...
782
  	hlist_del_init_rcu(&mnt->mnt_hash);
0a5eb7c81   Eric W. Biederman   vfs: Keep a list ...
783
  	hlist_del_init(&mnt->mnt_mp_list);
e4e59906c   Al Viro   fs/namespace.c: s...
784
  	mp = mnt->mnt_mp;
84d17192d   Al Viro   get rid of full-h...
785
  	mnt->mnt_mp = NULL;
e4e59906c   Al Viro   fs/namespace.c: s...
786
  	return mp;
7bdb11de8   Eric W. Biederman   mnt: Factor out u...
787
788
789
790
791
  }
  
  /*
   * vfsmount lock must be held for write
   */
6a46c5735   Eric W. Biederman   mnt: Factor umoun...
792
793
  static void umount_mnt(struct mount *mnt)
  {
e4e59906c   Al Viro   fs/namespace.c: s...
794
  	put_mountpoint(unhash_mnt(mnt));
6a46c5735   Eric W. Biederman   mnt: Factor umoun...
795
796
797
798
799
  }
  
  /*
   * vfsmount lock must be held for write
   */
84d17192d   Al Viro   get rid of full-h...
800
801
  void mnt_set_mountpoint(struct mount *mnt,
  			struct mountpoint *mp,
44d964d60   Al Viro   vfs: spread struc...
802
  			struct mount *child_mnt)
b90fa9ae8   Ram Pai   [PATCH] shared mo...
803
  {
84d17192d   Al Viro   get rid of full-h...
804
  	mp->m_count++;
3a2393d71   Al Viro   vfs: opencode mnt...
805
  	mnt_add_count(mnt, 1);	/* essentially, that's mntget */
4edbe133f   Al Viro   make struct mount...
806
  	child_mnt->mnt_mountpoint = mp->m_dentry;
3a2393d71   Al Viro   vfs: opencode mnt...
807
  	child_mnt->mnt_parent = mnt;
84d17192d   Al Viro   get rid of full-h...
808
  	child_mnt->mnt_mp = mp;
0a5eb7c81   Eric W. Biederman   vfs: Keep a list ...
809
  	hlist_add_head(&child_mnt->mnt_mp_list, &mp->m_list);
b90fa9ae8   Ram Pai   [PATCH] shared mo...
810
  }
1064f874a   Eric W. Biederman   mnt: Tuck mounts ...
811
812
813
814
815
816
  static void __attach_mnt(struct mount *mnt, struct mount *parent)
  {
  	hlist_add_head_rcu(&mnt->mnt_hash,
  			   m_hash(&parent->mnt, mnt->mnt_mountpoint));
  	list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
  }
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
817
818
819
  /*
   * vfsmount lock must be held for write
   */
84d17192d   Al Viro   get rid of full-h...
820
821
822
  static void attach_mnt(struct mount *mnt,
  			struct mount *parent,
  			struct mountpoint *mp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
823
  {
84d17192d   Al Viro   get rid of full-h...
824
  	mnt_set_mountpoint(parent, mp, mnt);
1064f874a   Eric W. Biederman   mnt: Tuck mounts ...
825
  	__attach_mnt(mnt, parent);
b90fa9ae8   Ram Pai   [PATCH] shared mo...
826
  }
1064f874a   Eric W. Biederman   mnt: Tuck mounts ...
827
  void mnt_change_mountpoint(struct mount *parent, struct mountpoint *mp, struct mount *mnt)
12a5b5294   Al Viro   fix copy_tree() r...
828
  {
1064f874a   Eric W. Biederman   mnt: Tuck mounts ...
829
  	struct mountpoint *old_mp = mnt->mnt_mp;
1064f874a   Eric W. Biederman   mnt: Tuck mounts ...
830
831
832
833
834
835
836
837
838
  	struct mount *old_parent = mnt->mnt_parent;
  
  	list_del_init(&mnt->mnt_child);
  	hlist_del_init(&mnt->mnt_mp_list);
  	hlist_del_init_rcu(&mnt->mnt_hash);
  
  	attach_mnt(mnt, parent, mp);
  
  	put_mountpoint(old_mp);
1064f874a   Eric W. Biederman   mnt: Tuck mounts ...
839
  	mnt_add_count(old_parent, -1);
12a5b5294   Al Viro   fix copy_tree() r...
840
  }
b90fa9ae8   Ram Pai   [PATCH] shared mo...
841
  /*
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
842
   * vfsmount lock must be held for write
b90fa9ae8   Ram Pai   [PATCH] shared mo...
843
   */
1064f874a   Eric W. Biederman   mnt: Tuck mounts ...
844
  static void commit_tree(struct mount *mnt)
b90fa9ae8   Ram Pai   [PATCH] shared mo...
845
  {
0714a5338   Al Viro   vfs: now it can b...
846
  	struct mount *parent = mnt->mnt_parent;
83adc7532   Al Viro   vfs: spread struc...
847
  	struct mount *m;
b90fa9ae8   Ram Pai   [PATCH] shared mo...
848
  	LIST_HEAD(head);
143c8c91c   Al Viro   vfs: mnt_ns moved...
849
  	struct mnt_namespace *n = parent->mnt_ns;
b90fa9ae8   Ram Pai   [PATCH] shared mo...
850

0714a5338   Al Viro   vfs: now it can b...
851
  	BUG_ON(parent == mnt);
b90fa9ae8   Ram Pai   [PATCH] shared mo...
852

1a4eeaf2a   Al Viro   vfs: move mnt_lis...
853
  	list_add_tail(&head, &mnt->mnt_list);
f7a99c5b7   Al Viro   get rid of ->mnt_...
854
  	list_for_each_entry(m, &head, mnt_list)
143c8c91c   Al Viro   vfs: mnt_ns moved...
855
  		m->mnt_ns = n;
f03c65993   Al Viro   sanitize vfsmount...
856

b90fa9ae8   Ram Pai   [PATCH] shared mo...
857
  	list_splice(&head, n->list.prev);
d29216842   Eric W. Biederman   mnt: Add a per mo...
858
859
  	n->mounts += n->pending_mounts;
  	n->pending_mounts = 0;
1064f874a   Eric W. Biederman   mnt: Tuck mounts ...
860
  	__attach_mnt(mnt, parent);
6b3286ed1   Kirill Korotaev   [PATCH] rename st...
861
  	touch_mnt_namespace(n);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
862
  }
909b0a88e   Al Viro   vfs: spread struc...
863
  static struct mount *next_mnt(struct mount *p, struct mount *root)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
864
  {
6b41d536f   Al Viro   vfs: take mnt_chi...
865
866
  	struct list_head *next = p->mnt_mounts.next;
  	if (next == &p->mnt_mounts) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
867
  		while (1) {
909b0a88e   Al Viro   vfs: spread struc...
868
  			if (p == root)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
869
  				return NULL;
6b41d536f   Al Viro   vfs: take mnt_chi...
870
871
  			next = p->mnt_child.next;
  			if (next != &p->mnt_parent->mnt_mounts)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
872
  				break;
0714a5338   Al Viro   vfs: now it can b...
873
  			p = p->mnt_parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
874
875
  		}
  	}
6b41d536f   Al Viro   vfs: take mnt_chi...
876
  	return list_entry(next, struct mount, mnt_child);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
877
  }
315fc83e5   Al Viro   vfs: spread struc...
878
  static struct mount *skip_mnt_tree(struct mount *p)
9676f0c63   Ram Pai   [PATCH] unbindabl...
879
  {
6b41d536f   Al Viro   vfs: take mnt_chi...
880
881
882
883
  	struct list_head *prev = p->mnt_mounts.prev;
  	while (prev != &p->mnt_mounts) {
  		p = list_entry(prev, struct mount, mnt_child);
  		prev = p->mnt_mounts.prev;
9676f0c63   Ram Pai   [PATCH] unbindabl...
884
885
886
  	}
  	return p;
  }
8f2918898   Al Viro   new helpers: vfs_...
887
888
889
890
891
892
893
894
895
896
  /**
   * vfs_create_mount - Create a mount for a configured superblock
   * @fc: The configuration context with the superblock attached
   *
   * Create a mount to an already configured superblock.  If necessary, the
   * caller should invoke vfs_get_tree() before calling this.
   *
   * Note that this does not attach the mount to anything.
   */
  struct vfsmount *vfs_create_mount(struct fs_context *fc)
9d412a43c   Al Viro   vfs: split off vf...
897
  {
b105e270b   Al Viro   vfs: spread struc...
898
  	struct mount *mnt;
9d412a43c   Al Viro   vfs: split off vf...
899

8f2918898   Al Viro   new helpers: vfs_...
900
901
  	if (!fc->root)
  		return ERR_PTR(-EINVAL);
9d412a43c   Al Viro   vfs: split off vf...
902

8f2918898   Al Viro   new helpers: vfs_...
903
  	mnt = alloc_vfsmnt(fc->source ?: "none");
9d412a43c   Al Viro   vfs: split off vf...
904
905
  	if (!mnt)
  		return ERR_PTR(-ENOMEM);
8f2918898   Al Viro   new helpers: vfs_...
906
  	if (fc->sb_flags & SB_KERNMOUNT)
b105e270b   Al Viro   vfs: spread struc...
907
  		mnt->mnt.mnt_flags = MNT_INTERNAL;
9d412a43c   Al Viro   vfs: split off vf...
908

8f2918898   Al Viro   new helpers: vfs_...
909
910
911
912
913
  	atomic_inc(&fc->root->d_sb->s_active);
  	mnt->mnt.mnt_sb		= fc->root->d_sb;
  	mnt->mnt.mnt_root	= dget(fc->root);
  	mnt->mnt_mountpoint	= mnt->mnt.mnt_root;
  	mnt->mnt_parent		= mnt;
9d412a43c   Al Viro   vfs: split off vf...
914

719ea2fbb   Al Viro   new helpers: lock...
915
  	lock_mount_hash();
8f2918898   Al Viro   new helpers: vfs_...
916
  	list_add_tail(&mnt->mnt_instance, &mnt->mnt.mnt_sb->s_mounts);
719ea2fbb   Al Viro   new helpers: lock...
917
  	unlock_mount_hash();
b105e270b   Al Viro   vfs: spread struc...
918
  	return &mnt->mnt;
9d412a43c   Al Viro   vfs: split off vf...
919
  }
8f2918898   Al Viro   new helpers: vfs_...
920
921
922
923
924
925
926
927
928
929
930
931
  EXPORT_SYMBOL(vfs_create_mount);
  
  struct vfsmount *fc_mount(struct fs_context *fc)
  {
  	int err = vfs_get_tree(fc);
  	if (!err) {
  		up_write(&fc->root->d_sb->s_umount);
  		return vfs_create_mount(fc);
  	}
  	return ERR_PTR(err);
  }
  EXPORT_SYMBOL(fc_mount);
9bc61ab18   David Howells   vfs: Introduce fs...
932
933
934
  struct vfsmount *vfs_kern_mount(struct file_system_type *type,
  				int flags, const char *name,
  				void *data)
9d412a43c   Al Viro   vfs: split off vf...
935
  {
9bc61ab18   David Howells   vfs: Introduce fs...
936
  	struct fs_context *fc;
8f2918898   Al Viro   new helpers: vfs_...
937
  	struct vfsmount *mnt;
9bc61ab18   David Howells   vfs: Introduce fs...
938
  	int ret = 0;
9d412a43c   Al Viro   vfs: split off vf...
939
940
  
  	if (!type)
3e1aeb00e   David Howells   vfs: Implement a ...
941
  		return ERR_PTR(-EINVAL);
9d412a43c   Al Viro   vfs: split off vf...
942

9bc61ab18   David Howells   vfs: Introduce fs...
943
944
945
  	fc = fs_context_for_mount(type, flags);
  	if (IS_ERR(fc))
  		return ERR_CAST(fc);
3e1aeb00e   David Howells   vfs: Implement a ...
946
947
948
  	if (name)
  		ret = vfs_parse_fs_string(fc, "source",
  					  name, strlen(name));
9bc61ab18   David Howells   vfs: Introduce fs...
949
950
951
  	if (!ret)
  		ret = parse_monolithic_mount_data(fc, data);
  	if (!ret)
8f2918898   Al Viro   new helpers: vfs_...
952
953
954
  		mnt = fc_mount(fc);
  	else
  		mnt = ERR_PTR(ret);
9d412a43c   Al Viro   vfs: split off vf...
955

9bc61ab18   David Howells   vfs: Introduce fs...
956
  	put_fs_context(fc);
8f2918898   Al Viro   new helpers: vfs_...
957
  	return mnt;
9d412a43c   Al Viro   vfs: split off vf...
958
959
  }
  EXPORT_SYMBOL_GPL(vfs_kern_mount);
93faccbbf   Eric W. Biederman   fs: Better permis...
960
961
962
963
964
965
966
967
968
969
  struct vfsmount *
  vfs_submount(const struct dentry *mountpoint, struct file_system_type *type,
  	     const char *name, void *data)
  {
  	/* Until it is worked out how to pass the user namespace
  	 * through from the parent mount to the submount don't support
  	 * unprivileged mounts with submounts.
  	 */
  	if (mountpoint->d_sb->s_user_ns != &init_user_ns)
  		return ERR_PTR(-EPERM);
e462ec50c   David Howells   VFS: Differentiat...
970
  	return vfs_kern_mount(type, SB_SUBMOUNT, name, data);
93faccbbf   Eric W. Biederman   fs: Better permis...
971
972
  }
  EXPORT_SYMBOL_GPL(vfs_submount);
87129cc0e   Al Viro   vfs: spread struc...
973
  static struct mount *clone_mnt(struct mount *old, struct dentry *root,
36341f645   Ram Pai   [PATCH] mount exp...
974
  					int flag)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
975
  {
87129cc0e   Al Viro   vfs: spread struc...
976
  	struct super_block *sb = old->mnt.mnt_sb;
be34d1a3b   David Howells   VFS: Make clone_m...
977
978
  	struct mount *mnt;
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
979

be34d1a3b   David Howells   VFS: Make clone_m...
980
981
982
  	mnt = alloc_vfsmnt(old->mnt_devname);
  	if (!mnt)
  		return ERR_PTR(-ENOMEM);
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
983

7a472ef4b   Eric W. Biederman   vfs: Only support...
984
  	if (flag & (CL_SLAVE | CL_PRIVATE | CL_SHARED_TO_SLAVE))
be34d1a3b   David Howells   VFS: Make clone_m...
985
986
987
  		mnt->mnt_group_id = 0; /* not a peer of original */
  	else
  		mnt->mnt_group_id = old->mnt_group_id;
b90fa9ae8   Ram Pai   [PATCH] shared mo...
988

be34d1a3b   David Howells   VFS: Make clone_m...
989
990
991
992
  	if ((flag & CL_MAKE_SHARED) && !mnt->mnt_group_id) {
  		err = mnt_alloc_group_id(mnt);
  		if (err)
  			goto out_free;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
993
  	}
be34d1a3b   David Howells   VFS: Make clone_m...
994

16a34adb9   Al Viro   Don't leak MNT_IN...
995
996
  	mnt->mnt.mnt_flags = old->mnt.mnt_flags;
  	mnt->mnt.mnt_flags &= ~(MNT_WRITE_HOLD|MNT_MARKED|MNT_INTERNAL);
5ff9d8a65   Eric W. Biederman   vfs: Lock in plac...
997

be34d1a3b   David Howells   VFS: Make clone_m...
998
999
1000
1001
1002
  	atomic_inc(&sb->s_active);
  	mnt->mnt.mnt_sb = sb;
  	mnt->mnt.mnt_root = dget(root);
  	mnt->mnt_mountpoint = mnt->mnt.mnt_root;
  	mnt->mnt_parent = mnt;
719ea2fbb   Al Viro   new helpers: lock...
1003
  	lock_mount_hash();
be34d1a3b   David Howells   VFS: Make clone_m...
1004
  	list_add_tail(&mnt->mnt_instance, &sb->s_mounts);
719ea2fbb   Al Viro   new helpers: lock...
1005
  	unlock_mount_hash();
be34d1a3b   David Howells   VFS: Make clone_m...
1006

7a472ef4b   Eric W. Biederman   vfs: Only support...
1007
1008
  	if ((flag & CL_SLAVE) ||
  	    ((flag & CL_SHARED_TO_SLAVE) && IS_MNT_SHARED(old))) {
be34d1a3b   David Howells   VFS: Make clone_m...
1009
1010
1011
1012
1013
1014
1015
1016
1017
  		list_add(&mnt->mnt_slave, &old->mnt_slave_list);
  		mnt->mnt_master = old;
  		CLEAR_MNT_SHARED(mnt);
  	} else if (!(flag & CL_PRIVATE)) {
  		if ((flag & CL_MAKE_SHARED) || IS_MNT_SHARED(old))
  			list_add(&mnt->mnt_share, &old->mnt_share);
  		if (IS_MNT_SLAVE(old))
  			list_add(&mnt->mnt_slave, &old->mnt_slave);
  		mnt->mnt_master = old->mnt_master;
5235d448c   Al Viro   reorganize do_mak...
1018
1019
  	} else {
  		CLEAR_MNT_SHARED(mnt);
be34d1a3b   David Howells   VFS: Make clone_m...
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
  	}
  	if (flag & CL_MAKE_SHARED)
  		set_mnt_shared(mnt);
  
  	/* stick the duplicate mount on the same expiry list
  	 * as the original if that was on one */
  	if (flag & CL_EXPIRE) {
  		if (!list_empty(&old->mnt_expire))
  			list_add(&mnt->mnt_expire, &old->mnt_expire);
  	}
cb338d06e   Al Viro   vfs: spread struc...
1030
  	return mnt;
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
1031
1032
  
   out_free:
8ffcb32e0   David Howells   VFS: Make delayed...
1033
  	mnt_free_id(mnt);
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
1034
  	free_vfsmnt(mnt);
be34d1a3b   David Howells   VFS: Make clone_m...
1035
  	return ERR_PTR(err);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1036
  }
9ea459e11   Al Viro   delayed mntput
1037
1038
  static void cleanup_mnt(struct mount *mnt)
  {
56cbb429d   Al Viro   switch the remnan...
1039
1040
  	struct hlist_node *p;
  	struct mount *m;
9ea459e11   Al Viro   delayed mntput
1041
  	/*
56cbb429d   Al Viro   switch the remnan...
1042
1043
1044
  	 * The warning here probably indicates that somebody messed
  	 * up a mnt_want/drop_write() pair.  If this happens, the
  	 * filesystem was probably unable to make r/w->r/o transitions.
9ea459e11   Al Viro   delayed mntput
1045
1046
1047
1048
1049
1050
  	 * The locking used to deal with mnt_count decrement provides barriers,
  	 * so mnt_get_writers() below is safe.
  	 */
  	WARN_ON(mnt_get_writers(mnt));
  	if (unlikely(mnt->mnt_pins.first))
  		mnt_pin_kill(mnt);
56cbb429d   Al Viro   switch the remnan...
1051
1052
1053
1054
  	hlist_for_each_entry_safe(m, p, &mnt->mnt_stuck_children, mnt_umount) {
  		hlist_del(&m->mnt_umount);
  		mntput(&m->mnt);
  	}
9ea459e11   Al Viro   delayed mntput
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
  	fsnotify_vfsmount_delete(&mnt->mnt);
  	dput(mnt->mnt.mnt_root);
  	deactivate_super(mnt->mnt.mnt_sb);
  	mnt_free_id(mnt);
  	call_rcu(&mnt->mnt_rcu, delayed_free_vfsmnt);
  }
  
  static void __cleanup_mnt(struct rcu_head *head)
  {
  	cleanup_mnt(container_of(head, struct mount, mnt_rcu));
  }
  
  static LLIST_HEAD(delayed_mntput_list);
  static void delayed_mntput(struct work_struct *unused)
  {
  	struct llist_node *node = llist_del_all(&delayed_mntput_list);
297857357   Byungchul Park   namespace.c: Don'...
1071
  	struct mount *m, *t;
9ea459e11   Al Viro   delayed mntput
1072

297857357   Byungchul Park   namespace.c: Don'...
1073
1074
  	llist_for_each_entry_safe(m, t, node, mnt_llist)
  		cleanup_mnt(m);
9ea459e11   Al Viro   delayed mntput
1075
1076
  }
  static DECLARE_DELAYED_WORK(delayed_mntput_work, delayed_mntput);
900148dca   Al Viro   vfs: spread struc...
1077
  static void mntput_no_expire(struct mount *mnt)
b3e19d924   Nick Piggin   fs: scale mntget/...
1078
  {
4edbe133f   Al Viro   make struct mount...
1079
  	LIST_HEAD(list);
eae1fb3bc   Eric Biggers   fs/namespace.c: W...
1080
  	int count;
4edbe133f   Al Viro   make struct mount...
1081

48a066e72   Al Viro   RCU'd vfsmounts
1082
  	rcu_read_lock();
9ea0a46ca   Al Viro   fix mntput/mntput...
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
  	if (likely(READ_ONCE(mnt->mnt_ns))) {
  		/*
  		 * Since we don't do lock_mount_hash() here,
  		 * ->mnt_ns can change under us.  However, if it's
  		 * non-NULL, then there's a reference that won't
  		 * be dropped until after an RCU delay done after
  		 * turning ->mnt_ns NULL.  So if we observe it
  		 * non-NULL under rcu_read_lock(), the reference
  		 * we are dropping is not the final one.
  		 */
  		mnt_add_count(mnt, -1);
48a066e72   Al Viro   RCU'd vfsmounts
1094
  		rcu_read_unlock();
f03c65993   Al Viro   sanitize vfsmount...
1095
  		return;
b3e19d924   Nick Piggin   fs: scale mntget/...
1096
  	}
719ea2fbb   Al Viro   new helpers: lock...
1097
  	lock_mount_hash();
119e1ef80   Al Viro   fix __legitimize_...
1098
1099
1100
1101
1102
  	/*
  	 * make sure that if __legitimize_mnt() has not seen us grab
  	 * mount_lock, we'll see their refcount increment here.
  	 */
  	smp_mb();
9ea0a46ca   Al Viro   fix mntput/mntput...
1103
  	mnt_add_count(mnt, -1);
eae1fb3bc   Eric Biggers   fs/namespace.c: W...
1104
1105
1106
  	count = mnt_get_count(mnt);
  	if (count != 0) {
  		WARN_ON(count < 0);
48a066e72   Al Viro   RCU'd vfsmounts
1107
  		rcu_read_unlock();
719ea2fbb   Al Viro   new helpers: lock...
1108
  		unlock_mount_hash();
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
1109
1110
  		return;
  	}
48a066e72   Al Viro   RCU'd vfsmounts
1111
1112
1113
1114
1115
1116
1117
  	if (unlikely(mnt->mnt.mnt_flags & MNT_DOOMED)) {
  		rcu_read_unlock();
  		unlock_mount_hash();
  		return;
  	}
  	mnt->mnt.mnt_flags |= MNT_DOOMED;
  	rcu_read_unlock();
962830df3   Andi Kleen   brlocks/lglocks: ...
1118

39f7c4db1   Miklos Szeredi   vfs: keep list of...
1119
  	list_del(&mnt->mnt_instance);
ce07d891a   Eric W. Biederman   mnt: Honor MNT_LO...
1120
1121
1122
1123
  
  	if (unlikely(!list_empty(&mnt->mnt_mounts))) {
  		struct mount *p, *tmp;
  		list_for_each_entry_safe(p, tmp, &mnt->mnt_mounts,  mnt_child) {
4edbe133f   Al Viro   make struct mount...
1124
  			__put_mountpoint(unhash_mnt(p), &list);
56cbb429d   Al Viro   switch the remnan...
1125
  			hlist_add_head(&p->mnt_umount, &mnt->mnt_stuck_children);
ce07d891a   Eric W. Biederman   mnt: Honor MNT_LO...
1126
1127
  		}
  	}
719ea2fbb   Al Viro   new helpers: lock...
1128
  	unlock_mount_hash();
4edbe133f   Al Viro   make struct mount...
1129
  	shrink_dentry_list(&list);
649a795af   Al Viro   fold mntfree() in...
1130

9ea459e11   Al Viro   delayed mntput
1131
1132
1133
1134
  	if (likely(!(mnt->mnt.mnt_flags & MNT_INTERNAL))) {
  		struct task_struct *task = current;
  		if (likely(!(task->flags & PF_KTHREAD))) {
  			init_task_work(&mnt->mnt_rcu, __cleanup_mnt);
91989c707   Jens Axboe   task_work: cleanu...
1135
  			if (!task_work_add(task, &mnt->mnt_rcu, TWA_RESUME))
9ea459e11   Al Viro   delayed mntput
1136
1137
1138
1139
1140
1141
1142
  				return;
  		}
  		if (llist_add(&mnt->mnt_llist, &delayed_mntput_list))
  			schedule_delayed_work(&delayed_mntput_work, 1);
  		return;
  	}
  	cleanup_mnt(mnt);
b3e19d924   Nick Piggin   fs: scale mntget/...
1143
  }
b3e19d924   Nick Piggin   fs: scale mntget/...
1144
1145
1146
1147
  
  void mntput(struct vfsmount *mnt)
  {
  	if (mnt) {
863d684f9   Al Viro   vfs: move the res...
1148
  		struct mount *m = real_mount(mnt);
b3e19d924   Nick Piggin   fs: scale mntget/...
1149
  		/* avoid cacheline pingpong, hope gcc doesn't get "smart" */
863d684f9   Al Viro   vfs: move the res...
1150
1151
1152
  		if (unlikely(m->mnt_expiry_mark))
  			m->mnt_expiry_mark = 0;
  		mntput_no_expire(m);
b3e19d924   Nick Piggin   fs: scale mntget/...
1153
1154
1155
1156
1157
1158
1159
  	}
  }
  EXPORT_SYMBOL(mntput);
  
  struct vfsmount *mntget(struct vfsmount *mnt)
  {
  	if (mnt)
83adc7532   Al Viro   vfs: spread struc...
1160
  		mnt_add_count(real_mount(mnt), 1);
b3e19d924   Nick Piggin   fs: scale mntget/...
1161
1162
1163
  	return mnt;
  }
  EXPORT_SYMBOL(mntget);
c6609c0a1   Ian Kent   vfs: add path_is_...
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
  /* path_is_mountpoint() - Check if path is a mount in the current
   *                          namespace.
   *
   *  d_mountpoint() can only be used reliably to establish if a dentry is
   *  not mounted in any namespace and that common case is handled inline.
   *  d_mountpoint() isn't aware of the possibility there may be multiple
   *  mounts using a given dentry in a different namespace. This function
   *  checks if the passed in path is a mountpoint rather than the dentry
   *  alone.
   */
  bool path_is_mountpoint(const struct path *path)
  {
  	unsigned seq;
  	bool res;
  
  	if (!d_mountpoint(path->dentry))
  		return false;
  
  	rcu_read_lock();
  	do {
  		seq = read_seqbegin(&mount_lock);
  		res = __path_is_mountpoint(path);
  	} while (read_seqretry(&mount_lock, seq));
  	rcu_read_unlock();
  
  	return res;
  }
  EXPORT_SYMBOL(path_is_mountpoint);
ca71cf71e   Al Viro   namespace.c: cons...
1192
  struct vfsmount *mnt_clone_internal(const struct path *path)
7b7b1ace2   Al Viro   [PATCH] saner han...
1193
  {
3064c3563   Al Viro   death to mnt_pinned
1194
1195
1196
1197
1198
1199
  	struct mount *p;
  	p = clone_mnt(real_mount(path->mnt), path->dentry, CL_PRIVATE);
  	if (IS_ERR(p))
  		return ERR_CAST(p);
  	p->mnt.mnt_flags |= MNT_INTERNAL;
  	return &p->mnt;
7b7b1ace2   Al Viro   [PATCH] saner han...
1200
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1201

a1a2c409b   Miklos Szeredi   [patch 5/7] vfs: ...
1202
  #ifdef CONFIG_PROC_FS
9f6c61f96   Miklos Szeredi   proc/mounts: add ...
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
  static struct mount *mnt_list_next(struct mnt_namespace *ns,
  				   struct list_head *p)
  {
  	struct mount *mnt, *ret = NULL;
  
  	lock_ns_list(ns);
  	list_for_each_continue(p, &ns->list) {
  		mnt = list_entry(p, typeof(*mnt), mnt_list);
  		if (!mnt_is_cursor(mnt)) {
  			ret = mnt;
  			break;
  		}
  	}
  	unlock_ns_list(ns);
  
  	return ret;
  }
0226f4923   Al Viro   vfs: take /proc/*...
1220
  /* iterator; we want it to have access to namespace_sem, thus here... */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1221
1222
  static void *m_start(struct seq_file *m, loff_t *pos)
  {
ede1bf0dc   Yann Droneaud   fs: use seq_open_...
1223
  	struct proc_mounts *p = m->private;
9f6c61f96   Miklos Szeredi   proc/mounts: add ...
1224
  	struct list_head *prev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1225

390c68436   Ram Pai   [PATCH] making na...
1226
  	down_read(&namespace_sem);
9f6c61f96   Miklos Szeredi   proc/mounts: add ...
1227
1228
1229
1230
1231
1232
1233
1234
  	if (!*pos) {
  		prev = &p->ns->list;
  	} else {
  		prev = &p->cursor.mnt_list;
  
  		/* Read after we'd reached the end? */
  		if (list_empty(prev))
  			return NULL;
c7999c362   Al Viro   reduce m_start() ...
1235
  	}
9f6c61f96   Miklos Szeredi   proc/mounts: add ...
1236
  	return mnt_list_next(p->ns, prev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1237
1238
1239
1240
  }
  
  static void *m_next(struct seq_file *m, void *v, loff_t *pos)
  {
ede1bf0dc   Yann Droneaud   fs: use seq_open_...
1241
  	struct proc_mounts *p = m->private;
9f6c61f96   Miklos Szeredi   proc/mounts: add ...
1242
  	struct mount *mnt = v;
b0765fb85   Pavel Emelianov   Make /proc/self/m...
1243

9f6c61f96   Miklos Szeredi   proc/mounts: add ...
1244
1245
  	++*pos;
  	return mnt_list_next(p->ns, &mnt->mnt_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1246
1247
1248
1249
  }
  
  static void m_stop(struct seq_file *m, void *v)
  {
9f6c61f96   Miklos Szeredi   proc/mounts: add ...
1250
1251
1252
1253
1254
1255
1256
1257
1258
  	struct proc_mounts *p = m->private;
  	struct mount *mnt = v;
  
  	lock_ns_list(p->ns);
  	if (mnt)
  		list_move_tail(&p->cursor.mnt_list, &mnt->mnt_list);
  	else
  		list_del_init(&p->cursor.mnt_list);
  	unlock_ns_list(p->ns);
390c68436   Ram Pai   [PATCH] making na...
1259
  	up_read(&namespace_sem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1260
  }
0226f4923   Al Viro   vfs: take /proc/*...
1261
  static int m_show(struct seq_file *m, void *v)
2d4d4864a   Ram Pai   [patch 6/7] vfs: ...
1262
  {
ede1bf0dc   Yann Droneaud   fs: use seq_open_...
1263
  	struct proc_mounts *p = m->private;
9f6c61f96   Miklos Szeredi   proc/mounts: add ...
1264
  	struct mount *r = v;
0226f4923   Al Viro   vfs: take /proc/*...
1265
  	return p->show(m, &r->mnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1266
  }
a1a2c409b   Miklos Szeredi   [patch 5/7] vfs: ...
1267
  const struct seq_operations mounts_op = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1268
1269
1270
  	.start	= m_start,
  	.next	= m_next,
  	.stop	= m_stop,
0226f4923   Al Viro   vfs: take /proc/*...
1271
  	.show	= m_show,
b4629fe2f   Chuck Lever   VFS: New /proc fi...
1272
  };
9f6c61f96   Miklos Szeredi   proc/mounts: add ...
1273
1274
1275
1276
1277
1278
1279
1280
1281
  
  void mnt_cursor_del(struct mnt_namespace *ns, struct mount *cursor)
  {
  	down_read(&namespace_sem);
  	lock_ns_list(ns);
  	list_del(&cursor->mnt_list);
  	unlock_ns_list(ns);
  	up_read(&namespace_sem);
  }
a1a2c409b   Miklos Szeredi   [patch 5/7] vfs: ...
1282
  #endif  /* CONFIG_PROC_FS */
b4629fe2f   Chuck Lever   VFS: New /proc fi...
1283

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1284
1285
1286
1287
1288
1289
1290
1291
  /**
   * may_umount_tree - check if a mount tree is busy
   * @mnt: root of mount tree
   *
   * This is called to check if a tree of mounts has any
   * open files, pwds, chroots or sub mounts that are
   * busy.
   */
909b0a88e   Al Viro   vfs: spread struc...
1292
  int may_umount_tree(struct vfsmount *m)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1293
  {
909b0a88e   Al Viro   vfs: spread struc...
1294
  	struct mount *mnt = real_mount(m);
36341f645   Ram Pai   [PATCH] mount exp...
1295
1296
  	int actual_refs = 0;
  	int minimum_refs = 0;
315fc83e5   Al Viro   vfs: spread struc...
1297
  	struct mount *p;
909b0a88e   Al Viro   vfs: spread struc...
1298
  	BUG_ON(!m);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1299

b3e19d924   Nick Piggin   fs: scale mntget/...
1300
  	/* write lock needed for mnt_get_count */
719ea2fbb   Al Viro   new helpers: lock...
1301
  	lock_mount_hash();
909b0a88e   Al Viro   vfs: spread struc...
1302
  	for (p = mnt; p; p = next_mnt(p, mnt)) {
83adc7532   Al Viro   vfs: spread struc...
1303
  		actual_refs += mnt_get_count(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1304
  		minimum_refs += 2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1305
  	}
719ea2fbb   Al Viro   new helpers: lock...
1306
  	unlock_mount_hash();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1307
1308
  
  	if (actual_refs > minimum_refs)
e3474a8eb   Ian Kent   [PATCH] autofs4: ...
1309
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1310

e3474a8eb   Ian Kent   [PATCH] autofs4: ...
1311
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
  }
  
  EXPORT_SYMBOL(may_umount_tree);
  
  /**
   * may_umount - check if a mount point is busy
   * @mnt: root of mount
   *
   * This is called to check if a mount point has any
   * open files, pwds, chroots or sub mounts. If the
   * mount has sub mounts this will return busy
   * regardless of whether the sub mounts are busy.
   *
   * Doesn't take quota and stuff into account. IOW, in some cases it will
   * give false negatives. The main reason why it's here is that we need
   * a non-destructive way to look for easily umountable filesystems.
   */
  int may_umount(struct vfsmount *mnt)
  {
e3474a8eb   Ian Kent   [PATCH] autofs4: ...
1331
  	int ret = 1;
8ad08d8a0   Al Viro   may_umount() need...
1332
  	down_read(&namespace_sem);
719ea2fbb   Al Viro   new helpers: lock...
1333
  	lock_mount_hash();
1ab597386   Al Viro   vfs: spread struc...
1334
  	if (propagate_mount_busy(real_mount(mnt), 2))
e3474a8eb   Ian Kent   [PATCH] autofs4: ...
1335
  		ret = 0;
719ea2fbb   Al Viro   new helpers: lock...
1336
  	unlock_mount_hash();
8ad08d8a0   Al Viro   may_umount() need...
1337
  	up_read(&namespace_sem);
a05964f39   Ram Pai   [PATCH] shared mo...
1338
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1339
1340
1341
  }
  
  EXPORT_SYMBOL(may_umount);
97216be09   Al Viro   fold release_moun...
1342
  static void namespace_unlock(void)
70fbcdf4d   Ram Pai   [PATCH] umount_tr...
1343
  {
a3b3c5627   Eric W. Biederman   mnt: Use hlist_mo...
1344
  	struct hlist_head head;
56cbb429d   Al Viro   switch the remnan...
1345
1346
  	struct hlist_node *p;
  	struct mount *m;
4edbe133f   Al Viro   make struct mount...
1347
  	LIST_HEAD(list);
97216be09   Al Viro   fold release_moun...
1348

a3b3c5627   Eric W. Biederman   mnt: Use hlist_mo...
1349
  	hlist_move_list(&unmounted, &head);
4edbe133f   Al Viro   make struct mount...
1350
  	list_splice_init(&ex_mountpoints, &list);
97216be09   Al Viro   fold release_moun...
1351

97216be09   Al Viro   fold release_moun...
1352
  	up_write(&namespace_sem);
4edbe133f   Al Viro   make struct mount...
1353
  	shrink_dentry_list(&list);
a3b3c5627   Eric W. Biederman   mnt: Use hlist_mo...
1354
1355
  	if (likely(hlist_empty(&head)))
  		return;
22cb7405f   NeilBrown   VFS: use synchron...
1356
  	synchronize_rcu_expedited();
48a066e72   Al Viro   RCU'd vfsmounts
1357

56cbb429d   Al Viro   switch the remnan...
1358
1359
1360
1361
  	hlist_for_each_entry_safe(m, p, &head, mnt_umount) {
  		hlist_del(&m->mnt_umount);
  		mntput(&m->mnt);
  	}
70fbcdf4d   Ram Pai   [PATCH] umount_tr...
1362
  }
97216be09   Al Viro   fold release_moun...
1363
  static inline void namespace_lock(void)
e3197d83d   Al Viro   saner umount_tree...
1364
  {
97216be09   Al Viro   fold release_moun...
1365
  	down_write(&namespace_sem);
e3197d83d   Al Viro   saner umount_tree...
1366
  }
e819f1521   Eric W. Biederman   mnt: Improve the ...
1367
1368
1369
  enum umount_tree_flags {
  	UMOUNT_SYNC = 1,
  	UMOUNT_PROPAGATE = 2,
e0c9c0afd   Eric W. Biederman   mnt: Update detac...
1370
  	UMOUNT_CONNECTED = 4,
e819f1521   Eric W. Biederman   mnt: Improve the ...
1371
  };
f2d0a123b   Eric W. Biederman   mnt: Clarify and ...
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
  
  static bool disconnect_mount(struct mount *mnt, enum umount_tree_flags how)
  {
  	/* Leaving mounts connected is only valid for lazy umounts */
  	if (how & UMOUNT_SYNC)
  		return true;
  
  	/* A mount without a parent has nothing to be connected to */
  	if (!mnt_has_parent(mnt))
  		return true;
  
  	/* Because the reference counting rules change when mounts are
  	 * unmounted and connected, umounted mounts may not be
  	 * connected to mounted mounts.
  	 */
  	if (!(mnt->mnt_parent->mnt.mnt_flags & MNT_UMOUNT))
  		return true;
  
  	/* Has it been requested that the mount remain connected? */
  	if (how & UMOUNT_CONNECTED)
  		return false;
  
  	/* Is the mount locked such that it needs to remain connected? */
  	if (IS_MNT_LOCKED(mnt))
  		return false;
  
  	/* By default disconnect the mount */
  	return true;
  }
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
1401
  /*
48a066e72   Al Viro   RCU'd vfsmounts
1402
   * mount_lock must be held
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
1403
1404
   * namespace_sem must be held for write
   */
e819f1521   Eric W. Biederman   mnt: Improve the ...
1405
  static void umount_tree(struct mount *mnt, enum umount_tree_flags how)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1406
  {
c003b26ff   Eric W. Biederman   mnt: In umount_tr...
1407
  	LIST_HEAD(tmp_list);
315fc83e5   Al Viro   vfs: spread struc...
1408
  	struct mount *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1409

5d88457eb   Eric W. Biederman   mnt: On an unmoun...
1410
1411
  	if (how & UMOUNT_PROPAGATE)
  		propagate_mount_unlock(mnt);
c003b26ff   Eric W. Biederman   mnt: In umount_tr...
1412
  	/* Gather the mounts to umount */
590ce4bcb   Eric W. Biederman   mnt: Add MNT_UMOU...
1413
1414
  	for (p = mnt; p; p = next_mnt(p, mnt)) {
  		p->mnt.mnt_flags |= MNT_UMOUNT;
c003b26ff   Eric W. Biederman   mnt: In umount_tr...
1415
  		list_move(&p->mnt_list, &tmp_list);
590ce4bcb   Eric W. Biederman   mnt: Add MNT_UMOU...
1416
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1417

411a938b5   Eric W. Biederman   mnt: Delay remova...
1418
  	/* Hide the mounts from mnt_mounts */
c003b26ff   Eric W. Biederman   mnt: In umount_tr...
1419
  	list_for_each_entry(p, &tmp_list, mnt_list) {
88b368f27   Al Viro   get rid of propag...
1420
  		list_del_init(&p->mnt_child);
c003b26ff   Eric W. Biederman   mnt: In umount_tr...
1421
  	}
88b368f27   Al Viro   get rid of propag...
1422

c003b26ff   Eric W. Biederman   mnt: In umount_tr...
1423
  	/* Add propogated mounts to the tmp_list */
e819f1521   Eric W. Biederman   mnt: Improve the ...
1424
  	if (how & UMOUNT_PROPAGATE)
7b8a53fd8   Al Viro   fix old umount_tr...
1425
  		propagate_umount(&tmp_list);
a05964f39   Ram Pai   [PATCH] shared mo...
1426

c003b26ff   Eric W. Biederman   mnt: In umount_tr...
1427
  	while (!list_empty(&tmp_list)) {
d29216842   Eric W. Biederman   mnt: Add a per mo...
1428
  		struct mnt_namespace *ns;
ce07d891a   Eric W. Biederman   mnt: Honor MNT_LO...
1429
  		bool disconnect;
c003b26ff   Eric W. Biederman   mnt: In umount_tr...
1430
  		p = list_first_entry(&tmp_list, struct mount, mnt_list);
6776db3d3   Al Viro   vfs: take mnt_sha...
1431
  		list_del_init(&p->mnt_expire);
1a4eeaf2a   Al Viro   vfs: move mnt_lis...
1432
  		list_del_init(&p->mnt_list);
d29216842   Eric W. Biederman   mnt: Add a per mo...
1433
1434
1435
1436
1437
  		ns = p->mnt_ns;
  		if (ns) {
  			ns->mounts--;
  			__touch_mnt_namespace(ns);
  		}
143c8c91c   Al Viro   vfs: mnt_ns moved...
1438
  		p->mnt_ns = NULL;
e819f1521   Eric W. Biederman   mnt: Improve the ...
1439
  		if (how & UMOUNT_SYNC)
48a066e72   Al Viro   RCU'd vfsmounts
1440
  			p->mnt.mnt_flags |= MNT_SYNC_UMOUNT;
87b95ce09   Al Viro   switch the IO-tri...
1441

f2d0a123b   Eric W. Biederman   mnt: Clarify and ...
1442
  		disconnect = disconnect_mount(p, how);
676da58df   Al Viro   vfs: spread struc...
1443
  		if (mnt_has_parent(p)) {
81b6b0619   Al Viro   fix EBUSY on umou...
1444
  			mnt_add_count(p->mnt_parent, -1);
ce07d891a   Eric W. Biederman   mnt: Honor MNT_LO...
1445
1446
1447
1448
1449
1450
  			if (!disconnect) {
  				/* Don't forget about p */
  				list_add_tail(&p->mnt_child, &p->mnt_parent->mnt_mounts);
  			} else {
  				umount_mnt(p);
  			}
7c4b93d82   Al Viro   [PATCH] count gho...
1451
  		}
0f0afb1dc   Al Viro   vfs: spread struc...
1452
  		change_mnt_propagation(p, MS_PRIVATE);
19a1c4092   Al Viro   fix the struct mo...
1453
1454
  		if (disconnect)
  			hlist_add_head(&p->mnt_umount, &unmounted);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1455
1456
  	}
  }
b54b9be78   Al Viro   get rid of the se...
1457
  static void shrink_submounts(struct mount *mnt);
c35038bec   Al Viro   [PATCH] do shrink...
1458

8d0347f6c   David Howells   convert do_remoun...
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
  static int do_umount_root(struct super_block *sb)
  {
  	int ret = 0;
  
  	down_write(&sb->s_umount);
  	if (!sb_rdonly(sb)) {
  		struct fs_context *fc;
  
  		fc = fs_context_for_reconfigure(sb->s_root, SB_RDONLY,
  						SB_RDONLY);
  		if (IS_ERR(fc)) {
  			ret = PTR_ERR(fc);
  		} else {
  			ret = parse_monolithic_mount_data(fc, NULL);
  			if (!ret)
  				ret = reconfigure_super(fc);
  			put_fs_context(fc);
  		}
  	}
  	up_write(&sb->s_umount);
  	return ret;
  }
1ab597386   Al Viro   vfs: spread struc...
1481
  static int do_umount(struct mount *mnt, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1482
  {
1ab597386   Al Viro   vfs: spread struc...
1483
  	struct super_block *sb = mnt->mnt.mnt_sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1484
  	int retval;
1ab597386   Al Viro   vfs: spread struc...
1485
  	retval = security_sb_umount(&mnt->mnt, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
  	if (retval)
  		return retval;
  
  	/*
  	 * Allow userspace to request a mountpoint be expired rather than
  	 * unmounting unconditionally. Unmount only happens if:
  	 *  (1) the mark is already set (the mark is cleared by mntput())
  	 *  (2) the usage count == 1 [parent vfsmount] + 1 [sys_umount]
  	 */
  	if (flags & MNT_EXPIRE) {
1ab597386   Al Viro   vfs: spread struc...
1496
  		if (&mnt->mnt == current->fs->root.mnt ||
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1497
1498
  		    flags & (MNT_FORCE | MNT_DETACH))
  			return -EINVAL;
b3e19d924   Nick Piggin   fs: scale mntget/...
1499
1500
1501
1502
  		/*
  		 * probably don't strictly need the lock here if we examined
  		 * all race cases, but it's a slowpath.
  		 */
719ea2fbb   Al Viro   new helpers: lock...
1503
  		lock_mount_hash();
83adc7532   Al Viro   vfs: spread struc...
1504
  		if (mnt_get_count(mnt) != 2) {
719ea2fbb   Al Viro   new helpers: lock...
1505
  			unlock_mount_hash();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1506
  			return -EBUSY;
b3e19d924   Nick Piggin   fs: scale mntget/...
1507
  		}
719ea2fbb   Al Viro   new helpers: lock...
1508
  		unlock_mount_hash();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1509

863d684f9   Al Viro   vfs: move the res...
1510
  		if (!xchg(&mnt->mnt_expiry_mark, 1))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
  			return -EAGAIN;
  	}
  
  	/*
  	 * If we may have to abort operations to get out of this
  	 * mount, and they will themselves hold resources we must
  	 * allow the fs to do things. In the Unix tradition of
  	 * 'Gee thats tricky lets do it in userspace' the umount_begin
  	 * might fail to complete on the first run through as other tasks
  	 * must return, and the like. Thats for the mount program to worry
  	 * about for the moment.
  	 */
42faad996   Al Viro   [PATCH] restore s...
1523
  	if (flags & MNT_FORCE && sb->s_op->umount_begin) {
42faad996   Al Viro   [PATCH] restore s...
1524
  		sb->s_op->umount_begin(sb);
42faad996   Al Viro   [PATCH] restore s...
1525
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
  
  	/*
  	 * No sense to grab the lock for this test, but test itself looks
  	 * somewhat bogus. Suggestions for better replacement?
  	 * Ho-hum... In principle, we might treat that as umount + switch
  	 * to rootfs. GC would eventually take care of the old vfsmount.
  	 * Actually it makes sense, especially if rootfs would contain a
  	 * /reboot - static binary that would close all descriptors and
  	 * call reboot(9). Then init(8) could umount root and exec /reboot.
  	 */
1ab597386   Al Viro   vfs: spread struc...
1536
  	if (&mnt->mnt == current->fs->root.mnt && !(flags & MNT_DETACH)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1537
1538
1539
1540
  		/*
  		 * Special case for "unmounting" root ...
  		 * we just try to remount it readonly.
  		 */
bc6155d13   Eric W. Biederman   fs: Allow superbl...
1541
  		if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN))
a1480dcc3   Andy Lutomirski   fs: Add a missing...
1542
  			return -EPERM;
8d0347f6c   David Howells   convert do_remoun...
1543
  		return do_umount_root(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1544
  	}
97216be09   Al Viro   fold release_moun...
1545
  	namespace_lock();
719ea2fbb   Al Viro   new helpers: lock...
1546
  	lock_mount_hash();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1547

25d202ed8   Eric W. Biederman   mount: Retest MNT...
1548
1549
1550
1551
1552
1553
  	/* Recheck MNT_LOCKED with the locks held */
  	retval = -EINVAL;
  	if (mnt->mnt.mnt_flags & MNT_LOCKED)
  		goto out;
  
  	event++;
48a066e72   Al Viro   RCU'd vfsmounts
1554
  	if (flags & MNT_DETACH) {
1a4eeaf2a   Al Viro   vfs: move mnt_lis...
1555
  		if (!list_empty(&mnt->mnt_list))
e819f1521   Eric W. Biederman   mnt: Improve the ...
1556
  			umount_tree(mnt, UMOUNT_PROPAGATE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1557
  		retval = 0;
48a066e72   Al Viro   RCU'd vfsmounts
1558
1559
1560
1561
1562
  	} else {
  		shrink_submounts(mnt);
  		retval = -EBUSY;
  		if (!propagate_mount_busy(mnt, 2)) {
  			if (!list_empty(&mnt->mnt_list))
e819f1521   Eric W. Biederman   mnt: Improve the ...
1563
  				umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC);
48a066e72   Al Viro   RCU'd vfsmounts
1564
1565
  			retval = 0;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1566
  	}
25d202ed8   Eric W. Biederman   mount: Retest MNT...
1567
  out:
719ea2fbb   Al Viro   new helpers: lock...
1568
  	unlock_mount_hash();
e3197d83d   Al Viro   saner umount_tree...
1569
  	namespace_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1570
1571
  	return retval;
  }
80b5dce8c   Eric W. Biederman   vfs: Add a functi...
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
  /*
   * __detach_mounts - lazily unmount all mounts on the specified dentry
   *
   * During unlink, rmdir, and d_drop it is possible to loose the path
   * to an existing mountpoint, and wind up leaking the mount.
   * detach_mounts allows lazily unmounting those mounts instead of
   * leaking them.
   *
   * The caller may hold dentry->d_inode->i_mutex.
   */
  void __detach_mounts(struct dentry *dentry)
  {
  	struct mountpoint *mp;
  	struct mount *mnt;
  
  	namespace_lock();
3895dbf89   Eric W. Biederman   mnt: Protect the ...
1588
  	lock_mount_hash();
80b5dce8c   Eric W. Biederman   vfs: Add a functi...
1589
  	mp = lookup_mountpoint(dentry);
adc9b5c09   Al Viro   __detach_mounts()...
1590
  	if (!mp)
80b5dce8c   Eric W. Biederman   vfs: Add a functi...
1591
  		goto out_unlock;
e06b933e6   Andrey Ulanov   namespace: update...
1592
  	event++;
80b5dce8c   Eric W. Biederman   vfs: Add a functi...
1593
1594
  	while (!hlist_empty(&mp->m_list)) {
  		mnt = hlist_entry(mp->m_list.first, struct mount, mnt_mp_list);
ce07d891a   Eric W. Biederman   mnt: Honor MNT_LO...
1595
  		if (mnt->mnt.mnt_flags & MNT_UMOUNT) {
fe78fcc85   Eric W. Biederman   mnt: In detach_mo...
1596
  			umount_mnt(mnt);
56cbb429d   Al Viro   switch the remnan...
1597
  			hlist_add_head(&mnt->mnt_umount, &unmounted);
ce07d891a   Eric W. Biederman   mnt: Honor MNT_LO...
1598
  		}
e0c9c0afd   Eric W. Biederman   mnt: Update detac...
1599
  		else umount_tree(mnt, UMOUNT_CONNECTED);
80b5dce8c   Eric W. Biederman   vfs: Add a functi...
1600
  	}
80b5dce8c   Eric W. Biederman   vfs: Add a functi...
1601
1602
  	put_mountpoint(mp);
  out_unlock:
3895dbf89   Eric W. Biederman   mnt: Protect the ...
1603
  	unlock_mount_hash();
80b5dce8c   Eric W. Biederman   vfs: Add a functi...
1604
1605
  	namespace_unlock();
  }
dd111b31e   David Howells   VFS: Clean up whi...
1606
  /*
9b40bc90a   Al Viro   get rid of unprot...
1607
1608
1609
1610
1611
1612
   * Is the caller allowed to modify his namespace?
   */
  static inline bool may_mount(void)
  {
  	return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN);
  }
df2474a22   Jeff Layton   locks: print a wa...
1613
  #ifdef	CONFIG_MANDATORY_FILE_LOCKING
9e8925b67   Jeff Layton   locks: Allow disa...
1614
1615
  static inline bool may_mandlock(void)
  {
95ace7541   Eric W. Biederman   locks: Don't allo...
1616
  	return capable(CAP_SYS_ADMIN);
9e8925b67   Jeff Layton   locks: Allow disa...
1617
  }
df2474a22   Jeff Layton   locks: print a wa...
1618
1619
1620
1621
1622
1623
1624
  #else
  static inline bool may_mandlock(void)
  {
  	pr_warn("VFS: \"mand\" mount option not supported");
  	return false;
  }
  #endif
9e8925b67   Jeff Layton   locks: Allow disa...
1625

25ccd24ff   Christoph Hellwig   fs: fix a struct ...
1626
  static int can_umount(const struct path *path, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1627
  {
25ccd24ff   Christoph Hellwig   fs: fix a struct ...
1628
  	struct mount *mnt = real_mount(path->mnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1629

9b40bc90a   Al Viro   get rid of unprot...
1630
1631
  	if (!may_mount())
  		return -EPERM;
41525f56e   Christoph Hellwig   fs: refactor ksys...
1632
  	if (path->dentry != path->mnt->mnt_root)
25ccd24ff   Christoph Hellwig   fs: fix a struct ...
1633
  		return -EINVAL;
143c8c91c   Al Viro   vfs: mnt_ns moved...
1634
  	if (!check_mnt(mnt))
25ccd24ff   Christoph Hellwig   fs: fix a struct ...
1635
  		return -EINVAL;
25d202ed8   Eric W. Biederman   mount: Retest MNT...
1636
  	if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */
25ccd24ff   Christoph Hellwig   fs: fix a struct ...
1637
  		return -EINVAL;
b2f5d4dc3   Eric W. Biederman   umount: Disallow ...
1638
  	if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN))
25ccd24ff   Christoph Hellwig   fs: fix a struct ...
1639
1640
1641
  		return -EPERM;
  	return 0;
  }
c6dc4f8e6   Al Viro   umount(2): move t...
1642
  // caller is responsible for flags being sane
25ccd24ff   Christoph Hellwig   fs: fix a struct ...
1643
1644
1645
1646
1647
1648
1649
1650
  int path_umount(struct path *path, int flags)
  {
  	struct mount *mnt = real_mount(path->mnt);
  	int ret;
  
  	ret = can_umount(path, flags);
  	if (!ret)
  		ret = do_umount(mnt, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1651

429731b15   Jan Blunck   Remove path_relea...
1652
  	/* we mustn't call path_put() as that would clear mnt_expiry_mark */
41525f56e   Christoph Hellwig   fs: refactor ksys...
1653
  	dput(path->dentry);
900148dca   Al Viro   vfs: spread struc...
1654
  	mntput_no_expire(mnt);
25ccd24ff   Christoph Hellwig   fs: fix a struct ...
1655
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1656
  }
09267defa   Christoph Hellwig   init: add an init...
1657
  static int ksys_umount(char __user *name, int flags)
41525f56e   Christoph Hellwig   fs: refactor ksys...
1658
1659
1660
1661
  {
  	int lookup_flags = LOOKUP_MOUNTPOINT;
  	struct path path;
  	int ret;
c6dc4f8e6   Al Viro   umount(2): move t...
1662
1663
1664
  	// basic validity checks done first
  	if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW))
  		return -EINVAL;
41525f56e   Christoph Hellwig   fs: refactor ksys...
1665
1666
1667
1668
1669
1670
1671
  	if (!(flags & UMOUNT_NOFOLLOW))
  		lookup_flags |= LOOKUP_FOLLOW;
  	ret = user_path_at(AT_FDCWD, name, lookup_flags, &path);
  	if (ret)
  		return ret;
  	return path_umount(&path, flags);
  }
3a18ef5c1   Dominik Brodowski   fs: add ksys_umou...
1672
1673
1674
1675
  SYSCALL_DEFINE2(umount, char __user *, name, int, flags)
  {
  	return ksys_umount(name, flags);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1676
1677
1678
  #ifdef __ARCH_WANT_SYS_OLDUMOUNT
  
  /*
b58fed8b1   Ram Pai   [PATCH] lindent f...
1679
   *	The 2.0 compatible umount. No flags.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1680
   */
bdc480e3b   Heiko Carstens   [CVE-2009-0029] S...
1681
  SYSCALL_DEFINE1(oldumount, char __user *, name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1682
  {
3a18ef5c1   Dominik Brodowski   fs: add ksys_umou...
1683
  	return ksys_umount(name, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1684
1685
1686
  }
  
  #endif
4ce5d2b1a   Eric W. Biederman   vfs: Don't copy m...
1687
  static bool is_mnt_ns_file(struct dentry *dentry)
8823c079b   Eric W. Biederman   vfs: Add setns su...
1688
  {
4ce5d2b1a   Eric W. Biederman   vfs: Don't copy m...
1689
  	/* Is this a proxy for a mount namespace? */
e149ed2b8   Al Viro   take the targets ...
1690
1691
  	return dentry->d_op == &ns_dentry_operations &&
  	       dentry->d_fsdata == &mntns_operations;
4ce5d2b1a   Eric W. Biederman   vfs: Don't copy m...
1692
  }
213921f96   Eric Biggers   fs/namespace.c: m...
1693
  static struct mnt_namespace *to_mnt_ns(struct ns_common *ns)
58be28256   Al Viro   make mntns ->get(...
1694
1695
1696
  {
  	return container_of(ns, struct mnt_namespace, ns);
  }
303cc571d   Christian Brauner   nsproxy: attach t...
1697
1698
1699
1700
  struct ns_common *from_mnt_ns(struct mnt_namespace *mnt)
  {
  	return &mnt->ns;
  }
4ce5d2b1a   Eric W. Biederman   vfs: Don't copy m...
1701
1702
1703
1704
1705
1706
1707
1708
  static bool mnt_ns_loop(struct dentry *dentry)
  {
  	/* Could bind mounting the mount namespace inode cause a
  	 * mount namespace loop?
  	 */
  	struct mnt_namespace *mnt_ns;
  	if (!is_mnt_ns_file(dentry))
  		return false;
f77c80142   Al Viro   bury struct proc_...
1709
  	mnt_ns = to_mnt_ns(get_proc_ns(dentry->d_inode));
8823c079b   Eric W. Biederman   vfs: Add setns su...
1710
1711
  	return current->nsproxy->mnt_ns->seq >= mnt_ns->seq;
  }
87129cc0e   Al Viro   vfs: spread struc...
1712
  struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
36341f645   Ram Pai   [PATCH] mount exp...
1713
  					int flag)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1714
  {
84d17192d   Al Viro   get rid of full-h...
1715
  	struct mount *res, *p, *q, *r, *parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1716

4ce5d2b1a   Eric W. Biederman   vfs: Don't copy m...
1717
1718
1719
1720
  	if (!(flag & CL_COPY_UNBINDABLE) && IS_MNT_UNBINDABLE(mnt))
  		return ERR_PTR(-EINVAL);
  
  	if (!(flag & CL_COPY_MNT_NS_FILE) && is_mnt_ns_file(dentry))
be34d1a3b   David Howells   VFS: Make clone_m...
1721
  		return ERR_PTR(-EINVAL);
9676f0c63   Ram Pai   [PATCH] unbindabl...
1722

36341f645   Ram Pai   [PATCH] mount exp...
1723
  	res = q = clone_mnt(mnt, dentry, flag);
be34d1a3b   David Howells   VFS: Make clone_m...
1724
1725
  	if (IS_ERR(q))
  		return q;
a73324da7   Al Viro   vfs: move mnt_mou...
1726
  	q->mnt_mountpoint = mnt->mnt_mountpoint;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1727
1728
  
  	p = mnt;
6b41d536f   Al Viro   vfs: take mnt_chi...
1729
  	list_for_each_entry(r, &mnt->mnt_mounts, mnt_child) {
315fc83e5   Al Viro   vfs: spread struc...
1730
  		struct mount *s;
7ec02ef15   Jan Blunck   vfs: remove lives...
1731
  		if (!is_subdir(r->mnt_mountpoint, dentry))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1732
  			continue;
909b0a88e   Al Viro   vfs: spread struc...
1733
  		for (s = r; s; s = next_mnt(s, r)) {
4ce5d2b1a   Eric W. Biederman   vfs: Don't copy m...
1734
1735
  			if (!(flag & CL_COPY_UNBINDABLE) &&
  			    IS_MNT_UNBINDABLE(s)) {
df7342b24   Eric W. Biederman   mount: Don't allo...
1736
1737
1738
1739
1740
1741
1742
1743
  				if (s->mnt.mnt_flags & MNT_LOCKED) {
  					/* Both unbindable and locked. */
  					q = ERR_PTR(-EPERM);
  					goto out;
  				} else {
  					s = skip_mnt_tree(s);
  					continue;
  				}
4ce5d2b1a   Eric W. Biederman   vfs: Don't copy m...
1744
1745
1746
  			}
  			if (!(flag & CL_COPY_MNT_NS_FILE) &&
  			    is_mnt_ns_file(s->mnt.mnt_root)) {
9676f0c63   Ram Pai   [PATCH] unbindabl...
1747
1748
1749
  				s = skip_mnt_tree(s);
  				continue;
  			}
0714a5338   Al Viro   vfs: now it can b...
1750
1751
1752
  			while (p != s->mnt_parent) {
  				p = p->mnt_parent;
  				q = q->mnt_parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1753
  			}
87129cc0e   Al Viro   vfs: spread struc...
1754
  			p = s;
84d17192d   Al Viro   get rid of full-h...
1755
  			parent = q;
87129cc0e   Al Viro   vfs: spread struc...
1756
  			q = clone_mnt(p, p->mnt.mnt_root, flag);
be34d1a3b   David Howells   VFS: Make clone_m...
1757
1758
  			if (IS_ERR(q))
  				goto out;
719ea2fbb   Al Viro   new helpers: lock...
1759
  			lock_mount_hash();
1a4eeaf2a   Al Viro   vfs: move mnt_lis...
1760
  			list_add_tail(&q->mnt_list, &res->mnt_list);
1064f874a   Eric W. Biederman   mnt: Tuck mounts ...
1761
  			attach_mnt(q, parent, p->mnt_mp);
719ea2fbb   Al Viro   new helpers: lock...
1762
  			unlock_mount_hash();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1763
1764
1765
  		}
  	}
  	return res;
be34d1a3b   David Howells   VFS: Make clone_m...
1766
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1767
  	if (res) {
719ea2fbb   Al Viro   new helpers: lock...
1768
  		lock_mount_hash();
e819f1521   Eric W. Biederman   mnt: Improve the ...
1769
  		umount_tree(res, UMOUNT_SYNC);
719ea2fbb   Al Viro   new helpers: lock...
1770
  		unlock_mount_hash();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1771
  	}
be34d1a3b   David Howells   VFS: Make clone_m...
1772
  	return q;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1773
  }
be34d1a3b   David Howells   VFS: Make clone_m...
1774
  /* Caller should check returned pointer for errors */
ca71cf71e   Al Viro   namespace.c: cons...
1775
  struct vfsmount *collect_mounts(const struct path *path)
8aec08094   Al Viro   [PATCH] new helpe...
1776
  {
cb338d06e   Al Viro   vfs: spread struc...
1777
  	struct mount *tree;
97216be09   Al Viro   fold release_moun...
1778
  	namespace_lock();
cd4a40174   Eric W. Biederman   mnt: Fail collect...
1779
1780
1781
1782
1783
  	if (!check_mnt(real_mount(path->mnt)))
  		tree = ERR_PTR(-EINVAL);
  	else
  		tree = copy_tree(real_mount(path->mnt), path->dentry,
  				 CL_COPY_ALL | CL_PRIVATE);
328e6d901   Al Viro   switch unlock_mou...
1784
  	namespace_unlock();
be34d1a3b   David Howells   VFS: Make clone_m...
1785
  	if (IS_ERR(tree))
52e220d35   Dan Carpenter   VFS: collect_moun...
1786
  		return ERR_CAST(tree);
be34d1a3b   David Howells   VFS: Make clone_m...
1787
  	return &tree->mnt;
8aec08094   Al Viro   [PATCH] new helpe...
1788
  }
a07b20004   Al Viro   vfs: syscall: Add...
1789
1790
1791
1792
1793
1794
1795
1796
1797
  static void free_mnt_ns(struct mnt_namespace *);
  static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *, bool);
  
  void dissolve_on_fput(struct vfsmount *mnt)
  {
  	struct mnt_namespace *ns;
  	namespace_lock();
  	lock_mount_hash();
  	ns = real_mount(mnt)->mnt_ns;
44dfd84a6   David Howells   teach move_mount(...
1798
1799
1800
1801
1802
1803
  	if (ns) {
  		if (is_anon_ns(ns))
  			umount_tree(real_mount(mnt), UMOUNT_CONNECTED);
  		else
  			ns = NULL;
  	}
a07b20004   Al Viro   vfs: syscall: Add...
1804
1805
  	unlock_mount_hash();
  	namespace_unlock();
44dfd84a6   David Howells   teach move_mount(...
1806
1807
  	if (ns)
  		free_mnt_ns(ns);
a07b20004   Al Viro   vfs: syscall: Add...
1808
  }
8aec08094   Al Viro   [PATCH] new helpe...
1809
1810
  void drop_collected_mounts(struct vfsmount *mnt)
  {
97216be09   Al Viro   fold release_moun...
1811
  	namespace_lock();
719ea2fbb   Al Viro   new helpers: lock...
1812
  	lock_mount_hash();
9c8e0a1b6   Eric W. Biederman   mount: Prevent MN...
1813
  	umount_tree(real_mount(mnt), 0);
719ea2fbb   Al Viro   new helpers: lock...
1814
  	unlock_mount_hash();
3ab6abee5   Al Viro   more conversions ...
1815
  	namespace_unlock();
8aec08094   Al Viro   [PATCH] new helpe...
1816
  }
c771d683a   Miklos Szeredi   vfs: introduce cl...
1817
1818
1819
1820
1821
1822
1823
1824
1825
  /**
   * clone_private_mount - create a private clone of a path
   *
   * This creates a new vfsmount, which will be the clone of @path.  The new will
   * not be attached anywhere in the namespace and will be private (i.e. changes
   * to the originating mount won't be propagated into this).
   *
   * Release with mntput().
   */
ca71cf71e   Al Viro   namespace.c: cons...
1826
  struct vfsmount *clone_private_mount(const struct path *path)
c771d683a   Miklos Szeredi   vfs: introduce cl...
1827
1828
1829
1830
1831
1832
  {
  	struct mount *old_mnt = real_mount(path->mnt);
  	struct mount *new_mnt;
  
  	if (IS_MNT_UNBINDABLE(old_mnt))
  		return ERR_PTR(-EINVAL);
c771d683a   Miklos Szeredi   vfs: introduce cl...
1833
  	new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE);
c771d683a   Miklos Szeredi   vfs: introduce cl...
1834
1835
  	if (IS_ERR(new_mnt))
  		return ERR_CAST(new_mnt);
df820f8de   Miklos Szeredi   ovl: make private...
1836
1837
  	/* Longterm mount to be removed by kern_unmount*() */
  	new_mnt->mnt_ns = MNT_NS_INTERNAL;
c771d683a   Miklos Szeredi   vfs: introduce cl...
1838
1839
1840
  	return &new_mnt->mnt;
  }
  EXPORT_SYMBOL_GPL(clone_private_mount);
1f707137b   Al Viro   new helper: itera...
1841
1842
1843
  int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
  		   struct vfsmount *root)
  {
1a4eeaf2a   Al Viro   vfs: move mnt_lis...
1844
  	struct mount *mnt;
1f707137b   Al Viro   new helper: itera...
1845
1846
1847
  	int res = f(root, arg);
  	if (res)
  		return res;
1a4eeaf2a   Al Viro   vfs: move mnt_lis...
1848
1849
  	list_for_each_entry(mnt, &real_mount(root)->mnt_list, mnt_list) {
  		res = f(&mnt->mnt, arg);
1f707137b   Al Viro   new helper: itera...
1850
1851
1852
1853
1854
  		if (res)
  			return res;
  	}
  	return 0;
  }
3bd045cc9   Al Viro   separate copying ...
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
  static void lock_mnt_tree(struct mount *mnt)
  {
  	struct mount *p;
  
  	for (p = mnt; p; p = next_mnt(p, mnt)) {
  		int flags = p->mnt.mnt_flags;
  		/* Don't allow unprivileged users to change mount flags */
  		flags |= MNT_LOCK_ATIME;
  
  		if (flags & MNT_READONLY)
  			flags |= MNT_LOCK_READONLY;
  
  		if (flags & MNT_NODEV)
  			flags |= MNT_LOCK_NODEV;
  
  		if (flags & MNT_NOSUID)
  			flags |= MNT_LOCK_NOSUID;
  
  		if (flags & MNT_NOEXEC)
  			flags |= MNT_LOCK_NOEXEC;
  		/* Don't allow unprivileged users to reveal what is under a mount */
  		if (list_empty(&p->mnt_expire))
  			flags |= MNT_LOCKED;
  		p->mnt.mnt_flags = flags;
  	}
  }
4b8b21f4f   Al Viro   vfs: spread struc...
1881
  static void cleanup_group_ids(struct mount *mnt, struct mount *end)
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
1882
  {
315fc83e5   Al Viro   vfs: spread struc...
1883
  	struct mount *p;
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
1884

909b0a88e   Al Viro   vfs: spread struc...
1885
  	for (p = mnt; p != end; p = next_mnt(p, mnt)) {
fc7be130c   Al Viro   vfs: switch pnode...
1886
  		if (p->mnt_group_id && !IS_MNT_SHARED(p))
4b8b21f4f   Al Viro   vfs: spread struc...
1887
  			mnt_release_group_id(p);
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
1888
1889
  	}
  }
4b8b21f4f   Al Viro   vfs: spread struc...
1890
  static int invent_group_ids(struct mount *mnt, bool recurse)
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
1891
  {
315fc83e5   Al Viro   vfs: spread struc...
1892
  	struct mount *p;
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
1893

909b0a88e   Al Viro   vfs: spread struc...
1894
  	for (p = mnt; p; p = recurse ? next_mnt(p, mnt) : NULL) {
fc7be130c   Al Viro   vfs: switch pnode...
1895
  		if (!p->mnt_group_id && !IS_MNT_SHARED(p)) {
4b8b21f4f   Al Viro   vfs: spread struc...
1896
  			int err = mnt_alloc_group_id(p);
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
1897
  			if (err) {
4b8b21f4f   Al Viro   vfs: spread struc...
1898
  				cleanup_group_ids(mnt, p);
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
1899
1900
1901
1902
1903
1904
1905
  				return err;
  			}
  		}
  	}
  
  	return 0;
  }
d29216842   Eric W. Biederman   mnt: Add a per mo...
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
  int count_mounts(struct mnt_namespace *ns, struct mount *mnt)
  {
  	unsigned int max = READ_ONCE(sysctl_mount_max);
  	unsigned int mounts = 0, old, pending, sum;
  	struct mount *p;
  
  	for (p = mnt; p; p = next_mnt(p, mnt))
  		mounts++;
  
  	old = ns->mounts;
  	pending = ns->pending_mounts;
  	sum = old + pending;
  	if ((old > sum) ||
  	    (pending > sum) ||
  	    (max < sum) ||
  	    (mounts > (max - sum)))
  		return -ENOSPC;
  
  	ns->pending_mounts = pending + mounts;
  	return 0;
  }
b90fa9ae8   Ram Pai   [PATCH] shared mo...
1927
1928
  /*
   *  @source_mnt : mount tree to be attached
214444032   Ram Pai   [PATCH] shared mo...
1929
1930
1931
1932
   *  @nd         : place the mount tree @source_mnt is attached
   *  @parent_nd  : if non-null, detach the source_mnt from its parent and
   *  		   store the parent mount and mountpoint dentry.
   *  		   (done when source_mnt is moved)
b90fa9ae8   Ram Pai   [PATCH] shared mo...
1933
1934
1935
   *
   *  NOTE: in the table below explains the semantics when a source mount
   *  of a given type is attached to a destination mount of a given type.
9676f0c63   Ram Pai   [PATCH] unbindabl...
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
   * ---------------------------------------------------------------------------
   * |         BIND MOUNT OPERATION                                            |
   * |**************************************************************************
   * | source-->| shared        |       private  |       slave    | unbindable |
   * | dest     |               |                |                |            |
   * |   |      |               |                |                |            |
   * |   v      |               |                |                |            |
   * |**************************************************************************
   * |  shared  | shared (++)   |     shared (+) |     shared(+++)|  invalid   |
   * |          |               |                |                |            |
   * |non-shared| shared (+)    |      private   |      slave (*) |  invalid   |
   * ***************************************************************************
b90fa9ae8   Ram Pai   [PATCH] shared mo...
1948
1949
1950
1951
1952
1953
1954
1955
1956
   * A bind operation clones the source mount and mounts the clone on the
   * destination mount.
   *
   * (++)  the cloned mount is propagated to all the mounts in the propagation
   * 	 tree of the destination mount and the cloned mount is added to
   * 	 the peer group of the source mount.
   * (+)   the cloned mount is created under the destination mount and is marked
   *       as shared. The cloned mount is added to the peer group of the source
   *       mount.
5afe00221   Ram Pai   [PATCH] handling ...
1957
1958
1959
1960
1961
1962
1963
   * (+++) the mount is propagated to all the mounts in the propagation tree
   *       of the destination mount and the cloned mount is made slave
   *       of the same master as that of the source mount. The cloned mount
   *       is marked as 'shared and slave'.
   * (*)   the cloned mount is made a slave of the same master as that of the
   * 	 source mount.
   *
9676f0c63   Ram Pai   [PATCH] unbindabl...
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
   * ---------------------------------------------------------------------------
   * |         		MOVE MOUNT OPERATION                                 |
   * |**************************************************************************
   * | source-->| shared        |       private  |       slave    | unbindable |
   * | dest     |               |                |                |            |
   * |   |      |               |                |                |            |
   * |   v      |               |                |                |            |
   * |**************************************************************************
   * |  shared  | shared (+)    |     shared (+) |    shared(+++) |  invalid   |
   * |          |               |                |                |            |
   * |non-shared| shared (+*)   |      private   |    slave (*)   | unbindable |
   * ***************************************************************************
5afe00221   Ram Pai   [PATCH] handling ...
1976
1977
1978
   *
   * (+)  the mount is moved to the destination. And is then propagated to
   * 	all the mounts in the propagation tree of the destination mount.
214444032   Ram Pai   [PATCH] shared mo...
1979
   * (+*)  the mount is moved to the destination.
5afe00221   Ram Pai   [PATCH] handling ...
1980
1981
1982
1983
   * (+++)  the mount is moved to the destination and is then propagated to
   * 	all the mounts belonging to the destination mount's propagation tree.
   * 	the mount is marked as 'shared and slave'.
   * (*)	the mount continues to be a slave at the new location.
b90fa9ae8   Ram Pai   [PATCH] shared mo...
1984
1985
1986
1987
1988
1989
   *
   * if the source mount is a tree, the operations explained above is
   * applied to each mount in the tree.
   * Must be called without spinlocks held, since this function can sleep
   * in allocations.
   */
0fb54e505   Al Viro   vfs: spread struc...
1990
  static int attach_recursive_mnt(struct mount *source_mnt,
84d17192d   Al Viro   get rid of full-h...
1991
1992
  			struct mount *dest_mnt,
  			struct mountpoint *dest_mp,
2763d1191   Al Viro   get rid of detach...
1993
  			bool moving)
b90fa9ae8   Ram Pai   [PATCH] shared mo...
1994
  {
3bd045cc9   Al Viro   separate copying ...
1995
  	struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns;
38129a13e   Al Viro   switch mnt_hash t...
1996
  	HLIST_HEAD(tree_list);
d29216842   Eric W. Biederman   mnt: Add a per mo...
1997
  	struct mnt_namespace *ns = dest_mnt->mnt_ns;
1064f874a   Eric W. Biederman   mnt: Tuck mounts ...
1998
  	struct mountpoint *smp;
315fc83e5   Al Viro   vfs: spread struc...
1999
  	struct mount *child, *p;
38129a13e   Al Viro   switch mnt_hash t...
2000
  	struct hlist_node *n;
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
2001
  	int err;
b90fa9ae8   Ram Pai   [PATCH] shared mo...
2002

1064f874a   Eric W. Biederman   mnt: Tuck mounts ...
2003
2004
2005
2006
2007
2008
  	/* Preallocate a mountpoint in case the new mounts need
  	 * to be tucked under other mounts.
  	 */
  	smp = get_mountpoint(source_mnt->mnt.mnt_root);
  	if (IS_ERR(smp))
  		return PTR_ERR(smp);
d29216842   Eric W. Biederman   mnt: Add a per mo...
2009
  	/* Is there space to add these mounts to the mount namespace? */
2763d1191   Al Viro   get rid of detach...
2010
  	if (!moving) {
d29216842   Eric W. Biederman   mnt: Add a per mo...
2011
2012
2013
2014
  		err = count_mounts(ns, source_mnt);
  		if (err)
  			goto out;
  	}
fc7be130c   Al Viro   vfs: switch pnode...
2015
  	if (IS_MNT_SHARED(dest_mnt)) {
0fb54e505   Al Viro   vfs: spread struc...
2016
  		err = invent_group_ids(source_mnt, true);
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
2017
2018
  		if (err)
  			goto out;
0b1b901b5   Al Viro   don't bother with...
2019
  		err = propagate_mnt(dest_mnt, dest_mp, source_mnt, &tree_list);
f2ebb3a92   Al Viro   smarter propagate...
2020
  		lock_mount_hash();
0b1b901b5   Al Viro   don't bother with...
2021
2022
  		if (err)
  			goto out_cleanup_ids;
909b0a88e   Al Viro   vfs: spread struc...
2023
  		for (p = source_mnt; p; p = next_mnt(p, source_mnt))
0f0afb1dc   Al Viro   vfs: spread struc...
2024
  			set_mnt_shared(p);
0b1b901b5   Al Viro   don't bother with...
2025
2026
  	} else {
  		lock_mount_hash();
b90fa9ae8   Ram Pai   [PATCH] shared mo...
2027
  	}
2763d1191   Al Viro   get rid of detach...
2028
2029
  	if (moving) {
  		unhash_mnt(source_mnt);
84d17192d   Al Viro   get rid of full-h...
2030
  		attach_mnt(source_mnt, dest_mnt, dest_mp);
143c8c91c   Al Viro   vfs: mnt_ns moved...
2031
  		touch_mnt_namespace(source_mnt->mnt_ns);
214444032   Ram Pai   [PATCH] shared mo...
2032
  	} else {
44dfd84a6   David Howells   teach move_mount(...
2033
2034
2035
2036
  		if (source_mnt->mnt_ns) {
  			/* move from anon - the caller will destroy */
  			list_del_init(&source_mnt->mnt_ns->list);
  		}
84d17192d   Al Viro   get rid of full-h...
2037
  		mnt_set_mountpoint(dest_mnt, dest_mp, source_mnt);
1064f874a   Eric W. Biederman   mnt: Tuck mounts ...
2038
  		commit_tree(source_mnt);
214444032   Ram Pai   [PATCH] shared mo...
2039
  	}
b90fa9ae8   Ram Pai   [PATCH] shared mo...
2040

38129a13e   Al Viro   switch mnt_hash t...
2041
  	hlist_for_each_entry_safe(child, n, &tree_list, mnt_hash) {
1d6a32acd   Al Viro   keep shadowed vfs...
2042
  		struct mount *q;
38129a13e   Al Viro   switch mnt_hash t...
2043
  		hlist_del_init(&child->mnt_hash);
1064f874a   Eric W. Biederman   mnt: Tuck mounts ...
2044
2045
2046
2047
  		q = __lookup_mnt(&child->mnt_parent->mnt,
  				 child->mnt_mountpoint);
  		if (q)
  			mnt_change_mountpoint(child, smp, q);
3bd045cc9   Al Viro   separate copying ...
2048
2049
2050
  		/* Notice when we are propagating across user namespaces */
  		if (child->mnt_parent->mnt_ns->user_ns != user_ns)
  			lock_mnt_tree(child);
d728cf791   Christian Brauner   fs/namespace: fix...
2051
  		child->mnt.mnt_flags &= ~MNT_LOCKED;
1064f874a   Eric W. Biederman   mnt: Tuck mounts ...
2052
  		commit_tree(child);
b90fa9ae8   Ram Pai   [PATCH] shared mo...
2053
  	}
1064f874a   Eric W. Biederman   mnt: Tuck mounts ...
2054
  	put_mountpoint(smp);
719ea2fbb   Al Viro   new helpers: lock...
2055
  	unlock_mount_hash();
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
2056

b90fa9ae8   Ram Pai   [PATCH] shared mo...
2057
  	return 0;
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
2058
2059
  
   out_cleanup_ids:
f2ebb3a92   Al Viro   smarter propagate...
2060
2061
  	while (!hlist_empty(&tree_list)) {
  		child = hlist_entry(tree_list.first, struct mount, mnt_hash);
d29216842   Eric W. Biederman   mnt: Add a per mo...
2062
  		child->mnt_parent->mnt_ns->pending_mounts = 0;
e819f1521   Eric W. Biederman   mnt: Improve the ...
2063
  		umount_tree(child, UMOUNT_SYNC);
f2ebb3a92   Al Viro   smarter propagate...
2064
2065
  	}
  	unlock_mount_hash();
0b1b901b5   Al Viro   don't bother with...
2066
  	cleanup_group_ids(source_mnt, NULL);
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
2067
   out:
d29216842   Eric W. Biederman   mnt: Add a per mo...
2068
  	ns->pending_mounts = 0;
1064f874a   Eric W. Biederman   mnt: Tuck mounts ...
2069
2070
2071
2072
  
  	read_seqlock_excl(&mount_lock);
  	put_mountpoint(smp);
  	read_sequnlock_excl(&mount_lock);
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
2073
  	return err;
b90fa9ae8   Ram Pai   [PATCH] shared mo...
2074
  }
84d17192d   Al Viro   get rid of full-h...
2075
  static struct mountpoint *lock_mount(struct path *path)
b12cea919   Al Viro   change the lockin...
2076
2077
  {
  	struct vfsmount *mnt;
84d17192d   Al Viro   get rid of full-h...
2078
  	struct dentry *dentry = path->dentry;
b12cea919   Al Viro   change the lockin...
2079
  retry:
5955102c9   Al Viro   wrappers for ->i_...
2080
  	inode_lock(dentry->d_inode);
84d17192d   Al Viro   get rid of full-h...
2081
  	if (unlikely(cant_mount(dentry))) {
5955102c9   Al Viro   wrappers for ->i_...
2082
  		inode_unlock(dentry->d_inode);
84d17192d   Al Viro   get rid of full-h...
2083
  		return ERR_PTR(-ENOENT);
b12cea919   Al Viro   change the lockin...
2084
  	}
97216be09   Al Viro   fold release_moun...
2085
  	namespace_lock();
b12cea919   Al Viro   change the lockin...
2086
  	mnt = lookup_mnt(path);
84d17192d   Al Viro   get rid of full-h...
2087
  	if (likely(!mnt)) {
3895dbf89   Eric W. Biederman   mnt: Protect the ...
2088
  		struct mountpoint *mp = get_mountpoint(dentry);
84d17192d   Al Viro   get rid of full-h...
2089
  		if (IS_ERR(mp)) {
97216be09   Al Viro   fold release_moun...
2090
  			namespace_unlock();
5955102c9   Al Viro   wrappers for ->i_...
2091
  			inode_unlock(dentry->d_inode);
84d17192d   Al Viro   get rid of full-h...
2092
2093
2094
2095
  			return mp;
  		}
  		return mp;
  	}
97216be09   Al Viro   fold release_moun...
2096
  	namespace_unlock();
5955102c9   Al Viro   wrappers for ->i_...
2097
  	inode_unlock(path->dentry->d_inode);
b12cea919   Al Viro   change the lockin...
2098
2099
  	path_put(path);
  	path->mnt = mnt;
84d17192d   Al Viro   get rid of full-h...
2100
  	dentry = path->dentry = dget(mnt->mnt_root);
b12cea919   Al Viro   change the lockin...
2101
2102
  	goto retry;
  }
84d17192d   Al Viro   get rid of full-h...
2103
  static void unlock_mount(struct mountpoint *where)
b12cea919   Al Viro   change the lockin...
2104
  {
84d17192d   Al Viro   get rid of full-h...
2105
  	struct dentry *dentry = where->m_dentry;
3895dbf89   Eric W. Biederman   mnt: Protect the ...
2106
2107
  
  	read_seqlock_excl(&mount_lock);
84d17192d   Al Viro   get rid of full-h...
2108
  	put_mountpoint(where);
3895dbf89   Eric W. Biederman   mnt: Protect the ...
2109
  	read_sequnlock_excl(&mount_lock);
328e6d901   Al Viro   switch unlock_mou...
2110
  	namespace_unlock();
5955102c9   Al Viro   wrappers for ->i_...
2111
  	inode_unlock(dentry->d_inode);
b12cea919   Al Viro   change the lockin...
2112
  }
84d17192d   Al Viro   get rid of full-h...
2113
  static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2114
  {
e462ec50c   David Howells   VFS: Differentiat...
2115
  	if (mnt->mnt.mnt_sb->s_flags & SB_NOUSER)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2116
  		return -EINVAL;
e36cb0b89   David Howells   VFS: (Scripted) C...
2117
2118
  	if (d_is_dir(mp->m_dentry) !=
  	      d_is_dir(mnt->mnt.mnt_root))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2119
  		return -ENOTDIR;
2763d1191   Al Viro   get rid of detach...
2120
  	return attach_recursive_mnt(mnt, p, mp, false);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2121
2122
2123
  }
  
  /*
7a2e8a8fa   Valerie Aurora   VFS: Sanity check...
2124
2125
   * Sanity check the flags to change_mnt_propagation.
   */
e462ec50c   David Howells   VFS: Differentiat...
2126
  static int flags_to_propagation_type(int ms_flags)
7a2e8a8fa   Valerie Aurora   VFS: Sanity check...
2127
  {
e462ec50c   David Howells   VFS: Differentiat...
2128
  	int type = ms_flags & ~(MS_REC | MS_SILENT);
7a2e8a8fa   Valerie Aurora   VFS: Sanity check...
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
  
  	/* Fail if any non-propagation flags are set */
  	if (type & ~(MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
  		return 0;
  	/* Only one propagation flag should be set */
  	if (!is_power_of_2(type))
  		return 0;
  	return type;
  }
  
  /*
07b20889e   Ram Pai   [PATCH] beginning...
2140
2141
   * recursively change the type of the mountpoint.
   */
e462ec50c   David Howells   VFS: Differentiat...
2142
  static int do_change_type(struct path *path, int ms_flags)
07b20889e   Ram Pai   [PATCH] beginning...
2143
  {
315fc83e5   Al Viro   vfs: spread struc...
2144
  	struct mount *m;
4b8b21f4f   Al Viro   vfs: spread struc...
2145
  	struct mount *mnt = real_mount(path->mnt);
e462ec50c   David Howells   VFS: Differentiat...
2146
  	int recurse = ms_flags & MS_REC;
7a2e8a8fa   Valerie Aurora   VFS: Sanity check...
2147
  	int type;
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
2148
  	int err = 0;
07b20889e   Ram Pai   [PATCH] beginning...
2149

2d92ab3c6   Al Viro   [PATCH] finally g...
2150
  	if (path->dentry != path->mnt->mnt_root)
07b20889e   Ram Pai   [PATCH] beginning...
2151
  		return -EINVAL;
e462ec50c   David Howells   VFS: Differentiat...
2152
  	type = flags_to_propagation_type(ms_flags);
7a2e8a8fa   Valerie Aurora   VFS: Sanity check...
2153
2154
  	if (!type)
  		return -EINVAL;
97216be09   Al Viro   fold release_moun...
2155
  	namespace_lock();
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
2156
2157
2158
2159
2160
  	if (type == MS_SHARED) {
  		err = invent_group_ids(mnt, recurse);
  		if (err)
  			goto out_unlock;
  	}
719ea2fbb   Al Viro   new helpers: lock...
2161
  	lock_mount_hash();
909b0a88e   Al Viro   vfs: spread struc...
2162
  	for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL))
0f0afb1dc   Al Viro   vfs: spread struc...
2163
  		change_mnt_propagation(m, type);
719ea2fbb   Al Viro   new helpers: lock...
2164
  	unlock_mount_hash();
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
2165
2166
  
   out_unlock:
97216be09   Al Viro   fold release_moun...
2167
  	namespace_unlock();
719f5d7f0   Miklos Szeredi   [patch 4/7] vfs: ...
2168
  	return err;
07b20889e   Ram Pai   [PATCH] beginning...
2169
  }
5ff9d8a65   Eric W. Biederman   vfs: Lock in plac...
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
  static bool has_locked_children(struct mount *mnt, struct dentry *dentry)
  {
  	struct mount *child;
  	list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
  		if (!is_subdir(child->mnt_mountpoint, dentry))
  			continue;
  
  		if (child->mnt.mnt_flags & MNT_LOCKED)
  			return true;
  	}
  	return false;
  }
a07b20004   Al Viro   vfs: syscall: Add...
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
  static struct mount *__do_loopback(struct path *old_path, int recurse)
  {
  	struct mount *mnt = ERR_PTR(-EINVAL), *old = real_mount(old_path->mnt);
  
  	if (IS_MNT_UNBINDABLE(old))
  		return mnt;
  
  	if (!check_mnt(old) && old_path->dentry->d_op != &ns_dentry_operations)
  		return mnt;
  
  	if (!recurse && has_locked_children(old, old_path->dentry))
  		return mnt;
  
  	if (recurse)
  		mnt = copy_tree(old, old_path->dentry, CL_COPY_MNT_NS_FILE);
  	else
  		mnt = clone_mnt(old, old_path->dentry, 0);
  
  	if (!IS_ERR(mnt))
  		mnt->mnt.mnt_flags &= ~MNT_LOCKED;
  
  	return mnt;
  }
07b20889e   Ram Pai   [PATCH] beginning...
2205
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2206
2207
   * do loopback mount.
   */
808d4e3cf   Al Viro   consitify do_moun...
2208
  static int do_loopback(struct path *path, const char *old_name,
2dafe1c4d   Eric Sandeen   reduce large do_m...
2209
  				int recurse)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2210
  {
2d92ab3c6   Al Viro   [PATCH] finally g...
2211
  	struct path old_path;
a07b20004   Al Viro   vfs: syscall: Add...
2212
  	struct mount *mnt = NULL, *parent;
84d17192d   Al Viro   get rid of full-h...
2213
  	struct mountpoint *mp;
57eccb830   Al Viro   mount: consolidat...
2214
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2215
2216
  	if (!old_name || !*old_name)
  		return -EINVAL;
815d405ce   Trond Myklebust   VFS: Fix the rema...
2217
  	err = kern_path(old_name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &old_path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2218
2219
  	if (err)
  		return err;
8823c079b   Eric W. Biederman   vfs: Add setns su...
2220
  	err = -EINVAL;
4ce5d2b1a   Eric W. Biederman   vfs: Don't copy m...
2221
  	if (mnt_ns_loop(old_path.dentry))
dd111b31e   David Howells   VFS: Clean up whi...
2222
  		goto out;
8823c079b   Eric W. Biederman   vfs: Add setns su...
2223

84d17192d   Al Viro   get rid of full-h...
2224
  	mp = lock_mount(path);
a07b20004   Al Viro   vfs: syscall: Add...
2225
2226
  	if (IS_ERR(mp)) {
  		err = PTR_ERR(mp);
b12cea919   Al Viro   change the lockin...
2227
  		goto out;
a07b20004   Al Viro   vfs: syscall: Add...
2228
  	}
b12cea919   Al Viro   change the lockin...
2229

84d17192d   Al Viro   get rid of full-h...
2230
  	parent = real_mount(path->mnt);
e149ed2b8   Al Viro   take the targets ...
2231
2232
  	if (!check_mnt(parent))
  		goto out2;
a07b20004   Al Viro   vfs: syscall: Add...
2233
  	mnt = __do_loopback(&old_path, recurse);
be34d1a3b   David Howells   VFS: Make clone_m...
2234
2235
  	if (IS_ERR(mnt)) {
  		err = PTR_ERR(mnt);
e9c5d8a56   Andrey Vagin   mnt: release lock...
2236
  		goto out2;
be34d1a3b   David Howells   VFS: Make clone_m...
2237
  	}
ccd48bc7f   Al Viro   [PATCH] cleanups ...
2238

84d17192d   Al Viro   get rid of full-h...
2239
  	err = graft_tree(mnt, parent, mp);
ccd48bc7f   Al Viro   [PATCH] cleanups ...
2240
  	if (err) {
719ea2fbb   Al Viro   new helpers: lock...
2241
  		lock_mount_hash();
e819f1521   Eric W. Biederman   mnt: Improve the ...
2242
  		umount_tree(mnt, UMOUNT_SYNC);
719ea2fbb   Al Viro   new helpers: lock...
2243
  		unlock_mount_hash();
5b83d2c5c   Ram Pai   [PATCH] sanitize ...
2244
  	}
b12cea919   Al Viro   change the lockin...
2245
  out2:
84d17192d   Al Viro   get rid of full-h...
2246
  	unlock_mount(mp);
ccd48bc7f   Al Viro   [PATCH] cleanups ...
2247
  out:
2d92ab3c6   Al Viro   [PATCH] finally g...
2248
  	path_put(&old_path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2249
2250
  	return err;
  }
a07b20004   Al Viro   vfs: syscall: Add...
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
  static struct file *open_detached_copy(struct path *path, bool recursive)
  {
  	struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns;
  	struct mnt_namespace *ns = alloc_mnt_ns(user_ns, true);
  	struct mount *mnt, *p;
  	struct file *file;
  
  	if (IS_ERR(ns))
  		return ERR_CAST(ns);
  
  	namespace_lock();
  	mnt = __do_loopback(path, recursive);
  	if (IS_ERR(mnt)) {
  		namespace_unlock();
  		free_mnt_ns(ns);
  		return ERR_CAST(mnt);
  	}
  
  	lock_mount_hash();
  	for (p = mnt; p; p = next_mnt(p, mnt)) {
  		p->mnt_ns = ns;
  		ns->mounts++;
  	}
  	ns->root = mnt;
  	list_add_tail(&ns->list, &mnt->mnt_list);
  	mntget(&mnt->mnt);
  	unlock_mount_hash();
  	namespace_unlock();
  
  	mntput(path->mnt);
  	path->mnt = &mnt->mnt;
  	file = dentry_open(path, O_PATH, current_cred());
  	if (IS_ERR(file))
  		dissolve_on_fput(path->mnt);
  	else
  		file->f_mode |= FMODE_NEED_UNMOUNT;
  	return file;
  }
2658ce095   Ben Dooks   fs/namespace: add...
2289
  SYSCALL_DEFINE3(open_tree, int, dfd, const char __user *, filename, unsigned, flags)
a07b20004   Al Viro   vfs: syscall: Add...
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
  {
  	struct file *file;
  	struct path path;
  	int lookup_flags = LOOKUP_AUTOMOUNT | LOOKUP_FOLLOW;
  	bool detached = flags & OPEN_TREE_CLONE;
  	int error;
  	int fd;
  
  	BUILD_BUG_ON(OPEN_TREE_CLOEXEC != O_CLOEXEC);
  
  	if (flags & ~(AT_EMPTY_PATH | AT_NO_AUTOMOUNT | AT_RECURSIVE |
  		      AT_SYMLINK_NOFOLLOW | OPEN_TREE_CLONE |
  		      OPEN_TREE_CLOEXEC))
  		return -EINVAL;
  
  	if ((flags & (AT_RECURSIVE | OPEN_TREE_CLONE)) == AT_RECURSIVE)
  		return -EINVAL;
  
  	if (flags & AT_NO_AUTOMOUNT)
  		lookup_flags &= ~LOOKUP_AUTOMOUNT;
  	if (flags & AT_SYMLINK_NOFOLLOW)
  		lookup_flags &= ~LOOKUP_FOLLOW;
  	if (flags & AT_EMPTY_PATH)
  		lookup_flags |= LOOKUP_EMPTY;
  
  	if (detached && !may_mount())
  		return -EPERM;
  
  	fd = get_unused_fd_flags(flags & O_CLOEXEC);
  	if (fd < 0)
  		return fd;
  
  	error = user_path_at(dfd, filename, lookup_flags, &path);
  	if (unlikely(error)) {
  		file = ERR_PTR(error);
  	} else {
  		if (detached)
  			file = open_detached_copy(&path, flags & AT_RECURSIVE);
  		else
  			file = dentry_open(&path, O_PATH, current_cred());
  		path_put(&path);
  	}
  	if (IS_ERR(file)) {
  		put_unused_fd(fd);
  		return PTR_ERR(file);
  	}
  	fd_install(fd, file);
  	return fd;
  }
43f5e655e   David Howells   vfs: Separate cha...
2339
2340
2341
2342
2343
2344
2345
  /*
   * Don't allow locked mount flags to be cleared.
   *
   * No locks need to be held here while testing the various MNT_LOCK
   * flags because those flags can never be cleared once they are set.
   */
  static bool can_change_locked_flags(struct mount *mnt, unsigned int mnt_flags)
2e4b7fcd9   Dave Hansen   [PATCH] r/o bind ...
2346
  {
43f5e655e   David Howells   vfs: Separate cha...
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
  	unsigned int fl = mnt->mnt.mnt_flags;
  
  	if ((fl & MNT_LOCK_READONLY) &&
  	    !(mnt_flags & MNT_READONLY))
  		return false;
  
  	if ((fl & MNT_LOCK_NODEV) &&
  	    !(mnt_flags & MNT_NODEV))
  		return false;
  
  	if ((fl & MNT_LOCK_NOSUID) &&
  	    !(mnt_flags & MNT_NOSUID))
  		return false;
  
  	if ((fl & MNT_LOCK_NOEXEC) &&
  	    !(mnt_flags & MNT_NOEXEC))
  		return false;
  
  	if ((fl & MNT_LOCK_ATIME) &&
  	    ((fl & MNT_ATIME_MASK) != (mnt_flags & MNT_ATIME_MASK)))
  		return false;
2e4b7fcd9   Dave Hansen   [PATCH] r/o bind ...
2368

43f5e655e   David Howells   vfs: Separate cha...
2369
2370
2371
2372
  	return true;
  }
  
  static int change_mount_ro_state(struct mount *mnt, unsigned int mnt_flags)
2e4b7fcd9   Dave Hansen   [PATCH] r/o bind ...
2373
  {
43f5e655e   David Howells   vfs: Separate cha...
2374
  	bool readonly_request = (mnt_flags & MNT_READONLY);
2e4b7fcd9   Dave Hansen   [PATCH] r/o bind ...
2375

43f5e655e   David Howells   vfs: Separate cha...
2376
  	if (readonly_request == __mnt_is_readonly(&mnt->mnt))
2e4b7fcd9   Dave Hansen   [PATCH] r/o bind ...
2377
2378
2379
  		return 0;
  
  	if (readonly_request)
43f5e655e   David Howells   vfs: Separate cha...
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
  		return mnt_make_readonly(mnt);
  
  	return __mnt_unmake_readonly(mnt);
  }
  
  /*
   * Update the user-settable attributes on a mount.  The caller must hold
   * sb->s_umount for writing.
   */
  static void set_mount_attributes(struct mount *mnt, unsigned int mnt_flags)
  {
  	lock_mount_hash();
  	mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK;
  	mnt->mnt.mnt_flags = mnt_flags;
  	touch_mnt_namespace(mnt->mnt_ns);
  	unlock_mount_hash();
  }
f8b92ba67   Deepa Dinamani   mount: Add mount ...
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
  static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *mnt)
  {
  	struct super_block *sb = mnt->mnt_sb;
  
  	if (!__mnt_is_readonly(mnt) &&
  	   (ktime_get_real_seconds() + TIME_UPTIME_SEC_MAX > sb->s_time_max)) {
  		char *buf = (char *)__get_free_page(GFP_KERNEL);
  		char *mntpath = buf ? d_path(mountpoint, buf, PAGE_SIZE) : ERR_PTR(-ENOMEM);
  		struct tm tm;
  
  		time64_to_tm(sb->s_time_max, 0, &tm);
0ecee6699   Eric Biggers   fs/namespace.c: f...
2408
2409
2410
2411
2412
  		pr_warn("%s filesystem being %s at %s supports timestamps until %04ld (0x%llx)
  ",
  			sb->s_type->name,
  			is_mounted(mnt) ? "remounted" : "mounted",
  			mntpath,
f8b92ba67   Deepa Dinamani   mount: Add mount ...
2413
2414
2415
2416
2417
  			tm.tm_year+1900, (unsigned long long)sb->s_time_max);
  
  		free_page((unsigned long)buf);
  	}
  }
43f5e655e   David Howells   vfs: Separate cha...
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
  /*
   * Handle reconfiguration of the mountpoint only without alteration of the
   * superblock it refers to.  This is triggered by specifying MS_REMOUNT|MS_BIND
   * to mount(2).
   */
  static int do_reconfigure_mnt(struct path *path, unsigned int mnt_flags)
  {
  	struct super_block *sb = path->mnt->mnt_sb;
  	struct mount *mnt = real_mount(path->mnt);
  	int ret;
  
  	if (!check_mnt(mnt))
  		return -EINVAL;
  
  	if (path->dentry != mnt->mnt.mnt_root)
  		return -EINVAL;
  
  	if (!can_change_locked_flags(mnt, mnt_flags))
  		return -EPERM;
  
  	down_write(&sb->s_umount);
  	ret = change_mount_ro_state(mnt, mnt_flags);
  	if (ret == 0)
  		set_mount_attributes(mnt, mnt_flags);
  	up_write(&sb->s_umount);
f8b92ba67   Deepa Dinamani   mount: Add mount ...
2443
2444
  
  	mnt_warn_timestamp_expiry(path, &mnt->mnt);
43f5e655e   David Howells   vfs: Separate cha...
2445
  	return ret;
2e4b7fcd9   Dave Hansen   [PATCH] r/o bind ...
2446
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2447
2448
2449
2450
2451
  /*
   * change filesystem flags. dir should be a physical root of filesystem.
   * If you've mounted a non-root directory somewhere and want to do remount
   * on it - tough luck.
   */
e462ec50c   David Howells   VFS: Differentiat...
2452
2453
  static int do_remount(struct path *path, int ms_flags, int sb_flags,
  		      int mnt_flags, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2454
2455
  {
  	int err;
2d92ab3c6   Al Viro   [PATCH] finally g...
2456
  	struct super_block *sb = path->mnt->mnt_sb;
143c8c91c   Al Viro   vfs: mnt_ns moved...
2457
  	struct mount *mnt = real_mount(path->mnt);
8d0347f6c   David Howells   convert do_remoun...
2458
  	struct fs_context *fc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2459

143c8c91c   Al Viro   vfs: mnt_ns moved...
2460
  	if (!check_mnt(mnt))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2461
  		return -EINVAL;
2d92ab3c6   Al Viro   [PATCH] finally g...
2462
  	if (path->dentry != path->mnt->mnt_root)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2463
  		return -EINVAL;
43f5e655e   David Howells   vfs: Separate cha...
2464
  	if (!can_change_locked_flags(mnt, mnt_flags))
9566d6742   Eric W. Biederman   mnt: Correct perm...
2465
  		return -EPERM;
9566d6742   Eric W. Biederman   mnt: Correct perm...
2466

8d0347f6c   David Howells   convert do_remoun...
2467
2468
2469
  	fc = fs_context_for_reconfigure(path->dentry, sb_flags, MS_RMT_MASK);
  	if (IS_ERR(fc))
  		return PTR_ERR(fc);
ff36fe2c8   Eric Paris   LSM: Pass -o remo...
2470

b330966f7   Miklos Szeredi   fuse: reject opti...
2471
  	fc->oldapi = true;
8d0347f6c   David Howells   convert do_remoun...
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
  	err = parse_monolithic_mount_data(fc, data);
  	if (!err) {
  		down_write(&sb->s_umount);
  		err = -EPERM;
  		if (ns_capable(sb->s_user_ns, CAP_SYS_ADMIN)) {
  			err = reconfigure_super(fc);
  			if (!err)
  				set_mount_attributes(mnt, mnt_flags);
  		}
  		up_write(&sb->s_umount);
0e55a7cca   Dan Williams   [RFC PATCH] touch...
2482
  	}
f8b92ba67   Deepa Dinamani   mount: Add mount ...
2483
2484
  
  	mnt_warn_timestamp_expiry(path, &mnt->mnt);
8d0347f6c   David Howells   convert do_remoun...
2485
  	put_fs_context(fc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2486
2487
  	return err;
  }
cbbe362cd   Al Viro   vfs: spread struc...
2488
  static inline int tree_contains_unbindable(struct mount *mnt)
9676f0c63   Ram Pai   [PATCH] unbindabl...
2489
  {
315fc83e5   Al Viro   vfs: spread struc...
2490
  	struct mount *p;
909b0a88e   Al Viro   vfs: spread struc...
2491
  	for (p = mnt; p; p = next_mnt(p, mnt)) {
fc7be130c   Al Viro   vfs: switch pnode...
2492
  		if (IS_MNT_UNBINDABLE(p))
9676f0c63   Ram Pai   [PATCH] unbindabl...
2493
2494
2495
2496
  			return 1;
  	}
  	return 0;
  }
44dfd84a6   David Howells   teach move_mount(...
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
  /*
   * Check that there aren't references to earlier/same mount namespaces in the
   * specified subtree.  Such references can act as pins for mount namespaces
   * that aren't checked by the mount-cycle checking code, thereby allowing
   * cycles to be made.
   */
  static bool check_for_nsfs_mounts(struct mount *subtree)
  {
  	struct mount *p;
  	bool ret = false;
  
  	lock_mount_hash();
  	for (p = subtree; p; p = next_mnt(p, subtree))
  		if (mnt_ns_loop(p->mnt.mnt_root))
  			goto out;
  
  	ret = true;
  out:
  	unlock_mount_hash();
  	return ret;
  }
2db154b3e   David Howells   vfs: syscall: Add...
2518
  static int do_move_mount(struct path *old_path, struct path *new_path)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2519
  {
44dfd84a6   David Howells   teach move_mount(...
2520
  	struct mnt_namespace *ns;
676da58df   Al Viro   vfs: spread struc...
2521
  	struct mount *p;
0fb54e505   Al Viro   vfs: spread struc...
2522
  	struct mount *old;
2763d1191   Al Viro   get rid of detach...
2523
2524
  	struct mount *parent;
  	struct mountpoint *mp, *old_mp;
57eccb830   Al Viro   mount: consolidat...
2525
  	int err;
44dfd84a6   David Howells   teach move_mount(...
2526
  	bool attached;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2527

2db154b3e   David Howells   vfs: syscall: Add...
2528
  	mp = lock_mount(new_path);
84d17192d   Al Viro   get rid of full-h...
2529
  	if (IS_ERR(mp))
2db154b3e   David Howells   vfs: syscall: Add...
2530
  		return PTR_ERR(mp);
cc53ce53c   David Howells   Add a dentry op t...
2531

2db154b3e   David Howells   vfs: syscall: Add...
2532
2533
  	old = real_mount(old_path->mnt);
  	p = real_mount(new_path->mnt);
2763d1191   Al Viro   get rid of detach...
2534
  	parent = old->mnt_parent;
44dfd84a6   David Howells   teach move_mount(...
2535
  	attached = mnt_has_parent(old);
2763d1191   Al Viro   get rid of detach...
2536
  	old_mp = old->mnt_mp;
44dfd84a6   David Howells   teach move_mount(...
2537
  	ns = old->mnt_ns;
143c8c91c   Al Viro   vfs: mnt_ns moved...
2538

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2539
  	err = -EINVAL;
44dfd84a6   David Howells   teach move_mount(...
2540
2541
  	/* The mountpoint must be in our namespace. */
  	if (!check_mnt(p))
2db154b3e   David Howells   vfs: syscall: Add...
2542
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2543

570d7a98e   Eric Biggers   vfs: move_mount: ...
2544
2545
  	/* The thing moved must be mounted... */
  	if (!is_mounted(&old->mnt))
44dfd84a6   David Howells   teach move_mount(...
2546
  		goto out;
570d7a98e   Eric Biggers   vfs: move_mount: ...
2547
2548
  	/* ... and either ours or the root of anon namespace */
  	if (!(attached ? check_mnt(old) : is_anon_ns(ns)))
2db154b3e   David Howells   vfs: syscall: Add...
2549
  		goto out;
5ff9d8a65   Eric W. Biederman   vfs: Lock in plac...
2550

2db154b3e   David Howells   vfs: syscall: Add...
2551
2552
  	if (old->mnt.mnt_flags & MNT_LOCKED)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2553

2db154b3e   David Howells   vfs: syscall: Add...
2554
2555
  	if (old_path->dentry != old_path->mnt->mnt_root)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2556

2db154b3e   David Howells   vfs: syscall: Add...
2557
2558
2559
  	if (d_is_dir(new_path->dentry) !=
  	    d_is_dir(old_path->dentry))
  		goto out;
214444032   Ram Pai   [PATCH] shared mo...
2560
2561
2562
  	/*
  	 * Don't move a mount residing in a shared parent.
  	 */
2763d1191   Al Viro   get rid of detach...
2563
  	if (attached && IS_MNT_SHARED(parent))
2db154b3e   David Howells   vfs: syscall: Add...
2564
  		goto out;
9676f0c63   Ram Pai   [PATCH] unbindabl...
2565
2566
2567
2568
  	/*
  	 * Don't move a mount tree containing unbindable mounts to a destination
  	 * mount which is shared.
  	 */
fc7be130c   Al Viro   vfs: switch pnode...
2569
  	if (IS_MNT_SHARED(p) && tree_contains_unbindable(old))
2db154b3e   David Howells   vfs: syscall: Add...
2570
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2571
  	err = -ELOOP;
44dfd84a6   David Howells   teach move_mount(...
2572
2573
  	if (!check_for_nsfs_mounts(old))
  		goto out;
fc7be130c   Al Viro   vfs: switch pnode...
2574
  	for (; mnt_has_parent(p); p = p->mnt_parent)
676da58df   Al Viro   vfs: spread struc...
2575
  		if (p == old)
2db154b3e   David Howells   vfs: syscall: Add...
2576
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2577

2db154b3e   David Howells   vfs: syscall: Add...
2578
  	err = attach_recursive_mnt(old, real_mount(new_path->mnt), mp,
2763d1191   Al Viro   get rid of detach...
2579
  				   attached);
4ac913785   Jan Blunck   Embed a struct pa...
2580
  	if (err)
2db154b3e   David Howells   vfs: syscall: Add...
2581
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2582
2583
2584
  
  	/* if the mount is moved, it should no longer be expire
  	 * automatically */
6776db3d3   Al Viro   vfs: take mnt_sha...
2585
  	list_del_init(&old->mnt_expire);
2763d1191   Al Viro   get rid of detach...
2586
2587
  	if (attached)
  		put_mountpoint(old_mp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2588
  out:
2db154b3e   David Howells   vfs: syscall: Add...
2589
  	unlock_mount(mp);
44dfd84a6   David Howells   teach move_mount(...
2590
  	if (!err) {
2763d1191   Al Viro   get rid of detach...
2591
2592
2593
  		if (attached)
  			mntput_no_expire(parent);
  		else
44dfd84a6   David Howells   teach move_mount(...
2594
2595
  			free_mnt_ns(ns);
  	}
2db154b3e   David Howells   vfs: syscall: Add...
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
  	return err;
  }
  
  static int do_move_mount_old(struct path *path, const char *old_name)
  {
  	struct path old_path;
  	int err;
  
  	if (!old_name || !*old_name)
  		return -EINVAL;
  
  	err = kern_path(old_name, LOOKUP_FOLLOW, &old_path);
  	if (err)
  		return err;
  
  	err = do_move_mount(&old_path, path);
2d92ab3c6   Al Viro   [PATCH] finally g...
2612
  	path_put(&old_path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2613
2614
  	return err;
  }
9d412a43c   Al Viro   vfs: split off vf...
2615
2616
2617
  /*
   * add a mount into a namespace's mount tree
   */
8f11538eb   Al Viro   do_add_mount(): l...
2618
2619
  static int do_add_mount(struct mount *newmnt, struct mountpoint *mp,
  			struct path *path, int mnt_flags)
9d412a43c   Al Viro   vfs: split off vf...
2620
  {
8f11538eb   Al Viro   do_add_mount(): l...
2621
  	struct mount *parent = real_mount(path->mnt);
9d412a43c   Al Viro   vfs: split off vf...
2622

f2ebb3a92   Al Viro   smarter propagate...
2623
  	mnt_flags &= ~MNT_INTERNAL_FLAGS;
9d412a43c   Al Viro   vfs: split off vf...
2624

84d17192d   Al Viro   get rid of full-h...
2625
  	if (unlikely(!check_mnt(parent))) {
156cacb1d   Al Viro   do_add_mount()/um...
2626
2627
  		/* that's acceptable only for automounts done in private ns */
  		if (!(mnt_flags & MNT_SHRINKABLE))
8f11538eb   Al Viro   do_add_mount(): l...
2628
  			return -EINVAL;
156cacb1d   Al Viro   do_add_mount()/um...
2629
  		/* ... and for those we'd better have mountpoint still alive */
84d17192d   Al Viro   get rid of full-h...
2630
  		if (!parent->mnt_ns)
8f11538eb   Al Viro   do_add_mount(): l...
2631
  			return -EINVAL;
156cacb1d   Al Viro   do_add_mount()/um...
2632
  	}
9d412a43c   Al Viro   vfs: split off vf...
2633
2634
  
  	/* Refuse the same filesystem on the same mount point */
95bc5f25c   Al Viro   vfs: spread struc...
2635
  	if (path->mnt->mnt_sb == newmnt->mnt.mnt_sb &&
9d412a43c   Al Viro   vfs: split off vf...
2636
  	    path->mnt->mnt_root == path->dentry)
8f11538eb   Al Viro   do_add_mount(): l...
2637
  		return -EBUSY;
9d412a43c   Al Viro   vfs: split off vf...
2638

e36cb0b89   David Howells   VFS: (Scripted) C...
2639
  	if (d_is_symlink(newmnt->mnt.mnt_root))
8f11538eb   Al Viro   do_add_mount(): l...
2640
  		return -EINVAL;
9d412a43c   Al Viro   vfs: split off vf...
2641

95bc5f25c   Al Viro   vfs: spread struc...
2642
  	newmnt->mnt.mnt_flags = mnt_flags;
8f11538eb   Al Viro   do_add_mount(): l...
2643
  	return graft_tree(newmnt, parent, mp);
9d412a43c   Al Viro   vfs: split off vf...
2644
  }
b1e75df45   Al Viro   tidy up around fi...
2645

132e46084   David Howells   new helper: do_ne...
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
  static bool mount_too_revealing(const struct super_block *sb, int *new_mnt_flags);
  
  /*
   * Create a new mount using a superblock configuration and request it
   * be added to the namespace tree.
   */
  static int do_new_mount_fc(struct fs_context *fc, struct path *mountpoint,
  			   unsigned int mnt_flags)
  {
  	struct vfsmount *mnt;
8f11538eb   Al Viro   do_add_mount(): l...
2656
  	struct mountpoint *mp;
132e46084   David Howells   new helper: do_ne...
2657
2658
  	struct super_block *sb = fc->root->d_sb;
  	int error;
c9ce29ed7   Al Viro   vfs_get_tree(): e...
2659
2660
2661
2662
2663
2664
2665
  	error = security_sb_kern_mount(sb);
  	if (!error && mount_too_revealing(sb, &mnt_flags))
  		error = -EPERM;
  
  	if (unlikely(error)) {
  		fc_drop_locked(fc);
  		return error;
132e46084   David Howells   new helper: do_ne...
2666
2667
2668
2669
2670
2671
2672
  	}
  
  	up_write(&sb->s_umount);
  
  	mnt = vfs_create_mount(fc);
  	if (IS_ERR(mnt))
  		return PTR_ERR(mnt);
f8b92ba67   Deepa Dinamani   mount: Add mount ...
2673
  	mnt_warn_timestamp_expiry(mountpoint, mnt);
8f11538eb   Al Viro   do_add_mount(): l...
2674
2675
2676
2677
2678
2679
2680
  	mp = lock_mount(mountpoint);
  	if (IS_ERR(mp)) {
  		mntput(mnt);
  		return PTR_ERR(mp);
  	}
  	error = do_add_mount(real_mount(mnt), mp, mountpoint, mnt_flags);
  	unlock_mount(mp);
0ecee6699   Eric Biggers   fs/namespace.c: f...
2681
2682
  	if (error < 0)
  		mntput(mnt);
132e46084   David Howells   new helper: do_ne...
2683
2684
  	return error;
  }
1b852bceb   Eric W. Biederman   mnt: Refactor the...
2685

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2686
2687
2688
2689
  /*
   * create a new mount for userspace and request it to be added into the
   * namespace's tree
   */
e462ec50c   David Howells   VFS: Differentiat...
2690
  static int do_new_mount(struct path *path, const char *fstype, int sb_flags,
808d4e3cf   Al Viro   consitify do_moun...
2691
  			int mnt_flags, const char *name, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2692
  {
0c55cfc41   Eric W. Biederman   vfs: Allow unpriv...
2693
  	struct file_system_type *type;
a0c9a8b8f   Al Viro   teach vfs_get_tre...
2694
2695
2696
  	struct fs_context *fc;
  	const char *subtype = NULL;
  	int err = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2697

0c55cfc41   Eric W. Biederman   vfs: Allow unpriv...
2698
  	if (!fstype)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2699
  		return -EINVAL;
0c55cfc41   Eric W. Biederman   vfs: Allow unpriv...
2700
2701
2702
  	type = get_fs_type(fstype);
  	if (!type)
  		return -ENODEV;
a0c9a8b8f   Al Viro   teach vfs_get_tre...
2703
2704
2705
2706
2707
2708
2709
2710
  	if (type->fs_flags & FS_HAS_SUBTYPE) {
  		subtype = strchr(fstype, '.');
  		if (subtype) {
  			subtype++;
  			if (!*subtype) {
  				put_filesystem(type);
  				return -EINVAL;
  			}
a0c9a8b8f   Al Viro   teach vfs_get_tre...
2711
2712
  		}
  	}
0c55cfc41   Eric W. Biederman   vfs: Allow unpriv...
2713

a0c9a8b8f   Al Viro   teach vfs_get_tre...
2714
  	fc = fs_context_for_mount(type, sb_flags);
0c55cfc41   Eric W. Biederman   vfs: Allow unpriv...
2715
  	put_filesystem(type);
a0c9a8b8f   Al Viro   teach vfs_get_tre...
2716
2717
  	if (IS_ERR(fc))
  		return PTR_ERR(fc);
3e1aeb00e   David Howells   vfs: Implement a ...
2718
2719
2720
2721
2722
  	if (subtype)
  		err = vfs_parse_fs_string(fc, "subtype",
  					  subtype, strlen(subtype));
  	if (!err && name)
  		err = vfs_parse_fs_string(fc, "source", name, strlen(name));
a0c9a8b8f   Al Viro   teach vfs_get_tre...
2723
2724
  	if (!err)
  		err = parse_monolithic_mount_data(fc, data);
c3aabf078   Al Viro   move mount_capabl...
2725
2726
  	if (!err && !mount_capable(fc))
  		err = -EPERM;
a0c9a8b8f   Al Viro   teach vfs_get_tre...
2727
2728
  	if (!err)
  		err = vfs_get_tree(fc);
132e46084   David Howells   new helper: do_ne...
2729
2730
  	if (!err)
  		err = do_new_mount_fc(fc, path, mnt_flags);
8654df4e2   Eric W. Biederman   mnt: Refactor fs_...
2731

a0c9a8b8f   Al Viro   teach vfs_get_tre...
2732
  	put_fs_context(fc);
15f9a3f3e   Al Viro   don't drop newmnt...
2733
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2734
  }
19a167af7   Al Viro   Take the completi...
2735
2736
  int finish_automount(struct vfsmount *m, struct path *path)
  {
26df6034f   Al Viro   fix automount/aut...
2737
  	struct dentry *dentry = path->dentry;
8f11538eb   Al Viro   do_add_mount(): l...
2738
  	struct mountpoint *mp;
25e195aa1   Al Viro   follow_automount(...
2739
  	struct mount *mnt;
19a167af7   Al Viro   Take the completi...
2740
  	int err;
25e195aa1   Al Viro   follow_automount(...
2741
2742
2743
2744
2745
2746
2747
  
  	if (!m)
  		return 0;
  	if (IS_ERR(m))
  		return PTR_ERR(m);
  
  	mnt = real_mount(m);
19a167af7   Al Viro   Take the completi...
2748
2749
2750
  	/* The new mount record should have at least 2 refs to prevent it being
  	 * expired before we get a chance to add it
  	 */
6776db3d3   Al Viro   vfs: take mnt_sha...
2751
  	BUG_ON(mnt_get_count(mnt) < 2);
19a167af7   Al Viro   Take the completi...
2752
2753
  
  	if (m->mnt_sb == path->mnt->mnt_sb &&
26df6034f   Al Viro   fix automount/aut...
2754
  	    m->mnt_root == dentry) {
b1e75df45   Al Viro   tidy up around fi...
2755
  		err = -ELOOP;
26df6034f   Al Viro   fix automount/aut...
2756
  		goto discard;
19a167af7   Al Viro   Take the completi...
2757
  	}
26df6034f   Al Viro   fix automount/aut...
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
  	/*
  	 * we don't want to use lock_mount() - in this case finding something
  	 * that overmounts our mountpoint to be means "quitely drop what we've
  	 * got", not "try to mount it on top".
  	 */
  	inode_lock(dentry->d_inode);
  	namespace_lock();
  	if (unlikely(cant_mount(dentry))) {
  		err = -ENOENT;
  		goto discard_locked;
  	}
  	rcu_read_lock();
  	if (unlikely(__lookup_mnt(path->mnt, dentry))) {
  		rcu_read_unlock();
  		err = 0;
  		goto discard_locked;
  	}
  	rcu_read_unlock();
  	mp = get_mountpoint(dentry);
8f11538eb   Al Viro   do_add_mount(): l...
2777
2778
  	if (IS_ERR(mp)) {
  		err = PTR_ERR(mp);
26df6034f   Al Viro   fix automount/aut...
2779
  		goto discard_locked;
8f11538eb   Al Viro   do_add_mount(): l...
2780
  	}
26df6034f   Al Viro   fix automount/aut...
2781

8f11538eb   Al Viro   do_add_mount(): l...
2782
2783
  	err = do_add_mount(mnt, mp, path, path->mnt->mnt_flags | MNT_SHRINKABLE);
  	unlock_mount(mp);
26df6034f   Al Viro   fix automount/aut...
2784
2785
2786
2787
2788
2789
2790
2791
2792
  	if (unlikely(err))
  		goto discard;
  	mntput(m);
  	return 0;
  
  discard_locked:
  	namespace_unlock();
  	inode_unlock(dentry->d_inode);
  discard:
b1e75df45   Al Viro   tidy up around fi...
2793
  	/* remove m from any expiration list it may be on */
6776db3d3   Al Viro   vfs: take mnt_sha...
2794
  	if (!list_empty(&mnt->mnt_expire)) {
97216be09   Al Viro   fold release_moun...
2795
  		namespace_lock();
6776db3d3   Al Viro   vfs: take mnt_sha...
2796
  		list_del_init(&mnt->mnt_expire);
97216be09   Al Viro   fold release_moun...
2797
  		namespace_unlock();
19a167af7   Al Viro   Take the completi...
2798
  	}
b1e75df45   Al Viro   tidy up around fi...
2799
2800
  	mntput(m);
  	mntput(m);
19a167af7   Al Viro   Take the completi...
2801
2802
  	return err;
  }
ea5b778a8   David Howells   Unexport do_add_m...
2803
2804
2805
2806
2807
2808
2809
  /**
   * mnt_set_expiry - Put a mount on an expiration list
   * @mnt: The mount to list.
   * @expiry_list: The list to add the mount to.
   */
  void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list)
  {
97216be09   Al Viro   fold release_moun...
2810
  	namespace_lock();
ea5b778a8   David Howells   Unexport do_add_m...
2811

6776db3d3   Al Viro   vfs: take mnt_sha...
2812
  	list_add_tail(&real_mount(mnt)->mnt_expire, expiry_list);
ea5b778a8   David Howells   Unexport do_add_m...
2813

97216be09   Al Viro   fold release_moun...
2814
  	namespace_unlock();
ea5b778a8   David Howells   Unexport do_add_m...
2815
2816
2817
2818
  }
  EXPORT_SYMBOL(mnt_set_expiry);
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2819
2820
2821
2822
2823
2824
   * process a list of expirable mountpoints with the intent of discarding any
   * mountpoints that aren't in use and haven't been touched since last we came
   * here
   */
  void mark_mounts_for_expiry(struct list_head *mounts)
  {
761d5c38e   Al Viro   vfs: spread struc...
2825
  	struct mount *mnt, *next;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2826
2827
2828
2829
  	LIST_HEAD(graveyard);
  
  	if (list_empty(mounts))
  		return;
97216be09   Al Viro   fold release_moun...
2830
  	namespace_lock();
719ea2fbb   Al Viro   new helpers: lock...
2831
  	lock_mount_hash();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2832
2833
2834
2835
2836
2837
2838
  
  	/* extract from the expiration list every vfsmount that matches the
  	 * following criteria:
  	 * - only referenced by its parent vfsmount
  	 * - still marked for expiry (marked on the last call here; marks are
  	 *   cleared by mntput())
  	 */
6776db3d3   Al Viro   vfs: take mnt_sha...
2839
  	list_for_each_entry_safe(mnt, next, mounts, mnt_expire) {
863d684f9   Al Viro   vfs: move the res...
2840
  		if (!xchg(&mnt->mnt_expiry_mark, 1) ||
1ab597386   Al Viro   vfs: spread struc...
2841
  			propagate_mount_busy(mnt, 1))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2842
  			continue;
6776db3d3   Al Viro   vfs: take mnt_sha...
2843
  		list_move(&mnt->mnt_expire, &graveyard);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2844
  	}
bcc5c7d2b   Al Viro   [PATCH] sanitize ...
2845
  	while (!list_empty(&graveyard)) {
6776db3d3   Al Viro   vfs: take mnt_sha...
2846
  		mnt = list_first_entry(&graveyard, struct mount, mnt_expire);
143c8c91c   Al Viro   vfs: mnt_ns moved...
2847
  		touch_mnt_namespace(mnt->mnt_ns);
e819f1521   Eric W. Biederman   mnt: Improve the ...
2848
  		umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC);
bcc5c7d2b   Al Viro   [PATCH] sanitize ...
2849
  	}
719ea2fbb   Al Viro   new helpers: lock...
2850
  	unlock_mount_hash();
3ab6abee5   Al Viro   more conversions ...
2851
  	namespace_unlock();
5528f911b   Trond Myklebust   VFS: Add shrink_s...
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
  }
  
  EXPORT_SYMBOL_GPL(mark_mounts_for_expiry);
  
  /*
   * Ripoff of 'select_parent()'
   *
   * search the list of submounts for a given mountpoint, and move any
   * shrinkable submounts to the 'graveyard' list.
   */
692afc312   Al Viro   vfs: spread struc...
2862
  static int select_submounts(struct mount *parent, struct list_head *graveyard)
5528f911b   Trond Myklebust   VFS: Add shrink_s...
2863
  {
692afc312   Al Viro   vfs: spread struc...
2864
  	struct mount *this_parent = parent;
5528f911b   Trond Myklebust   VFS: Add shrink_s...
2865
2866
2867
2868
  	struct list_head *next;
  	int found = 0;
  
  repeat:
6b41d536f   Al Viro   vfs: take mnt_chi...
2869
  	next = this_parent->mnt_mounts.next;
5528f911b   Trond Myklebust   VFS: Add shrink_s...
2870
  resume:
6b41d536f   Al Viro   vfs: take mnt_chi...
2871
  	while (next != &this_parent->mnt_mounts) {
5528f911b   Trond Myklebust   VFS: Add shrink_s...
2872
  		struct list_head *tmp = next;
6b41d536f   Al Viro   vfs: take mnt_chi...
2873
  		struct mount *mnt = list_entry(tmp, struct mount, mnt_child);
5528f911b   Trond Myklebust   VFS: Add shrink_s...
2874
2875
  
  		next = tmp->next;
692afc312   Al Viro   vfs: spread struc...
2876
  		if (!(mnt->mnt.mnt_flags & MNT_SHRINKABLE))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2877
  			continue;
5528f911b   Trond Myklebust   VFS: Add shrink_s...
2878
2879
2880
  		/*
  		 * Descend a level if the d_mounts list is non-empty.
  		 */
6b41d536f   Al Viro   vfs: take mnt_chi...
2881
  		if (!list_empty(&mnt->mnt_mounts)) {
5528f911b   Trond Myklebust   VFS: Add shrink_s...
2882
2883
2884
  			this_parent = mnt;
  			goto repeat;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2885

1ab597386   Al Viro   vfs: spread struc...
2886
  		if (!propagate_mount_busy(mnt, 1)) {
6776db3d3   Al Viro   vfs: take mnt_sha...
2887
  			list_move_tail(&mnt->mnt_expire, graveyard);
5528f911b   Trond Myklebust   VFS: Add shrink_s...
2888
2889
  			found++;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2890
  	}
5528f911b   Trond Myklebust   VFS: Add shrink_s...
2891
2892
2893
2894
  	/*
  	 * All done at this level ... ascend and resume the search
  	 */
  	if (this_parent != parent) {
6b41d536f   Al Viro   vfs: take mnt_chi...
2895
  		next = this_parent->mnt_child.next;
0714a5338   Al Viro   vfs: now it can b...
2896
  		this_parent = this_parent->mnt_parent;
5528f911b   Trond Myklebust   VFS: Add shrink_s...
2897
2898
2899
2900
2901
2902
2903
2904
  		goto resume;
  	}
  	return found;
  }
  
  /*
   * process a list of expirable mountpoints with the intent of discarding any
   * submounts of a specific parent mountpoint
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
2905
   *
48a066e72   Al Viro   RCU'd vfsmounts
2906
   * mount_lock must be held for write
5528f911b   Trond Myklebust   VFS: Add shrink_s...
2907
   */
b54b9be78   Al Viro   get rid of the se...
2908
  static void shrink_submounts(struct mount *mnt)
5528f911b   Trond Myklebust   VFS: Add shrink_s...
2909
2910
  {
  	LIST_HEAD(graveyard);
761d5c38e   Al Viro   vfs: spread struc...
2911
  	struct mount *m;
5528f911b   Trond Myklebust   VFS: Add shrink_s...
2912

5528f911b   Trond Myklebust   VFS: Add shrink_s...
2913
  	/* extract submounts of 'mountpoint' from the expiration list */
c35038bec   Al Viro   [PATCH] do shrink...
2914
  	while (select_submounts(mnt, &graveyard)) {
bcc5c7d2b   Al Viro   [PATCH] sanitize ...
2915
  		while (!list_empty(&graveyard)) {
761d5c38e   Al Viro   vfs: spread struc...
2916
  			m = list_first_entry(&graveyard, struct mount,
6776db3d3   Al Viro   vfs: take mnt_sha...
2917
  						mnt_expire);
143c8c91c   Al Viro   vfs: mnt_ns moved...
2918
  			touch_mnt_namespace(m->mnt_ns);
e819f1521   Eric W. Biederman   mnt: Improve the ...
2919
  			umount_tree(m, UMOUNT_PROPAGATE|UMOUNT_SYNC);
bcc5c7d2b   Al Viro   [PATCH] sanitize ...
2920
2921
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2922
  }
028abd922   Christoph Hellwig   fs: remove compat...
2923
  static void *copy_mount_options(const void __user * data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2924
  {
b40ef8696   Al Viro   saner calling con...
2925
  	char *copy;
d563d678a   Catalin Marinas   fs: Handle intra-...
2926
  	unsigned left, offset;
b58fed8b1   Ram Pai   [PATCH] lindent f...
2927

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2928
  	if (!data)
b40ef8696   Al Viro   saner calling con...
2929
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2930

b40ef8696   Al Viro   saner calling con...
2931
2932
2933
  	copy = kmalloc(PAGE_SIZE, GFP_KERNEL);
  	if (!copy)
  		return ERR_PTR(-ENOMEM);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2934

d563d678a   Catalin Marinas   fs: Handle intra-...
2935
  	left = copy_from_user(copy, data, PAGE_SIZE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2936

d563d678a   Catalin Marinas   fs: Handle intra-...
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
  	/*
  	 * Not all architectures have an exact copy_from_user(). Resort to
  	 * byte at a time.
  	 */
  	offset = PAGE_SIZE - left;
  	while (left) {
  		char c;
  		if (get_user(c, (const char __user *)data + offset))
  			break;
  		copy[offset] = c;
  		left--;
  		offset++;
  	}
  
  	if (left == PAGE_SIZE) {
b40ef8696   Al Viro   saner calling con...
2952
2953
  		kfree(copy);
  		return ERR_PTR(-EFAULT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2954
  	}
d563d678a   Catalin Marinas   fs: Handle intra-...
2955

b40ef8696   Al Viro   saner calling con...
2956
  	return copy;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2957
  }
028abd922   Christoph Hellwig   fs: remove compat...
2958
  static char *copy_mount_string(const void __user *data)
eca6f534e   Vegard Nossum   fs: fix overflow ...
2959
  {
fbdb44013   Chandan Rajendra   copy_mount_string...
2960
  	return data ? strndup_user(data, PATH_MAX) : NULL;
eca6f534e   Vegard Nossum   fs: fix overflow ...
2961
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
  /*
   * Flags is a 32-bit value that allows up to 31 non-fs dependent flags to
   * be given to the mount() call (ie: read-only, no-dev, no-suid etc).
   *
   * data is a (void *) that can point to any structure up to
   * PAGE_SIZE-1 bytes, which can contain arbitrary fs-dependent
   * information (or be NULL).
   *
   * Pre-0.97 versions of mount() didn't have a flags word.
   * When the flags word was introduced its top half was required
   * to have the magic value 0xC0ED, and this remained so until 2.4.0-test9.
   * Therefore, if this magic number is present, it carries no information
   * and must be discarded.
   */
c60166f04   Christoph Hellwig   init: add an init...
2976
  int path_mount(const char *dev_name, struct path *path,
808d4e3cf   Al Viro   consitify do_moun...
2977
  		const char *type_page, unsigned long flags, void *data_page)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2978
  {
e462ec50c   David Howells   VFS: Differentiat...
2979
  	unsigned int mnt_flags = 0, sb_flags;
a1e6aaa37   Christoph Hellwig   fs: refactor do_m...
2980
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2981
2982
2983
2984
2985
2986
  
  	/* Discard magic */
  	if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
  		flags &= ~MS_MGC_MSK;
  
  	/* Basic sanity checks */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2987
2988
  	if (data_page)
  		((char *)data_page)[PAGE_SIZE - 1] = 0;
e462ec50c   David Howells   VFS: Differentiat...
2989
2990
  	if (flags & MS_NOUSER)
  		return -EINVAL;
a1e6aaa37   Christoph Hellwig   fs: refactor do_m...
2991
2992
2993
2994
2995
2996
2997
  	ret = security_sb_mount(dev_name, path, type_page, flags, data_page);
  	if (ret)
  		return ret;
  	if (!may_mount())
  		return -EPERM;
  	if ((flags & SB_MANDLOCK) && !may_mandlock())
  		return -EPERM;
a27ab9f26   Tetsuo Handa   LSM: Pass origina...
2998

613cbe3d4   Andi Kleen   Don't set relatim...
2999
3000
3001
  	/* Default to relatime unless overriden */
  	if (!(flags & MS_NOATIME))
  		mnt_flags |= MNT_RELATIME;
0a1c01c94   Matthew Garrett   Make relatime def...
3002

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3003
3004
3005
3006
3007
3008
3009
  	/* Separate the per-mountpoint flags */
  	if (flags & MS_NOSUID)
  		mnt_flags |= MNT_NOSUID;
  	if (flags & MS_NODEV)
  		mnt_flags |= MNT_NODEV;
  	if (flags & MS_NOEXEC)
  		mnt_flags |= MNT_NOEXEC;
fc33a7bb9   Christoph Hellwig   [PATCH] per-mount...
3010
3011
3012
3013
  	if (flags & MS_NOATIME)
  		mnt_flags |= MNT_NOATIME;
  	if (flags & MS_NODIRATIME)
  		mnt_flags |= MNT_NODIRATIME;
d0adde574   Matthew Garrett   Add a strictatime...
3014
3015
  	if (flags & MS_STRICTATIME)
  		mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME);
a9e5b7328   David Howells   vfs: Undo an over...
3016
  	if (flags & MS_RDONLY)
2e4b7fcd9   Dave Hansen   [PATCH] r/o bind ...
3017
  		mnt_flags |= MNT_READONLY;
dab741e0e   Mattias Nissler   Add a "nosymfollo...
3018
3019
  	if (flags & MS_NOSYMFOLLOW)
  		mnt_flags |= MNT_NOSYMFOLLOW;
fc33a7bb9   Christoph Hellwig   [PATCH] per-mount...
3020

ffbc6f0ea   Eric W. Biederman   mnt: Change the d...
3021
3022
3023
3024
3025
  	/* The default atime for remount is preservation */
  	if ((flags & MS_REMOUNT) &&
  	    ((flags & (MS_NOATIME | MS_NODIRATIME | MS_RELATIME |
  		       MS_STRICTATIME)) == 0)) {
  		mnt_flags &= ~MNT_ATIME_MASK;
a1e6aaa37   Christoph Hellwig   fs: refactor do_m...
3026
  		mnt_flags |= path->mnt->mnt_flags & MNT_ATIME_MASK;
ffbc6f0ea   Eric W. Biederman   mnt: Change the d...
3027
  	}
e462ec50c   David Howells   VFS: Differentiat...
3028
3029
3030
3031
3032
  	sb_flags = flags & (SB_RDONLY |
  			    SB_SYNCHRONOUS |
  			    SB_MANDLOCK |
  			    SB_DIRSYNC |
  			    SB_SILENT |
917086ff2   Mimi Zohar   vfs: fix mounting...
3033
  			    SB_POSIXACL |
d7ee94694   Markus Trippelsdorf   VFS: Handle lazyt...
3034
  			    SB_LAZYTIME |
917086ff2   Mimi Zohar   vfs: fix mounting...
3035
  			    SB_I_VERSION);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3036

43f5e655e   David Howells   vfs: Separate cha...
3037
  	if ((flags & (MS_REMOUNT | MS_BIND)) == (MS_REMOUNT | MS_BIND))
a1e6aaa37   Christoph Hellwig   fs: refactor do_m...
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
  		return do_reconfigure_mnt(path, mnt_flags);
  	if (flags & MS_REMOUNT)
  		return do_remount(path, flags, sb_flags, mnt_flags, data_page);
  	if (flags & MS_BIND)
  		return do_loopback(path, dev_name, flags & MS_REC);
  	if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
  		return do_change_type(path, flags);
  	if (flags & MS_MOVE)
  		return do_move_mount_old(path, dev_name);
  
  	return do_new_mount(path, type_page, sb_flags, mnt_flags, dev_name,
  			    data_page);
  }
  
  long do_mount(const char *dev_name, const char __user *dir_name,
  		const char *type_page, unsigned long flags, void *data_page)
  {
  	struct path path;
  	int ret;
  
  	ret = user_path_at(AT_FDCWD, dir_name, LOOKUP_FOLLOW, &path);
  	if (ret)
  		return ret;
  	ret = path_mount(dev_name, &path, type_page, flags, data_page);
2d92ab3c6   Al Viro   [PATCH] finally g...
3062
  	path_put(&path);
a1e6aaa37   Christoph Hellwig   fs: refactor do_m...
3063
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3064
  }
537f7ccb3   Eric W. Biederman   mntns: Add a limi...
3065
3066
3067
3068
3069
3070
3071
3072
3073
  static struct ucounts *inc_mnt_namespaces(struct user_namespace *ns)
  {
  	return inc_ucount(ns, current_euid(), UCOUNT_MNT_NAMESPACES);
  }
  
  static void dec_mnt_namespaces(struct ucounts *ucounts)
  {
  	dec_ucount(ucounts, UCOUNT_MNT_NAMESPACES);
  }
771b13716   Eric W. Biederman   vfs: Add a user n...
3074
3075
  static void free_mnt_ns(struct mnt_namespace *ns)
  {
74e831221   Al Viro   saner handling of...
3076
3077
  	if (!is_anon_ns(ns))
  		ns_free_inum(&ns->ns);
537f7ccb3   Eric W. Biederman   mntns: Add a limi...
3078
  	dec_mnt_namespaces(ns->ucounts);
771b13716   Eric W. Biederman   vfs: Add a user n...
3079
3080
3081
  	put_user_ns(ns->user_ns);
  	kfree(ns);
  }
8823c079b   Eric W. Biederman   vfs: Add setns su...
3082
3083
3084
3085
3086
3087
3088
3089
  /*
   * Assign a sequence number so we can detect when we attempt to bind
   * mount a reference to an older mount namespace into the current
   * mount namespace, preventing reference counting loops.  A 64bit
   * number incrementing at 10Ghz will take 12,427 years to wrap which
   * is effectively never, so we can ignore the possibility.
   */
  static atomic64_t mnt_ns_seq = ATOMIC64_INIT(1);
74e831221   Al Viro   saner handling of...
3090
  static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns, bool anon)
cf8d2c11c   Trond Myklebust   VFS: Add VFS help...
3091
3092
  {
  	struct mnt_namespace *new_ns;
537f7ccb3   Eric W. Biederman   mntns: Add a limi...
3093
  	struct ucounts *ucounts;
98f842e67   Eric W. Biederman   proc: Usable inod...
3094
  	int ret;
cf8d2c11c   Trond Myklebust   VFS: Add VFS help...
3095

537f7ccb3   Eric W. Biederman   mntns: Add a limi...
3096
3097
  	ucounts = inc_mnt_namespaces(user_ns);
  	if (!ucounts)
df75e7748   Eric W. Biederman   userns: When the ...
3098
  		return ERR_PTR(-ENOSPC);
537f7ccb3   Eric W. Biederman   mntns: Add a limi...
3099

74e831221   Al Viro   saner handling of...
3100
  	new_ns = kzalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
537f7ccb3   Eric W. Biederman   mntns: Add a limi...
3101
3102
  	if (!new_ns) {
  		dec_mnt_namespaces(ucounts);
cf8d2c11c   Trond Myklebust   VFS: Add VFS help...
3103
  		return ERR_PTR(-ENOMEM);
537f7ccb3   Eric W. Biederman   mntns: Add a limi...
3104
  	}
74e831221   Al Viro   saner handling of...
3105
3106
3107
3108
3109
3110
3111
  	if (!anon) {
  		ret = ns_alloc_inum(&new_ns->ns);
  		if (ret) {
  			kfree(new_ns);
  			dec_mnt_namespaces(ucounts);
  			return ERR_PTR(ret);
  		}
98f842e67   Eric W. Biederman   proc: Usable inod...
3112
  	}
33c429405   Al Viro   copy address of p...
3113
  	new_ns->ns.ops = &mntns_operations;
74e831221   Al Viro   saner handling of...
3114
3115
  	if (!anon)
  		new_ns->seq = atomic64_add_return(1, &mnt_ns_seq);
cf8d2c11c   Trond Myklebust   VFS: Add VFS help...
3116
  	atomic_set(&new_ns->count, 1);
cf8d2c11c   Trond Myklebust   VFS: Add VFS help...
3117
3118
  	INIT_LIST_HEAD(&new_ns->list);
  	init_waitqueue_head(&new_ns->poll);
9f6c61f96   Miklos Szeredi   proc/mounts: add ...
3119
  	spin_lock_init(&new_ns->ns_lock);
771b13716   Eric W. Biederman   vfs: Add a user n...
3120
  	new_ns->user_ns = get_user_ns(user_ns);
537f7ccb3   Eric W. Biederman   mntns: Add a limi...
3121
  	new_ns->ucounts = ucounts;
cf8d2c11c   Trond Myklebust   VFS: Add VFS help...
3122
3123
  	return new_ns;
  }
0766f788e   Emese Revfy   latent_entropy: M...
3124
  __latent_entropy
9559f6891   Al Viro   fold dup_mnt_ns()...
3125
3126
  struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
  		struct user_namespace *user_ns, struct fs_struct *new_fs)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3127
  {
6b3286ed1   Kirill Korotaev   [PATCH] rename st...
3128
  	struct mnt_namespace *new_ns;
7f2da1e7d   Al Viro   [PATCH] kill altroot
3129
  	struct vfsmount *rootmnt = NULL, *pwdmnt = NULL;
315fc83e5   Al Viro   vfs: spread struc...
3130
  	struct mount *p, *q;
9559f6891   Al Viro   fold dup_mnt_ns()...
3131
  	struct mount *old;
cb338d06e   Al Viro   vfs: spread struc...
3132
  	struct mount *new;
7a472ef4b   Eric W. Biederman   vfs: Only support...
3133
  	int copy_flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3134

9559f6891   Al Viro   fold dup_mnt_ns()...
3135
3136
3137
3138
3139
3140
3141
3142
  	BUG_ON(!ns);
  
  	if (likely(!(flags & CLONE_NEWNS))) {
  		get_mnt_ns(ns);
  		return ns;
  	}
  
  	old = ns->root;
74e831221   Al Viro   saner handling of...
3143
  	new_ns = alloc_mnt_ns(user_ns, false);
cf8d2c11c   Trond Myklebust   VFS: Add VFS help...
3144
3145
  	if (IS_ERR(new_ns))
  		return new_ns;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3146

97216be09   Al Viro   fold release_moun...
3147
  	namespace_lock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3148
  	/* First pass: copy the tree topology */
4ce5d2b1a   Eric W. Biederman   vfs: Don't copy m...
3149
  	copy_flags = CL_COPY_UNBINDABLE | CL_EXPIRE;
9559f6891   Al Viro   fold dup_mnt_ns()...
3150
  	if (user_ns != ns->user_ns)
3bd045cc9   Al Viro   separate copying ...
3151
  		copy_flags |= CL_SHARED_TO_SLAVE;
7a472ef4b   Eric W. Biederman   vfs: Only support...
3152
  	new = copy_tree(old, old->mnt.mnt_root, copy_flags);
be34d1a3b   David Howells   VFS: Make clone_m...
3153
  	if (IS_ERR(new)) {
328e6d901   Al Viro   switch unlock_mou...
3154
  		namespace_unlock();
771b13716   Eric W. Biederman   vfs: Add a user n...
3155
  		free_mnt_ns(new_ns);
be34d1a3b   David Howells   VFS: Make clone_m...
3156
  		return ERR_CAST(new);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3157
  	}
3bd045cc9   Al Viro   separate copying ...
3158
3159
3160
3161
3162
  	if (user_ns != ns->user_ns) {
  		lock_mount_hash();
  		lock_mnt_tree(new);
  		unlock_mount_hash();
  	}
be08d6d26   Al Viro   switch mnt_namesp...
3163
  	new_ns->root = new;
1a4eeaf2a   Al Viro   vfs: move mnt_lis...
3164
  	list_add_tail(&new_ns->list, &new->mnt_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3165
3166
3167
3168
3169
3170
  
  	/*
  	 * Second pass: switch the tsk->fs->* elements and mark new vfsmounts
  	 * as belonging to new namespace.  We have already acquired a private
  	 * fs_struct, so tsk->fs->lock is not needed.
  	 */
909b0a88e   Al Viro   vfs: spread struc...
3171
  	p = old;
cb338d06e   Al Viro   vfs: spread struc...
3172
  	q = new;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3173
  	while (p) {
143c8c91c   Al Viro   vfs: mnt_ns moved...
3174
  		q->mnt_ns = new_ns;
d29216842   Eric W. Biederman   mnt: Add a per mo...
3175
  		new_ns->mounts++;
9559f6891   Al Viro   fold dup_mnt_ns()...
3176
3177
3178
  		if (new_fs) {
  			if (&p->mnt == new_fs->root.mnt) {
  				new_fs->root.mnt = mntget(&q->mnt);
315fc83e5   Al Viro   vfs: spread struc...
3179
  				rootmnt = &p->mnt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3180
  			}
9559f6891   Al Viro   fold dup_mnt_ns()...
3181
3182
  			if (&p->mnt == new_fs->pwd.mnt) {
  				new_fs->pwd.mnt = mntget(&q->mnt);
315fc83e5   Al Viro   vfs: spread struc...
3183
  				pwdmnt = &p->mnt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3184
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3185
  		}
909b0a88e   Al Viro   vfs: spread struc...
3186
3187
  		p = next_mnt(p, old);
  		q = next_mnt(q, new);
4ce5d2b1a   Eric W. Biederman   vfs: Don't copy m...
3188
3189
3190
3191
  		if (!q)
  			break;
  		while (p->mnt.mnt_root != q->mnt.mnt_root)
  			p = next_mnt(p, old);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3192
  	}
328e6d901   Al Viro   switch unlock_mou...
3193
  	namespace_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3194

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3195
  	if (rootmnt)
f03c65993   Al Viro   sanitize vfsmount...
3196
  		mntput(rootmnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3197
  	if (pwdmnt)
f03c65993   Al Viro   sanitize vfsmount...
3198
  		mntput(pwdmnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3199

741a29513   JANAK DESAI   [PATCH] unshare s...
3200
  	return new_ns;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3201
  }
74e831221   Al Viro   saner handling of...
3202
  struct dentry *mount_subtree(struct vfsmount *m, const char *name)
ea441d110   Al Viro   new helper: mount...
3203
  {
74e831221   Al Viro   saner handling of...
3204
  	struct mount *mnt = real_mount(m);
ea441d110   Al Viro   new helper: mount...
3205
  	struct mnt_namespace *ns;
d31da0f0b   Al Viro   mount_subtree() p...
3206
  	struct super_block *s;
ea441d110   Al Viro   new helper: mount...
3207
3208
  	struct path path;
  	int err;
74e831221   Al Viro   saner handling of...
3209
3210
3211
  	ns = alloc_mnt_ns(&init_user_ns, true);
  	if (IS_ERR(ns)) {
  		mntput(m);
ea441d110   Al Viro   new helper: mount...
3212
  		return ERR_CAST(ns);
74e831221   Al Viro   saner handling of...
3213
3214
3215
3216
3217
  	}
  	mnt->mnt_ns = ns;
  	ns->root = mnt;
  	ns->mounts++;
  	list_add(&mnt->mnt_list, &ns->list);
ea441d110   Al Viro   new helper: mount...
3218

74e831221   Al Viro   saner handling of...
3219
  	err = vfs_path_lookup(m->mnt_root, m,
ea441d110   Al Viro   new helper: mount...
3220
3221
3222
3223
3224
3225
3226
3227
  			name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &path);
  
  	put_mnt_ns(ns);
  
  	if (err)
  		return ERR_PTR(err);
  
  	/* trade a vfsmount reference for active sb one */
d31da0f0b   Al Viro   mount_subtree() p...
3228
3229
  	s = path.mnt->mnt_sb;
  	atomic_inc(&s->s_active);
ea441d110   Al Viro   new helper: mount...
3230
3231
  	mntput(path.mnt);
  	/* lock the sucker */
d31da0f0b   Al Viro   mount_subtree() p...
3232
  	down_write(&s->s_umount);
ea441d110   Al Viro   new helper: mount...
3233
3234
3235
3236
  	/* ... and return the root of (sub)tree on it */
  	return path.dentry;
  }
  EXPORT_SYMBOL(mount_subtree);
cccaa5e33   Dominik Brodowski   init: use do_moun...
3237
3238
  SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
  		char __user *, type, unsigned long, flags, void __user *, data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3239
  {
eca6f534e   Vegard Nossum   fs: fix overflow ...
3240
3241
  	int ret;
  	char *kernel_type;
eca6f534e   Vegard Nossum   fs: fix overflow ...
3242
  	char *kernel_dev;
b40ef8696   Al Viro   saner calling con...
3243
  	void *options;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3244

b8850d1fa   Tim Gardner   fs: namespace: su...
3245
3246
3247
  	kernel_type = copy_mount_string(type);
  	ret = PTR_ERR(kernel_type);
  	if (IS_ERR(kernel_type))
eca6f534e   Vegard Nossum   fs: fix overflow ...
3248
  		goto out_type;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3249

b8850d1fa   Tim Gardner   fs: namespace: su...
3250
3251
3252
  	kernel_dev = copy_mount_string(dev_name);
  	ret = PTR_ERR(kernel_dev);
  	if (IS_ERR(kernel_dev))
eca6f534e   Vegard Nossum   fs: fix overflow ...
3253
  		goto out_dev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3254

b40ef8696   Al Viro   saner calling con...
3255
3256
3257
  	options = copy_mount_options(data);
  	ret = PTR_ERR(options);
  	if (IS_ERR(options))
eca6f534e   Vegard Nossum   fs: fix overflow ...
3258
  		goto out_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3259

b40ef8696   Al Viro   saner calling con...
3260
  	ret = do_mount(kernel_dev, dir_name, kernel_type, flags, options);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3261

b40ef8696   Al Viro   saner calling con...
3262
  	kfree(options);
eca6f534e   Vegard Nossum   fs: fix overflow ...
3263
3264
3265
  out_data:
  	kfree(kernel_dev);
  out_dev:
eca6f534e   Vegard Nossum   fs: fix overflow ...
3266
3267
3268
  	kfree(kernel_type);
  out_type:
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3269
3270
3271
  }
  
  /*
93766fbd2   David Howells   vfs: syscall: Add...
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
   * Create a kernel mount representation for a new, prepared superblock
   * (specified by fs_fd) and attach to an open_tree-like file descriptor.
   */
  SYSCALL_DEFINE3(fsmount, int, fs_fd, unsigned int, flags,
  		unsigned int, attr_flags)
  {
  	struct mnt_namespace *ns;
  	struct fs_context *fc;
  	struct file *file;
  	struct path newmount;
  	struct mount *mnt;
  	struct fd f;
  	unsigned int mnt_flags = 0;
  	long ret;
  
  	if (!may_mount())
  		return -EPERM;
  
  	if ((flags & ~(FSMOUNT_CLOEXEC)) != 0)
  		return -EINVAL;
  
  	if (attr_flags & ~(MOUNT_ATTR_RDONLY |
  			   MOUNT_ATTR_NOSUID |
  			   MOUNT_ATTR_NODEV |
  			   MOUNT_ATTR_NOEXEC |
  			   MOUNT_ATTR__ATIME |
  			   MOUNT_ATTR_NODIRATIME))
  		return -EINVAL;
  
  	if (attr_flags & MOUNT_ATTR_RDONLY)
  		mnt_flags |= MNT_READONLY;
  	if (attr_flags & MOUNT_ATTR_NOSUID)
  		mnt_flags |= MNT_NOSUID;
  	if (attr_flags & MOUNT_ATTR_NODEV)
  		mnt_flags |= MNT_NODEV;
  	if (attr_flags & MOUNT_ATTR_NOEXEC)
  		mnt_flags |= MNT_NOEXEC;
  	if (attr_flags & MOUNT_ATTR_NODIRATIME)
  		mnt_flags |= MNT_NODIRATIME;
  
  	switch (attr_flags & MOUNT_ATTR__ATIME) {
  	case MOUNT_ATTR_STRICTATIME:
  		break;
  	case MOUNT_ATTR_NOATIME:
  		mnt_flags |= MNT_NOATIME;
  		break;
  	case MOUNT_ATTR_RELATIME:
  		mnt_flags |= MNT_RELATIME;
  		break;
  	default:
  		return -EINVAL;
  	}
  
  	f = fdget(fs_fd);
  	if (!f.file)
  		return -EBADF;
  
  	ret = -EINVAL;
  	if (f.file->f_op != &fscontext_fops)
  		goto err_fsfd;
  
  	fc = f.file->private_data;
  
  	ret = mutex_lock_interruptible(&fc->uapi_mutex);
  	if (ret < 0)
  		goto err_fsfd;
  
  	/* There must be a valid superblock or we can't mount it */
  	ret = -EINVAL;
  	if (!fc->root)
  		goto err_unlock;
  
  	ret = -EPERM;
  	if (mount_too_revealing(fc->root->d_sb, &mnt_flags)) {
  		pr_warn("VFS: Mount too revealing
  ");
  		goto err_unlock;
  	}
  
  	ret = -EBUSY;
  	if (fc->phase != FS_CONTEXT_AWAITING_MOUNT)
  		goto err_unlock;
  
  	ret = -EPERM;
  	if ((fc->sb_flags & SB_MANDLOCK) && !may_mandlock())
  		goto err_unlock;
  
  	newmount.mnt = vfs_create_mount(fc);
  	if (IS_ERR(newmount.mnt)) {
  		ret = PTR_ERR(newmount.mnt);
  		goto err_unlock;
  	}
  	newmount.dentry = dget(fc->root);
  	newmount.mnt->mnt_flags = mnt_flags;
  
  	/* We've done the mount bit - now move the file context into more or
  	 * less the same state as if we'd done an fspick().  We don't want to
  	 * do any memory allocation or anything like that at this point as we
  	 * don't want to have to handle any errors incurred.
  	 */
  	vfs_clean_context(fc);
  
  	ns = alloc_mnt_ns(current->nsproxy->mnt_ns->user_ns, true);
  	if (IS_ERR(ns)) {
  		ret = PTR_ERR(ns);
  		goto err_path;
  	}
  	mnt = real_mount(newmount.mnt);
  	mnt->mnt_ns = ns;
  	ns->root = mnt;
  	ns->mounts = 1;
  	list_add(&mnt->mnt_list, &ns->list);
1b0b9cc8d   Eric Biggers   vfs: fsmount: add...
3384
  	mntget(newmount.mnt);
93766fbd2   David Howells   vfs: syscall: Add...
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
  
  	/* Attach to an apparent O_PATH fd with a note that we need to unmount
  	 * it, not just simply put it.
  	 */
  	file = dentry_open(&newmount, O_PATH, fc->cred);
  	if (IS_ERR(file)) {
  		dissolve_on_fput(newmount.mnt);
  		ret = PTR_ERR(file);
  		goto err_path;
  	}
  	file->f_mode |= FMODE_NEED_UNMOUNT;
  
  	ret = get_unused_fd_flags((flags & FSMOUNT_CLOEXEC) ? O_CLOEXEC : 0);
  	if (ret >= 0)
  		fd_install(ret, file);
  	else
  		fput(file);
  
  err_path:
  	path_put(&newmount);
  err_unlock:
  	mutex_unlock(&fc->uapi_mutex);
  err_fsfd:
  	fdput(f);
  	return ret;
  }
  
  /*
   * Move a mount from one place to another.  In combination with
   * fsopen()/fsmount() this is used to install a new mount and in combination
   * with open_tree(OPEN_TREE_CLONE [| AT_RECURSIVE]) it can be used to copy
   * a mount subtree.
2db154b3e   David Howells   vfs: syscall: Add...
3417
3418
3419
3420
   *
   * Note the flags value is a combination of MOVE_MOUNT_* flags.
   */
  SYSCALL_DEFINE5(move_mount,
2658ce095   Ben Dooks   fs/namespace: add...
3421
3422
  		int, from_dfd, const char __user *, from_pathname,
  		int, to_dfd, const char __user *, to_pathname,
2db154b3e   David Howells   vfs: syscall: Add...
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
  		unsigned int, flags)
  {
  	struct path from_path, to_path;
  	unsigned int lflags;
  	int ret = 0;
  
  	if (!may_mount())
  		return -EPERM;
  
  	if (flags & ~MOVE_MOUNT__MASK)
  		return -EINVAL;
  
  	/* If someone gives a pathname, they aren't permitted to move
  	 * from an fd that requires unmount as we can't get at the flag
  	 * to clear it afterwards.
  	 */
  	lflags = 0;
  	if (flags & MOVE_MOUNT_F_SYMLINKS)	lflags |= LOOKUP_FOLLOW;
  	if (flags & MOVE_MOUNT_F_AUTOMOUNTS)	lflags |= LOOKUP_AUTOMOUNT;
  	if (flags & MOVE_MOUNT_F_EMPTY_PATH)	lflags |= LOOKUP_EMPTY;
  
  	ret = user_path_at(from_dfd, from_pathname, lflags, &from_path);
  	if (ret < 0)
  		return ret;
  
  	lflags = 0;
  	if (flags & MOVE_MOUNT_T_SYMLINKS)	lflags |= LOOKUP_FOLLOW;
  	if (flags & MOVE_MOUNT_T_AUTOMOUNTS)	lflags |= LOOKUP_AUTOMOUNT;
  	if (flags & MOVE_MOUNT_T_EMPTY_PATH)	lflags |= LOOKUP_EMPTY;
  
  	ret = user_path_at(to_dfd, to_pathname, lflags, &to_path);
  	if (ret < 0)
  		goto out_from;
  
  	ret = security_move_mount(&from_path, &to_path);
  	if (ret < 0)
  		goto out_to;
  
  	ret = do_move_mount(&from_path, &to_path);
  
  out_to:
  	path_put(&to_path);
  out_from:
  	path_put(&from_path);
  	return ret;
  }
  
  /*
afac7cba7   Al Viro   vfs: more mnt_par...
3471
3472
   * Return true if path is reachable from root
   *
48a066e72   Al Viro   RCU'd vfsmounts
3473
   * namespace_sem or mount_lock is held
afac7cba7   Al Viro   vfs: more mnt_par...
3474
   */
643822b41   Al Viro   vfs: spread struc...
3475
  bool is_path_reachable(struct mount *mnt, struct dentry *dentry,
afac7cba7   Al Viro   vfs: more mnt_par...
3476
3477
  			 const struct path *root)
  {
643822b41   Al Viro   vfs: spread struc...
3478
  	while (&mnt->mnt != root->mnt && mnt_has_parent(mnt)) {
a73324da7   Al Viro   vfs: move mnt_mou...
3479
  		dentry = mnt->mnt_mountpoint;
0714a5338   Al Viro   vfs: now it can b...
3480
  		mnt = mnt->mnt_parent;
afac7cba7   Al Viro   vfs: more mnt_par...
3481
  	}
643822b41   Al Viro   vfs: spread struc...
3482
  	return &mnt->mnt == root->mnt && is_subdir(dentry, root->dentry);
afac7cba7   Al Viro   vfs: more mnt_par...
3483
  }
640eb7e7b   Mickaël Salaün   fs: Constify path...
3484
  bool path_is_under(const struct path *path1, const struct path *path2)
afac7cba7   Al Viro   vfs: more mnt_par...
3485
  {
25ab4c9b1   Yaowei Bai   fs/namespace.c: p...
3486
  	bool res;
48a066e72   Al Viro   RCU'd vfsmounts
3487
  	read_seqlock_excl(&mount_lock);
643822b41   Al Viro   vfs: spread struc...
3488
  	res = is_path_reachable(real_mount(path1->mnt), path1->dentry, path2);
48a066e72   Al Viro   RCU'd vfsmounts
3489
  	read_sequnlock_excl(&mount_lock);
afac7cba7   Al Viro   vfs: more mnt_par...
3490
3491
3492
3493
3494
  	return res;
  }
  EXPORT_SYMBOL(path_is_under);
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
   * pivot_root Semantics:
   * Moves the root file system of the current process to the directory put_old,
   * makes new_root as the new root file system of the current process, and sets
   * root/cwd of all processes which had them on the current root to new_root.
   *
   * Restrictions:
   * The new_root and put_old must be directories, and  must not be on the
   * same file  system as the current process root. The put_old  must  be
   * underneath new_root,  i.e. adding a non-zero number of /.. to the string
   * pointed to by put_old must yield the same directory as new_root. No other
   * file system may be mounted on put_old. After all, new_root is a mountpoint.
   *
4a0d11fae   Neil Brown   [PATCH] pivot_roo...
3507
   * Also, the current root cannot be on the 'rootfs' (initial ramfs) filesystem.
0c1bc6b84   Mauro Carvalho Chehab   docs: filesystems...
3508
   * See Documentation/filesystems/ramfs-rootfs-initramfs.rst for alternatives
4a0d11fae   Neil Brown   [PATCH] pivot_roo...
3509
3510
   * in this situation.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3511
3512
3513
3514
3515
3516
3517
3518
   * Notes:
   *  - we don't move root/cwd if they are not at the root (reason: if something
   *    cared enough to change them, it's probably wrong to force them elsewhere)
   *  - it's okay to pick a root that isn't the root of a file system, e.g.
   *    /nfs/my_root where /nfs is the mount point. It must be a mountpoint,
   *    though, so you may need to say mount --bind /nfs/my_root /nfs/my_root
   *    first.
   */
3480b2574   Heiko Carstens   [CVE-2009-0029] S...
3519
3520
  SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
  		const char __user *, put_old)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3521
  {
2763d1191   Al Viro   get rid of detach...
3522
3523
  	struct path new, old, root;
  	struct mount *new_mnt, *root_mnt, *old_mnt, *root_parent, *ex_parent;
84d17192d   Al Viro   get rid of full-h...
3524
  	struct mountpoint *old_mp, *root_mp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3525
  	int error;
9b40bc90a   Al Viro   get rid of unprot...
3526
  	if (!may_mount())
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3527
  		return -EPERM;
ce6595a28   Al Viro   kill the last use...
3528
3529
  	error = user_path_at(AT_FDCWD, new_root,
  			     LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &new);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3530
3531
  	if (error)
  		goto out0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3532

ce6595a28   Al Viro   kill the last use...
3533
3534
  	error = user_path_at(AT_FDCWD, put_old,
  			     LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3535
3536
  	if (error)
  		goto out1;
2d8f30380   Al Viro   [PATCH] sanitize ...
3537
  	error = security_sb_pivotroot(&old, &new);
b12cea919   Al Viro   change the lockin...
3538
3539
  	if (error)
  		goto out2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3540

f7ad3c6be   Miklos Szeredi   vfs: add helpers ...
3541
  	get_fs_root(current->fs, &root);
84d17192d   Al Viro   get rid of full-h...
3542
3543
3544
  	old_mp = lock_mount(&old);
  	error = PTR_ERR(old_mp);
  	if (IS_ERR(old_mp))
b12cea919   Al Viro   change the lockin...
3545
  		goto out3;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3546
  	error = -EINVAL;
419148da6   Al Viro   vfs: spread struc...
3547
3548
  	new_mnt = real_mount(new.mnt);
  	root_mnt = real_mount(root.mnt);
84d17192d   Al Viro   get rid of full-h...
3549
  	old_mnt = real_mount(old.mnt);
2763d1191   Al Viro   get rid of detach...
3550
3551
  	ex_parent = new_mnt->mnt_parent;
  	root_parent = root_mnt->mnt_parent;
84d17192d   Al Viro   get rid of full-h...
3552
  	if (IS_MNT_SHARED(old_mnt) ||
2763d1191   Al Viro   get rid of detach...
3553
3554
  		IS_MNT_SHARED(ex_parent) ||
  		IS_MNT_SHARED(root_parent))
b12cea919   Al Viro   change the lockin...
3555
  		goto out4;
143c8c91c   Al Viro   vfs: mnt_ns moved...
3556
  	if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
b12cea919   Al Viro   change the lockin...
3557
  		goto out4;
5ff9d8a65   Eric W. Biederman   vfs: Lock in plac...
3558
3559
  	if (new_mnt->mnt.mnt_flags & MNT_LOCKED)
  		goto out4;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3560
  	error = -ENOENT;
f3da392e9   Alexey Dobriyan   dcache: extrace a...
3561
  	if (d_unlinked(new.dentry))
b12cea919   Al Viro   change the lockin...
3562
  		goto out4;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3563
  	error = -EBUSY;
84d17192d   Al Viro   get rid of full-h...
3564
  	if (new_mnt == root_mnt || old_mnt == root_mnt)
b12cea919   Al Viro   change the lockin...
3565
  		goto out4; /* loop, on the same file system  */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3566
  	error = -EINVAL;
8c3ee42e8   Al Viro   [PATCH] get rid o...
3567
  	if (root.mnt->mnt_root != root.dentry)
b12cea919   Al Viro   change the lockin...
3568
  		goto out4; /* not a mountpoint */
676da58df   Al Viro   vfs: spread struc...
3569
  	if (!mnt_has_parent(root_mnt))
b12cea919   Al Viro   change the lockin...
3570
  		goto out4; /* not attached */
2d8f30380   Al Viro   [PATCH] sanitize ...
3571
  	if (new.mnt->mnt_root != new.dentry)
b12cea919   Al Viro   change the lockin...
3572
  		goto out4; /* not a mountpoint */
676da58df   Al Viro   vfs: spread struc...
3573
  	if (!mnt_has_parent(new_mnt))
b12cea919   Al Viro   change the lockin...
3574
  		goto out4; /* not attached */
4ac913785   Jan Blunck   Embed a struct pa...
3575
  	/* make sure we can reach put_old from new_root */
84d17192d   Al Viro   get rid of full-h...
3576
  	if (!is_path_reachable(old_mnt, old.dentry, &new))
b12cea919   Al Viro   change the lockin...
3577
  		goto out4;
0d0826019   Eric W. Biederman   mnt: Prevent pivo...
3578
3579
3580
  	/* make certain new is below the root */
  	if (!is_path_reachable(new_mnt, new.dentry, &root))
  		goto out4;
719ea2fbb   Al Viro   new helpers: lock...
3581
  	lock_mount_hash();
2763d1191   Al Viro   get rid of detach...
3582
3583
  	umount_mnt(new_mnt);
  	root_mp = unhash_mnt(root_mnt);  /* we'll need its mountpoint */
5ff9d8a65   Eric W. Biederman   vfs: Lock in plac...
3584
3585
3586
3587
  	if (root_mnt->mnt.mnt_flags & MNT_LOCKED) {
  		new_mnt->mnt.mnt_flags |= MNT_LOCKED;
  		root_mnt->mnt.mnt_flags &= ~MNT_LOCKED;
  	}
4ac913785   Jan Blunck   Embed a struct pa...
3588
  	/* mount old root on put_old */
84d17192d   Al Viro   get rid of full-h...
3589
  	attach_mnt(root_mnt, old_mnt, old_mp);
4ac913785   Jan Blunck   Embed a struct pa...
3590
  	/* mount new_root on / */
2763d1191   Al Viro   get rid of detach...
3591
3592
  	attach_mnt(new_mnt, root_parent, root_mp);
  	mnt_add_count(root_parent, -1);
6b3286ed1   Kirill Korotaev   [PATCH] rename st...
3593
  	touch_mnt_namespace(current->nsproxy->mnt_ns);
4fed655c4   Eric W. Biederman   mnt: Clear mnt_ex...
3594
3595
  	/* A moved mount should not expire automatically */
  	list_del_init(&new_mnt->mnt_expire);
3895dbf89   Eric W. Biederman   mnt: Protect the ...
3596
  	put_mountpoint(root_mp);
719ea2fbb   Al Viro   new helpers: lock...
3597
  	unlock_mount_hash();
2d8f30380   Al Viro   [PATCH] sanitize ...
3598
  	chroot_fs_refs(&root, &new);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3599
  	error = 0;
b12cea919   Al Viro   change the lockin...
3600
  out4:
84d17192d   Al Viro   get rid of full-h...
3601
  	unlock_mount(old_mp);
2763d1191   Al Viro   get rid of detach...
3602
3603
  	if (!error)
  		mntput_no_expire(ex_parent);
b12cea919   Al Viro   change the lockin...
3604
  out3:
8c3ee42e8   Al Viro   [PATCH] get rid o...
3605
  	path_put(&root);
b12cea919   Al Viro   change the lockin...
3606
  out2:
2d8f30380   Al Viro   [PATCH] sanitize ...
3607
  	path_put(&old);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3608
  out1:
2d8f30380   Al Viro   [PATCH] sanitize ...
3609
  	path_put(&new);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3610
  out0:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3611
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3612
3613
3614
3615
3616
  }
  
  static void __init init_mount_tree(void)
  {
  	struct vfsmount *mnt;
74e831221   Al Viro   saner handling of...
3617
  	struct mount *m;
6b3286ed1   Kirill Korotaev   [PATCH] rename st...
3618
  	struct mnt_namespace *ns;
ac748a09f   Jan Blunck   Make set_fs_{root...
3619
  	struct path root;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3620

fd3e007f6   Al Viro   don't bother with...
3621
  	mnt = vfs_kern_mount(&rootfs_fs_type, 0, "rootfs", NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3622
3623
  	if (IS_ERR(mnt))
  		panic("Can't create rootfs");
b3e19d924   Nick Piggin   fs: scale mntget/...
3624

74e831221   Al Viro   saner handling of...
3625
  	ns = alloc_mnt_ns(&init_user_ns, false);
3b22edc57   Trond Myklebust   VFS: Switch init_...
3626
  	if (IS_ERR(ns))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3627
  		panic("Can't allocate initial namespace");
74e831221   Al Viro   saner handling of...
3628
3629
3630
3631
3632
  	m = real_mount(mnt);
  	m->mnt_ns = ns;
  	ns->root = m;
  	ns->mounts = 1;
  	list_add(&m->mnt_list, &ns->list);
6b3286ed1   Kirill Korotaev   [PATCH] rename st...
3633
3634
  	init_task.nsproxy->mnt_ns = ns;
  	get_mnt_ns(ns);
be08d6d26   Al Viro   switch mnt_namesp...
3635
3636
  	root.mnt = mnt;
  	root.dentry = mnt->mnt_root;
da362b09e   Eric W. Biederman   umount: Do not al...
3637
  	mnt->mnt_flags |= MNT_LOCKED;
ac748a09f   Jan Blunck   Make set_fs_{root...
3638
3639
3640
  
  	set_fs_pwd(current->fs, &root);
  	set_fs_root(current->fs, &root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3641
  }
74bf17cff   Denis Cheng   fs: remove the un...
3642
  void __init mnt_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3643
  {
15a67dd8c   Randy Dunlap   [PATCH] fs/namesp...
3644
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3645

7d6fec45a   Al Viro   vfs: start hiding...
3646
  	mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct mount),
20c2df83d   Paul Mundt   mm: Remove slab d...
3647
  			0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3648

0818bf27c   Al Viro   resizable namespa...
3649
  	mount_hashtable = alloc_large_system_hash("Mount-cache",
38129a13e   Al Viro   switch mnt_hash t...
3650
  				sizeof(struct hlist_head),
0818bf27c   Al Viro   resizable namespa...
3651
  				mhash_entries, 19,
3d375d785   Pavel Tatashin   mm: update caller...
3652
  				HASH_ZERO,
0818bf27c   Al Viro   resizable namespa...
3653
3654
3655
3656
  				&m_hash_shift, &m_hash_mask, 0, 0);
  	mountpoint_hashtable = alloc_large_system_hash("Mountpoint-cache",
  				sizeof(struct hlist_head),
  				mphash_entries, 19,
3d375d785   Pavel Tatashin   mm: update caller...
3657
  				HASH_ZERO,
0818bf27c   Al Viro   resizable namespa...
3658
  				&mp_hash_shift, &mp_hash_mask, 0, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3659

84d17192d   Al Viro   get rid of full-h...
3660
  	if (!mount_hashtable || !mountpoint_hashtable)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3661
3662
  		panic("Failed to allocate mount hash table
  ");
4b93dc9b1   Tejun Heo   sysfs, kernfs: pr...
3663
  	kernfs_init();
15a67dd8c   Randy Dunlap   [PATCH] fs/namesp...
3664
3665
3666
3667
  	err = sysfs_init();
  	if (err)
  		printk(KERN_WARNING "%s: sysfs_init error: %d
  ",
8e24eea72   Harvey Harrison   fs: replace remai...
3668
  			__func__, err);
00d266662   Greg Kroah-Hartman   kobject: convert ...
3669
3670
  	fs_kobj = kobject_create_and_add("fs", NULL);
  	if (!fs_kobj)
8e24eea72   Harvey Harrison   fs: replace remai...
3671
3672
  		printk(KERN_WARNING "%s: kobj create error
  ", __func__);
037f11b47   Al Viro   mnt_init(): call ...
3673
  	shmem_init();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3674
3675
3676
  	init_rootfs();
  	init_mount_tree();
  }
616511d03   Trond Myklebust   VFS: Uninline the...
3677
  void put_mnt_ns(struct mnt_namespace *ns)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3678
  {
d498b25a4   Al Viro   get rid of useles...
3679
  	if (!atomic_dec_and_test(&ns->count))
616511d03   Trond Myklebust   VFS: Uninline the...
3680
  		return;
7b00ed6fe   Al Viro   put_mnt_ns(): use...
3681
  	drop_collected_mounts(&ns->root->mnt);
771b13716   Eric W. Biederman   vfs: Add a user n...
3682
  	free_mnt_ns(ns);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3683
  }
9d412a43c   Al Viro   vfs: split off vf...
3684

d911b4585   David Howells   vfs: Remove kern_...
3685
  struct vfsmount *kern_mount(struct file_system_type *type)
9d412a43c   Al Viro   vfs: split off vf...
3686
  {
423e0ab08   Tim Chen   VFS : mount lock ...
3687
  	struct vfsmount *mnt;
d911b4585   David Howells   vfs: Remove kern_...
3688
  	mnt = vfs_kern_mount(type, SB_KERNMOUNT, type->name, NULL);
423e0ab08   Tim Chen   VFS : mount lock ...
3689
3690
3691
3692
3693
  	if (!IS_ERR(mnt)) {
  		/*
  		 * it is a longterm mount, don't release mnt until
  		 * we unmount before file sys is unregistered
  		*/
f7a99c5b7   Al Viro   get rid of ->mnt_...
3694
  		real_mount(mnt)->mnt_ns = MNT_NS_INTERNAL;
423e0ab08   Tim Chen   VFS : mount lock ...
3695
3696
  	}
  	return mnt;
9d412a43c   Al Viro   vfs: split off vf...
3697
  }
d911b4585   David Howells   vfs: Remove kern_...
3698
  EXPORT_SYMBOL_GPL(kern_mount);
423e0ab08   Tim Chen   VFS : mount lock ...
3699
3700
3701
3702
3703
  
  void kern_unmount(struct vfsmount *mnt)
  {
  	/* release long term mount so mount point can be released */
  	if (!IS_ERR_OR_NULL(mnt)) {
f7a99c5b7   Al Viro   get rid of ->mnt_...
3704
  		real_mount(mnt)->mnt_ns = NULL;
48a066e72   Al Viro   RCU'd vfsmounts
3705
  		synchronize_rcu();	/* yecchhh... */
423e0ab08   Tim Chen   VFS : mount lock ...
3706
3707
3708
3709
  		mntput(mnt);
  	}
  }
  EXPORT_SYMBOL(kern_unmount);
02125a826   Al Viro   fix apparmor dere...
3710

df820f8de   Miklos Szeredi   ovl: make private...
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
  void kern_unmount_array(struct vfsmount *mnt[], unsigned int num)
  {
  	unsigned int i;
  
  	for (i = 0; i < num; i++)
  		if (mnt[i])
  			real_mount(mnt[i])->mnt_ns = NULL;
  	synchronize_rcu_expedited();
  	for (i = 0; i < num; i++)
  		mntput(mnt[i]);
  }
  EXPORT_SYMBOL(kern_unmount_array);
02125a826   Al Viro   fix apparmor dere...
3723
3724
  bool our_mnt(struct vfsmount *mnt)
  {
143c8c91c   Al Viro   vfs: mnt_ns moved...
3725
  	return check_mnt(real_mount(mnt));
02125a826   Al Viro   fix apparmor dere...
3726
  }
8823c079b   Eric W. Biederman   vfs: Add setns su...
3727

3151527ee   Eric W. Biederman   userns: Don't al...
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
  bool current_chrooted(void)
  {
  	/* Does the current process have a non-standard root */
  	struct path ns_root;
  	struct path fs_root;
  	bool chrooted;
  
  	/* Find the namespace root */
  	ns_root.mnt = &current->nsproxy->mnt_ns->root->mnt;
  	ns_root.dentry = ns_root.mnt->mnt_root;
  	path_get(&ns_root);
  	while (d_mountpoint(ns_root.dentry) && follow_down_one(&ns_root))
  		;
  
  	get_fs_root(current->fs, &fs_root);
  
  	chrooted = !path_equal(&fs_root, &ns_root);
  
  	path_put(&fs_root);
  	path_put(&ns_root);
  
  	return chrooted;
  }
132e46084   David Howells   new helper: do_ne...
3751
3752
  static bool mnt_already_visible(struct mnt_namespace *ns,
  				const struct super_block *sb,
8654df4e2   Eric W. Biederman   mnt: Refactor fs_...
3753
  				int *new_mnt_flags)
87a8ebd63   Eric W. Biederman   userns: Restrict ...
3754
  {
8c6cf9cc8   Eric W. Biederman   mnt: Modify fs_fu...
3755
  	int new_flags = *new_mnt_flags;
87a8ebd63   Eric W. Biederman   userns: Restrict ...
3756
  	struct mount *mnt;
e51db7353   Eric W. Biederman   userns: Better re...
3757
  	bool visible = false;
87a8ebd63   Eric W. Biederman   userns: Restrict ...
3758

44bb4385c   Al Viro   fs_is_visible onl...
3759
  	down_read(&namespace_sem);
9f6c61f96   Miklos Szeredi   proc/mounts: add ...
3760
  	lock_ns_list(ns);
87a8ebd63   Eric W. Biederman   userns: Restrict ...
3761
  	list_for_each_entry(mnt, &ns->list, mnt_list) {
e51db7353   Eric W. Biederman   userns: Better re...
3762
  		struct mount *child;
77b1a97d2   Eric W. Biederman   mnt: fs_fully_vis...
3763
  		int mnt_flags;
9f6c61f96   Miklos Szeredi   proc/mounts: add ...
3764
3765
  		if (mnt_is_cursor(mnt))
  			continue;
132e46084   David Howells   new helper: do_ne...
3766
  		if (mnt->mnt.mnt_sb->s_type != sb->s_type)
e51db7353   Eric W. Biederman   userns: Better re...
3767
  			continue;
7e96c1b0e   Eric W. Biederman   mnt: Fix fs_fully...
3768
3769
3770
3771
3772
  		/* This mount is not fully visible if it's root directory
  		 * is not the root directory of the filesystem.
  		 */
  		if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root)
  			continue;
a1935c173   Eric W. Biederman   mnt: Simplify mou...
3773
  		/* A local view of the mount flags */
77b1a97d2   Eric W. Biederman   mnt: fs_fully_vis...
3774
  		mnt_flags = mnt->mnt.mnt_flags;
77b1a97d2   Eric W. Biederman   mnt: fs_fully_vis...
3775

695e9df01   Eric W. Biederman   mnt: Account for ...
3776
  		/* Don't miss readonly hidden in the superblock flags */
bc98a42c1   David Howells   VFS: Convert sb->...
3777
  		if (sb_rdonly(mnt->mnt.mnt_sb))
695e9df01   Eric W. Biederman   mnt: Account for ...
3778
  			mnt_flags |= MNT_LOCK_READONLY;
8c6cf9cc8   Eric W. Biederman   mnt: Modify fs_fu...
3779
3780
3781
  		/* Verify the mount flags are equal to or more permissive
  		 * than the proposed new mount.
  		 */
77b1a97d2   Eric W. Biederman   mnt: fs_fully_vis...
3782
  		if ((mnt_flags & MNT_LOCK_READONLY) &&
8c6cf9cc8   Eric W. Biederman   mnt: Modify fs_fu...
3783
3784
  		    !(new_flags & MNT_READONLY))
  			continue;
77b1a97d2   Eric W. Biederman   mnt: fs_fully_vis...
3785
3786
  		if ((mnt_flags & MNT_LOCK_ATIME) &&
  		    ((mnt_flags & MNT_ATIME_MASK) != (new_flags & MNT_ATIME_MASK)))
8c6cf9cc8   Eric W. Biederman   mnt: Modify fs_fu...
3787
  			continue;
ceeb0e5d3   Eric W. Biederman   vfs: Ignore unloc...
3788
3789
3790
  		/* This mount is not fully visible if there are any
  		 * locked child mounts that cover anything except for
  		 * empty directories.
e51db7353   Eric W. Biederman   userns: Better re...
3791
3792
3793
  		 */
  		list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
  			struct inode *inode = child->mnt_mountpoint->d_inode;
ceeb0e5d3   Eric W. Biederman   vfs: Ignore unloc...
3794
  			/* Only worry about locked mounts */
d71ed6c93   Eric W. Biederman   mnt: fs_fully_vis...
3795
  			if (!(child->mnt.mnt_flags & MNT_LOCKED))
ceeb0e5d3   Eric W. Biederman   vfs: Ignore unloc...
3796
  				continue;
7236c85e1   Eric W. Biederman   mnt: Update fs_fu...
3797
3798
  			/* Is the directory permanetly empty? */
  			if (!is_empty_dir_inode(inode))
e51db7353   Eric W. Biederman   userns: Better re...
3799
  				goto next;
87a8ebd63   Eric W. Biederman   userns: Restrict ...
3800
  		}
8c6cf9cc8   Eric W. Biederman   mnt: Modify fs_fu...
3801
  		/* Preserve the locked attributes */
77b1a97d2   Eric W. Biederman   mnt: fs_fully_vis...
3802
  		*new_mnt_flags |= mnt_flags & (MNT_LOCK_READONLY | \
77b1a97d2   Eric W. Biederman   mnt: fs_fully_vis...
3803
  					       MNT_LOCK_ATIME);
e51db7353   Eric W. Biederman   userns: Better re...
3804
3805
3806
  		visible = true;
  		goto found;
  	next:	;
87a8ebd63   Eric W. Biederman   userns: Restrict ...
3807
  	}
e51db7353   Eric W. Biederman   userns: Better re...
3808
  found:
9f6c61f96   Miklos Szeredi   proc/mounts: add ...
3809
  	unlock_ns_list(ns);
44bb4385c   Al Viro   fs_is_visible onl...
3810
  	up_read(&namespace_sem);
e51db7353   Eric W. Biederman   userns: Better re...
3811
  	return visible;
87a8ebd63   Eric W. Biederman   userns: Restrict ...
3812
  }
132e46084   David Howells   new helper: do_ne...
3813
  static bool mount_too_revealing(const struct super_block *sb, int *new_mnt_flags)
8654df4e2   Eric W. Biederman   mnt: Refactor fs_...
3814
  {
a1935c173   Eric W. Biederman   mnt: Simplify mou...
3815
  	const unsigned long required_iflags = SB_I_NOEXEC | SB_I_NODEV;
8654df4e2   Eric W. Biederman   mnt: Refactor fs_...
3816
3817
3818
3819
3820
3821
3822
  	struct mnt_namespace *ns = current->nsproxy->mnt_ns;
  	unsigned long s_iflags;
  
  	if (ns->user_ns == &init_user_ns)
  		return false;
  
  	/* Can this filesystem be too revealing? */
132e46084   David Howells   new helper: do_ne...
3823
  	s_iflags = sb->s_iflags;
8654df4e2   Eric W. Biederman   mnt: Refactor fs_...
3824
3825
  	if (!(s_iflags & SB_I_USERNS_VISIBLE))
  		return false;
a1935c173   Eric W. Biederman   mnt: Simplify mou...
3826
3827
3828
3829
3830
3831
  	if ((s_iflags & required_iflags) != required_iflags) {
  		WARN_ONCE(1, "Expected s_iflags to contain 0x%lx
  ",
  			  required_iflags);
  		return true;
  	}
132e46084   David Howells   new helper: do_ne...
3832
  	return !mnt_already_visible(ns, sb, new_mnt_flags);
8654df4e2   Eric W. Biederman   mnt: Refactor fs_...
3833
  }
380cf5ba6   Andy Lutomirski   fs: Treat foreign...
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
  bool mnt_may_suid(struct vfsmount *mnt)
  {
  	/*
  	 * Foreign mounts (accessed via fchdir or through /proc
  	 * symlinks) are always treated as if they are nosuid.  This
  	 * prevents namespaces from trusting potentially unsafe
  	 * suid/sgid bits, file caps, or security labels that originate
  	 * in other namespaces.
  	 */
  	return !(mnt->mnt_flags & MNT_NOSUID) && check_mnt(real_mount(mnt)) &&
  	       current_in_userns(mnt->mnt_sb->s_user_ns);
  }
64964528b   Al Viro   make proc_ns_oper...
3846
  static struct ns_common *mntns_get(struct task_struct *task)
8823c079b   Eric W. Biederman   vfs: Add setns su...
3847
  {
58be28256   Al Viro   make mntns ->get(...
3848
  	struct ns_common *ns = NULL;
8823c079b   Eric W. Biederman   vfs: Add setns su...
3849
  	struct nsproxy *nsproxy;
728dba3a3   Eric W. Biederman   namespaces: Use t...
3850
3851
  	task_lock(task);
  	nsproxy = task->nsproxy;
8823c079b   Eric W. Biederman   vfs: Add setns su...
3852
  	if (nsproxy) {
58be28256   Al Viro   make mntns ->get(...
3853
3854
  		ns = &nsproxy->mnt_ns->ns;
  		get_mnt_ns(to_mnt_ns(ns));
8823c079b   Eric W. Biederman   vfs: Add setns su...
3855
  	}
728dba3a3   Eric W. Biederman   namespaces: Use t...
3856
  	task_unlock(task);
8823c079b   Eric W. Biederman   vfs: Add setns su...
3857
3858
3859
  
  	return ns;
  }
64964528b   Al Viro   make proc_ns_oper...
3860
  static void mntns_put(struct ns_common *ns)
8823c079b   Eric W. Biederman   vfs: Add setns su...
3861
  {
58be28256   Al Viro   make mntns ->get(...
3862
  	put_mnt_ns(to_mnt_ns(ns));
8823c079b   Eric W. Biederman   vfs: Add setns su...
3863
  }
f2a8d52e0   Christian Brauner   nsproxy: add stru...
3864
  static int mntns_install(struct nsset *nsset, struct ns_common *ns)
8823c079b   Eric W. Biederman   vfs: Add setns su...
3865
  {
f2a8d52e0   Christian Brauner   nsproxy: add stru...
3866
3867
  	struct nsproxy *nsproxy = nsset->nsproxy;
  	struct fs_struct *fs = nsset->fs;
4f757f3cb   Al Viro   make sure that mn...
3868
  	struct mnt_namespace *mnt_ns = to_mnt_ns(ns), *old_mnt_ns;
f2a8d52e0   Christian Brauner   nsproxy: add stru...
3869
  	struct user_namespace *user_ns = nsset->cred->user_ns;
8823c079b   Eric W. Biederman   vfs: Add setns su...
3870
  	struct path root;
4f757f3cb   Al Viro   make sure that mn...
3871
  	int err;
8823c079b   Eric W. Biederman   vfs: Add setns su...
3872

0c55cfc41   Eric W. Biederman   vfs: Allow unpriv...
3873
  	if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) ||
f2a8d52e0   Christian Brauner   nsproxy: add stru...
3874
3875
  	    !ns_capable(user_ns, CAP_SYS_CHROOT) ||
  	    !ns_capable(user_ns, CAP_SYS_ADMIN))
ae11e0f18   Zhao Hongjiang   userns: fix retur...
3876
  		return -EPERM;
8823c079b   Eric W. Biederman   vfs: Add setns su...
3877

74e831221   Al Viro   saner handling of...
3878
3879
  	if (is_anon_ns(mnt_ns))
  		return -EINVAL;
8823c079b   Eric W. Biederman   vfs: Add setns su...
3880
3881
3882
3883
  	if (fs->users != 1)
  		return -EINVAL;
  
  	get_mnt_ns(mnt_ns);
4f757f3cb   Al Viro   make sure that mn...
3884
  	old_mnt_ns = nsproxy->mnt_ns;
8823c079b   Eric W. Biederman   vfs: Add setns su...
3885
3886
3887
  	nsproxy->mnt_ns = mnt_ns;
  
  	/* Find the root */
4f757f3cb   Al Viro   make sure that mn...
3888
3889
3890
3891
3892
3893
3894
3895
  	err = vfs_path_lookup(mnt_ns->root->mnt.mnt_root, &mnt_ns->root->mnt,
  				"/", LOOKUP_DOWN, &root);
  	if (err) {
  		/* revert to old namespace */
  		nsproxy->mnt_ns = old_mnt_ns;
  		put_mnt_ns(mnt_ns);
  		return err;
  	}
8823c079b   Eric W. Biederman   vfs: Add setns su...
3896

4068367c9   Andrei Vagin   fs: don't forget ...
3897
  	put_mnt_ns(old_mnt_ns);
8823c079b   Eric W. Biederman   vfs: Add setns su...
3898
3899
3900
3901
3902
3903
3904
  	/* Update the pwd and root */
  	set_fs_pwd(fs, &root);
  	set_fs_root(fs, &root);
  
  	path_put(&root);
  	return 0;
  }
bcac25a58   Andrey Vagin   kernel: add a hel...
3905
3906
3907
3908
  static struct user_namespace *mntns_owner(struct ns_common *ns)
  {
  	return to_mnt_ns(ns)->user_ns;
  }
8823c079b   Eric W. Biederman   vfs: Add setns su...
3909
3910
3911
3912
3913
3914
  const struct proc_ns_operations mntns_operations = {
  	.name		= "mnt",
  	.type		= CLONE_NEWNS,
  	.get		= mntns_get,
  	.put		= mntns_put,
  	.install	= mntns_install,
bcac25a58   Andrey Vagin   kernel: add a hel...
3915
  	.owner		= mntns_owner,
8823c079b   Eric W. Biederman   vfs: Add setns su...
3916
  };