Blame view

fs/namei.c 81.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  /*
   *  linux/fs/namei.c
   *
   *  Copyright (C) 1991, 1992  Linus Torvalds
   */
  
  /*
   * Some corrections by tytso.
   */
  
  /* [Feb 1997 T. Schoebel-Theuer] Complete rewrite of the pathname
   * lookup logic.
   */
  /* [Feb-Apr 2000, AV] Rewrite to the new namespace architecture.
   */
  
  #include <linux/init.h>
  #include <linux/module.h>
  #include <linux/slab.h>
  #include <linux/fs.h>
  #include <linux/namei.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
  #include <linux/pagemap.h>
0eeca2830   Robert Love   [PATCH] inotify
23
  #include <linux/fsnotify.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
25
  #include <linux/personality.h>
  #include <linux/security.h>
6146f0d5e   Mimi Zohar   integrity: IMA hooks
26
  #include <linux/ima.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
  #include <linux/syscalls.h>
  #include <linux/mount.h>
  #include <linux/audit.h>
16f7e0fe2   Randy Dunlap   [PATCH] capable/c...
30
  #include <linux/capability.h>
834f2a4a1   Trond Myklebust   VFS: Allow the fi...
31
  #include <linux/file.h>
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
32
  #include <linux/fcntl.h>
08ce5f16e   Serge E. Hallyn   cgroups: implemen...
33
  #include <linux/device_cgroup.h>
5ad4e53bd   Al Viro   Get rid of indire...
34
  #include <linux/fs_struct.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
  #include <asm/uaccess.h>
e81e3f4dc   Eric Paris   fs: move get_empt...
36
  #include "internal.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
  /* [Feb-1997 T. Schoebel-Theuer]
   * Fundamental changes in the pathname lookup mechanisms (namei)
   * were necessary because of omirr.  The reason is that omirr needs
   * to know the _real_ pathname, not the user-supplied one, in case
   * of symlinks (and also when transname replacements occur).
   *
   * The new code replaces the old recursive symlink resolution with
   * an iterative one (in case of non-nested symlink chains).  It does
   * this with calls to <fs>_follow_link().
   * As a side effect, dir_namei(), _namei() and follow_link() are now 
   * replaced with a single function lookup_dentry() that can handle all 
   * the special cases of the former code.
   *
   * With the new dcache, the pathname is stored at each inode, at least as
   * long as the refcount of the inode is positive.  As a side effect, the
   * size of the dcache depends on the inode cache and thus is dynamic.
   *
   * [29-Apr-1998 C. Scott Ananian] Updated above description of symlink
   * resolution to correspond with current state of the code.
   *
   * Note that the symlink resolution is not *completely* iterative.
   * There is still a significant amount of tail- and mid- recursion in
   * the algorithm.  Also, note that <fs>_readlink() is not used in
   * lookup_dentry(): lookup_dentry() on the result of <fs>_readlink()
   * may return different results than <fs>_follow_link().  Many virtual
   * filesystems (including /proc) exhibit this behavior.
   */
  
  /* [24-Feb-97 T. Schoebel-Theuer] Side effects caused by new implementation:
   * New symlink semantics: when open() is called with flags O_CREAT | O_EXCL
   * and the name already exists in form of a symlink, try to create the new
   * name indicated by the symlink. The old code always complained that the
   * name already exists, due to not following the symlink even if its target
   * is nonexistent.  The new semantics affects also mknod() and link() when
25985edce   Lucas De Marchi   Fix common misspe...
71
   * the name is a symlink pointing to a non-existent name.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
   *
   * I don't know which semantics is the right one, since I have no access
   * to standards. But I found by trial that HP-UX 9.0 has the full "new"
   * semantics implemented, while SunOS 4.1.1 and Solaris (SunOS 5.4) have the
   * "old" one. Personally, I think the new semantics is much more logical.
   * Note that "ln old new" where "new" is a symlink pointing to a non-existing
   * file does succeed in both HP-UX and SunOs, but not in Solaris
   * and in the old Linux semantics.
   */
  
  /* [16-Dec-97 Kevin Buhr] For security reasons, we change some symlink
   * semantics.  See the comments in "open_namei" and "do_link" below.
   *
   * [10-Sep-98 Alan Modra] Another symlink change.
   */
  
  /* [Feb-Apr 2000 AV] Complete rewrite. Rules for symlinks:
   *	inside the path - always follow.
   *	in the last component in creation/removal/renaming - never follow.
   *	if LOOKUP_FOLLOW passed - follow.
   *	if the pathname has trailing slashes - follow.
   *	otherwise - don't follow.
   * (applied in that order).
   *
   * [Jun 2000 AV] Inconsistent behaviour of open() in case if flags==O_CREAT
   * restored for 2.4. This is the last surviving part of old 4.2BSD bug.
   * During the 2.4 we need to fix the userland stuff depending on it -
   * hopefully we will be able to get rid of that wart in 2.5. So far only
   * XEmacs seems to be relying on it...
   */
  /*
   * [Sep 2001 AV] Single-semaphore locking scheme (kudos to David Holland)
a11f3a057   Arjan van de Ven   [PATCH] sem2mutex...
104
   * implemented.  Let's see if raised priority of ->s_vfs_rename_mutex gives
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
105
106
107
108
109
110
111
112
113
114
   * any extra contention...
   */
  
  /* In order to reduce some races, while at the same time doing additional
   * checking and hopefully speeding things up, we copy filenames to the
   * kernel data space before using them..
   *
   * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
   * PATH_MAX includes the nul terminator --RR.
   */
858119e15   Arjan van de Ven   [PATCH] Unlinline...
115
  static int do_getname(const char __user *filename, char *page)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
  {
  	int retval;
  	unsigned long len = PATH_MAX;
  
  	if (!segment_eq(get_fs(), KERNEL_DS)) {
  		if ((unsigned long) filename >= TASK_SIZE)
  			return -EFAULT;
  		if (TASK_SIZE - (unsigned long) filename < PATH_MAX)
  			len = TASK_SIZE - (unsigned long) filename;
  	}
  
  	retval = strncpy_from_user(page, filename, len);
  	if (retval > 0) {
  		if (retval < len)
  			return 0;
  		return -ENAMETOOLONG;
  	} else if (!retval)
  		retval = -ENOENT;
  	return retval;
  }
f52e0c113   Al Viro   New AT_... flag: ...
136
  static char *getname_flags(const char __user * filename, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
138
139
140
141
142
143
144
145
146
  {
  	char *tmp, *result;
  
  	result = ERR_PTR(-ENOMEM);
  	tmp = __getname();
  	if (tmp)  {
  		int retval = do_getname(filename, tmp);
  
  		result = tmp;
  		if (retval < 0) {
f52e0c113   Al Viro   New AT_... flag: ...
147
148
149
150
  			if (retval != -ENOENT || !(flags & LOOKUP_EMPTY)) {
  				__putname(tmp);
  				result = ERR_PTR(retval);
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
153
154
155
  		}
  	}
  	audit_getname(result);
  	return result;
  }
f52e0c113   Al Viro   New AT_... flag: ...
156
157
158
159
  char *getname(const char __user * filename)
  {
  	return getname_flags(filename, 0);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
161
162
  #ifdef CONFIG_AUDITSYSCALL
  void putname(const char *name)
  {
5ac3a9c26   Al Viro   [PATCH] don't bot...
163
  	if (unlikely(!audit_dummy_context()))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
165
166
167
168
169
  		audit_putname(name);
  	else
  		__putname(name);
  }
  EXPORT_SYMBOL(putname);
  #endif
5909ccaa3   Linus Torvalds   Make 'check_acl()...
170
171
  /*
   * This does basic POSIX ACL permission checking
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
   */
b74c79e99   Nick Piggin   fs: provide rcu-w...
173
174
  static int acl_permission_check(struct inode *inode, int mask, unsigned int flags,
  		int (*check_acl)(struct inode *inode, int mask, unsigned int flags))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
175
  {
26cf46be9   Linus Torvalds   vfs: micro-optimi...
176
  	unsigned int mode = inode->i_mode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177

e6305c43e   Al Viro   [PATCH] sanitize ...
178
  	mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
e795b7179   Serge E. Hallyn   userns: userns: c...
179
180
  	if (current_user_ns() != inode_userns(inode))
  		goto other_perms;
da9592ede   David Howells   CRED: Wrap task c...
181
  	if (current_fsuid() == inode->i_uid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
183
184
  		mode >>= 6;
  	else {
  		if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl) {
b74c79e99   Nick Piggin   fs: provide rcu-w...
185
186
187
  			int error = check_acl(inode, mask, flags);
  			if (error != -EAGAIN)
  				return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
189
190
191
192
  		}
  
  		if (in_group_p(inode->i_gid))
  			mode >>= 3;
  	}
e795b7179   Serge E. Hallyn   userns: userns: c...
193
  other_perms:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
194
195
196
  	/*
  	 * If the DACs are ok we don't need any capability check.
  	 */
e6305c43e   Al Viro   [PATCH] sanitize ...
197
  	if ((mask & ~mode) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
198
  		return 0;
5909ccaa3   Linus Torvalds   Make 'check_acl()...
199
200
201
202
  	return -EACCES;
  }
  
  /**
b74c79e99   Nick Piggin   fs: provide rcu-w...
203
   * generic_permission -  check for access rights on a Posix-like filesystem
5909ccaa3   Linus Torvalds   Make 'check_acl()...
204
205
206
   * @inode:	inode to check access rights for
   * @mask:	right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
   * @check_acl:	optional callback to check for Posix ACLs
39191628e   Randy Dunlap   fs: fix namei.c k...
207
   * @flags:	IPERM_FLAG_ flags.
5909ccaa3   Linus Torvalds   Make 'check_acl()...
208
209
210
211
   *
   * Used to check for read/write/execute permissions on a file.
   * We use "fsuid" for this, letting us set arbitrary permissions
   * for filesystem access without changing the "normal" uids which
b74c79e99   Nick Piggin   fs: provide rcu-w...
212
213
214
215
216
   * are used for other things.
   *
   * generic_permission is rcu-walk aware. It returns -ECHILD in case an rcu-walk
   * request cannot be satisfied (eg. requires blocking or too much complexity).
   * It would then be called again in ref-walk mode.
5909ccaa3   Linus Torvalds   Make 'check_acl()...
217
   */
b74c79e99   Nick Piggin   fs: provide rcu-w...
218
219
  int generic_permission(struct inode *inode, int mask, unsigned int flags,
  	int (*check_acl)(struct inode *inode, int mask, unsigned int flags))
5909ccaa3   Linus Torvalds   Make 'check_acl()...
220
221
222
223
224
225
  {
  	int ret;
  
  	/*
  	 * Do the basic POSIX ACL permission checks.
  	 */
b74c79e99   Nick Piggin   fs: provide rcu-w...
226
  	ret = acl_permission_check(inode, mask, flags, check_acl);
5909ccaa3   Linus Torvalds   Make 'check_acl()...
227
228
  	if (ret != -EACCES)
  		return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
231
  	/*
  	 * Read/write DACs are always overridable.
8e833fd2e   Al Viro   fix comment in ge...
232
233
  	 * Executable DACs are overridable for all directories and
  	 * for non-directories that have least one exec bit set.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
  	 */
f696a3659   Miklos Szeredi   [PATCH] move exec...
235
  	if (!(mask & MAY_EXEC) || execute_ok(inode))
e795b7179   Serge E. Hallyn   userns: userns: c...
236
  		if (ns_capable(inode_userns(inode), CAP_DAC_OVERRIDE))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
237
238
239
240
241
  			return 0;
  
  	/*
  	 * Searching includes executable on directories, else just read.
  	 */
7ea660014   Serge E. Hallyn   generic_permissio...
242
  	mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
  	if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))
e795b7179   Serge E. Hallyn   userns: userns: c...
244
  		if (ns_capable(inode_userns(inode), CAP_DAC_READ_SEARCH))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
246
247
248
  			return 0;
  
  	return -EACCES;
  }
cb23beb55   Christoph Hellwig   kill vfs_permission
249
250
251
252
253
254
255
256
257
258
  /**
   * inode_permission  -  check for access rights to a given inode
   * @inode:	inode to check permission on
   * @mask:	right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
   *
   * Used to check for read/write/execute permissions on an inode.
   * We use "fsuid" for this, letting us set arbitrary permissions
   * for filesystem access without changing the "normal" uids which
   * are used for other things.
   */
f419a2e3b   Al Viro   [PATCH] kill name...
259
  int inode_permission(struct inode *inode, int mask)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
260
  {
e6305c43e   Al Viro   [PATCH] sanitize ...
261
  	int retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
263
  
  	if (mask & MAY_WRITE) {
22590e41c   Miklos Szeredi   fix execute check...
264
  		umode_t mode = inode->i_mode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
266
267
268
269
270
271
272
273
274
275
276
277
278
  
  		/*
  		 * Nobody gets write access to a read-only fs.
  		 */
  		if (IS_RDONLY(inode) &&
  		    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
  			return -EROFS;
  
  		/*
  		 * Nobody gets write access to an immutable file.
  		 */
  		if (IS_IMMUTABLE(inode))
  			return -EACCES;
  	}
acfa4380e   Al Viro   inode->i_op is ne...
279
  	if (inode->i_op->permission)
b74c79e99   Nick Piggin   fs: provide rcu-w...
280
  		retval = inode->i_op->permission(inode, mask, 0);
f696a3659   Miklos Szeredi   [PATCH] move exec...
281
  	else
b74c79e99   Nick Piggin   fs: provide rcu-w...
282
283
  		retval = generic_permission(inode, mask, 0,
  				inode->i_op->check_acl);
f696a3659   Miklos Szeredi   [PATCH] move exec...
284

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
286
  	if (retval)
  		return retval;
08ce5f16e   Serge E. Hallyn   cgroups: implemen...
287
288
289
  	retval = devcgroup_inode_permission(inode, mask);
  	if (retval)
  		return retval;
d09ca7397   Eric Paris   security: make LS...
290
  	return security_inode_permission(inode, mask);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
  }
e4543eddf   Christoph Hellwig   [PATCH] add a vfs...
292
  /**
8c744fb83   Christoph Hellwig   [PATCH] add a fil...
293
294
295
296
297
298
299
300
301
   * file_permission  -  check for additional access rights to a given file
   * @file:	file to check access rights for
   * @mask:	right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
   *
   * Used to check for read/write/execute permissions on an already opened
   * file.
   *
   * Note:
   *	Do not use this function in new code.  All access checks should
cb23beb55   Christoph Hellwig   kill vfs_permission
302
   *	be done using inode_permission().
8c744fb83   Christoph Hellwig   [PATCH] add a fil...
303
304
305
   */
  int file_permission(struct file *file, int mask)
  {
f419a2e3b   Al Viro   [PATCH] kill name...
306
  	return inode_permission(file->f_path.dentry->d_inode, mask);
8c744fb83   Christoph Hellwig   [PATCH] add a fil...
307
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
  /*
   * get_write_access() gets write permission for a file.
   * put_write_access() releases this write permission.
   * This is used for regular files.
   * We cannot support write (and maybe mmap read-write shared) accesses and
   * MAP_DENYWRITE mmappings simultaneously. The i_writecount field of an inode
   * can have the following values:
   * 0: no writers, no VM_DENYWRITE mappings
   * < 0: (-i_writecount) vm_area_structs with VM_DENYWRITE set exist
   * > 0: (i_writecount) users are writing to the file.
   *
   * Normally we operate on that counter with atomic_{inc,dec} and it's safe
   * except for the cases where we don't hold i_writecount yet. Then we need to
   * use {get,deny}_write_access() - these functions check the sign and refuse
   * to do the change if sign is wrong. Exclusion between them is provided by
   * the inode->i_lock spinlock.
   */
  
  int get_write_access(struct inode * inode)
  {
  	spin_lock(&inode->i_lock);
  	if (atomic_read(&inode->i_writecount) < 0) {
  		spin_unlock(&inode->i_lock);
  		return -ETXTBSY;
  	}
  	atomic_inc(&inode->i_writecount);
  	spin_unlock(&inode->i_lock);
  
  	return 0;
  }
  
  int deny_write_access(struct file * file)
  {
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
341
  	struct inode *inode = file->f_path.dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342
343
344
345
346
347
348
349
350
351
352
  
  	spin_lock(&inode->i_lock);
  	if (atomic_read(&inode->i_writecount) > 0) {
  		spin_unlock(&inode->i_lock);
  		return -ETXTBSY;
  	}
  	atomic_dec(&inode->i_writecount);
  	spin_unlock(&inode->i_lock);
  
  	return 0;
  }
1d957f9bf   Jan Blunck   Introduce path_put()
353
  /**
5dd784d04   Jan Blunck   Introduce path_get()
354
355
356
357
358
359
360
361
362
363
364
365
366
   * path_get - get a reference to a path
   * @path: path to get the reference to
   *
   * Given a path increment the reference count to the dentry and the vfsmount.
   */
  void path_get(struct path *path)
  {
  	mntget(path->mnt);
  	dget(path->dentry);
  }
  EXPORT_SYMBOL(path_get);
  
  /**
1d957f9bf   Jan Blunck   Introduce path_put()
367
368
369
370
371
372
   * path_put - put a reference to a path
   * @path: path to put the reference to
   *
   * Given a path decrement the reference count to the dentry and the vfsmount.
   */
  void path_put(struct path *path)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373
  {
1d957f9bf   Jan Blunck   Introduce path_put()
374
375
  	dput(path->dentry);
  	mntput(path->mnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
376
  }
1d957f9bf   Jan Blunck   Introduce path_put()
377
  EXPORT_SYMBOL(path_put);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378

19660af73   Al Viro   consolidate namei...
379
  /*
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
380
   * Path walking has 2 modes, rcu-walk and ref-walk (see
19660af73   Al Viro   consolidate namei...
381
382
383
384
385
386
387
   * Documentation/filesystems/path-lookup.txt).  In situations when we can't
   * continue in RCU mode, we attempt to drop out of rcu-walk mode and grab
   * normal reference counts on dentries and vfsmounts to transition to rcu-walk
   * mode.  Refcounts are grabbed at the last known good point before rcu-walk
   * got stuck, so ref-walk may continue from there. If this is not successful
   * (eg. a seqcount has changed), then failure is returned and it's up to caller
   * to restart the path walk from the beginning in ref-walk mode.
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
388
   */
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
389
390
  
  /**
19660af73   Al Viro   consolidate namei...
391
392
393
   * unlazy_walk - try to switch to ref-walk mode.
   * @nd: nameidata pathwalk data
   * @dentry: child of nd->path.dentry or NULL
39191628e   Randy Dunlap   fs: fix namei.c k...
394
   * Returns: 0 on success, -ECHILD on failure
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
395
   *
19660af73   Al Viro   consolidate namei...
396
397
398
   * unlazy_walk attempts to legitimize the current nd->path, nd->root and dentry
   * for ref-walk mode.  @dentry must be a path found by a do_lookup call on
   * @nd or NULL.  Must be called from rcu-walk context.
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
399
   */
19660af73   Al Viro   consolidate namei...
400
  static int unlazy_walk(struct nameidata *nd, struct dentry *dentry)
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
401
402
403
  {
  	struct fs_struct *fs = current->fs;
  	struct dentry *parent = nd->path.dentry;
5b6ca027d   Al Viro   reduce vfs_path_l...
404
  	int want_root = 0;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
405
406
  
  	BUG_ON(!(nd->flags & LOOKUP_RCU));
5b6ca027d   Al Viro   reduce vfs_path_l...
407
408
  	if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) {
  		want_root = 1;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
409
410
411
412
413
414
  		spin_lock(&fs->lock);
  		if (nd->root.mnt != fs->root.mnt ||
  				nd->root.dentry != fs->root.dentry)
  			goto err_root;
  	}
  	spin_lock(&parent->d_lock);
19660af73   Al Viro   consolidate namei...
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
  	if (!dentry) {
  		if (!__d_rcu_to_refcount(parent, nd->seq))
  			goto err_parent;
  		BUG_ON(nd->inode != parent->d_inode);
  	} else {
  		spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
  		if (!__d_rcu_to_refcount(dentry, nd->seq))
  			goto err_child;
  		/*
  		 * If the sequence check on the child dentry passed, then
  		 * the child has not been removed from its parent. This
  		 * means the parent dentry must be valid and able to take
  		 * a reference at this point.
  		 */
  		BUG_ON(!IS_ROOT(dentry) && dentry->d_parent != parent);
  		BUG_ON(!parent->d_count);
  		parent->d_count++;
  		spin_unlock(&dentry->d_lock);
  	}
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
434
  	spin_unlock(&parent->d_lock);
5b6ca027d   Al Viro   reduce vfs_path_l...
435
  	if (want_root) {
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
436
437
438
439
440
441
442
443
444
  		path_get(&nd->root);
  		spin_unlock(&fs->lock);
  	}
  	mntget(nd->path.mnt);
  
  	rcu_read_unlock();
  	br_read_unlock(vfsmount_lock);
  	nd->flags &= ~LOOKUP_RCU;
  	return 0;
19660af73   Al Viro   consolidate namei...
445
446
  
  err_child:
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
447
  	spin_unlock(&dentry->d_lock);
19660af73   Al Viro   consolidate namei...
448
  err_parent:
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
449
450
  	spin_unlock(&parent->d_lock);
  err_root:
5b6ca027d   Al Viro   reduce vfs_path_l...
451
  	if (want_root)
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
452
453
454
  		spin_unlock(&fs->lock);
  	return -ECHILD;
  }
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
455
  /**
834f2a4a1   Trond Myklebust   VFS: Allow the fi...
456
457
458
459
460
   * release_open_intent - free up open intent resources
   * @nd: pointer to nameidata
   */
  void release_open_intent(struct nameidata *nd)
  {
2dab59744   Linus Torvalds   Fix possible filp...
461
462
463
464
465
466
467
468
  	struct file *file = nd->intent.open.file;
  
  	if (file && !IS_ERR(file)) {
  		if (file->f_path.dentry == NULL)
  			put_filp(file);
  		else
  			fput(file);
  	}
834f2a4a1   Trond Myklebust   VFS: Allow the fi...
469
  }
f60aef7ec   Al Viro   drop out of RCU i...
470
  static inline int d_revalidate(struct dentry *dentry, struct nameidata *nd)
34286d666   Nick Piggin   fs: rcu-walk awar...
471
  {
f60aef7ec   Al Viro   drop out of RCU i...
472
  	return dentry->d_op->d_revalidate(dentry, nd);
34286d666   Nick Piggin   fs: rcu-walk awar...
473
  }
f5e1c1c1a   Al Viro   split do_revalida...
474
  static struct dentry *
bcdc5e019   Ian Kent   [PATCH] autofs4 n...
475
476
  do_revalidate(struct dentry *dentry, struct nameidata *nd)
  {
f5e1c1c1a   Al Viro   split do_revalida...
477
  	int status = d_revalidate(dentry, nd);
bcdc5e019   Ian Kent   [PATCH] autofs4 n...
478
479
480
481
482
483
484
  	if (unlikely(status <= 0)) {
  		/*
  		 * The dentry failed validation.
  		 * If d_revalidate returned 0 attempt to invalidate
  		 * the dentry otherwise d_revalidate is asking us
  		 * to return a fail status.
  		 */
34286d666   Nick Piggin   fs: rcu-walk awar...
485
  		if (status < 0) {
f5e1c1c1a   Al Viro   split do_revalida...
486
  			dput(dentry);
34286d666   Nick Piggin   fs: rcu-walk awar...
487
  			dentry = ERR_PTR(status);
f5e1c1c1a   Al Viro   split do_revalida...
488
489
490
  		} else if (!d_invalidate(dentry)) {
  			dput(dentry);
  			dentry = NULL;
bcdc5e019   Ian Kent   [PATCH] autofs4 n...
491
492
493
494
  		}
  	}
  	return dentry;
  }
9f1fafee9   Al Viro   merge handle_reva...
495
496
497
  /**
   * complete_walk - successful completion of path walk
   * @nd:  pointer nameidata
39159de2a   Jeff Layton   vfs: force reval ...
498
   *
9f1fafee9   Al Viro   merge handle_reva...
499
500
501
502
503
   * If we had been in RCU mode, drop out of it and legitimize nd->path.
   * Revalidate the final result, unless we'd already done that during
   * the path walk or the filesystem doesn't ask for it.  Return 0 on
   * success, -error on failure.  In case of failure caller does not
   * need to drop nd->path.
39159de2a   Jeff Layton   vfs: force reval ...
504
   */
9f1fafee9   Al Viro   merge handle_reva...
505
  static int complete_walk(struct nameidata *nd)
39159de2a   Jeff Layton   vfs: force reval ...
506
  {
16c2cd717   Al Viro   untangle the "nee...
507
  	struct dentry *dentry = nd->path.dentry;
39159de2a   Jeff Layton   vfs: force reval ...
508
  	int status;
39159de2a   Jeff Layton   vfs: force reval ...
509

9f1fafee9   Al Viro   merge handle_reva...
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
  	if (nd->flags & LOOKUP_RCU) {
  		nd->flags &= ~LOOKUP_RCU;
  		if (!(nd->flags & LOOKUP_ROOT))
  			nd->root.mnt = NULL;
  		spin_lock(&dentry->d_lock);
  		if (unlikely(!__d_rcu_to_refcount(dentry, nd->seq))) {
  			spin_unlock(&dentry->d_lock);
  			rcu_read_unlock();
  			br_read_unlock(vfsmount_lock);
  			return -ECHILD;
  		}
  		BUG_ON(nd->inode != dentry->d_inode);
  		spin_unlock(&dentry->d_lock);
  		mntget(nd->path.mnt);
  		rcu_read_unlock();
  		br_read_unlock(vfsmount_lock);
  	}
16c2cd717   Al Viro   untangle the "nee...
527
528
529
530
  	if (likely(!(nd->flags & LOOKUP_JUMPED)))
  		return 0;
  
  	if (likely(!(dentry->d_flags & DCACHE_OP_REVALIDATE)))
39159de2a   Jeff Layton   vfs: force reval ...
531
  		return 0;
16c2cd717   Al Viro   untangle the "nee...
532
533
534
535
  	if (likely(!(dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)))
  		return 0;
  
  	/* Note: we do not d_invalidate() */
34286d666   Nick Piggin   fs: rcu-walk awar...
536
  	status = d_revalidate(dentry, nd);
39159de2a   Jeff Layton   vfs: force reval ...
537
538
  	if (status > 0)
  		return 0;
16c2cd717   Al Viro   untangle the "nee...
539
  	if (!status)
39159de2a   Jeff Layton   vfs: force reval ...
540
  		status = -ESTALE;
16c2cd717   Al Viro   untangle the "nee...
541

9f1fafee9   Al Viro   merge handle_reva...
542
  	path_put(&nd->path);
39159de2a   Jeff Layton   vfs: force reval ...
543
544
545
546
  	return status;
  }
  
  /*
b75b5086b   Al Viro   Sanitize exec_per...
547
548
549
   * Short-cut version of permission(), for calling on directories
   * during pathname resolution.  Combines parts of permission()
   * and generic_permission(), and tests ONLY for MAY_EXEC permission.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
550
551
   *
   * If appropriate, check DAC only.  If not appropriate, or
b75b5086b   Al Viro   Sanitize exec_per...
552
   * short-cut DAC fails, then call ->permission() to do more
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
553
554
   * complete permission check.
   */
b74c79e99   Nick Piggin   fs: provide rcu-w...
555
  static inline int exec_permission(struct inode *inode, unsigned int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
556
  {
5909ccaa3   Linus Torvalds   Make 'check_acl()...
557
  	int ret;
e795b7179   Serge E. Hallyn   userns: userns: c...
558
  	struct user_namespace *ns = inode_userns(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
559

cb9179ead   Linus Torvalds   Simplify exec_per...
560
  	if (inode->i_op->permission) {
b74c79e99   Nick Piggin   fs: provide rcu-w...
561
562
563
564
  		ret = inode->i_op->permission(inode, MAY_EXEC, flags);
  	} else {
  		ret = acl_permission_check(inode, MAY_EXEC, flags,
  				inode->i_op->check_acl);
cb9179ead   Linus Torvalds   Simplify exec_per...
565
  	}
b74c79e99   Nick Piggin   fs: provide rcu-w...
566
  	if (likely(!ret))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
567
  		goto ok;
b74c79e99   Nick Piggin   fs: provide rcu-w...
568
  	if (ret == -ECHILD)
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
569
  		return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
570

e795b7179   Serge E. Hallyn   userns: userns: c...
571
572
  	if (ns_capable(ns, CAP_DAC_OVERRIDE) ||
  			ns_capable(ns, CAP_DAC_READ_SEARCH))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
573
  		goto ok;
5909ccaa3   Linus Torvalds   Make 'check_acl()...
574
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
575
  ok:
b74c79e99   Nick Piggin   fs: provide rcu-w...
576
  	return security_inode_exec_permission(inode, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
577
  }
2a7378711   Al Viro   Cache root in nam...
578
579
  static __always_inline void set_root(struct nameidata *nd)
  {
f7ad3c6be   Miklos Szeredi   vfs: add helpers ...
580
581
  	if (!nd->root.mnt)
  		get_fs_root(current->fs, &nd->root);
2a7378711   Al Viro   Cache root in nam...
582
  }
6de88d729   Al Viro   kill __link_path_...
583
  static int link_path_walk(const char *, struct nameidata *);
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
584
585
586
587
  static __always_inline void set_root_rcu(struct nameidata *nd)
  {
  	if (!nd->root.mnt) {
  		struct fs_struct *fs = current->fs;
c28cc3646   Nick Piggin   fs: fs_struct use...
588
589
590
591
592
  		unsigned seq;
  
  		do {
  			seq = read_seqcount_begin(&fs->seq);
  			nd->root = fs->root;
c1530019e   Tim Chen   vfs: Fix absolute...
593
  			nd->seq = __read_seqcount_begin(&nd->root.dentry->d_seq);
c28cc3646   Nick Piggin   fs: fs_struct use...
594
  		} while (read_seqcount_retry(&fs->seq, seq));
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
595
596
  	}
  }
f16623569   Arjan van de Ven   [PATCH] Mark some...
597
  static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
598
  {
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
599
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
600
601
602
603
  	if (IS_ERR(link))
  		goto fail;
  
  	if (*link == '/') {
2a7378711   Al Viro   Cache root in nam...
604
  		set_root(nd);
1d957f9bf   Jan Blunck   Introduce path_put()
605
  		path_put(&nd->path);
2a7378711   Al Viro   Cache root in nam...
606
607
  		nd->path = nd->root;
  		path_get(&nd->root);
16c2cd717   Al Viro   untangle the "nee...
608
  		nd->flags |= LOOKUP_JUMPED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609
  	}
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
610
  	nd->inode = nd->path.dentry->d_inode;
b4091d5f6   Christoph Hellwig   kill walk_init_root
611

31e6b01f4   Nick Piggin   fs: rcu-walk for ...
612
613
  	ret = link_path_walk(link, nd);
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
614
  fail:
1d957f9bf   Jan Blunck   Introduce path_put()
615
  	path_put(&nd->path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
616
617
  	return PTR_ERR(link);
  }
1d957f9bf   Jan Blunck   Introduce path_put()
618
  static void path_put_conditional(struct path *path, struct nameidata *nd)
051d38125   Ian Kent   [PATCH] autofs4: ...
619
620
  {
  	dput(path->dentry);
4ac913785   Jan Blunck   Embed a struct pa...
621
  	if (path->mnt != nd->path.mnt)
051d38125   Ian Kent   [PATCH] autofs4: ...
622
623
  		mntput(path->mnt);
  }
7b9337aaf   Nick Piggin   fs: namei fix ->p...
624
625
  static inline void path_to_nameidata(const struct path *path,
  					struct nameidata *nd)
051d38125   Ian Kent   [PATCH] autofs4: ...
626
  {
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
627
628
629
630
  	if (!(nd->flags & LOOKUP_RCU)) {
  		dput(nd->path.dentry);
  		if (nd->path.mnt != path->mnt)
  			mntput(nd->path.mnt);
9a2296832   Huang Shijie   namei.c : update ...
631
  	}
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
632
  	nd->path.mnt = path->mnt;
4ac913785   Jan Blunck   Embed a struct pa...
633
  	nd->path.dentry = path->dentry;
051d38125   Ian Kent   [PATCH] autofs4: ...
634
  }
574197e0d   Al Viro   tidy the trailing...
635
636
637
638
639
640
641
  static inline void put_link(struct nameidata *nd, struct path *link, void *cookie)
  {
  	struct inode *inode = link->dentry->d_inode;
  	if (!IS_ERR(cookie) && inode->i_op->put_link)
  		inode->i_op->put_link(link->dentry, nd, cookie);
  	path_put(link);
  }
def4af30c   Al Viro   Get rid of symlin...
642
  static __always_inline int
574197e0d   Al Viro   tidy the trailing...
643
  follow_link(struct path *link, struct nameidata *nd, void **p)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
644
645
  {
  	int error;
7b9337aaf   Nick Piggin   fs: namei fix ->p...
646
  	struct dentry *dentry = link->dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
647

844a39179   Al Viro   nothing in do_fol...
648
  	BUG_ON(nd->flags & LOOKUP_RCU);
0e794589e   Al Viro   fix follow_link()...
649
650
  	if (link->mnt == nd->path.mnt)
  		mntget(link->mnt);
574197e0d   Al Viro   tidy the trailing...
651
652
  	if (unlikely(current->total_link_count >= 40)) {
  		*p = ERR_PTR(-ELOOP); /* no ->put_link(), please */
574197e0d   Al Viro   tidy the trailing...
653
654
655
656
657
  		path_put(&nd->path);
  		return -ELOOP;
  	}
  	cond_resched();
  	current->total_link_count++;
7b9337aaf   Nick Piggin   fs: namei fix ->p...
658
  	touch_atime(link->mnt, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
659
  	nd_set_link(nd, NULL);
cd4e91d3b   Al Viro   [PATCH] namei fix...
660

36f3b4f69   Al Viro   pull security_ino...
661
662
663
664
665
666
  	error = security_inode_follow_link(link->dentry, nd);
  	if (error) {
  		*p = ERR_PTR(error); /* no ->put_link(), please */
  		path_put(&nd->path);
  		return error;
  	}
86acdca1b   Al Viro   fix autofs/afs/et...
667
  	nd->last_type = LAST_BIND;
def4af30c   Al Viro   Get rid of symlin...
668
669
670
  	*p = dentry->d_inode->i_op->follow_link(dentry, nd);
  	error = PTR_ERR(*p);
  	if (!IS_ERR(*p)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
671
  		char *s = nd_get_link(nd);
cc314eef0   Linus Torvalds   Fix nasty ncpfs s...
672
  		error = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
673
674
  		if (s)
  			error = __vfs_follow_link(nd, s);
bcda76524   Al Viro   Allow O_PATH for ...
675
  		else if (nd->last_type == LAST_BIND) {
16c2cd717   Al Viro   untangle the "nee...
676
  			nd->flags |= LOOKUP_JUMPED;
b21041d0f   Al Viro   update nd->inode ...
677
678
  			nd->inode = nd->path.dentry->d_inode;
  			if (nd->inode->i_op->follow_link) {
bcda76524   Al Viro   Allow O_PATH for ...
679
680
681
682
683
  				/* stepped on a _really_ weird one */
  				path_put(&nd->path);
  				error = -ELOOP;
  			}
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
684
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
685
686
  	return error;
  }
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
687
688
689
690
691
692
693
694
695
696
697
698
699
  static int follow_up_rcu(struct path *path)
  {
  	struct vfsmount *parent;
  	struct dentry *mountpoint;
  
  	parent = path->mnt->mnt_parent;
  	if (parent == path->mnt)
  		return 0;
  	mountpoint = path->mnt->mnt_mountpoint;
  	path->dentry = mountpoint;
  	path->mnt = parent;
  	return 1;
  }
bab77ebf5   Al Viro   switch follow_up(...
700
  int follow_up(struct path *path)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
701
702
703
  {
  	struct vfsmount *parent;
  	struct dentry *mountpoint;
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
704
705
  
  	br_read_lock(vfsmount_lock);
bab77ebf5   Al Viro   switch follow_up(...
706
707
  	parent = path->mnt->mnt_parent;
  	if (parent == path->mnt) {
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
708
  		br_read_unlock(vfsmount_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
709
710
711
  		return 0;
  	}
  	mntget(parent);
bab77ebf5   Al Viro   switch follow_up(...
712
  	mountpoint = dget(path->mnt->mnt_mountpoint);
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
713
  	br_read_unlock(vfsmount_lock);
bab77ebf5   Al Viro   switch follow_up(...
714
715
716
717
  	dput(path->dentry);
  	path->dentry = mountpoint;
  	mntput(path->mnt);
  	path->mnt = parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
718
719
  	return 1;
  }
b5c84bf6f   Nick Piggin   fs: dcache remove...
720
  /*
9875cf806   David Howells   Add a dentry op t...
721
722
723
   * Perform an automount
   * - return -EISDIR to tell follow_managed() to stop and return the path we
   *   were called with.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
724
   */
9875cf806   David Howells   Add a dentry op t...
725
726
  static int follow_automount(struct path *path, unsigned flags,
  			    bool *need_mntput)
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
727
  {
9875cf806   David Howells   Add a dentry op t...
728
  	struct vfsmount *mnt;
ea5b778a8   David Howells   Unexport do_add_m...
729
  	int err;
9875cf806   David Howells   Add a dentry op t...
730
731
732
  
  	if (!path->dentry->d_op || !path->dentry->d_op->d_automount)
  		return -EREMOTE;
6f45b6567   David Howells   Add an AT_NO_AUTO...
733
734
735
736
737
  	/* We don't want to mount if someone supplied AT_NO_AUTOMOUNT
  	 * and this is the terminal part of the path.
  	 */
  	if ((flags & LOOKUP_NO_AUTOMOUNT) && !(flags & LOOKUP_CONTINUE))
  		return -EISDIR; /* we actually want to stop here */
9875cf806   David Howells   Add a dentry op t...
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
  	/* We want to mount if someone is trying to open/create a file of any
  	 * type under the mountpoint, wants to traverse through the mountpoint
  	 * or wants to open the mounted directory.
  	 *
  	 * We don't want to mount if someone's just doing a stat and they've
  	 * set AT_SYMLINK_NOFOLLOW - unless they're stat'ing a directory and
  	 * appended a '/' to the name.
  	 */
  	if (!(flags & LOOKUP_FOLLOW) &&
  	    !(flags & (LOOKUP_CONTINUE | LOOKUP_DIRECTORY |
  		       LOOKUP_OPEN | LOOKUP_CREATE)))
  		return -EISDIR;
  
  	current->total_link_count++;
  	if (current->total_link_count >= 40)
  		return -ELOOP;
  
  	mnt = path->dentry->d_op->d_automount(path);
  	if (IS_ERR(mnt)) {
  		/*
  		 * The filesystem is allowed to return -EISDIR here to indicate
  		 * it doesn't want to automount.  For instance, autofs would do
  		 * this so that its userspace daemon can mount on this dentry.
  		 *
  		 * However, we can only permit this if it's a terminal point in
  		 * the path being looked up; if it wasn't then the remainder of
  		 * the path is inaccessible and we should say so.
  		 */
  		if (PTR_ERR(mnt) == -EISDIR && (flags & LOOKUP_CONTINUE))
  			return -EREMOTE;
  		return PTR_ERR(mnt);
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
769
  	}
ea5b778a8   David Howells   Unexport do_add_m...
770

9875cf806   David Howells   Add a dentry op t...
771
772
  	if (!mnt) /* mount collision */
  		return 0;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
773

8aef18845   Al Viro   VFS: Fix vfsmount...
774
775
776
777
778
  	if (!*need_mntput) {
  		/* lock_mount() may release path->mnt on error */
  		mntget(path->mnt);
  		*need_mntput = true;
  	}
19a167af7   Al Viro   Take the completi...
779
  	err = finish_automount(mnt, path);
9875cf806   David Howells   Add a dentry op t...
780

ea5b778a8   David Howells   Unexport do_add_m...
781
782
783
  	switch (err) {
  	case -EBUSY:
  		/* Someone else made a mount here whilst we were busy */
19a167af7   Al Viro   Take the completi...
784
  		return 0;
ea5b778a8   David Howells   Unexport do_add_m...
785
  	case 0:
8aef18845   Al Viro   VFS: Fix vfsmount...
786
  		path_put(path);
ea5b778a8   David Howells   Unexport do_add_m...
787
788
  		path->mnt = mnt;
  		path->dentry = dget(mnt->mnt_root);
ea5b778a8   David Howells   Unexport do_add_m...
789
  		return 0;
19a167af7   Al Viro   Take the completi...
790
791
  	default:
  		return err;
ea5b778a8   David Howells   Unexport do_add_m...
792
  	}
19a167af7   Al Viro   Take the completi...
793

463ffb2e9   Al Viro   [PATCH] namei fix...
794
  }
9875cf806   David Howells   Add a dentry op t...
795
796
  /*
   * Handle a dentry that is managed in some way.
cc53ce53c   David Howells   Add a dentry op t...
797
   * - Flagged for transit management (autofs)
9875cf806   David Howells   Add a dentry op t...
798
799
800
801
802
803
804
805
   * - Flagged as mountpoint
   * - Flagged as automount point
   *
   * This may only be called in refwalk mode.
   *
   * Serialization is taken care of in namespace.c
   */
  static int follow_managed(struct path *path, unsigned flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
806
  {
8aef18845   Al Viro   VFS: Fix vfsmount...
807
  	struct vfsmount *mnt = path->mnt; /* held by caller, must be left alone */
9875cf806   David Howells   Add a dentry op t...
808
809
  	unsigned managed;
  	bool need_mntput = false;
8aef18845   Al Viro   VFS: Fix vfsmount...
810
  	int ret = 0;
9875cf806   David Howells   Add a dentry op t...
811
812
813
814
815
816
817
  
  	/* Given that we're not holding a lock here, we retain the value in a
  	 * local variable for each dentry as we look at it so that we don't see
  	 * the components of that value change under us */
  	while (managed = ACCESS_ONCE(path->dentry->d_flags),
  	       managed &= DCACHE_MANAGED_DENTRY,
  	       unlikely(managed != 0)) {
cc53ce53c   David Howells   Add a dentry op t...
818
819
820
821
822
  		/* Allow the filesystem to manage the transit without i_mutex
  		 * being held. */
  		if (managed & DCACHE_MANAGE_TRANSIT) {
  			BUG_ON(!path->dentry->d_op);
  			BUG_ON(!path->dentry->d_op->d_manage);
1aed3e420   Al Viro   lose 'mounting_he...
823
  			ret = path->dentry->d_op->d_manage(path->dentry, false);
cc53ce53c   David Howells   Add a dentry op t...
824
  			if (ret < 0)
8aef18845   Al Viro   VFS: Fix vfsmount...
825
  				break;
cc53ce53c   David Howells   Add a dentry op t...
826
  		}
9875cf806   David Howells   Add a dentry op t...
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
  		/* Transit to a mounted filesystem. */
  		if (managed & DCACHE_MOUNTED) {
  			struct vfsmount *mounted = lookup_mnt(path);
  			if (mounted) {
  				dput(path->dentry);
  				if (need_mntput)
  					mntput(path->mnt);
  				path->mnt = mounted;
  				path->dentry = dget(mounted->mnt_root);
  				need_mntput = true;
  				continue;
  			}
  
  			/* Something is mounted on this dentry in another
  			 * namespace and/or whatever was mounted there in this
  			 * namespace got unmounted before we managed to get the
  			 * vfsmount_lock */
  		}
  
  		/* Handle an automount point */
  		if (managed & DCACHE_NEED_AUTOMOUNT) {
  			ret = follow_automount(path, flags, &need_mntput);
  			if (ret < 0)
8aef18845   Al Viro   VFS: Fix vfsmount...
850
  				break;
9875cf806   David Howells   Add a dentry op t...
851
852
853
854
855
  			continue;
  		}
  
  		/* We didn't change the current path point */
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
856
  	}
8aef18845   Al Viro   VFS: Fix vfsmount...
857
858
859
860
861
862
  
  	if (need_mntput && path->mnt == mnt)
  		mntput(path->mnt);
  	if (ret == -EISDIR)
  		ret = 0;
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
863
  }
cc53ce53c   David Howells   Add a dentry op t...
864
  int follow_down_one(struct path *path)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
865
866
  {
  	struct vfsmount *mounted;
1c755af4d   Al Viro   switch lookup_mnt()
867
  	mounted = lookup_mnt(path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
868
  	if (mounted) {
9393bd07c   Al Viro   switch follow_down()
869
870
871
872
  		dput(path->dentry);
  		mntput(path->mnt);
  		path->mnt = mounted;
  		path->dentry = dget(mounted->mnt_root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
873
874
875
876
  		return 1;
  	}
  	return 0;
  }
62a7375e5   Ian Kent   vfs - check non-m...
877
878
879
880
881
  static inline bool managed_dentry_might_block(struct dentry *dentry)
  {
  	return (dentry->d_flags & DCACHE_MANAGE_TRANSIT &&
  		dentry->d_op->d_manage(dentry, true) < 0);
  }
9875cf806   David Howells   Add a dentry op t...
882
  /*
287548e46   Al Viro   split __follow_mo...
883
884
   * Try to skip to top of mountpoint pile in rcuwalk mode.  Fail if
   * we meet a managed dentry that would need blocking.
9875cf806   David Howells   Add a dentry op t...
885
886
   */
  static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
287548e46   Al Viro   split __follow_mo...
887
  			       struct inode **inode)
9875cf806   David Howells   Add a dentry op t...
888
  {
62a7375e5   Ian Kent   vfs - check non-m...
889
  	for (;;) {
9875cf806   David Howells   Add a dentry op t...
890
  		struct vfsmount *mounted;
62a7375e5   Ian Kent   vfs - check non-m...
891
892
893
894
895
  		/*
  		 * Don't forget we might have a non-mountpoint managed dentry
  		 * that wants to block transit.
  		 */
  		*inode = path->dentry->d_inode;
287548e46   Al Viro   split __follow_mo...
896
  		if (unlikely(managed_dentry_might_block(path->dentry)))
ab90911ff   David Howells   Allow d_manage() ...
897
  			return false;
62a7375e5   Ian Kent   vfs - check non-m...
898
899
900
  
  		if (!d_mountpoint(path->dentry))
  			break;
9875cf806   David Howells   Add a dentry op t...
901
902
903
904
905
906
  		mounted = __lookup_mnt(path->mnt, path->dentry, 1);
  		if (!mounted)
  			break;
  		path->mnt = mounted;
  		path->dentry = mounted->mnt_root;
  		nd->seq = read_seqcount_begin(&path->dentry->d_seq);
9875cf806   David Howells   Add a dentry op t...
907
  	}
9875cf806   David Howells   Add a dentry op t...
908
909
  	return true;
  }
dea393761   Al Viro   Trim excessive ar...
910
  static void follow_mount_rcu(struct nameidata *nd)
287548e46   Al Viro   split __follow_mo...
911
  {
dea393761   Al Viro   Trim excessive ar...
912
  	while (d_mountpoint(nd->path.dentry)) {
287548e46   Al Viro   split __follow_mo...
913
  		struct vfsmount *mounted;
dea393761   Al Viro   Trim excessive ar...
914
  		mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry, 1);
287548e46   Al Viro   split __follow_mo...
915
916
  		if (!mounted)
  			break;
dea393761   Al Viro   Trim excessive ar...
917
918
919
  		nd->path.mnt = mounted;
  		nd->path.dentry = mounted->mnt_root;
  		nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
287548e46   Al Viro   split __follow_mo...
920
921
  	}
  }
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
922
923
  static int follow_dotdot_rcu(struct nameidata *nd)
  {
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
924
  	set_root_rcu(nd);
9875cf806   David Howells   Add a dentry op t...
925
  	while (1) {
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
926
927
928
929
930
931
932
933
934
935
936
  		if (nd->path.dentry == nd->root.dentry &&
  		    nd->path.mnt == nd->root.mnt) {
  			break;
  		}
  		if (nd->path.dentry != nd->path.mnt->mnt_root) {
  			struct dentry *old = nd->path.dentry;
  			struct dentry *parent = old->d_parent;
  			unsigned seq;
  
  			seq = read_seqcount_begin(&parent->d_seq);
  			if (read_seqcount_retry(&old->d_seq, nd->seq))
ef7562d52   Al Viro   make handle_dots(...
937
  				goto failed;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
938
939
940
941
942
943
944
  			nd->path.dentry = parent;
  			nd->seq = seq;
  			break;
  		}
  		if (!follow_up_rcu(&nd->path))
  			break;
  		nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
945
  	}
dea393761   Al Viro   Trim excessive ar...
946
947
  	follow_mount_rcu(nd);
  	nd->inode = nd->path.dentry->d_inode;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
948
  	return 0;
ef7562d52   Al Viro   make handle_dots(...
949
950
951
  
  failed:
  	nd->flags &= ~LOOKUP_RCU;
5b6ca027d   Al Viro   reduce vfs_path_l...
952
953
  	if (!(nd->flags & LOOKUP_ROOT))
  		nd->root.mnt = NULL;
ef7562d52   Al Viro   make handle_dots(...
954
955
956
  	rcu_read_unlock();
  	br_read_unlock(vfsmount_lock);
  	return -ECHILD;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
957
  }
9875cf806   David Howells   Add a dentry op t...
958
  /*
cc53ce53c   David Howells   Add a dentry op t...
959
960
961
   * Follow down to the covering mount currently visible to userspace.  At each
   * point, the filesystem owning that dentry may be queried as to whether the
   * caller is permitted to proceed or not.
cc53ce53c   David Howells   Add a dentry op t...
962
   */
7cc90cc3f   Al Viro   don't pass 'mount...
963
  int follow_down(struct path *path)
cc53ce53c   David Howells   Add a dentry op t...
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
  {
  	unsigned managed;
  	int ret;
  
  	while (managed = ACCESS_ONCE(path->dentry->d_flags),
  	       unlikely(managed & DCACHE_MANAGED_DENTRY)) {
  		/* Allow the filesystem to manage the transit without i_mutex
  		 * being held.
  		 *
  		 * We indicate to the filesystem if someone is trying to mount
  		 * something here.  This gives autofs the chance to deny anyone
  		 * other than its daemon the right to mount on its
  		 * superstructure.
  		 *
  		 * The filesystem may sleep at this point.
  		 */
  		if (managed & DCACHE_MANAGE_TRANSIT) {
  			BUG_ON(!path->dentry->d_op);
  			BUG_ON(!path->dentry->d_op->d_manage);
ab90911ff   David Howells   Allow d_manage() ...
983
  			ret = path->dentry->d_op->d_manage(
1aed3e420   Al Viro   lose 'mounting_he...
984
  				path->dentry, false);
cc53ce53c   David Howells   Add a dentry op t...
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
  			if (ret < 0)
  				return ret == -EISDIR ? 0 : ret;
  		}
  
  		/* Transit to a mounted filesystem. */
  		if (managed & DCACHE_MOUNTED) {
  			struct vfsmount *mounted = lookup_mnt(path);
  			if (!mounted)
  				break;
  			dput(path->dentry);
  			mntput(path->mnt);
  			path->mnt = mounted;
  			path->dentry = dget(mounted->mnt_root);
  			continue;
  		}
  
  		/* Don't handle automount points here */
  		break;
  	}
  	return 0;
  }
  
  /*
9875cf806   David Howells   Add a dentry op t...
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
   * Skip to top of mountpoint pile in refwalk mode for follow_dotdot()
   */
  static void follow_mount(struct path *path)
  {
  	while (d_mountpoint(path->dentry)) {
  		struct vfsmount *mounted = lookup_mnt(path);
  		if (!mounted)
  			break;
  		dput(path->dentry);
  		mntput(path->mnt);
  		path->mnt = mounted;
  		path->dentry = dget(mounted->mnt_root);
  	}
  }
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1022
  static void follow_dotdot(struct nameidata *nd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1023
  {
2a7378711   Al Viro   Cache root in nam...
1024
  	set_root(nd);
e518ddb7b   Andreas Mohr   [PATCH] fs/namei....
1025

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1026
  	while(1) {
4ac913785   Jan Blunck   Embed a struct pa...
1027
  		struct dentry *old = nd->path.dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1028

2a7378711   Al Viro   Cache root in nam...
1029
1030
  		if (nd->path.dentry == nd->root.dentry &&
  		    nd->path.mnt == nd->root.mnt) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1031
1032
  			break;
  		}
4ac913785   Jan Blunck   Embed a struct pa...
1033
  		if (nd->path.dentry != nd->path.mnt->mnt_root) {
3088dd708   Al Viro   Clean follow_dotd...
1034
1035
  			/* rare case of legitimate dget_parent()... */
  			nd->path.dentry = dget_parent(nd->path.dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1036
1037
1038
  			dput(old);
  			break;
  		}
3088dd708   Al Viro   Clean follow_dotd...
1039
  		if (!follow_up(&nd->path))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1040
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1041
  	}
79ed02261   Al Viro   switch follow_mou...
1042
  	follow_mount(&nd->path);
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1043
  	nd->inode = nd->path.dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1044
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1045
  /*
baa038907   Nick Piggin   fs: dentry alloca...
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
   * Allocate a dentry with name and parent, and perform a parent
   * directory ->lookup on it. Returns the new dentry, or ERR_PTR
   * on error. parent->d_inode->i_mutex must be held. d_lookup must
   * have verified that no child exists while under i_mutex.
   */
  static struct dentry *d_alloc_and_lookup(struct dentry *parent,
  				struct qstr *name, struct nameidata *nd)
  {
  	struct inode *inode = parent->d_inode;
  	struct dentry *dentry;
  	struct dentry *old;
  
  	/* Don't create child dentry for a dead directory. */
  	if (unlikely(IS_DEADDIR(inode)))
  		return ERR_PTR(-ENOENT);
  
  	dentry = d_alloc(parent, name);
  	if (unlikely(!dentry))
  		return ERR_PTR(-ENOMEM);
  
  	old = inode->i_op->lookup(inode, dentry, nd);
  	if (unlikely(old)) {
  		dput(dentry);
  		dentry = old;
  	}
  	return dentry;
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1075
1076
1077
1078
1079
   *  It's more convoluted than I'd like it to be, but... it's still fairly
   *  small and for now I'd prefer to have fast path as straight as possible.
   *  It _is_ time-critical.
   */
  static int do_lookup(struct nameidata *nd, struct qstr *name,
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1080
  			struct path *path, struct inode **inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1081
  {
4ac913785   Jan Blunck   Embed a struct pa...
1082
  	struct vfsmount *mnt = nd->path.mnt;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1083
  	struct dentry *dentry, *parent = nd->path.dentry;
5a18fff20   Al Viro   untangle do_lookup()
1084
1085
  	int need_reval = 1;
  	int status = 1;
9875cf806   David Howells   Add a dentry op t...
1086
  	int err;
3cac260ad   Al Viro   Take hash recalcu...
1087
  	/*
b04f784e5   Nick Piggin   fs: remove extra ...
1088
1089
1090
1091
  	 * Rename seqlock is not required here because in the off chance
  	 * of a false negative due to a concurrent rename, we're going to
  	 * do the non-racy lookup, below.
  	 */
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1092
1093
  	if (nd->flags & LOOKUP_RCU) {
  		unsigned seq;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1094
1095
  		*inode = nd->inode;
  		dentry = __d_lookup_rcu(parent, name, &seq, inode);
5a18fff20   Al Viro   untangle do_lookup()
1096
1097
  		if (!dentry)
  			goto unlazy;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1098
1099
1100
  		/* Memory barrier in read_seqcount_begin of child is enough */
  		if (__read_seqcount_retry(&parent->d_seq, nd->seq))
  			return -ECHILD;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1101
  		nd->seq = seq;
5a18fff20   Al Viro   untangle do_lookup()
1102

24643087e   Al Viro   in do_lookup() sp...
1103
  		if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) {
5a18fff20   Al Viro   untangle do_lookup()
1104
1105
1106
1107
1108
1109
  			status = d_revalidate(dentry, nd);
  			if (unlikely(status <= 0)) {
  				if (status != -ECHILD)
  					need_reval = 0;
  				goto unlazy;
  			}
24643087e   Al Viro   in do_lookup() sp...
1110
  		}
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1111
1112
  		path->mnt = mnt;
  		path->dentry = dentry;
d6e9bd256   Al Viro   Lift the check fo...
1113
1114
1115
1116
1117
  		if (unlikely(!__follow_mount_rcu(nd, path, inode)))
  			goto unlazy;
  		if (unlikely(path->dentry->d_flags & DCACHE_NEED_AUTOMOUNT))
  			goto unlazy;
  		return 0;
5a18fff20   Al Viro   untangle do_lookup()
1118
  unlazy:
19660af73   Al Viro   consolidate namei...
1119
1120
  		if (unlazy_walk(nd, dentry))
  			return -ECHILD;
5a18fff20   Al Viro   untangle do_lookup()
1121
1122
  	} else {
  		dentry = __d_lookup(parent, name);
9875cf806   David Howells   Add a dentry op t...
1123
  	}
5a18fff20   Al Viro   untangle do_lookup()
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
  
  retry:
  	if (unlikely(!dentry)) {
  		struct inode *dir = parent->d_inode;
  		BUG_ON(nd->inode != dir);
  
  		mutex_lock(&dir->i_mutex);
  		dentry = d_lookup(parent, name);
  		if (likely(!dentry)) {
  			dentry = d_alloc_and_lookup(parent, name, nd);
  			if (IS_ERR(dentry)) {
  				mutex_unlock(&dir->i_mutex);
  				return PTR_ERR(dentry);
  			}
  			/* known good */
  			need_reval = 0;
  			status = 1;
  		}
  		mutex_unlock(&dir->i_mutex);
  	}
  	if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE) && need_reval)
  		status = d_revalidate(dentry, nd);
  	if (unlikely(status <= 0)) {
  		if (status < 0) {
  			dput(dentry);
  			return status;
  		}
  		if (!d_invalidate(dentry)) {
  			dput(dentry);
  			dentry = NULL;
  			need_reval = 1;
  			goto retry;
  		}
24643087e   Al Viro   in do_lookup() sp...
1157
  	}
5a18fff20   Al Viro   untangle do_lookup()
1158

9875cf806   David Howells   Add a dentry op t...
1159
1160
1161
  	path->mnt = mnt;
  	path->dentry = dentry;
  	err = follow_managed(path, nd->flags);
893122141   Ian Kent   vfs - fix dentry ...
1162
1163
  	if (unlikely(err < 0)) {
  		path_put_conditional(path, nd);
9875cf806   David Howells   Add a dentry op t...
1164
  		return err;
893122141   Ian Kent   vfs - fix dentry ...
1165
  	}
9875cf806   David Howells   Add a dentry op t...
1166
  	*inode = path->dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1167
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1168
  }
52094c8a0   Al Viro   take RCU-dependen...
1169
1170
1171
1172
1173
1174
  static inline int may_lookup(struct nameidata *nd)
  {
  	if (nd->flags & LOOKUP_RCU) {
  		int err = exec_permission(nd->inode, IPERM_FLAG_RCU);
  		if (err != -ECHILD)
  			return err;
19660af73   Al Viro   consolidate namei...
1175
  		if (unlazy_walk(nd, NULL))
52094c8a0   Al Viro   take RCU-dependen...
1176
1177
1178
1179
  			return -ECHILD;
  	}
  	return exec_permission(nd->inode, 0);
  }
9856fa1b2   Al Viro   pull handling of ...
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
  static inline int handle_dots(struct nameidata *nd, int type)
  {
  	if (type == LAST_DOTDOT) {
  		if (nd->flags & LOOKUP_RCU) {
  			if (follow_dotdot_rcu(nd))
  				return -ECHILD;
  		} else
  			follow_dotdot(nd);
  	}
  	return 0;
  }
951361f95   Al Viro   get rid of the la...
1191
1192
1193
1194
1195
1196
  static void terminate_walk(struct nameidata *nd)
  {
  	if (!(nd->flags & LOOKUP_RCU)) {
  		path_put(&nd->path);
  	} else {
  		nd->flags &= ~LOOKUP_RCU;
5b6ca027d   Al Viro   reduce vfs_path_l...
1197
1198
  		if (!(nd->flags & LOOKUP_ROOT))
  			nd->root.mnt = NULL;
951361f95   Al Viro   get rid of the la...
1199
1200
1201
1202
  		rcu_read_unlock();
  		br_read_unlock(vfsmount_lock);
  	}
  }
ce57dfc17   Al Viro   pull handling of ...
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
  static inline int walk_component(struct nameidata *nd, struct path *path,
  		struct qstr *name, int type, int follow)
  {
  	struct inode *inode;
  	int err;
  	/*
  	 * "." and ".." are special - ".." especially so because it has
  	 * to be able to know about the current root directory and
  	 * parent relationships.
  	 */
  	if (unlikely(type != LAST_NORM))
  		return handle_dots(nd, type);
  	err = do_lookup(nd, name, path, &inode);
  	if (unlikely(err)) {
  		terminate_walk(nd);
  		return err;
  	}
  	if (!inode) {
  		path_to_nameidata(path, nd);
  		terminate_walk(nd);
  		return -ENOENT;
  	}
  	if (unlikely(inode->i_op->follow_link) && follow) {
19660af73   Al Viro   consolidate namei...
1226
1227
1228
1229
1230
1231
  		if (nd->flags & LOOKUP_RCU) {
  			if (unlikely(unlazy_walk(nd, path->dentry))) {
  				terminate_walk(nd);
  				return -ECHILD;
  			}
  		}
ce57dfc17   Al Viro   pull handling of ...
1232
1233
1234
1235
1236
1237
1238
  		BUG_ON(inode != path->dentry->d_inode);
  		return 1;
  	}
  	path_to_nameidata(path, nd);
  	nd->inode = inode;
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1239
  /*
b356379a0   Al Viro   Turn resolution o...
1240
1241
1242
1243
1244
1245
1246
1247
1248
   * This limits recursive symlink follows to 8, while
   * limiting consecutive symlinks to 40.
   *
   * Without that kind of total limit, nasty chains of consecutive
   * symlinks can cause almost arbitrarily long lookups.
   */
  static inline int nested_symlink(struct path *path, struct nameidata *nd)
  {
  	int res;
b356379a0   Al Viro   Turn resolution o...
1249
1250
1251
1252
1253
  	if (unlikely(current->link_count >= MAX_NESTED_LINKS)) {
  		path_put_conditional(path, nd);
  		path_put(&nd->path);
  		return -ELOOP;
  	}
1a4022f88   Erez Zadok   VFS: move BUG_ON ...
1254
  	BUG_ON(nd->depth >= MAX_NESTED_LINKS);
b356379a0   Al Viro   Turn resolution o...
1255
1256
1257
1258
1259
1260
1261
  
  	nd->depth++;
  	current->link_count++;
  
  	do {
  		struct path link = *path;
  		void *cookie;
574197e0d   Al Viro   tidy the trailing...
1262
1263
  
  		res = follow_link(&link, nd, &cookie);
b356379a0   Al Viro   Turn resolution o...
1264
1265
1266
  		if (!res)
  			res = walk_component(nd, path, &nd->last,
  					     nd->last_type, LOOKUP_FOLLOW);
574197e0d   Al Viro   tidy the trailing...
1267
  		put_link(nd, &link, cookie);
b356379a0   Al Viro   Turn resolution o...
1268
1269
1270
1271
1272
1273
1274
1275
  	} while (res > 0);
  
  	current->link_count--;
  	nd->depth--;
  	return res;
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1276
   * Name resolution.
ea3834d9f   Prasanna Meda   namei: add audit_...
1277
1278
   * This is the basic name resolution function, turning a pathname into
   * the final dentry. We expect 'base' to be positive and a directory.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1279
   *
ea3834d9f   Prasanna Meda   namei: add audit_...
1280
1281
   * Returns 0 and nd will have valid dentry and mnt on success.
   * Returns error and drops reference to input namei data on failure.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1282
   */
6de88d729   Al Viro   kill __link_path_...
1283
  static int link_path_walk(const char *name, struct nameidata *nd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1284
1285
  {
  	struct path next;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1286
1287
1288
1289
1290
1291
  	int err;
  	unsigned int lookup_flags = nd->flags;
  	
  	while (*name=='/')
  		name++;
  	if (!*name)
086e183a6   Al Viro   pull dropping RCU...
1292
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1293

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1294
1295
1296
1297
1298
  	/* At this point we know we have a real path component. */
  	for(;;) {
  		unsigned long hash;
  		struct qstr this;
  		unsigned int c;
fe479a580   Al Viro   merge component t...
1299
  		int type;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1300

cdce5d6b9   Trond Myklebust   VFS: Make link_pa...
1301
  		nd->flags |= LOOKUP_CONTINUE;
52094c8a0   Al Viro   take RCU-dependen...
1302
1303
  
  		err = may_lookup(nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
   		if (err)
  			break;
  
  		this.name = name;
  		c = *(const unsigned char *)name;
  
  		hash = init_name_hash();
  		do {
  			name++;
  			hash = partial_name_hash(c, hash);
  			c = *(const unsigned char *)name;
  		} while (c && (c != '/'));
  		this.len = name - (const char *) this.name;
  		this.hash = end_name_hash(hash);
fe479a580   Al Viro   merge component t...
1318
1319
1320
  		type = LAST_NORM;
  		if (this.name[0] == '.') switch (this.len) {
  			case 2:
16c2cd717   Al Viro   untangle the "nee...
1321
  				if (this.name[1] == '.') {
fe479a580   Al Viro   merge component t...
1322
  					type = LAST_DOTDOT;
16c2cd717   Al Viro   untangle the "nee...
1323
1324
  					nd->flags |= LOOKUP_JUMPED;
  				}
fe479a580   Al Viro   merge component t...
1325
1326
1327
1328
  				break;
  			case 1:
  				type = LAST_DOT;
  		}
5a202bcd7   Al Viro   sanitize pathname...
1329
1330
  		if (likely(type == LAST_NORM)) {
  			struct dentry *parent = nd->path.dentry;
16c2cd717   Al Viro   untangle the "nee...
1331
  			nd->flags &= ~LOOKUP_JUMPED;
5a202bcd7   Al Viro   sanitize pathname...
1332
1333
1334
1335
1336
1337
1338
  			if (unlikely(parent->d_flags & DCACHE_OP_HASH)) {
  				err = parent->d_op->d_hash(parent, nd->inode,
  							   &this);
  				if (err < 0)
  					break;
  			}
  		}
fe479a580   Al Viro   merge component t...
1339

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1340
1341
1342
1343
1344
  		/* remove trailing slashes? */
  		if (!c)
  			goto last_component;
  		while (*++name == '/');
  		if (!*name)
b356379a0   Al Viro   Turn resolution o...
1345
  			goto last_component;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1346

ce57dfc17   Al Viro   pull handling of ...
1347
1348
1349
  		err = walk_component(nd, &next, &this, type, LOOKUP_FOLLOW);
  		if (err < 0)
  			return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1350

ce57dfc17   Al Viro   pull handling of ...
1351
  		if (err) {
b356379a0   Al Viro   Turn resolution o...
1352
  			err = nested_symlink(&next, nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1353
  			if (err)
a7472baba   Al Viro   make nameidata_de...
1354
  				return err;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1355
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1356
  		err = -ENOTDIR; 
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1357
  		if (!nd->inode->i_op->lookup)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1358
1359
1360
  			break;
  		continue;
  		/* here ends the main loop */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1361
  last_component:
f55eab822   Trond Myklebust   [PATCH] VFS: Ensu...
1362
1363
  		/* Clear LOOKUP_CONTINUE iff it was previously unset */
  		nd->flags &= lookup_flags | ~LOOKUP_CONTINUE;
b356379a0   Al Viro   Turn resolution o...
1364
1365
  		nd->last = this;
  		nd->last_type = type;
086e183a6   Al Viro   pull dropping RCU...
1366
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1367
  	}
951361f95   Al Viro   get rid of the la...
1368
  	terminate_walk(nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1369
1370
  	return err;
  }
70e9b3571   Al Viro   get rid of nd->file
1371
1372
  static int path_init(int dfd, const char *name, unsigned int flags,
  		     struct nameidata *nd, struct file **fp)
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1373
1374
1375
1376
1377
1378
  {
  	int retval = 0;
  	int fput_needed;
  	struct file *file;
  
  	nd->last_type = LAST_ROOT; /* if there are only slashes... */
16c2cd717   Al Viro   untangle the "nee...
1379
  	nd->flags = flags | LOOKUP_JUMPED;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1380
  	nd->depth = 0;
5b6ca027d   Al Viro   reduce vfs_path_l...
1381
1382
  	if (flags & LOOKUP_ROOT) {
  		struct inode *inode = nd->root.dentry->d_inode;
73d049a40   Al Viro   open-style analog...
1383
1384
1385
1386
1387
1388
1389
  		if (*name) {
  			if (!inode->i_op->lookup)
  				return -ENOTDIR;
  			retval = inode_permission(inode, MAY_EXEC);
  			if (retval)
  				return retval;
  		}
5b6ca027d   Al Viro   reduce vfs_path_l...
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
  		nd->path = nd->root;
  		nd->inode = inode;
  		if (flags & LOOKUP_RCU) {
  			br_read_lock(vfsmount_lock);
  			rcu_read_lock();
  			nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
  		} else {
  			path_get(&nd->path);
  		}
  		return 0;
  	}
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1401
  	nd->root.mnt = NULL;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1402
1403
  
  	if (*name=='/') {
e41f7d4ee   Al Viro   merge path_init a...
1404
1405
1406
1407
1408
1409
1410
1411
1412
  		if (flags & LOOKUP_RCU) {
  			br_read_lock(vfsmount_lock);
  			rcu_read_lock();
  			set_root_rcu(nd);
  		} else {
  			set_root(nd);
  			path_get(&nd->root);
  		}
  		nd->path = nd->root;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1413
  	} else if (dfd == AT_FDCWD) {
e41f7d4ee   Al Viro   merge path_init a...
1414
1415
1416
  		if (flags & LOOKUP_RCU) {
  			struct fs_struct *fs = current->fs;
  			unsigned seq;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1417

e41f7d4ee   Al Viro   merge path_init a...
1418
1419
  			br_read_lock(vfsmount_lock);
  			rcu_read_lock();
c28cc3646   Nick Piggin   fs: fs_struct use...
1420

e41f7d4ee   Al Viro   merge path_init a...
1421
1422
1423
1424
1425
1426
1427
1428
  			do {
  				seq = read_seqcount_begin(&fs->seq);
  				nd->path = fs->pwd;
  				nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
  			} while (read_seqcount_retry(&fs->seq, seq));
  		} else {
  			get_fs_pwd(current->fs, &nd->path);
  		}
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1429
1430
  	} else {
  		struct dentry *dentry;
1abf0c718   Al Viro   New kind of open ...
1431
  		file = fget_raw_light(dfd, &fput_needed);
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1432
1433
1434
1435
1436
  		retval = -EBADF;
  		if (!file)
  			goto out_fail;
  
  		dentry = file->f_path.dentry;
f52e0c113   Al Viro   New AT_... flag: ...
1437
1438
1439
1440
  		if (*name) {
  			retval = -ENOTDIR;
  			if (!S_ISDIR(dentry->d_inode->i_mode))
  				goto fput_fail;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1441

f52e0c113   Al Viro   New AT_... flag: ...
1442
1443
1444
1445
  			retval = file_permission(file, MAY_EXEC);
  			if (retval)
  				goto fput_fail;
  		}
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1446
1447
  
  		nd->path = file->f_path;
e41f7d4ee   Al Viro   merge path_init a...
1448
1449
  		if (flags & LOOKUP_RCU) {
  			if (fput_needed)
70e9b3571   Al Viro   get rid of nd->file
1450
  				*fp = file;
e41f7d4ee   Al Viro   merge path_init a...
1451
1452
1453
1454
1455
1456
1457
  			nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
  			br_read_lock(vfsmount_lock);
  			rcu_read_lock();
  		} else {
  			path_get(&file->f_path);
  			fput_light(file, fput_needed);
  		}
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1458
  	}
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1459

31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1460
  	nd->inode = nd->path.dentry->d_inode;
9b4a9b14a   Al Viro   Preparations to c...
1461
  	return 0;
2dfdd266b   Josef 'Jeff' Sipek   fs: use path_walk...
1462

9b4a9b14a   Al Viro   Preparations to c...
1463
1464
1465
1466
1467
  fput_fail:
  	fput_light(file, fput_needed);
  out_fail:
  	return retval;
  }
bd92d7fed   Al Viro   Make trailing sym...
1468
1469
1470
1471
1472
1473
1474
1475
1476
  static inline int lookup_last(struct nameidata *nd, struct path *path)
  {
  	if (nd->last_type == LAST_NORM && nd->last.name[nd->last.len])
  		nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
  
  	nd->flags &= ~LOOKUP_PARENT;
  	return walk_component(nd, path, &nd->last, nd->last_type,
  					nd->flags & LOOKUP_FOLLOW);
  }
9b4a9b14a   Al Viro   Preparations to c...
1477
  /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
ee0827cd6   Al Viro   sanitize path_wal...
1478
  static int path_lookupat(int dfd, const char *name,
9b4a9b14a   Al Viro   Preparations to c...
1479
1480
  				unsigned int flags, struct nameidata *nd)
  {
70e9b3571   Al Viro   get rid of nd->file
1481
  	struct file *base = NULL;
bd92d7fed   Al Viro   Make trailing sym...
1482
1483
  	struct path path;
  	int err;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
  
  	/*
  	 * Path walking is largely split up into 2 different synchronisation
  	 * schemes, rcu-walk and ref-walk (explained in
  	 * Documentation/filesystems/path-lookup.txt). These share much of the
  	 * path walk code, but some things particularly setup, cleanup, and
  	 * following mounts are sufficiently divergent that functions are
  	 * duplicated. Typically there is a function foo(), and its RCU
  	 * analogue, foo_rcu().
  	 *
  	 * -ECHILD is the error number of choice (just to avoid clashes) that
  	 * is returned if some aspect of an rcu-walk fails. Such an error must
  	 * be handled by restarting a traditional ref-walk (which will always
  	 * be able to complete).
  	 */
bd92d7fed   Al Viro   Make trailing sym...
1499
  	err = path_init(dfd, name, flags | LOOKUP_PARENT, nd, &base);
ee0827cd6   Al Viro   sanitize path_wal...
1500

bd92d7fed   Al Viro   Make trailing sym...
1501
1502
  	if (unlikely(err))
  		return err;
ee0827cd6   Al Viro   sanitize path_wal...
1503
1504
  
  	current->total_link_count = 0;
bd92d7fed   Al Viro   Make trailing sym...
1505
1506
1507
  	err = link_path_walk(name, nd);
  
  	if (!err && !(flags & LOOKUP_PARENT)) {
bd92d7fed   Al Viro   Make trailing sym...
1508
1509
1510
1511
  		err = lookup_last(nd, &path);
  		while (err > 0) {
  			void *cookie;
  			struct path link = path;
bd92d7fed   Al Viro   Make trailing sym...
1512
  			nd->flags |= LOOKUP_PARENT;
574197e0d   Al Viro   tidy the trailing...
1513
  			err = follow_link(&link, nd, &cookie);
bd92d7fed   Al Viro   Make trailing sym...
1514
1515
  			if (!err)
  				err = lookup_last(nd, &path);
574197e0d   Al Viro   tidy the trailing...
1516
  			put_link(nd, &link, cookie);
bd92d7fed   Al Viro   Make trailing sym...
1517
1518
  		}
  	}
ee0827cd6   Al Viro   sanitize path_wal...
1519

9f1fafee9   Al Viro   merge handle_reva...
1520
1521
  	if (!err)
  		err = complete_walk(nd);
bd92d7fed   Al Viro   Make trailing sym...
1522
1523
1524
1525
  
  	if (!err && nd->flags & LOOKUP_DIRECTORY) {
  		if (!nd->inode->i_op->lookup) {
  			path_put(&nd->path);
bd23a539d   Al Viro   fix leaks in path...
1526
  			err = -ENOTDIR;
bd92d7fed   Al Viro   Make trailing sym...
1527
1528
  		}
  	}
16c2cd717   Al Viro   untangle the "nee...
1529

70e9b3571   Al Viro   get rid of nd->file
1530
1531
  	if (base)
  		fput(base);
ee0827cd6   Al Viro   sanitize path_wal...
1532

5b6ca027d   Al Viro   reduce vfs_path_l...
1533
  	if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) {
2a7378711   Al Viro   Cache root in nam...
1534
1535
1536
  		path_put(&nd->root);
  		nd->root.mnt = NULL;
  	}
bd92d7fed   Al Viro   Make trailing sym...
1537
  	return err;
ee0827cd6   Al Viro   sanitize path_wal...
1538
  }
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1539

ee0827cd6   Al Viro   sanitize path_wal...
1540
1541
1542
1543
1544
1545
1546
1547
  static int do_path_lookup(int dfd, const char *name,
  				unsigned int flags, struct nameidata *nd)
  {
  	int retval = path_lookupat(dfd, name, flags | LOOKUP_RCU, nd);
  	if (unlikely(retval == -ECHILD))
  		retval = path_lookupat(dfd, name, flags, nd);
  	if (unlikely(retval == -ESTALE))
  		retval = path_lookupat(dfd, name, flags | LOOKUP_REVAL, nd);
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1548
1549
1550
1551
1552
1553
1554
  
  	if (likely(!retval)) {
  		if (unlikely(!audit_dummy_context())) {
  			if (nd->path.dentry && nd->inode)
  				audit_inode(name, nd->path.dentry);
  		}
  	}
170aa3d02   Ulrich Drepper   [PATCH] namei.c: ...
1555
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1556
  }
c9c6cac0c   Al Viro   kill path_lookup()
1557
  int kern_path_parent(const char *name, struct nameidata *nd)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
1558
  {
c9c6cac0c   Al Viro   kill path_lookup()
1559
  	return do_path_lookup(AT_FDCWD, name, LOOKUP_PARENT, nd);
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
1560
  }
d18114657   Al Viro   [PATCH] new helpe...
1561
1562
1563
1564
1565
1566
1567
1568
  int kern_path(const char *name, unsigned int flags, struct path *path)
  {
  	struct nameidata nd;
  	int res = do_path_lookup(AT_FDCWD, name, flags, &nd);
  	if (!res)
  		*path = nd.path;
  	return res;
  }
16f182002   Josef 'Jeff' Sipek   fs: introduce vfs...
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
  /**
   * vfs_path_lookup - lookup a file path relative to a dentry-vfsmount pair
   * @dentry:  pointer to dentry of the base directory
   * @mnt: pointer to vfs mount of the base directory
   * @name: pointer to file name
   * @flags: lookup flags
   * @nd: pointer to nameidata
   */
  int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
  		    const char *name, unsigned int flags,
  		    struct nameidata *nd)
  {
5b6ca027d   Al Viro   reduce vfs_path_l...
1581
1582
1583
1584
  	nd->root.dentry = dentry;
  	nd->root.mnt = mnt;
  	/* the first argument of do_path_lookup() is ignored with LOOKUP_ROOT */
  	return do_path_lookup(AT_FDCWD, name, flags | LOOKUP_ROOT, nd);
16f182002   Josef 'Jeff' Sipek   fs: introduce vfs...
1585
  }
eead19115   Christoph Hellwig   partially fix up ...
1586
1587
  static struct dentry *__lookup_hash(struct qstr *name,
  		struct dentry *base, struct nameidata *nd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1588
  {
81fca4440   Christoph Hellwig   fs: move permissi...
1589
  	struct inode *inode = base->d_inode;
057f6c019   James Morris   security: prevent...
1590
  	struct dentry *dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1591
  	int err;
b74c79e99   Nick Piggin   fs: provide rcu-w...
1592
  	err = exec_permission(inode, 0);
81fca4440   Christoph Hellwig   fs: move permissi...
1593
1594
  	if (err)
  		return ERR_PTR(err);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1595
1596
  
  	/*
b04f784e5   Nick Piggin   fs: remove extra ...
1597
1598
1599
  	 * Don't bother with __d_lookup: callers are for creat as
  	 * well as unlink, so a lot of the time it would cost
  	 * a double lookup.
6e6b1bd1e   Al Viro   Kill cached_looku...
1600
  	 */
b04f784e5   Nick Piggin   fs: remove extra ...
1601
  	dentry = d_lookup(base, name);
6e6b1bd1e   Al Viro   Kill cached_looku...
1602

fb045adb9   Nick Piggin   fs: dcache reduce...
1603
  	if (dentry && (dentry->d_flags & DCACHE_OP_REVALIDATE))
6e6b1bd1e   Al Viro   Kill cached_looku...
1604
  		dentry = do_revalidate(dentry, nd);
baa038907   Nick Piggin   fs: dentry alloca...
1605
1606
  	if (!dentry)
  		dentry = d_alloc_and_lookup(base, name, nd);
5a202bcd7   Al Viro   sanitize pathname...
1607

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1608
1609
  	return dentry;
  }
057f6c019   James Morris   security: prevent...
1610
1611
1612
1613
1614
  /*
   * Restricted form of lookup. Doesn't follow links, single-component only,
   * needs parent already locked. Doesn't follow mounts.
   * SMP-safe.
   */
eead19115   Christoph Hellwig   partially fix up ...
1615
  static struct dentry *lookup_hash(struct nameidata *nd)
057f6c019   James Morris   security: prevent...
1616
  {
4ac913785   Jan Blunck   Embed a struct pa...
1617
  	return __lookup_hash(&nd->last, nd->path.dentry, nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1618
  }
eead19115   Christoph Hellwig   partially fix up ...
1619
  /**
a6b91919e   Randy Dunlap   fs: fix kernel-do...
1620
   * lookup_one_len - filesystem helper to lookup single pathname component
eead19115   Christoph Hellwig   partially fix up ...
1621
1622
1623
1624
   * @name:	pathname component to lookup
   * @base:	base directory to lookup from
   * @len:	maximum length @len should be interpreted to
   *
a6b91919e   Randy Dunlap   fs: fix kernel-do...
1625
1626
   * Note that this routine is purely a helper for filesystem usage and should
   * not be called by generic code.  Also note that by using this function the
eead19115   Christoph Hellwig   partially fix up ...
1627
1628
1629
   * nameidata argument is passed to the filesystem methods and a filesystem
   * using this helper needs to be prepared for that.
   */
057f6c019   James Morris   security: prevent...
1630
1631
  struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
  {
057f6c019   James Morris   security: prevent...
1632
  	struct qstr this;
6a96ba544   Al Viro   kill __lookup_one...
1633
1634
  	unsigned long hash;
  	unsigned int c;
057f6c019   James Morris   security: prevent...
1635

2f9092e10   David Woodhouse   Fix i_mutex vs. r...
1636
  	WARN_ON_ONCE(!mutex_is_locked(&base->d_inode->i_mutex));
6a96ba544   Al Viro   kill __lookup_one...
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
  	this.name = name;
  	this.len = len;
  	if (!len)
  		return ERR_PTR(-EACCES);
  
  	hash = init_name_hash();
  	while (len--) {
  		c = *(const unsigned char *)name++;
  		if (c == '/' || c == '\0')
  			return ERR_PTR(-EACCES);
  		hash = partial_name_hash(c, hash);
  	}
  	this.hash = end_name_hash(hash);
5a202bcd7   Al Viro   sanitize pathname...
1650
1651
1652
1653
1654
1655
1656
1657
1658
  	/*
  	 * See if the low-level filesystem might want
  	 * to use its own hash..
  	 */
  	if (base->d_flags & DCACHE_OP_HASH) {
  		int err = base->d_op->d_hash(base, base->d_inode, &this);
  		if (err < 0)
  			return ERR_PTR(err);
  	}
eead19115   Christoph Hellwig   partially fix up ...
1659

49705b774   Christoph Hellwig   [PATCH] sanitize ...
1660
  	return __lookup_hash(&this, base, NULL);
057f6c019   James Morris   security: prevent...
1661
  }
2d8f30380   Al Viro   [PATCH] sanitize ...
1662
1663
  int user_path_at(int dfd, const char __user *name, unsigned flags,
  		 struct path *path)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1664
  {
2d8f30380   Al Viro   [PATCH] sanitize ...
1665
  	struct nameidata nd;
f52e0c113   Al Viro   New AT_... flag: ...
1666
  	char *tmp = getname_flags(name, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1667
  	int err = PTR_ERR(tmp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1668
  	if (!IS_ERR(tmp)) {
2d8f30380   Al Viro   [PATCH] sanitize ...
1669
1670
1671
1672
  
  		BUG_ON(flags & LOOKUP_PARENT);
  
  		err = do_path_lookup(dfd, tmp, flags, &nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1673
  		putname(tmp);
2d8f30380   Al Viro   [PATCH] sanitize ...
1674
1675
  		if (!err)
  			*path = nd.path;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1676
1677
1678
  	}
  	return err;
  }
2ad94ae65   Al Viro   [PATCH] new (loca...
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
  static int user_path_parent(int dfd, const char __user *path,
  			struct nameidata *nd, char **name)
  {
  	char *s = getname(path);
  	int error;
  
  	if (IS_ERR(s))
  		return PTR_ERR(s);
  
  	error = do_path_lookup(dfd, s, LOOKUP_PARENT, nd);
  	if (error)
  		putname(s);
  	else
  		*name = s;
  
  	return error;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1696
1697
1698
1699
1700
1701
  /*
   * It's inline, so penalty for filesystems that don't use sticky bit is
   * minimal.
   */
  static inline int check_sticky(struct inode *dir, struct inode *inode)
  {
da9592ede   David Howells   CRED: Wrap task c...
1702
  	uid_t fsuid = current_fsuid();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1703
1704
  	if (!(dir->i_mode & S_ISVTX))
  		return 0;
e795b7179   Serge E. Hallyn   userns: userns: c...
1705
1706
  	if (current_user_ns() != inode_userns(inode))
  		goto other_userns;
da9592ede   David Howells   CRED: Wrap task c...
1707
  	if (inode->i_uid == fsuid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1708
  		return 0;
da9592ede   David Howells   CRED: Wrap task c...
1709
  	if (dir->i_uid == fsuid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1710
  		return 0;
e795b7179   Serge E. Hallyn   userns: userns: c...
1711
1712
1713
  
  other_userns:
  	return !ns_capable(inode_userns(inode), CAP_FOWNER);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
  }
  
  /*
   *	Check whether we can remove a link victim from directory dir, check
   *  whether the type of victim is right.
   *  1. We can't do it if dir is read-only (done in permission())
   *  2. We should have write and exec permissions on dir
   *  3. We can't remove anything from append-only dir
   *  4. We can't do anything with immutable dir (done in permission())
   *  5. If the sticky bit on dir is set we should either
   *	a. be owner of dir, or
   *	b. be owner of victim, or
   *	c. have CAP_FOWNER capability
   *  6. If the victim is append-only or immutable we can't do antyhing with
   *     links pointing to it.
   *  7. If we were asked to remove a directory and victim isn't one - ENOTDIR.
   *  8. If we were asked to remove a non-directory and victim isn't one - EISDIR.
   *  9. We can't remove a root or mountpoint.
   * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
   *     nfs_async_unlink().
   */
858119e15   Arjan van de Ven   [PATCH] Unlinline...
1735
  static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1736
1737
1738
1739
1740
1741
1742
  {
  	int error;
  
  	if (!victim->d_inode)
  		return -ENOENT;
  
  	BUG_ON(victim->d_parent->d_inode != dir);
cccc6bba3   Al Viro   Lose the first ar...
1743
  	audit_inode_child(victim, dir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1744

f419a2e3b   Al Viro   [PATCH] kill name...
1745
  	error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1746
1747
1748
1749
1750
  	if (error)
  		return error;
  	if (IS_APPEND(dir))
  		return -EPERM;
  	if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)||
f9454548e   Hugh Dickins   don't unlink an a...
1751
  	    IS_IMMUTABLE(victim->d_inode) || IS_SWAPFILE(victim->d_inode))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
  		return -EPERM;
  	if (isdir) {
  		if (!S_ISDIR(victim->d_inode->i_mode))
  			return -ENOTDIR;
  		if (IS_ROOT(victim))
  			return -EBUSY;
  	} else if (S_ISDIR(victim->d_inode->i_mode))
  		return -EISDIR;
  	if (IS_DEADDIR(dir))
  		return -ENOENT;
  	if (victim->d_flags & DCACHE_NFSFS_RENAMED)
  		return -EBUSY;
  	return 0;
  }
  
  /*	Check whether we can create an object with dentry child in directory
   *  dir.
   *  1. We can't do it if child already exists (open has special treatment for
   *     this case, but since we are inlined it's OK)
   *  2. We can't do it if dir is read-only (done in permission())
   *  3. We should have write and exec permissions on dir
   *  4. We can't do it if dir is immutable (done in permission())
   */
a95164d97   Miklos Szeredi   [patch 3/4] vfs: ...
1775
  static inline int may_create(struct inode *dir, struct dentry *child)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1776
1777
1778
1779
1780
  {
  	if (child->d_inode)
  		return -EEXIST;
  	if (IS_DEADDIR(dir))
  		return -ENOENT;
f419a2e3b   Al Viro   [PATCH] kill name...
1781
  	return inode_permission(dir, MAY_WRITE | MAY_EXEC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1782
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1783
1784
1785
1786
1787
1788
1789
1790
  /*
   * p1 and p2 should be directories on the same fs.
   */
  struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
  {
  	struct dentry *p;
  
  	if (p1 == p2) {
f2eace23e   Ingo Molnar   [PATCH] lockdep: ...
1791
  		mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1792
1793
  		return NULL;
  	}
a11f3a057   Arjan van de Ven   [PATCH] sem2mutex...
1794
  	mutex_lock(&p1->d_inode->i_sb->s_vfs_rename_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1795

e2761a116   OGAWA Hirofumi   [PATCH vfs-2.6 2/...
1796
1797
1798
1799
1800
  	p = d_ancestor(p2, p1);
  	if (p) {
  		mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_PARENT);
  		mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_CHILD);
  		return p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1801
  	}
e2761a116   OGAWA Hirofumi   [PATCH vfs-2.6 2/...
1802
1803
1804
1805
1806
  	p = d_ancestor(p1, p2);
  	if (p) {
  		mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
  		mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD);
  		return p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1807
  	}
f2eace23e   Ingo Molnar   [PATCH] lockdep: ...
1808
1809
  	mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
  	mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1810
1811
1812
1813
1814
  	return NULL;
  }
  
  void unlock_rename(struct dentry *p1, struct dentry *p2)
  {
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
1815
  	mutex_unlock(&p1->d_inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1816
  	if (p1 != p2) {
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
1817
  		mutex_unlock(&p2->d_inode->i_mutex);
a11f3a057   Arjan van de Ven   [PATCH] sem2mutex...
1818
  		mutex_unlock(&p1->d_inode->i_sb->s_vfs_rename_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1819
1820
1821
1822
1823
1824
  	}
  }
  
  int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
  		struct nameidata *nd)
  {
a95164d97   Miklos Szeredi   [patch 3/4] vfs: ...
1825
  	int error = may_create(dir, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1826
1827
1828
  
  	if (error)
  		return error;
acfa4380e   Al Viro   inode->i_op is ne...
1829
  	if (!dir->i_op->create)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1830
1831
1832
1833
1834
1835
  		return -EACCES;	/* shouldn't it be ENOSYS? */
  	mode &= S_IALLUGO;
  	mode |= S_IFREG;
  	error = security_inode_create(dir, dentry, mode);
  	if (error)
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1836
  	error = dir->i_op->create(dir, dentry, mode, nd);
a74574aaf   Stephen Smalley   [PATCH] Remove se...
1837
  	if (!error)
f38aa9422   Amy Griffis   [PATCH] Pass dent...
1838
  		fsnotify_create(dir, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1839
1840
  	return error;
  }
73d049a40   Al Viro   open-style analog...
1841
  static int may_open(struct path *path, int acc_mode, int flag)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1842
  {
3fb64190a   Christoph Hellwig   pass a struct pat...
1843
  	struct dentry *dentry = path->dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1844
1845
  	struct inode *inode = dentry->d_inode;
  	int error;
bcda76524   Al Viro   Allow O_PATH for ...
1846
1847
1848
  	/* O_PATH? */
  	if (!acc_mode)
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1849
1850
  	if (!inode)
  		return -ENOENT;
c8fe8f30c   Christoph Hellwig   cleanup may_open
1851
1852
  	switch (inode->i_mode & S_IFMT) {
  	case S_IFLNK:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1853
  		return -ELOOP;
c8fe8f30c   Christoph Hellwig   cleanup may_open
1854
1855
1856
1857
1858
1859
  	case S_IFDIR:
  		if (acc_mode & MAY_WRITE)
  			return -EISDIR;
  		break;
  	case S_IFBLK:
  	case S_IFCHR:
3fb64190a   Christoph Hellwig   pass a struct pat...
1860
  		if (path->mnt->mnt_flags & MNT_NODEV)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1861
  			return -EACCES;
c8fe8f30c   Christoph Hellwig   cleanup may_open
1862
1863
1864
  		/*FALLTHRU*/
  	case S_IFIFO:
  	case S_IFSOCK:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1865
  		flag &= ~O_TRUNC;
c8fe8f30c   Christoph Hellwig   cleanup may_open
1866
  		break;
4a3fd211c   Dave Hansen   [PATCH] r/o bind ...
1867
  	}
b41572e92   Dave Hansen   r/o bind mounts: ...
1868

3fb64190a   Christoph Hellwig   pass a struct pat...
1869
  	error = inode_permission(inode, acc_mode);
b41572e92   Dave Hansen   r/o bind mounts: ...
1870
1871
  	if (error)
  		return error;
6146f0d5e   Mimi Zohar   integrity: IMA hooks
1872

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1873
1874
1875
1876
  	/*
  	 * An append-only file must be opened in append mode for writing.
  	 */
  	if (IS_APPEND(inode)) {
8737c9305   Al Viro   Switch may_open()...
1877
  		if  ((flag & O_ACCMODE) != O_RDONLY && !(flag & O_APPEND))
7715b5212   Al Viro   O_TRUNC open shou...
1878
  			return -EPERM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1879
  		if (flag & O_TRUNC)
7715b5212   Al Viro   O_TRUNC open shou...
1880
  			return -EPERM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1881
1882
1883
  	}
  
  	/* O_NOATIME can only be set by the owner or superuser */
2e1496707   Serge E. Hallyn   userns: rename is...
1884
  	if (flag & O_NOATIME && !inode_owner_or_capable(inode))
7715b5212   Al Viro   O_TRUNC open shou...
1885
  		return -EPERM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1886
1887
1888
1889
  
  	/*
  	 * Ensure there are no outstanding leases on the file.
  	 */
b65a9cfc2   Al Viro   Untangling ima me...
1890
  	return break_lease(inode, flag);
7715b5212   Al Viro   O_TRUNC open shou...
1891
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1892

e1181ee65   Jeff Layton   vfs: pass struct ...
1893
  static int handle_truncate(struct file *filp)
7715b5212   Al Viro   O_TRUNC open shou...
1894
  {
e1181ee65   Jeff Layton   vfs: pass struct ...
1895
  	struct path *path = &filp->f_path;
7715b5212   Al Viro   O_TRUNC open shou...
1896
1897
1898
1899
1900
1901
1902
1903
1904
  	struct inode *inode = path->dentry->d_inode;
  	int error = get_write_access(inode);
  	if (error)
  		return error;
  	/*
  	 * Refuse to truncate files with mandatory locks held on them.
  	 */
  	error = locks_verify_locked(inode);
  	if (!error)
ea0d3ab23   Tetsuo Handa   LSM: Remove unuse...
1905
  		error = security_path_truncate(path);
7715b5212   Al Viro   O_TRUNC open shou...
1906
1907
1908
  	if (!error) {
  		error = do_truncate(path->dentry, 0,
  				    ATTR_MTIME|ATTR_CTIME|ATTR_OPEN,
e1181ee65   Jeff Layton   vfs: pass struct ...
1909
  				    filp);
7715b5212   Al Viro   O_TRUNC open shou...
1910
1911
  	}
  	put_write_access(inode);
acd0c9351   Mimi Zohar   IMA: update ima_c...
1912
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1913
  }
d57999e15   Dave Hansen   [PATCH] do namei_...
1914
  /*
d57999e15   Dave Hansen   [PATCH] do namei_...
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
   * Note that while the flag value (low two bits) for sys_open means:
   *	00 - read-only
   *	01 - write-only
   *	10 - read-write
   *	11 - special
   * it is changed into
   *	00 - no permissions needed
   *	01 - read-permission
   *	10 - write-permission
   *	11 - read-write
   * for the internal routines (ie open_namei()/follow_link() etc)
   * This is more logical, and also allows the 00 "no perm needed"
   * to be used for symlinks (where the permissions are checked
   * later).
   *
  */
  static inline int open_to_namei_flags(int flag)
  {
  	if ((flag+1) & O_ACCMODE)
  		flag++;
  	return flag;
  }
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1937
  /*
fe2d35ff0   Al Viro   switch non-create...
1938
   * Handle the last step of open()
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
1939
   */
fb1cc555d   Al Viro   gut do_filp_open(...
1940
  static struct file *do_last(struct nameidata *nd, struct path *path,
c3e380b0b   Al Viro   Collect "operatio...
1941
  			    const struct open_flags *op, const char *pathname)
fb1cc555d   Al Viro   gut do_filp_open(...
1942
  {
a1e28038d   Al Viro   pull the common p...
1943
  	struct dentry *dir = nd->path.dentry;
6c0d46c49   Al Viro   fold __open_namei...
1944
  	struct dentry *dentry;
ca344a894   Al Viro   do_last: unify ma...
1945
  	int open_flag = op->open_flag;
6c0d46c49   Al Viro   fold __open_namei...
1946
  	int will_truncate = open_flag & O_TRUNC;
ca344a894   Al Viro   do_last: unify ma...
1947
  	int want_write = 0;
bcda76524   Al Viro   Allow O_PATH for ...
1948
  	int acc_mode = op->acc_mode;
fb1cc555d   Al Viro   gut do_filp_open(...
1949
  	struct file *filp;
16c2cd717   Al Viro   untangle the "nee...
1950
  	int error;
1f36f774b   Al Viro   Switch !O_CREAT c...
1951

c3e380b0b   Al Viro   Collect "operatio...
1952
1953
  	nd->flags &= ~LOOKUP_PARENT;
  	nd->flags |= op->intent;
1f36f774b   Al Viro   Switch !O_CREAT c...
1954
1955
  	switch (nd->last_type) {
  	case LAST_DOTDOT:
176306f59   Neil Brown   VFS: fix recent b...
1956
  	case LAST_DOT:
fe2d35ff0   Al Viro   switch non-create...
1957
1958
1959
  		error = handle_dots(nd, nd->last_type);
  		if (error)
  			return ERR_PTR(error);
1f36f774b   Al Viro   Switch !O_CREAT c...
1960
  		/* fallthrough */
1f36f774b   Al Viro   Switch !O_CREAT c...
1961
  	case LAST_ROOT:
9f1fafee9   Al Viro   merge handle_reva...
1962
  		error = complete_walk(nd);
16c2cd717   Al Viro   untangle the "nee...
1963
  		if (error)
9f1fafee9   Al Viro   merge handle_reva...
1964
  			return ERR_PTR(error);
fe2d35ff0   Al Viro   switch non-create...
1965
  		audit_inode(pathname, nd->path.dentry);
ca344a894   Al Viro   do_last: unify ma...
1966
  		if (open_flag & O_CREAT) {
fe2d35ff0   Al Viro   switch non-create...
1967
1968
1969
1970
  			error = -EISDIR;
  			goto exit;
  		}
  		goto ok;
1f36f774b   Al Viro   Switch !O_CREAT c...
1971
  	case LAST_BIND:
9f1fafee9   Al Viro   merge handle_reva...
1972
  		error = complete_walk(nd);
16c2cd717   Al Viro   untangle the "nee...
1973
  		if (error)
9f1fafee9   Al Viro   merge handle_reva...
1974
  			return ERR_PTR(error);
1f36f774b   Al Viro   Switch !O_CREAT c...
1975
  		audit_inode(pathname, dir);
67ee3ad21   Al Viro   Pull handling of ...
1976
  		goto ok;
1f36f774b   Al Viro   Switch !O_CREAT c...
1977
  	}
67ee3ad21   Al Viro   Pull handling of ...
1978

ca344a894   Al Viro   do_last: unify ma...
1979
  	if (!(open_flag & O_CREAT)) {
bcda76524   Al Viro   Allow O_PATH for ...
1980
  		int symlink_ok = 0;
fe2d35ff0   Al Viro   switch non-create...
1981
1982
  		if (nd->last.name[nd->last.len])
  			nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
bcda76524   Al Viro   Allow O_PATH for ...
1983
1984
  		if (open_flag & O_PATH && !(nd->flags & LOOKUP_FOLLOW))
  			symlink_ok = 1;
fe2d35ff0   Al Viro   switch non-create...
1985
  		/* we _can_ be in RCU mode here */
ce57dfc17   Al Viro   pull handling of ...
1986
1987
1988
  		error = walk_component(nd, path, &nd->last, LAST_NORM,
  					!symlink_ok);
  		if (error < 0)
fe2d35ff0   Al Viro   switch non-create...
1989
  			return ERR_PTR(error);
ce57dfc17   Al Viro   pull handling of ...
1990
  		if (error) /* symlink */
fe2d35ff0   Al Viro   switch non-create...
1991
  			return NULL;
fe2d35ff0   Al Viro   switch non-create...
1992
  		/* sayonara */
9f1fafee9   Al Viro   merge handle_reva...
1993
1994
1995
  		error = complete_walk(nd);
  		if (error)
  			return ERR_PTR(-ECHILD);
fe2d35ff0   Al Viro   switch non-create...
1996
1997
1998
  
  		error = -ENOTDIR;
  		if (nd->flags & LOOKUP_DIRECTORY) {
ce57dfc17   Al Viro   pull handling of ...
1999
  			if (!nd->inode->i_op->lookup)
fe2d35ff0   Al Viro   switch non-create...
2000
2001
2002
2003
2004
2005
2006
  				goto exit;
  		}
  		audit_inode(pathname, nd->path.dentry);
  		goto ok;
  	}
  
  	/* create side of things */
9f1fafee9   Al Viro   merge handle_reva...
2007
2008
2009
  	error = complete_walk(nd);
  	if (error)
  		return ERR_PTR(error);
fe2d35ff0   Al Viro   switch non-create...
2010
2011
  
  	audit_inode(pathname, dir);
16c2cd717   Al Viro   untangle the "nee...
2012
  	error = -EISDIR;
1f36f774b   Al Viro   Switch !O_CREAT c...
2013
  	/* trailing slashes? */
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
2014
2015
  	if (nd->last.name[nd->last.len])
  		goto exit;
a2c36b450   Al Viro   pull more into do...
2016

a1e28038d   Al Viro   pull the common p...
2017
  	mutex_lock(&dir->d_inode->i_mutex);
6c0d46c49   Al Viro   fold __open_namei...
2018
2019
2020
  	dentry = lookup_hash(nd);
  	error = PTR_ERR(dentry);
  	if (IS_ERR(dentry)) {
fb1cc555d   Al Viro   gut do_filp_open(...
2021
2022
2023
  		mutex_unlock(&dir->d_inode->i_mutex);
  		goto exit;
  	}
6c0d46c49   Al Viro   fold __open_namei...
2024
2025
  	path->dentry = dentry;
  	path->mnt = nd->path.mnt;
fb1cc555d   Al Viro   gut do_filp_open(...
2026
  	/* Negative dentry, just create the file */
6c0d46c49   Al Viro   fold __open_namei...
2027
2028
2029
2030
  	if (!dentry->d_inode) {
  		int mode = op->mode;
  		if (!IS_POSIXACL(dir->d_inode))
  			mode &= ~current_umask();
fb1cc555d   Al Viro   gut do_filp_open(...
2031
2032
  		/*
  		 * This write is needed to ensure that a
6c0d46c49   Al Viro   fold __open_namei...
2033
  		 * rw->ro transition does not occur between
fb1cc555d   Al Viro   gut do_filp_open(...
2034
2035
2036
2037
2038
2039
2040
  		 * the time when the file is created and when
  		 * a permanent write count is taken through
  		 * the 'struct file' in nameidata_to_filp().
  		 */
  		error = mnt_want_write(nd->path.mnt);
  		if (error)
  			goto exit_mutex_unlock;
ca344a894   Al Viro   do_last: unify ma...
2041
  		want_write = 1;
9b44f1b39   Al Viro   move may_open() f...
2042
  		/* Don't check for write permission, don't truncate */
ca344a894   Al Viro   do_last: unify ma...
2043
  		open_flag &= ~O_TRUNC;
6c0d46c49   Al Viro   fold __open_namei...
2044
  		will_truncate = 0;
bcda76524   Al Viro   Allow O_PATH for ...
2045
  		acc_mode = MAY_OPEN;
6c0d46c49   Al Viro   fold __open_namei...
2046
2047
2048
2049
2050
2051
2052
2053
2054
  		error = security_path_mknod(&nd->path, dentry, mode, 0);
  		if (error)
  			goto exit_mutex_unlock;
  		error = vfs_create(dir->d_inode, dentry, mode, nd);
  		if (error)
  			goto exit_mutex_unlock;
  		mutex_unlock(&dir->d_inode->i_mutex);
  		dput(nd->path.dentry);
  		nd->path.dentry = dentry;
ca344a894   Al Viro   do_last: unify ma...
2055
  		goto common;
fb1cc555d   Al Viro   gut do_filp_open(...
2056
2057
2058
2059
2060
2061
2062
2063
2064
  	}
  
  	/*
  	 * It already exists.
  	 */
  	mutex_unlock(&dir->d_inode->i_mutex);
  	audit_inode(pathname, path->dentry);
  
  	error = -EEXIST;
ca344a894   Al Viro   do_last: unify ma...
2065
  	if (open_flag & O_EXCL)
fb1cc555d   Al Viro   gut do_filp_open(...
2066
  		goto exit_dput;
9875cf806   David Howells   Add a dentry op t...
2067
2068
2069
  	error = follow_managed(path, nd->flags);
  	if (error < 0)
  		goto exit_dput;
fb1cc555d   Al Viro   gut do_filp_open(...
2070
2071
2072
2073
  
  	error = -ENOENT;
  	if (!path->dentry->d_inode)
  		goto exit_dput;
9e67f3616   Al Viro   Kill is_link argu...
2074
2075
  
  	if (path->dentry->d_inode->i_op->follow_link)
fb1cc555d   Al Viro   gut do_filp_open(...
2076
  		return NULL;
fb1cc555d   Al Viro   gut do_filp_open(...
2077
2078
  
  	path_to_nameidata(path, nd);
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
2079
  	nd->inode = path->dentry->d_inode;
fb1cc555d   Al Viro   gut do_filp_open(...
2080
  	error = -EISDIR;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
2081
  	if (S_ISDIR(nd->inode->i_mode))
fb1cc555d   Al Viro   gut do_filp_open(...
2082
  		goto exit;
67ee3ad21   Al Viro   Pull handling of ...
2083
  ok:
6c0d46c49   Al Viro   fold __open_namei...
2084
2085
  	if (!S_ISREG(nd->inode->i_mode))
  		will_truncate = 0;
0f9d1a10c   Al Viro   expand finish_ope...
2086
2087
2088
2089
  	if (will_truncate) {
  		error = mnt_want_write(nd->path.mnt);
  		if (error)
  			goto exit;
ca344a894   Al Viro   do_last: unify ma...
2090
  		want_write = 1;
0f9d1a10c   Al Viro   expand finish_ope...
2091
  	}
ca344a894   Al Viro   do_last: unify ma...
2092
  common:
bcda76524   Al Viro   Allow O_PATH for ...
2093
  	error = may_open(&nd->path, acc_mode, open_flag);
ca344a894   Al Viro   do_last: unify ma...
2094
  	if (error)
0f9d1a10c   Al Viro   expand finish_ope...
2095
  		goto exit;
0f9d1a10c   Al Viro   expand finish_ope...
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
  	filp = nameidata_to_filp(nd);
  	if (!IS_ERR(filp)) {
  		error = ima_file_check(filp, op->acc_mode);
  		if (error) {
  			fput(filp);
  			filp = ERR_PTR(error);
  		}
  	}
  	if (!IS_ERR(filp)) {
  		if (will_truncate) {
  			error = handle_truncate(filp);
  			if (error) {
  				fput(filp);
  				filp = ERR_PTR(error);
  			}
  		}
  	}
ca344a894   Al Viro   do_last: unify ma...
2113
2114
  out:
  	if (want_write)
0f9d1a10c   Al Viro   expand finish_ope...
2115
2116
  		mnt_drop_write(nd->path.mnt);
  	path_put(&nd->path);
fb1cc555d   Al Viro   gut do_filp_open(...
2117
2118
2119
2120
2121
2122
2123
  	return filp;
  
  exit_mutex_unlock:
  	mutex_unlock(&dir->d_inode->i_mutex);
  exit_dput:
  	path_put_conditional(path, nd);
  exit:
ca344a894   Al Viro   do_last: unify ma...
2124
2125
  	filp = ERR_PTR(error);
  	goto out;
fb1cc555d   Al Viro   gut do_filp_open(...
2126
  }
13aab428a   Al Viro   separate -ESTALE/...
2127
  static struct file *path_openat(int dfd, const char *pathname,
73d049a40   Al Viro   open-style analog...
2128
  		struct nameidata *nd, const struct open_flags *op, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2129
  {
fe2d35ff0   Al Viro   switch non-create...
2130
  	struct file *base = NULL;
4a3fd211c   Dave Hansen   [PATCH] r/o bind ...
2131
  	struct file *filp;
9850c0565   Al Viro   Fix the -ESTALE h...
2132
  	struct path path;
13aab428a   Al Viro   separate -ESTALE/...
2133
  	int error;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
2134
2135
2136
2137
  
  	filp = get_empty_filp();
  	if (!filp)
  		return ERR_PTR(-ENFILE);
47c805dc2   Al Viro   switch do_filp_op...
2138
  	filp->f_flags = op->open_flag;
73d049a40   Al Viro   open-style analog...
2139
2140
2141
  	nd->intent.open.file = filp;
  	nd->intent.open.flags = open_to_namei_flags(op->open_flag);
  	nd->intent.open.create_mode = op->mode;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
2142

73d049a40   Al Viro   open-style analog...
2143
  	error = path_init(dfd, pathname, flags | LOOKUP_PARENT, nd, &base);
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
2144
  	if (unlikely(error))
13aab428a   Al Viro   separate -ESTALE/...
2145
  		goto out_filp;
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
2146

fe2d35ff0   Al Viro   switch non-create...
2147
  	current->total_link_count = 0;
73d049a40   Al Viro   open-style analog...
2148
  	error = link_path_walk(pathname, nd);
31e6b01f4   Nick Piggin   fs: rcu-walk for ...
2149
2150
  	if (unlikely(error))
  		goto out_filp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2151

73d049a40   Al Viro   open-style analog...
2152
  	filp = do_last(nd, &path, op, pathname);
806b681cb   Al Viro   Turn do_link spag...
2153
  	while (unlikely(!filp)) { /* trailing symlink */
7b9337aaf   Nick Piggin   fs: namei fix ->p...
2154
  		struct path link = path;
def4af30c   Al Viro   Get rid of symlin...
2155
  		void *cookie;
574197e0d   Al Viro   tidy the trailing...
2156
  		if (!(nd->flags & LOOKUP_FOLLOW)) {
73d049a40   Al Viro   open-style analog...
2157
2158
  			path_put_conditional(&path, nd);
  			path_put(&nd->path);
40b39136f   Al Viro   path_openat: clea...
2159
2160
2161
  			filp = ERR_PTR(-ELOOP);
  			break;
  		}
73d049a40   Al Viro   open-style analog...
2162
2163
  		nd->flags |= LOOKUP_PARENT;
  		nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL);
574197e0d   Al Viro   tidy the trailing...
2164
  		error = follow_link(&link, nd, &cookie);
c3e380b0b   Al Viro   Collect "operatio...
2165
  		if (unlikely(error))
f1afe9efc   Al Viro   clean up the fail...
2166
  			filp = ERR_PTR(error);
c3e380b0b   Al Viro   Collect "operatio...
2167
  		else
73d049a40   Al Viro   open-style analog...
2168
  			filp = do_last(nd, &path, op, pathname);
574197e0d   Al Viro   tidy the trailing...
2169
  		put_link(nd, &link, cookie);
806b681cb   Al Viro   Turn do_link spag...
2170
  	}
10fa8e62f   Al Viro   Unify exits in O_...
2171
  out:
73d049a40   Al Viro   open-style analog...
2172
2173
  	if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT))
  		path_put(&nd->root);
fe2d35ff0   Al Viro   switch non-create...
2174
2175
  	if (base)
  		fput(base);
73d049a40   Al Viro   open-style analog...
2176
  	release_open_intent(nd);
10fa8e62f   Al Viro   Unify exits in O_...
2177
  	return filp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2178

31e6b01f4   Nick Piggin   fs: rcu-walk for ...
2179
  out_filp:
806b681cb   Al Viro   Turn do_link spag...
2180
  	filp = ERR_PTR(error);
10fa8e62f   Al Viro   Unify exits in O_...
2181
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2182
  }
13aab428a   Al Viro   separate -ESTALE/...
2183
2184
2185
  struct file *do_filp_open(int dfd, const char *pathname,
  		const struct open_flags *op, int flags)
  {
73d049a40   Al Viro   open-style analog...
2186
  	struct nameidata nd;
13aab428a   Al Viro   separate -ESTALE/...
2187
  	struct file *filp;
73d049a40   Al Viro   open-style analog...
2188
  	filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_RCU);
13aab428a   Al Viro   separate -ESTALE/...
2189
  	if (unlikely(filp == ERR_PTR(-ECHILD)))
73d049a40   Al Viro   open-style analog...
2190
  		filp = path_openat(dfd, pathname, &nd, op, flags);
13aab428a   Al Viro   separate -ESTALE/...
2191
  	if (unlikely(filp == ERR_PTR(-ESTALE)))
73d049a40   Al Viro   open-style analog...
2192
  		filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_REVAL);
13aab428a   Al Viro   separate -ESTALE/...
2193
2194
  	return filp;
  }
73d049a40   Al Viro   open-style analog...
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
  struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
  		const char *name, const struct open_flags *op, int flags)
  {
  	struct nameidata nd;
  	struct file *file;
  
  	nd.root.mnt = mnt;
  	nd.root.dentry = dentry;
  
  	flags |= LOOKUP_ROOT;
bcda76524   Al Viro   Allow O_PATH for ...
2205
  	if (dentry->d_inode->i_op->follow_link && op->intent & LOOKUP_OPEN)
73d049a40   Al Viro   open-style analog...
2206
2207
2208
2209
2210
2211
2212
2213
2214
  		return ERR_PTR(-ELOOP);
  
  	file = path_openat(-1, name, &nd, op, flags | LOOKUP_RCU);
  	if (unlikely(file == ERR_PTR(-ECHILD)))
  		file = path_openat(-1, name, &nd, op, flags);
  	if (unlikely(file == ERR_PTR(-ESTALE)))
  		file = path_openat(-1, name, &nd, op, flags | LOOKUP_REVAL);
  	return file;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2215
2216
2217
2218
2219
2220
2221
  /**
   * lookup_create - lookup a dentry, creating it if it doesn't exist
   * @nd: nameidata info
   * @is_dir: directory flag
   *
   * Simple function to lookup and return a dentry and create it
   * if it doesn't exist.  Is SMP-safe.
c663e5d80   Christoph Hellwig   [PATCH] add some ...
2222
   *
4ac913785   Jan Blunck   Embed a struct pa...
2223
   * Returns with nd->path.dentry->d_inode->i_mutex locked.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2224
2225
2226
   */
  struct dentry *lookup_create(struct nameidata *nd, int is_dir)
  {
c663e5d80   Christoph Hellwig   [PATCH] add some ...
2227
  	struct dentry *dentry = ERR_PTR(-EEXIST);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2228

4ac913785   Jan Blunck   Embed a struct pa...
2229
  	mutex_lock_nested(&nd->path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
c663e5d80   Christoph Hellwig   [PATCH] add some ...
2230
2231
2232
2233
  	/*
  	 * Yucky last component or no last component at all?
  	 * (foo/., foo/.., /////)
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2234
2235
2236
  	if (nd->last_type != LAST_NORM)
  		goto fail;
  	nd->flags &= ~LOOKUP_PARENT;
3516586a4   Al Viro   [PATCH] make O_EX...
2237
  	nd->flags |= LOOKUP_CREATE | LOOKUP_EXCL;
a634904a7   ASANO Masahiro   VFS: add lookup h...
2238
  	nd->intent.open.flags = O_EXCL;
c663e5d80   Christoph Hellwig   [PATCH] add some ...
2239
2240
2241
2242
  
  	/*
  	 * Do the final lookup.
  	 */
49705b774   Christoph Hellwig   [PATCH] sanitize ...
2243
  	dentry = lookup_hash(nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2244
2245
  	if (IS_ERR(dentry))
  		goto fail;
c663e5d80   Christoph Hellwig   [PATCH] add some ...
2246

e9baf6e59   Al Viro   [PATCH] return to...
2247
2248
  	if (dentry->d_inode)
  		goto eexist;
c663e5d80   Christoph Hellwig   [PATCH] add some ...
2249
2250
2251
2252
2253
2254
  	/*
  	 * Special case - lookup gave negative, but... we had foo/bar/
  	 * From the vfs_mknod() POV we just have a negative dentry -
  	 * all is fine. Let's be bastards - you had / on the end, you've
  	 * been asking for (non-existent) directory. -ENOENT for you.
  	 */
e9baf6e59   Al Viro   [PATCH] return to...
2255
2256
2257
2258
  	if (unlikely(!is_dir && nd->last.name[nd->last.len])) {
  		dput(dentry);
  		dentry = ERR_PTR(-ENOENT);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2259
  	return dentry;
e9baf6e59   Al Viro   [PATCH] return to...
2260
  eexist:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2261
  	dput(dentry);
e9baf6e59   Al Viro   [PATCH] return to...
2262
  	dentry = ERR_PTR(-EEXIST);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2263
2264
2265
  fail:
  	return dentry;
  }
f81a0bffa   Christoph Hellwig   [AF_UNIX]: Use lo...
2266
  EXPORT_SYMBOL_GPL(lookup_create);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2267
2268
2269
  
  int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
  {
a95164d97   Miklos Szeredi   [patch 3/4] vfs: ...
2270
  	int error = may_create(dir, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2271
2272
2273
  
  	if (error)
  		return error;
e795b7179   Serge E. Hallyn   userns: userns: c...
2274
2275
  	if ((S_ISCHR(mode) || S_ISBLK(mode)) &&
  	    !ns_capable(inode_userns(dir), CAP_MKNOD))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2276
  		return -EPERM;
acfa4380e   Al Viro   inode->i_op is ne...
2277
  	if (!dir->i_op->mknod)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2278
  		return -EPERM;
08ce5f16e   Serge E. Hallyn   cgroups: implemen...
2279
2280
2281
  	error = devcgroup_inode_mknod(mode, dev);
  	if (error)
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2282
2283
2284
  	error = security_inode_mknod(dir, dentry, mode, dev);
  	if (error)
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2285
  	error = dir->i_op->mknod(dir, dentry, mode, dev);
a74574aaf   Stephen Smalley   [PATCH] Remove se...
2286
  	if (!error)
f38aa9422   Amy Griffis   [PATCH] Pass dent...
2287
  		fsnotify_create(dir, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2288
2289
  	return error;
  }
463c31972   Dave Hansen   [PATCH] r/o bind ...
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
  static int may_mknod(mode_t mode)
  {
  	switch (mode & S_IFMT) {
  	case S_IFREG:
  	case S_IFCHR:
  	case S_IFBLK:
  	case S_IFIFO:
  	case S_IFSOCK:
  	case 0: /* zero mode translates to S_IFREG */
  		return 0;
  	case S_IFDIR:
  		return -EPERM;
  	default:
  		return -EINVAL;
  	}
  }
2e4d0924e   Heiko Carstens   [CVE-2009-0029] S...
2306
2307
  SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode,
  		unsigned, dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2308
  {
2ad94ae65   Al Viro   [PATCH] new (loca...
2309
2310
2311
  	int error;
  	char *tmp;
  	struct dentry *dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2312
2313
2314
2315
  	struct nameidata nd;
  
  	if (S_ISDIR(mode))
  		return -EPERM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2316

2ad94ae65   Al Viro   [PATCH] new (loca...
2317
  	error = user_path_parent(dfd, filename, &nd, &tmp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2318
  	if (error)
2ad94ae65   Al Viro   [PATCH] new (loca...
2319
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2320
  	dentry = lookup_create(&nd, 0);
463c31972   Dave Hansen   [PATCH] r/o bind ...
2321
2322
2323
2324
  	if (IS_ERR(dentry)) {
  		error = PTR_ERR(dentry);
  		goto out_unlock;
  	}
4ac913785   Jan Blunck   Embed a struct pa...
2325
  	if (!IS_POSIXACL(nd.path.dentry->d_inode))
ce3b0f8d5   Al Viro   New helper - curr...
2326
  		mode &= ~current_umask();
463c31972   Dave Hansen   [PATCH] r/o bind ...
2327
2328
2329
2330
2331
2332
  	error = may_mknod(mode);
  	if (error)
  		goto out_dput;
  	error = mnt_want_write(nd.path.mnt);
  	if (error)
  		goto out_dput;
be6d3e56a   Kentaro Takeda   introduce new LSM...
2333
2334
2335
  	error = security_path_mknod(&nd.path, dentry, mode, dev);
  	if (error)
  		goto out_drop_write;
463c31972   Dave Hansen   [PATCH] r/o bind ...
2336
  	switch (mode & S_IFMT) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2337
  		case 0: case S_IFREG:
4ac913785   Jan Blunck   Embed a struct pa...
2338
  			error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2339
2340
  			break;
  		case S_IFCHR: case S_IFBLK:
4ac913785   Jan Blunck   Embed a struct pa...
2341
  			error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2342
2343
2344
  					new_decode_dev(dev));
  			break;
  		case S_IFIFO: case S_IFSOCK:
4ac913785   Jan Blunck   Embed a struct pa...
2345
  			error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2346
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2347
  	}
be6d3e56a   Kentaro Takeda   introduce new LSM...
2348
  out_drop_write:
463c31972   Dave Hansen   [PATCH] r/o bind ...
2349
2350
2351
2352
  	mnt_drop_write(nd.path.mnt);
  out_dput:
  	dput(dentry);
  out_unlock:
4ac913785   Jan Blunck   Embed a struct pa...
2353
  	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
1d957f9bf   Jan Blunck   Introduce path_put()
2354
  	path_put(&nd.path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2355
2356
2357
2358
  	putname(tmp);
  
  	return error;
  }
3480b2574   Heiko Carstens   [CVE-2009-0029] S...
2359
  SYSCALL_DEFINE3(mknod, const char __user *, filename, int, mode, unsigned, dev)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2360
2361
2362
  {
  	return sys_mknodat(AT_FDCWD, filename, mode, dev);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2363
2364
  int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
  {
a95164d97   Miklos Szeredi   [patch 3/4] vfs: ...
2365
  	int error = may_create(dir, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2366
2367
2368
  
  	if (error)
  		return error;
acfa4380e   Al Viro   inode->i_op is ne...
2369
  	if (!dir->i_op->mkdir)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2370
2371
2372
2373
2374
2375
  		return -EPERM;
  
  	mode &= (S_IRWXUGO|S_ISVTX);
  	error = security_inode_mkdir(dir, dentry, mode);
  	if (error)
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2376
  	error = dir->i_op->mkdir(dir, dentry, mode);
a74574aaf   Stephen Smalley   [PATCH] Remove se...
2377
  	if (!error)
f38aa9422   Amy Griffis   [PATCH] Pass dent...
2378
  		fsnotify_mkdir(dir, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2379
2380
  	return error;
  }
2e4d0924e   Heiko Carstens   [CVE-2009-0029] S...
2381
  SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2382
2383
2384
  {
  	int error = 0;
  	char * tmp;
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2385
2386
  	struct dentry *dentry;
  	struct nameidata nd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2387

2ad94ae65   Al Viro   [PATCH] new (loca...
2388
2389
  	error = user_path_parent(dfd, pathname, &nd, &tmp);
  	if (error)
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2390
  		goto out_err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2391

6902d925d   Dave Hansen   [PATCH] r/o bind ...
2392
2393
2394
2395
  	dentry = lookup_create(&nd, 1);
  	error = PTR_ERR(dentry);
  	if (IS_ERR(dentry))
  		goto out_unlock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2396

4ac913785   Jan Blunck   Embed a struct pa...
2397
  	if (!IS_POSIXACL(nd.path.dentry->d_inode))
ce3b0f8d5   Al Viro   New helper - curr...
2398
  		mode &= ~current_umask();
463c31972   Dave Hansen   [PATCH] r/o bind ...
2399
2400
2401
  	error = mnt_want_write(nd.path.mnt);
  	if (error)
  		goto out_dput;
be6d3e56a   Kentaro Takeda   introduce new LSM...
2402
2403
2404
  	error = security_path_mkdir(&nd.path, dentry, mode);
  	if (error)
  		goto out_drop_write;
4ac913785   Jan Blunck   Embed a struct pa...
2405
  	error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
be6d3e56a   Kentaro Takeda   introduce new LSM...
2406
  out_drop_write:
463c31972   Dave Hansen   [PATCH] r/o bind ...
2407
2408
  	mnt_drop_write(nd.path.mnt);
  out_dput:
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2409
2410
  	dput(dentry);
  out_unlock:
4ac913785   Jan Blunck   Embed a struct pa...
2411
  	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
1d957f9bf   Jan Blunck   Introduce path_put()
2412
  	path_put(&nd.path);
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2413
2414
  	putname(tmp);
  out_err:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2415
2416
  	return error;
  }
3cdad4288   Heiko Carstens   [CVE-2009-0029] S...
2417
  SYSCALL_DEFINE2(mkdir, const char __user *, pathname, int, mode)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2418
2419
2420
  {
  	return sys_mkdirat(AT_FDCWD, pathname, mode);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2421
  /*
a71905f0d   Sage Weil   vfs: update dentr...
2422
2423
2424
2425
   * The dentry_unhash() helper will try to drop the dentry early: we
   * should have a usage count of 2 if we're the only user of this
   * dentry, and if that is true (possibly after pruning the dcache),
   * then we drop the dentry now.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
   *
   * A low-level filesystem can, if it choses, legally
   * do a
   *
   *	if (!d_unhashed(dentry))
   *		return -EBUSY;
   *
   * if it cannot handle the case of removing a directory
   * that is still in use by something else..
   */
  void dentry_unhash(struct dentry *dentry)
  {
dc168427e   Vasily Averin   [PATCH] VFS: extr...
2438
  	shrink_dcache_parent(dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2439
  	spin_lock(&dentry->d_lock);
64252c75a   Sage Weil   vfs: remove dget(...
2440
  	if (dentry->d_count == 1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2441
2442
  		__d_drop(dentry);
  	spin_unlock(&dentry->d_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2443
2444
2445
2446
2447
2448
2449
2450
  }
  
  int vfs_rmdir(struct inode *dir, struct dentry *dentry)
  {
  	int error = may_delete(dir, dentry, 1);
  
  	if (error)
  		return error;
acfa4380e   Al Viro   inode->i_op is ne...
2451
  	if (!dir->i_op->rmdir)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2452
  		return -EPERM;
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2453
  	mutex_lock(&dentry->d_inode->i_mutex);
912dbc15d   Sage Weil   vfs: clean up vfs...
2454
2455
  
  	error = -EBUSY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2456
  	if (d_mountpoint(dentry))
912dbc15d   Sage Weil   vfs: clean up vfs...
2457
2458
2459
2460
2461
  		goto out;
  
  	error = security_inode_rmdir(dir, dentry);
  	if (error)
  		goto out;
3cebde241   Sage Weil   vfs: shrink_dcach...
2462
  	shrink_dcache_parent(dentry);
912dbc15d   Sage Weil   vfs: clean up vfs...
2463
2464
2465
2466
2467
2468
2469
2470
  	error = dir->i_op->rmdir(dir, dentry);
  	if (error)
  		goto out;
  
  	dentry->d_inode->i_flags |= S_DEAD;
  	dont_mount(dentry);
  
  out:
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2471
  	mutex_unlock(&dentry->d_inode->i_mutex);
912dbc15d   Sage Weil   vfs: clean up vfs...
2472
  	if (!error)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2473
  		d_delete(dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2474
2475
  	return error;
  }
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2476
  static long do_rmdir(int dfd, const char __user *pathname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2477
2478
2479
2480
2481
  {
  	int error = 0;
  	char * name;
  	struct dentry *dentry;
  	struct nameidata nd;
2ad94ae65   Al Viro   [PATCH] new (loca...
2482
  	error = user_path_parent(dfd, pathname, &nd, &name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2483
  	if (error)
2ad94ae65   Al Viro   [PATCH] new (loca...
2484
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2485
2486
  
  	switch(nd.last_type) {
0612d9fb2   OGAWA Hirofumi   [PATCH vfs-2.6 5/...
2487
2488
2489
2490
2491
2492
2493
2494
2495
  	case LAST_DOTDOT:
  		error = -ENOTEMPTY;
  		goto exit1;
  	case LAST_DOT:
  		error = -EINVAL;
  		goto exit1;
  	case LAST_ROOT:
  		error = -EBUSY;
  		goto exit1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2496
  	}
0612d9fb2   OGAWA Hirofumi   [PATCH vfs-2.6 5/...
2497
2498
  
  	nd.flags &= ~LOOKUP_PARENT;
4ac913785   Jan Blunck   Embed a struct pa...
2499
  	mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
49705b774   Christoph Hellwig   [PATCH] sanitize ...
2500
  	dentry = lookup_hash(&nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2501
  	error = PTR_ERR(dentry);
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2502
2503
  	if (IS_ERR(dentry))
  		goto exit2;
e6bc45d65   Theodore Ts'o   vfs: make unlink(...
2504
2505
2506
2507
  	if (!dentry->d_inode) {
  		error = -ENOENT;
  		goto exit3;
  	}
0622753b8   Dave Hansen   [PATCH] r/o bind ...
2508
2509
2510
  	error = mnt_want_write(nd.path.mnt);
  	if (error)
  		goto exit3;
be6d3e56a   Kentaro Takeda   introduce new LSM...
2511
2512
2513
  	error = security_path_rmdir(&nd.path, dentry);
  	if (error)
  		goto exit4;
4ac913785   Jan Blunck   Embed a struct pa...
2514
  	error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
be6d3e56a   Kentaro Takeda   introduce new LSM...
2515
  exit4:
0622753b8   Dave Hansen   [PATCH] r/o bind ...
2516
2517
  	mnt_drop_write(nd.path.mnt);
  exit3:
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2518
2519
  	dput(dentry);
  exit2:
4ac913785   Jan Blunck   Embed a struct pa...
2520
  	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2521
  exit1:
1d957f9bf   Jan Blunck   Introduce path_put()
2522
  	path_put(&nd.path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2523
2524
2525
  	putname(name);
  	return error;
  }
3cdad4288   Heiko Carstens   [CVE-2009-0029] S...
2526
  SYSCALL_DEFINE1(rmdir, const char __user *, pathname)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2527
2528
2529
  {
  	return do_rmdir(AT_FDCWD, pathname);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2530
2531
2532
2533
2534
2535
  int vfs_unlink(struct inode *dir, struct dentry *dentry)
  {
  	int error = may_delete(dir, dentry, 0);
  
  	if (error)
  		return error;
acfa4380e   Al Viro   inode->i_op is ne...
2536
  	if (!dir->i_op->unlink)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2537
  		return -EPERM;
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2538
  	mutex_lock(&dentry->d_inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2539
2540
2541
2542
  	if (d_mountpoint(dentry))
  		error = -EBUSY;
  	else {
  		error = security_inode_unlink(dir, dentry);
bec1052e5   Al Viro   set S_DEAD on unl...
2543
  		if (!error) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2544
  			error = dir->i_op->unlink(dir, dentry);
bec1052e5   Al Viro   set S_DEAD on unl...
2545
  			if (!error)
d83c49f3e   Al Viro   Fix the regressio...
2546
  				dont_mount(dentry);
bec1052e5   Al Viro   set S_DEAD on unl...
2547
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2548
  	}
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2549
  	mutex_unlock(&dentry->d_inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2550
2551
2552
  
  	/* We don't d_delete() NFS sillyrenamed files--they still exist. */
  	if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) {
ece95912d   Jan Kara   inotify: send IN_...
2553
  		fsnotify_link_count(dentry->d_inode);
e234f35c5   John McCutchan   [PATCH] inotify d...
2554
  		d_delete(dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2555
  	}
0eeca2830   Robert Love   [PATCH] inotify
2556

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2557
2558
2559
2560
2561
  	return error;
  }
  
  /*
   * Make sure that the actual truncation of the file will occur outside its
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2562
   * directory's i_mutex.  Truncate can take a long time if there is a lot of
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2563
2564
2565
   * writeout happening, and we don't want to prevent access to the directory
   * while waiting on the I/O.
   */
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2566
  static long do_unlinkat(int dfd, const char __user *pathname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2567
  {
2ad94ae65   Al Viro   [PATCH] new (loca...
2568
2569
  	int error;
  	char *name;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2570
2571
2572
  	struct dentry *dentry;
  	struct nameidata nd;
  	struct inode *inode = NULL;
2ad94ae65   Al Viro   [PATCH] new (loca...
2573
  	error = user_path_parent(dfd, pathname, &nd, &name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2574
  	if (error)
2ad94ae65   Al Viro   [PATCH] new (loca...
2575
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2576
2577
2578
  	error = -EISDIR;
  	if (nd.last_type != LAST_NORM)
  		goto exit1;
0612d9fb2   OGAWA Hirofumi   [PATCH vfs-2.6 5/...
2579
2580
  
  	nd.flags &= ~LOOKUP_PARENT;
4ac913785   Jan Blunck   Embed a struct pa...
2581
  	mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
49705b774   Christoph Hellwig   [PATCH] sanitize ...
2582
  	dentry = lookup_hash(&nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2583
2584
2585
  	error = PTR_ERR(dentry);
  	if (!IS_ERR(dentry)) {
  		/* Why not before? Because we want correct error value */
50338b889   Török Edwin   fix wrong iput on...
2586
2587
  		if (nd.last.name[nd.last.len])
  			goto slashes;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2588
  		inode = dentry->d_inode;
50338b889   Török Edwin   fix wrong iput on...
2589
  		if (!inode)
e6bc45d65   Theodore Ts'o   vfs: make unlink(...
2590
2591
  			goto slashes;
  		ihold(inode);
0622753b8   Dave Hansen   [PATCH] r/o bind ...
2592
2593
2594
  		error = mnt_want_write(nd.path.mnt);
  		if (error)
  			goto exit2;
be6d3e56a   Kentaro Takeda   introduce new LSM...
2595
2596
2597
  		error = security_path_unlink(&nd.path, dentry);
  		if (error)
  			goto exit3;
4ac913785   Jan Blunck   Embed a struct pa...
2598
  		error = vfs_unlink(nd.path.dentry->d_inode, dentry);
be6d3e56a   Kentaro Takeda   introduce new LSM...
2599
  exit3:
0622753b8   Dave Hansen   [PATCH] r/o bind ...
2600
  		mnt_drop_write(nd.path.mnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2601
2602
2603
  	exit2:
  		dput(dentry);
  	}
4ac913785   Jan Blunck   Embed a struct pa...
2604
  	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2605
2606
2607
  	if (inode)
  		iput(inode);	/* truncate the inode here */
  exit1:
1d957f9bf   Jan Blunck   Introduce path_put()
2608
  	path_put(&nd.path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2609
2610
2611
2612
2613
2614
2615
2616
  	putname(name);
  	return error;
  
  slashes:
  	error = !dentry->d_inode ? -ENOENT :
  		S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
  	goto exit2;
  }
2e4d0924e   Heiko Carstens   [CVE-2009-0029] S...
2617
  SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2618
2619
2620
2621
2622
2623
2624
2625
2626
  {
  	if ((flag & ~AT_REMOVEDIR) != 0)
  		return -EINVAL;
  
  	if (flag & AT_REMOVEDIR)
  		return do_rmdir(dfd, pathname);
  
  	return do_unlinkat(dfd, pathname);
  }
3480b2574   Heiko Carstens   [CVE-2009-0029] S...
2627
  SYSCALL_DEFINE1(unlink, const char __user *, pathname)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2628
2629
2630
  {
  	return do_unlinkat(AT_FDCWD, pathname);
  }
db2e747b1   Miklos Szeredi   [patch 5/5] vfs: ...
2631
  int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2632
  {
a95164d97   Miklos Szeredi   [patch 3/4] vfs: ...
2633
  	int error = may_create(dir, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2634
2635
2636
  
  	if (error)
  		return error;
acfa4380e   Al Viro   inode->i_op is ne...
2637
  	if (!dir->i_op->symlink)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2638
2639
2640
2641
2642
  		return -EPERM;
  
  	error = security_inode_symlink(dir, dentry, oldname);
  	if (error)
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2643
  	error = dir->i_op->symlink(dir, dentry, oldname);
a74574aaf   Stephen Smalley   [PATCH] Remove se...
2644
  	if (!error)
f38aa9422   Amy Griffis   [PATCH] Pass dent...
2645
  		fsnotify_create(dir, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2646
2647
  	return error;
  }
2e4d0924e   Heiko Carstens   [CVE-2009-0029] S...
2648
2649
  SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
  		int, newdfd, const char __user *, newname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2650
  {
2ad94ae65   Al Viro   [PATCH] new (loca...
2651
2652
2653
  	int error;
  	char *from;
  	char *to;
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2654
2655
  	struct dentry *dentry;
  	struct nameidata nd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2656
2657
  
  	from = getname(oldname);
2ad94ae65   Al Viro   [PATCH] new (loca...
2658
  	if (IS_ERR(from))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2659
  		return PTR_ERR(from);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2660

2ad94ae65   Al Viro   [PATCH] new (loca...
2661
  	error = user_path_parent(newdfd, newname, &nd, &to);
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2662
  	if (error)
2ad94ae65   Al Viro   [PATCH] new (loca...
2663
  		goto out_putname;
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2664
2665
2666
2667
  	dentry = lookup_create(&nd, 0);
  	error = PTR_ERR(dentry);
  	if (IS_ERR(dentry))
  		goto out_unlock;
75c3f29de   Dave Hansen   [PATCH] r/o bind ...
2668
2669
2670
  	error = mnt_want_write(nd.path.mnt);
  	if (error)
  		goto out_dput;
be6d3e56a   Kentaro Takeda   introduce new LSM...
2671
2672
2673
  	error = security_path_symlink(&nd.path, dentry, from);
  	if (error)
  		goto out_drop_write;
db2e747b1   Miklos Szeredi   [patch 5/5] vfs: ...
2674
  	error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
be6d3e56a   Kentaro Takeda   introduce new LSM...
2675
  out_drop_write:
75c3f29de   Dave Hansen   [PATCH] r/o bind ...
2676
2677
  	mnt_drop_write(nd.path.mnt);
  out_dput:
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2678
2679
  	dput(dentry);
  out_unlock:
4ac913785   Jan Blunck   Embed a struct pa...
2680
  	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
1d957f9bf   Jan Blunck   Introduce path_put()
2681
  	path_put(&nd.path);
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2682
2683
  	putname(to);
  out_putname:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2684
2685
2686
  	putname(from);
  	return error;
  }
3480b2574   Heiko Carstens   [CVE-2009-0029] S...
2687
  SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newname)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2688
2689
2690
  {
  	return sys_symlinkat(oldname, AT_FDCWD, newname);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2691
2692
2693
2694
2695
2696
2697
  int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
  {
  	struct inode *inode = old_dentry->d_inode;
  	int error;
  
  	if (!inode)
  		return -ENOENT;
a95164d97   Miklos Szeredi   [patch 3/4] vfs: ...
2698
  	error = may_create(dir, new_dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
  	if (error)
  		return error;
  
  	if (dir->i_sb != inode->i_sb)
  		return -EXDEV;
  
  	/*
  	 * A link to an append-only or immutable file cannot be created.
  	 */
  	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
  		return -EPERM;
acfa4380e   Al Viro   inode->i_op is ne...
2710
  	if (!dir->i_op->link)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2711
  		return -EPERM;
7e79eedb3   Tetsuo Handa   [patch 4/5] vfs: ...
2712
  	if (S_ISDIR(inode->i_mode))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2713
2714
2715
2716
2717
  		return -EPERM;
  
  	error = security_inode_link(old_dentry, dir, new_dentry);
  	if (error)
  		return error;
7e79eedb3   Tetsuo Handa   [patch 4/5] vfs: ...
2718
  	mutex_lock(&inode->i_mutex);
aae8a97d3   Aneesh Kumar K.V   fs: Don't allow t...
2719
2720
2721
2722
2723
  	/* Make sure we don't allow creating hardlink to an unlinked file */
  	if (inode->i_nlink == 0)
  		error =  -ENOENT;
  	else
  		error = dir->i_op->link(old_dentry, dir, new_dentry);
7e79eedb3   Tetsuo Handa   [patch 4/5] vfs: ...
2724
  	mutex_unlock(&inode->i_mutex);
e31e14ec3   Stephen Smalley   [PATCH] remove th...
2725
  	if (!error)
7e79eedb3   Tetsuo Handa   [patch 4/5] vfs: ...
2726
  		fsnotify_link(dir, inode, new_dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
  	return error;
  }
  
  /*
   * Hardlinks are often used in delicate situations.  We avoid
   * security-related surprises by not following symlinks on the
   * newname.  --KAB
   *
   * We don't follow them on the oldname either to be compatible
   * with linux 2.0, and to avoid hard-linking to directories
   * and other special files.  --ADM
   */
2e4d0924e   Heiko Carstens   [CVE-2009-0029] S...
2739
2740
  SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
  		int, newdfd, const char __user *, newname, int, flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2741
2742
  {
  	struct dentry *new_dentry;
2d8f30380   Al Viro   [PATCH] sanitize ...
2743
2744
  	struct nameidata nd;
  	struct path old_path;
11a7b371b   Aneesh Kumar K.V   fs: allow AT_EMPT...
2745
  	int how = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2746
  	int error;
2ad94ae65   Al Viro   [PATCH] new (loca...
2747
  	char *to;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2748

11a7b371b   Aneesh Kumar K.V   fs: allow AT_EMPT...
2749
  	if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
c04030e16   Ulrich Drepper   [PATCH] flags par...
2750
  		return -EINVAL;
11a7b371b   Aneesh Kumar K.V   fs: allow AT_EMPT...
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
  	/*
  	 * To use null names we require CAP_DAC_READ_SEARCH
  	 * This ensures that not everyone will be able to create
  	 * handlink using the passed filedescriptor.
  	 */
  	if (flags & AT_EMPTY_PATH) {
  		if (!capable(CAP_DAC_READ_SEARCH))
  			return -ENOENT;
  		how = LOOKUP_EMPTY;
  	}
  
  	if (flags & AT_SYMLINK_FOLLOW)
  		how |= LOOKUP_FOLLOW;
c04030e16   Ulrich Drepper   [PATCH] flags par...
2764

11a7b371b   Aneesh Kumar K.V   fs: allow AT_EMPT...
2765
  	error = user_path_at(olddfd, oldname, how, &old_path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2766
  	if (error)
2ad94ae65   Al Viro   [PATCH] new (loca...
2767
2768
2769
  		return error;
  
  	error = user_path_parent(newdfd, newname, &nd, &to);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2770
2771
2772
  	if (error)
  		goto out;
  	error = -EXDEV;
2d8f30380   Al Viro   [PATCH] sanitize ...
2773
  	if (old_path.mnt != nd.path.mnt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2774
2775
2776
  		goto out_release;
  	new_dentry = lookup_create(&nd, 0);
  	error = PTR_ERR(new_dentry);
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2777
2778
  	if (IS_ERR(new_dentry))
  		goto out_unlock;
75c3f29de   Dave Hansen   [PATCH] r/o bind ...
2779
2780
2781
  	error = mnt_want_write(nd.path.mnt);
  	if (error)
  		goto out_dput;
be6d3e56a   Kentaro Takeda   introduce new LSM...
2782
2783
2784
  	error = security_path_link(old_path.dentry, &nd.path, new_dentry);
  	if (error)
  		goto out_drop_write;
2d8f30380   Al Viro   [PATCH] sanitize ...
2785
  	error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
be6d3e56a   Kentaro Takeda   introduce new LSM...
2786
  out_drop_write:
75c3f29de   Dave Hansen   [PATCH] r/o bind ...
2787
2788
  	mnt_drop_write(nd.path.mnt);
  out_dput:
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2789
2790
  	dput(new_dentry);
  out_unlock:
4ac913785   Jan Blunck   Embed a struct pa...
2791
  	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2792
  out_release:
1d957f9bf   Jan Blunck   Introduce path_put()
2793
  	path_put(&nd.path);
2ad94ae65   Al Viro   [PATCH] new (loca...
2794
  	putname(to);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2795
  out:
2d8f30380   Al Viro   [PATCH] sanitize ...
2796
  	path_put(&old_path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2797
2798
2799
  
  	return error;
  }
3480b2574   Heiko Carstens   [CVE-2009-0029] S...
2800
  SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2801
  {
c04030e16   Ulrich Drepper   [PATCH] flags par...
2802
  	return sys_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2803
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2804
2805
2806
2807
2808
2809
2810
  /*
   * The worst of all namespace operations - renaming directory. "Perverted"
   * doesn't even start to describe it. Somebody in UCB had a heck of a trip...
   * Problems:
   *	a) we can get into loop creation. Check is done in is_subdir().
   *	b) race potential - two innocent renames can create a loop together.
   *	   That's where 4.4 screws up. Current fix: serialization on
a11f3a057   Arjan van de Ven   [PATCH] sem2mutex...
2811
   *	   sb->s_vfs_rename_mutex. We might be more accurate, but that's another
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2812
2813
   *	   story.
   *	c) we have to lock _three_ objects - parents and victim (if it exists).
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2814
   *	   And that - after we got ->i_mutex on parents (until then we don't know
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2815
2816
   *	   whether the target exists).  Solution: try to be smart with locking
   *	   order for inodes.  We rely on the fact that tree topology may change
a11f3a057   Arjan van de Ven   [PATCH] sem2mutex...
2817
   *	   only under ->s_vfs_rename_mutex _and_ that parent of the object we
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2818
2819
2820
   *	   move will be locked.  Thus we can rank directories by the tree
   *	   (ancestors first) and rank all non-directories after them.
   *	   That works since everybody except rename does "lock parent, lookup,
a11f3a057   Arjan van de Ven   [PATCH] sem2mutex...
2821
   *	   lock child" and rename is under ->s_vfs_rename_mutex.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2822
2823
2824
   *	   HOWEVER, it relies on the assumption that any object with ->lookup()
   *	   has no more than 1 dentry.  If "hybrid" objects will ever appear,
   *	   we'd better make sure that there's no link(2) for them.
e4eaac06b   Sage Weil   vfs: push dentry_...
2825
   *	d) conversion from fhandle to dentry may come in the wrong moment - when
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2826
   *	   we are removing the target. Solution: we will have to grab ->i_mutex
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2827
   *	   in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on
c41b20e72   Adam Buchbinder   Fix misspellings ...
2828
   *	   ->i_mutex on parents, which works but leads to some truly excessive
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2829
2830
   *	   locking].
   */
75c96f858   Adrian Bunk   [PATCH] make some...
2831
2832
  static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
  			  struct inode *new_dir, struct dentry *new_dentry)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2833
2834
  {
  	int error = 0;
9055cba71   Sage Weil   vfs: clean up vfs...
2835
  	struct inode *target = new_dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2836
2837
2838
2839
2840
2841
  
  	/*
  	 * If we are going to change the parent - check write permissions,
  	 * we'll need to flip '..'.
  	 */
  	if (new_dir != old_dir) {
f419a2e3b   Al Viro   [PATCH] kill name...
2842
  		error = inode_permission(old_dentry->d_inode, MAY_WRITE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2843
2844
2845
2846
2847
2848
2849
  		if (error)
  			return error;
  	}
  
  	error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry);
  	if (error)
  		return error;
d83c49f3e   Al Viro   Fix the regressio...
2850
  	if (target)
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2851
  		mutex_lock(&target->i_mutex);
9055cba71   Sage Weil   vfs: clean up vfs...
2852
2853
2854
2855
  
  	error = -EBUSY;
  	if (d_mountpoint(old_dentry) || d_mountpoint(new_dentry))
  		goto out;
3cebde241   Sage Weil   vfs: shrink_dcach...
2856
2857
  	if (target)
  		shrink_dcache_parent(new_dentry);
9055cba71   Sage Weil   vfs: clean up vfs...
2858
2859
2860
  	error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
  	if (error)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2861
  	if (target) {
9055cba71   Sage Weil   vfs: clean up vfs...
2862
2863
  		target->i_flags |= S_DEAD;
  		dont_mount(new_dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2864
  	}
9055cba71   Sage Weil   vfs: clean up vfs...
2865
2866
2867
  out:
  	if (target)
  		mutex_unlock(&target->i_mutex);
e31e14ec3   Stephen Smalley   [PATCH] remove th...
2868
  	if (!error)
349457ccf   Mark Fasheh   [PATCH] Allow fil...
2869
2870
  		if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
  			d_move(old_dentry,new_dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2871
2872
  	return error;
  }
75c96f858   Adrian Bunk   [PATCH] make some...
2873
2874
  static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
  			    struct inode *new_dir, struct dentry *new_dentry)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2875
  {
51892bbb5   Sage Weil   vfs: clean up vfs...
2876
  	struct inode *target = new_dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2877
2878
2879
2880
2881
2882
2883
  	int error;
  
  	error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry);
  	if (error)
  		return error;
  
  	dget(new_dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2884
  	if (target)
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2885
  		mutex_lock(&target->i_mutex);
51892bbb5   Sage Weil   vfs: clean up vfs...
2886
2887
  
  	error = -EBUSY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2888
  	if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
51892bbb5   Sage Weil   vfs: clean up vfs...
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
  		goto out;
  
  	error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
  	if (error)
  		goto out;
  
  	if (target)
  		dont_mount(new_dentry);
  	if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
  		d_move(old_dentry, new_dentry);
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2900
  	if (target)
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2901
  		mutex_unlock(&target->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2902
2903
2904
2905
2906
2907
2908
2909
2910
  	dput(new_dentry);
  	return error;
  }
  
  int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
  	       struct inode *new_dir, struct dentry *new_dentry)
  {
  	int error;
  	int is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
59b0df211   Eric Paris   fsnotify: use uns...
2911
  	const unsigned char *old_name;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2912
2913
2914
2915
2916
2917
2918
2919
2920
  
  	if (old_dentry->d_inode == new_dentry->d_inode)
   		return 0;
   
  	error = may_delete(old_dir, old_dentry, is_dir);
  	if (error)
  		return error;
  
  	if (!new_dentry->d_inode)
a95164d97   Miklos Szeredi   [patch 3/4] vfs: ...
2921
  		error = may_create(new_dir, new_dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2922
2923
2924
2925
  	else
  		error = may_delete(new_dir, new_dentry, is_dir);
  	if (error)
  		return error;
acfa4380e   Al Viro   inode->i_op is ne...
2926
  	if (!old_dir->i_op->rename)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2927
  		return -EPERM;
0eeca2830   Robert Love   [PATCH] inotify
2928
  	old_name = fsnotify_oldname_init(old_dentry->d_name.name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2929
2930
2931
2932
  	if (is_dir)
  		error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
  	else
  		error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
123df2944   Al Viro   Lose the new_name...
2933
2934
  	if (!error)
  		fsnotify_move(old_dir, new_dir, old_name, is_dir,
5a190ae69   Al Viro   [PATCH] pass dent...
2935
  			      new_dentry->d_inode, old_dentry);
0eeca2830   Robert Love   [PATCH] inotify
2936
  	fsnotify_oldname_free(old_name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2937
2938
  	return error;
  }
2e4d0924e   Heiko Carstens   [CVE-2009-0029] S...
2939
2940
  SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
  		int, newdfd, const char __user *, newname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2941
  {
2ad94ae65   Al Viro   [PATCH] new (loca...
2942
2943
2944
  	struct dentry *old_dir, *new_dir;
  	struct dentry *old_dentry, *new_dentry;
  	struct dentry *trap;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2945
  	struct nameidata oldnd, newnd;
2ad94ae65   Al Viro   [PATCH] new (loca...
2946
2947
2948
  	char *from;
  	char *to;
  	int error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2949

2ad94ae65   Al Viro   [PATCH] new (loca...
2950
  	error = user_path_parent(olddfd, oldname, &oldnd, &from);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2951
2952
  	if (error)
  		goto exit;
2ad94ae65   Al Viro   [PATCH] new (loca...
2953
  	error = user_path_parent(newdfd, newname, &newnd, &to);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2954
2955
2956
2957
  	if (error)
  		goto exit1;
  
  	error = -EXDEV;
4ac913785   Jan Blunck   Embed a struct pa...
2958
  	if (oldnd.path.mnt != newnd.path.mnt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2959
  		goto exit2;
4ac913785   Jan Blunck   Embed a struct pa...
2960
  	old_dir = oldnd.path.dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2961
2962
2963
  	error = -EBUSY;
  	if (oldnd.last_type != LAST_NORM)
  		goto exit2;
4ac913785   Jan Blunck   Embed a struct pa...
2964
  	new_dir = newnd.path.dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2965
2966
  	if (newnd.last_type != LAST_NORM)
  		goto exit2;
0612d9fb2   OGAWA Hirofumi   [PATCH vfs-2.6 5/...
2967
2968
  	oldnd.flags &= ~LOOKUP_PARENT;
  	newnd.flags &= ~LOOKUP_PARENT;
4e9ed2f85   OGAWA Hirofumi   [PATCH vfs-2.6 6/...
2969
  	newnd.flags |= LOOKUP_RENAME_TARGET;
0612d9fb2   OGAWA Hirofumi   [PATCH vfs-2.6 5/...
2970

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2971
  	trap = lock_rename(new_dir, old_dir);
49705b774   Christoph Hellwig   [PATCH] sanitize ...
2972
  	old_dentry = lookup_hash(&oldnd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
  	error = PTR_ERR(old_dentry);
  	if (IS_ERR(old_dentry))
  		goto exit3;
  	/* source must exist */
  	error = -ENOENT;
  	if (!old_dentry->d_inode)
  		goto exit4;
  	/* unless the source is a directory trailing slashes give -ENOTDIR */
  	if (!S_ISDIR(old_dentry->d_inode->i_mode)) {
  		error = -ENOTDIR;
  		if (oldnd.last.name[oldnd.last.len])
  			goto exit4;
  		if (newnd.last.name[newnd.last.len])
  			goto exit4;
  	}
  	/* source should not be ancestor of target */
  	error = -EINVAL;
  	if (old_dentry == trap)
  		goto exit4;
49705b774   Christoph Hellwig   [PATCH] sanitize ...
2992
  	new_dentry = lookup_hash(&newnd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2993
2994
2995
2996
2997
2998
2999
  	error = PTR_ERR(new_dentry);
  	if (IS_ERR(new_dentry))
  		goto exit4;
  	/* target should not be an ancestor of source */
  	error = -ENOTEMPTY;
  	if (new_dentry == trap)
  		goto exit5;
9079b1eb1   Dave Hansen   [PATCH] r/o bind ...
3000
3001
3002
  	error = mnt_want_write(oldnd.path.mnt);
  	if (error)
  		goto exit5;
be6d3e56a   Kentaro Takeda   introduce new LSM...
3003
3004
3005
3006
  	error = security_path_rename(&oldnd.path, old_dentry,
  				     &newnd.path, new_dentry);
  	if (error)
  		goto exit6;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3007
3008
  	error = vfs_rename(old_dir->d_inode, old_dentry,
  				   new_dir->d_inode, new_dentry);
be6d3e56a   Kentaro Takeda   introduce new LSM...
3009
  exit6:
9079b1eb1   Dave Hansen   [PATCH] r/o bind ...
3010
  	mnt_drop_write(oldnd.path.mnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3011
3012
3013
3014
3015
3016
3017
  exit5:
  	dput(new_dentry);
  exit4:
  	dput(old_dentry);
  exit3:
  	unlock_rename(new_dir, old_dir);
  exit2:
1d957f9bf   Jan Blunck   Introduce path_put()
3018
  	path_put(&newnd.path);
2ad94ae65   Al Viro   [PATCH] new (loca...
3019
  	putname(to);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3020
  exit1:
1d957f9bf   Jan Blunck   Introduce path_put()
3021
  	path_put(&oldnd.path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3022
  	putname(from);
2ad94ae65   Al Viro   [PATCH] new (loca...
3023
  exit:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3024
3025
  	return error;
  }
a26eab240   Heiko Carstens   [CVE-2009-0029] S...
3026
  SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newname)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
3027
3028
3029
  {
  	return sys_renameat(AT_FDCWD, oldname, AT_FDCWD, newname);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
  int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const char *link)
  {
  	int len;
  
  	len = PTR_ERR(link);
  	if (IS_ERR(link))
  		goto out;
  
  	len = strlen(link);
  	if (len > (unsigned) buflen)
  		len = buflen;
  	if (copy_to_user(buffer, link, len))
  		len = -EFAULT;
  out:
  	return len;
  }
  
  /*
   * A helper for ->readlink().  This should be used *ONLY* for symlinks that
   * have ->follow_link() touching nd only in nd_set_link().  Using (or not
   * using) it for any given inode is up to filesystem.
   */
  int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
  {
  	struct nameidata nd;
cc314eef0   Linus Torvalds   Fix nasty ncpfs s...
3055
  	void *cookie;
694a1764d   Marcin Slusarz   [patch 3/4] vfs: ...
3056
  	int res;
cc314eef0   Linus Torvalds   Fix nasty ncpfs s...
3057

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3058
  	nd.depth = 0;
cc314eef0   Linus Torvalds   Fix nasty ncpfs s...
3059
  	cookie = dentry->d_inode->i_op->follow_link(dentry, &nd);
694a1764d   Marcin Slusarz   [patch 3/4] vfs: ...
3060
3061
3062
3063
3064
3065
3066
  	if (IS_ERR(cookie))
  		return PTR_ERR(cookie);
  
  	res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
  	if (dentry->d_inode->i_op->put_link)
  		dentry->d_inode->i_op->put_link(dentry, &nd, cookie);
  	return res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
  }
  
  int vfs_follow_link(struct nameidata *nd, const char *link)
  {
  	return __vfs_follow_link(nd, link);
  }
  
  /* get the link contents into pagecache */
  static char *page_getlink(struct dentry * dentry, struct page **ppage)
  {
ebd09abbd   Duane Griffin   vfs: ensure page ...
3077
3078
  	char *kaddr;
  	struct page *page;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3079
  	struct address_space *mapping = dentry->d_inode->i_mapping;
090d2b185   Pekka Enberg   [PATCH] read_mapp...
3080
  	page = read_mapping_page(mapping, 0, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3081
  	if (IS_ERR(page))
6fe6900e1   Nick Piggin   mm: make read_cac...
3082
  		return (char*)page;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3083
  	*ppage = page;
ebd09abbd   Duane Griffin   vfs: ensure page ...
3084
3085
3086
  	kaddr = kmap(page);
  	nd_terminate_link(kaddr, dentry->d_inode->i_size, PAGE_SIZE - 1);
  	return kaddr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
  }
  
  int page_readlink(struct dentry *dentry, char __user *buffer, int buflen)
  {
  	struct page *page = NULL;
  	char *s = page_getlink(dentry, &page);
  	int res = vfs_readlink(dentry,buffer,buflen,s);
  	if (page) {
  		kunmap(page);
  		page_cache_release(page);
  	}
  	return res;
  }
cc314eef0   Linus Torvalds   Fix nasty ncpfs s...
3100
  void *page_follow_link_light(struct dentry *dentry, struct nameidata *nd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3101
  {
cc314eef0   Linus Torvalds   Fix nasty ncpfs s...
3102
  	struct page *page = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3103
  	nd_set_link(nd, page_getlink(dentry, &page));
cc314eef0   Linus Torvalds   Fix nasty ncpfs s...
3104
  	return page;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3105
  }
cc314eef0   Linus Torvalds   Fix nasty ncpfs s...
3106
  void page_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3107
  {
cc314eef0   Linus Torvalds   Fix nasty ncpfs s...
3108
3109
3110
  	struct page *page = cookie;
  
  	if (page) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3111
3112
  		kunmap(page);
  		page_cache_release(page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3113
3114
  	}
  }
54566b2c1   Nick Piggin   fs: symlink write...
3115
3116
3117
3118
  /*
   * The nofs argument instructs pagecache_write_begin to pass AOP_FLAG_NOFS
   */
  int __page_symlink(struct inode *inode, const char *symname, int len, int nofs)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3119
3120
  {
  	struct address_space *mapping = inode->i_mapping;
0adb25d2e   Kirill Korotaev   [PATCH] ext3: ext...
3121
  	struct page *page;
afddba49d   Nick Piggin   fs: introduce wri...
3122
  	void *fsdata;
beb497ab4   Dmitriy Monakhov   [PATCH] __page_sy...
3123
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3124
  	char *kaddr;
54566b2c1   Nick Piggin   fs: symlink write...
3125
3126
3127
  	unsigned int flags = AOP_FLAG_UNINTERRUPTIBLE;
  	if (nofs)
  		flags |= AOP_FLAG_NOFS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3128

7e53cac41   NeilBrown   [PATCH] Honour AO...
3129
  retry:
afddba49d   Nick Piggin   fs: introduce wri...
3130
  	err = pagecache_write_begin(NULL, mapping, 0, len-1,
54566b2c1   Nick Piggin   fs: symlink write...
3131
  				flags, &page, &fsdata);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3132
  	if (err)
afddba49d   Nick Piggin   fs: introduce wri...
3133
  		goto fail;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3134
3135
3136
  	kaddr = kmap_atomic(page, KM_USER0);
  	memcpy(kaddr, symname, len-1);
  	kunmap_atomic(kaddr, KM_USER0);
afddba49d   Nick Piggin   fs: introduce wri...
3137
3138
3139
  
  	err = pagecache_write_end(NULL, mapping, 0, len-1, len-1,
  							page, fsdata);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3140
3141
  	if (err < 0)
  		goto fail;
afddba49d   Nick Piggin   fs: introduce wri...
3142
3143
  	if (err < len-1)
  		goto retry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3144
3145
  	mark_inode_dirty(inode);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3146
3147
3148
  fail:
  	return err;
  }
0adb25d2e   Kirill Korotaev   [PATCH] ext3: ext...
3149
3150
3151
  int page_symlink(struct inode *inode, const char *symname, int len)
  {
  	return __page_symlink(inode, symname, len,
54566b2c1   Nick Piggin   fs: symlink write...
3152
  			!(mapping_gfp_mask(inode->i_mapping) & __GFP_FS));
0adb25d2e   Kirill Korotaev   [PATCH] ext3: ext...
3153
  }
92e1d5be9   Arjan van de Ven   [PATCH] mark stru...
3154
  const struct inode_operations page_symlink_inode_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3155
3156
3157
3158
  	.readlink	= generic_readlink,
  	.follow_link	= page_follow_link_light,
  	.put_link	= page_put_link,
  };
2d8f30380   Al Viro   [PATCH] sanitize ...
3159
  EXPORT_SYMBOL(user_path_at);
cc53ce53c   David Howells   Add a dentry op t...
3160
  EXPORT_SYMBOL(follow_down_one);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3161
3162
3163
3164
3165
  EXPORT_SYMBOL(follow_down);
  EXPORT_SYMBOL(follow_up);
  EXPORT_SYMBOL(get_write_access); /* binfmt_aout */
  EXPORT_SYMBOL(getname);
  EXPORT_SYMBOL(lock_rename);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3166
3167
3168
3169
  EXPORT_SYMBOL(lookup_one_len);
  EXPORT_SYMBOL(page_follow_link_light);
  EXPORT_SYMBOL(page_put_link);
  EXPORT_SYMBOL(page_readlink);
0adb25d2e   Kirill Korotaev   [PATCH] ext3: ext...
3170
  EXPORT_SYMBOL(__page_symlink);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3171
3172
  EXPORT_SYMBOL(page_symlink);
  EXPORT_SYMBOL(page_symlink_inode_operations);
c9c6cac0c   Al Viro   kill path_lookup()
3173
  EXPORT_SYMBOL(kern_path_parent);
d18114657   Al Viro   [PATCH] new helpe...
3174
  EXPORT_SYMBOL(kern_path);
16f182002   Josef 'Jeff' Sipek   fs: introduce vfs...
3175
  EXPORT_SYMBOL(vfs_path_lookup);
f419a2e3b   Al Viro   [PATCH] kill name...
3176
  EXPORT_SYMBOL(inode_permission);
8c744fb83   Christoph Hellwig   [PATCH] add a fil...
3177
  EXPORT_SYMBOL(file_permission);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
  EXPORT_SYMBOL(unlock_rename);
  EXPORT_SYMBOL(vfs_create);
  EXPORT_SYMBOL(vfs_follow_link);
  EXPORT_SYMBOL(vfs_link);
  EXPORT_SYMBOL(vfs_mkdir);
  EXPORT_SYMBOL(vfs_mknod);
  EXPORT_SYMBOL(generic_permission);
  EXPORT_SYMBOL(vfs_readlink);
  EXPORT_SYMBOL(vfs_rename);
  EXPORT_SYMBOL(vfs_rmdir);
  EXPORT_SYMBOL(vfs_symlink);
  EXPORT_SYMBOL(vfs_unlink);
  EXPORT_SYMBOL(dentry_unhash);
  EXPORT_SYMBOL(generic_readlink);