Blame view

fs/namei.c 70.5 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
71
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
  /* [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
   * the name is a symlink pointing to a non-existant name.
   *
   * 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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  {
  	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;
  }
  
  char * getname(const char __user * filename)
  {
  	char *tmp, *result;
  
  	result = ERR_PTR(-ENOMEM);
  	tmp = __getname();
  	if (tmp)  {
  		int retval = do_getname(filename, tmp);
  
  		result = tmp;
  		if (retval < 0) {
  			__putname(tmp);
  			result = ERR_PTR(retval);
  		}
  	}
  	audit_getname(result);
  	return result;
  }
  
  #ifdef CONFIG_AUDITSYSCALL
  void putname(const char *name)
  {
5ac3a9c26   Al Viro   [PATCH] don't bot...
159
  	if (unlikely(!audit_dummy_context()))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
161
162
163
164
165
  		audit_putname(name);
  	else
  		__putname(name);
  }
  EXPORT_SYMBOL(putname);
  #endif
5909ccaa3   Linus Torvalds   Make 'check_acl()...
166
167
  /*
   * This does basic POSIX ACL permission checking
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
   */
5909ccaa3   Linus Torvalds   Make 'check_acl()...
169
  static int acl_permission_check(struct inode *inode, int mask,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
171
172
  		int (*check_acl)(struct inode *inode, int mask))
  {
  	umode_t			mode = inode->i_mode;
e6305c43e   Al Viro   [PATCH] sanitize ...
173
  	mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
da9592ede   David Howells   CRED: Wrap task c...
174
  	if (current_fsuid() == inode->i_uid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
175
176
177
178
  		mode >>= 6;
  	else {
  		if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl) {
  			int error = check_acl(inode, mask);
5909ccaa3   Linus Torvalds   Make 'check_acl()...
179
  			if (error != -EAGAIN)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
180
181
182
183
184
185
186
187
188
189
  				return error;
  		}
  
  		if (in_group_p(inode->i_gid))
  			mode >>= 3;
  	}
  
  	/*
  	 * If the DACs are ok we don't need any capability check.
  	 */
e6305c43e   Al Viro   [PATCH] sanitize ...
190
  	if ((mask & ~mode) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
  		return 0;
5909ccaa3   Linus Torvalds   Make 'check_acl()...
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
  	return -EACCES;
  }
  
  /**
   * generic_permission  -  check for access rights on a Posix-like filesystem
   * @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
   *
   * 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
   * are used for other things..
   */
  int generic_permission(struct inode *inode, int mask,
  		int (*check_acl)(struct inode *inode, int mask))
  {
  	int ret;
  
  	/*
  	 * Do the basic POSIX ACL permission checks.
  	 */
  	ret = acl_permission_check(inode, mask, check_acl);
  	if (ret != -EACCES)
  		return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
219
220
221
  	/*
  	 * Read/write DACs are always overridable.
  	 * Executable DACs are overridable if at least one exec bit is set.
  	 */
f696a3659   Miklos Szeredi   [PATCH] move exec...
222
  	if (!(mask & MAY_EXEC) || execute_ok(inode))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
223
224
225
226
227
228
  		if (capable(CAP_DAC_OVERRIDE))
  			return 0;
  
  	/*
  	 * Searching includes executable on directories, else just read.
  	 */
7ea660014   Serge E. Hallyn   generic_permissio...
229
  	mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
231
232
233
234
235
  	if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))
  		if (capable(CAP_DAC_READ_SEARCH))
  			return 0;
  
  	return -EACCES;
  }
cb23beb55   Christoph Hellwig   kill vfs_permission
236
237
238
239
240
241
242
243
244
245
  /**
   * 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...
246
  int inode_permission(struct inode *inode, int mask)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247
  {
e6305c43e   Al Viro   [PATCH] sanitize ...
248
  	int retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249
250
  
  	if (mask & MAY_WRITE) {
22590e41c   Miklos Szeredi   fix execute check...
251
  		umode_t mode = inode->i_mode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252
253
254
255
256
257
258
259
260
261
262
263
264
265
  
  		/*
  		 * 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...
266
  	if (inode->i_op->permission)
b77b0646e   Al Viro   [PATCH] pass MAY_...
267
  		retval = inode->i_op->permission(inode, mask);
f696a3659   Miklos Szeredi   [PATCH] move exec...
268
  	else
5909ccaa3   Linus Torvalds   Make 'check_acl()...
269
  		retval = generic_permission(inode, mask, inode->i_op->check_acl);
f696a3659   Miklos Szeredi   [PATCH] move exec...
270

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
271
272
  	if (retval)
  		return retval;
08ce5f16e   Serge E. Hallyn   cgroups: implemen...
273
274
275
  	retval = devcgroup_inode_permission(inode, mask);
  	if (retval)
  		return retval;
d09ca7397   Eric Paris   security: make LS...
276
  	return security_inode_permission(inode, mask);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
277
  }
e4543eddf   Christoph Hellwig   [PATCH] add a vfs...
278
  /**
8c744fb83   Christoph Hellwig   [PATCH] add a fil...
279
280
281
282
283
284
285
286
287
   * 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
288
   *	be done using inode_permission().
8c744fb83   Christoph Hellwig   [PATCH] add a fil...
289
290
291
   */
  int file_permission(struct file *file, int mask)
  {
f419a2e3b   Al Viro   [PATCH] kill name...
292
  	return inode_permission(file->f_path.dentry->d_inode, mask);
8c744fb83   Christoph Hellwig   [PATCH] add a fil...
293
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
  /*
   * 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...
327
  	struct inode *inode = file->f_path.dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
329
330
331
332
333
334
335
336
337
338
  
  	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()
339
  /**
5dd784d04   Jan Blunck   Introduce path_get()
340
341
342
343
344
345
346
347
348
349
350
351
352
   * 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()
353
354
355
356
357
358
   * 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
359
  {
1d957f9bf   Jan Blunck   Introduce path_put()
360
361
  	dput(path->dentry);
  	mntput(path->mnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
  }
1d957f9bf   Jan Blunck   Introduce path_put()
363
  EXPORT_SYMBOL(path_put);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364

834f2a4a1   Trond Myklebust   VFS: Allow the fi...
365
366
367
368
369
370
  /**
   * release_open_intent - free up open intent resources
   * @nd: pointer to nameidata
   */
  void release_open_intent(struct nameidata *nd)
  {
0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
371
  	if (nd->intent.open.file->f_path.dentry == NULL)
834f2a4a1   Trond Myklebust   VFS: Allow the fi...
372
373
374
375
  		put_filp(nd->intent.open.file);
  	else
  		fput(nd->intent.open.file);
  }
bcdc5e019   Ian Kent   [PATCH] autofs4 n...
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
  static inline struct dentry *
  do_revalidate(struct dentry *dentry, struct nameidata *nd)
  {
  	int status = dentry->d_op->d_revalidate(dentry, nd);
  	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.
  		 */
  		if (!status) {
  			if (!d_invalidate(dentry)) {
  				dput(dentry);
  				dentry = NULL;
  			}
  		} else {
  			dput(dentry);
  			dentry = ERR_PTR(status);
  		}
  	}
  	return dentry;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399
  /*
39159de2a   Jeff Layton   vfs: force reval ...
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
   * force_reval_path - force revalidation of a dentry
   *
   * In some situations the path walking code will trust dentries without
   * revalidating them. This causes problems for filesystems that depend on
   * d_revalidate to handle file opens (e.g. NFSv4). When FS_REVAL_DOT is set
   * (which indicates that it's possible for the dentry to go stale), force
   * a d_revalidate call before proceeding.
   *
   * Returns 0 if the revalidation was successful. If the revalidation fails,
   * either return the error returned by d_revalidate or -ESTALE if the
   * revalidation it just returned 0. If d_revalidate returns 0, we attempt to
   * invalidate the dentry. It's up to the caller to handle putting references
   * to the path if necessary.
   */
  static int
  force_reval_path(struct path *path, struct nameidata *nd)
  {
  	int status;
  	struct dentry *dentry = path->dentry;
  
  	/*
  	 * only check on filesystems where it's possible for the dentry to
  	 * become stale. It's assumed that if this flag is set then the
  	 * d_revalidate op will also be defined.
  	 */
  	if (!(dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT))
  		return 0;
  
  	status = dentry->d_op->d_revalidate(dentry, nd);
  	if (status > 0)
  		return 0;
  
  	if (!status) {
  		d_invalidate(dentry);
  		status = -ESTALE;
  	}
  	return status;
  }
  
  /*
b75b5086b   Al Viro   Sanitize exec_per...
440
441
442
   * 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
443
444
   *
   * If appropriate, check DAC only.  If not appropriate, or
b75b5086b   Al Viro   Sanitize exec_per...
445
   * short-cut DAC fails, then call ->permission() to do more
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446
447
   * complete permission check.
   */
b75b5086b   Al Viro   Sanitize exec_per...
448
  static int exec_permission(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
449
  {
5909ccaa3   Linus Torvalds   Make 'check_acl()...
450
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
451

cb9179ead   Linus Torvalds   Simplify exec_per...
452
  	if (inode->i_op->permission) {
5909ccaa3   Linus Torvalds   Make 'check_acl()...
453
  		ret = inode->i_op->permission(inode, MAY_EXEC);
cb9179ead   Linus Torvalds   Simplify exec_per...
454
455
456
457
  		if (!ret)
  			goto ok;
  		return ret;
  	}
5909ccaa3   Linus Torvalds   Make 'check_acl()...
458
459
  	ret = acl_permission_check(inode, MAY_EXEC, inode->i_op->check_acl);
  	if (!ret)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
460
  		goto ok;
f1ac9f6bf   Linus Torvalds   Simplify exec_per...
461
  	if (capable(CAP_DAC_OVERRIDE) || capable(CAP_DAC_READ_SEARCH))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462
  		goto ok;
5909ccaa3   Linus Torvalds   Make 'check_acl()...
463
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
464
  ok:
b77b0646e   Al Viro   [PATCH] pass MAY_...
465
  	return security_inode_permission(inode, MAY_EXEC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
466
  }
2a7378711   Al Viro   Cache root in nam...
467
468
  static __always_inline void set_root(struct nameidata *nd)
  {
f7ad3c6be   Miklos Szeredi   vfs: add helpers ...
469
470
  	if (!nd->root.mnt)
  		get_fs_root(current->fs, &nd->root);
2a7378711   Al Viro   Cache root in nam...
471
  }
6de88d729   Al Viro   kill __link_path_...
472
  static int link_path_walk(const char *, struct nameidata *);
f16623569   Arjan van de Ven   [PATCH] Mark some...
473
  static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
474
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
475
476
477
478
  	if (IS_ERR(link))
  		goto fail;
  
  	if (*link == '/') {
2a7378711   Al Viro   Cache root in nam...
479
  		set_root(nd);
1d957f9bf   Jan Blunck   Introduce path_put()
480
  		path_put(&nd->path);
2a7378711   Al Viro   Cache root in nam...
481
482
  		nd->path = nd->root;
  		path_get(&nd->root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
483
  	}
b4091d5f6   Christoph Hellwig   kill walk_init_root
484

def4af30c   Al Viro   Get rid of symlin...
485
  	return link_path_walk(link, nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
486
  fail:
1d957f9bf   Jan Blunck   Introduce path_put()
487
  	path_put(&nd->path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
488
489
  	return PTR_ERR(link);
  }
1d957f9bf   Jan Blunck   Introduce path_put()
490
  static void path_put_conditional(struct path *path, struct nameidata *nd)
051d38125   Ian Kent   [PATCH] autofs4: ...
491
492
  {
  	dput(path->dentry);
4ac913785   Jan Blunck   Embed a struct pa...
493
  	if (path->mnt != nd->path.mnt)
051d38125   Ian Kent   [PATCH] autofs4: ...
494
495
496
497
498
  		mntput(path->mnt);
  }
  
  static inline void path_to_nameidata(struct path *path, struct nameidata *nd)
  {
4ac913785   Jan Blunck   Embed a struct pa...
499
  	dput(nd->path.dentry);
9a2296832   Huang Shijie   namei.c : update ...
500
  	if (nd->path.mnt != path->mnt) {
4ac913785   Jan Blunck   Embed a struct pa...
501
  		mntput(nd->path.mnt);
9a2296832   Huang Shijie   namei.c : update ...
502
503
  		nd->path.mnt = path->mnt;
  	}
4ac913785   Jan Blunck   Embed a struct pa...
504
  	nd->path.dentry = path->dentry;
051d38125   Ian Kent   [PATCH] autofs4: ...
505
  }
def4af30c   Al Viro   Get rid of symlin...
506
507
  static __always_inline int
  __do_follow_link(struct path *path, struct nameidata *nd, void **p)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
508
509
  {
  	int error;
cd4e91d3b   Al Viro   [PATCH] namei fix...
510
  	struct dentry *dentry = path->dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
511

d671a1cbf   Al Viro   [PATCH] namei fix...
512
  	touch_atime(path->mnt, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
513
  	nd_set_link(nd, NULL);
cd4e91d3b   Al Viro   [PATCH] namei fix...
514

4ac913785   Jan Blunck   Embed a struct pa...
515
  	if (path->mnt != nd->path.mnt) {
051d38125   Ian Kent   [PATCH] autofs4: ...
516
517
518
519
  		path_to_nameidata(path, nd);
  		dget(dentry);
  	}
  	mntget(path->mnt);
86acdca1b   Al Viro   fix autofs/afs/et...
520
  	nd->last_type = LAST_BIND;
def4af30c   Al Viro   Get rid of symlin...
521
522
523
  	*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
524
  		char *s = nd_get_link(nd);
cc314eef0   Linus Torvalds   Fix nasty ncpfs s...
525
  		error = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
527
  		if (s)
  			error = __vfs_follow_link(nd, s);
39159de2a   Jeff Layton   vfs: force reval ...
528
529
530
531
532
  		else if (nd->last_type == LAST_BIND) {
  			error = force_reval_path(&nd->path, nd);
  			if (error)
  				path_put(&nd->path);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
533
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
534
535
536
537
538
539
540
541
542
543
  	return error;
  }
  
  /*
   * 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. 
   */
90ebe5654   Al Viro   [PATCH] namei fixes
544
  static inline int do_follow_link(struct path *path, struct nameidata *nd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
545
  {
def4af30c   Al Viro   Get rid of symlin...
546
  	void *cookie;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
547
548
549
550
551
552
553
  	int err = -ELOOP;
  	if (current->link_count >= MAX_NESTED_LINKS)
  		goto loop;
  	if (current->total_link_count >= 40)
  		goto loop;
  	BUG_ON(nd->depth >= MAX_NESTED_LINKS);
  	cond_resched();
90ebe5654   Al Viro   [PATCH] namei fixes
554
  	err = security_inode_follow_link(path->dentry, nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
555
556
557
558
559
  	if (err)
  		goto loop;
  	current->link_count++;
  	current->total_link_count++;
  	nd->depth++;
def4af30c   Al Viro   Get rid of symlin...
560
561
562
  	err = __do_follow_link(path, nd, &cookie);
  	if (!IS_ERR(cookie) && path->dentry->d_inode->i_op->put_link)
  		path->dentry->d_inode->i_op->put_link(path->dentry, nd, cookie);
258fa9990   Al Viro   lift path_put(pat...
563
  	path_put(path);
839d9f93c   Al Viro   [PATCH] namei fix...
564
565
  	current->link_count--;
  	nd->depth--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
566
567
  	return err;
  loop:
1d957f9bf   Jan Blunck   Introduce path_put()
568
569
  	path_put_conditional(path, nd);
  	path_put(&nd->path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
570
571
  	return err;
  }
bab77ebf5   Al Viro   switch follow_up(...
572
  int follow_up(struct path *path)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
573
574
575
  {
  	struct vfsmount *parent;
  	struct dentry *mountpoint;
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
576
577
  
  	br_read_lock(vfsmount_lock);
bab77ebf5   Al Viro   switch follow_up(...
578
579
  	parent = path->mnt->mnt_parent;
  	if (parent == path->mnt) {
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
580
  		br_read_unlock(vfsmount_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581
582
583
  		return 0;
  	}
  	mntget(parent);
bab77ebf5   Al Viro   switch follow_up(...
584
  	mountpoint = dget(path->mnt->mnt_mountpoint);
99b7db7b8   Nick Piggin   fs: brlock vfsmou...
585
  	br_read_unlock(vfsmount_lock);
bab77ebf5   Al Viro   switch follow_up(...
586
587
588
589
  	dput(path->dentry);
  	path->dentry = mountpoint;
  	mntput(path->mnt);
  	path->mnt = parent;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
590
591
592
593
594
595
  	return 1;
  }
  
  /* no need for dcache_lock, as serialization is taken care in
   * namespace.c
   */
463ffb2e9   Al Viro   [PATCH] namei fix...
596
597
598
599
  static int __follow_mount(struct path *path)
  {
  	int res = 0;
  	while (d_mountpoint(path->dentry)) {
1c755af4d   Al Viro   switch lookup_mnt()
600
  		struct vfsmount *mounted = lookup_mnt(path);
463ffb2e9   Al Viro   [PATCH] namei fix...
601
602
603
604
605
606
607
608
609
610
611
  		if (!mounted)
  			break;
  		dput(path->dentry);
  		if (res)
  			mntput(path->mnt);
  		path->mnt = mounted;
  		path->dentry = dget(mounted->mnt_root);
  		res = 1;
  	}
  	return res;
  }
79ed02261   Al Viro   switch follow_mou...
612
  static void follow_mount(struct path *path)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
613
  {
79ed02261   Al Viro   switch follow_mou...
614
  	while (d_mountpoint(path->dentry)) {
1c755af4d   Al Viro   switch lookup_mnt()
615
  		struct vfsmount *mounted = lookup_mnt(path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
616
617
  		if (!mounted)
  			break;
79ed02261   Al Viro   switch follow_mou...
618
619
620
621
  		dput(path->dentry);
  		mntput(path->mnt);
  		path->mnt = mounted;
  		path->dentry = dget(mounted->mnt_root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
622
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
623
624
625
626
627
  }
  
  /* no need for dcache_lock, as serialization is taken care in
   * namespace.c
   */
9393bd07c   Al Viro   switch follow_down()
628
  int follow_down(struct path *path)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
629
630
  {
  	struct vfsmount *mounted;
1c755af4d   Al Viro   switch lookup_mnt()
631
  	mounted = lookup_mnt(path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
632
  	if (mounted) {
9393bd07c   Al Viro   switch follow_down()
633
634
635
636
  		dput(path->dentry);
  		mntput(path->mnt);
  		path->mnt = mounted;
  		path->dentry = dget(mounted->mnt_root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
637
638
639
640
  		return 1;
  	}
  	return 0;
  }
f16623569   Arjan van de Ven   [PATCH] Mark some...
641
  static __always_inline void follow_dotdot(struct nameidata *nd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
642
  {
2a7378711   Al Viro   Cache root in nam...
643
  	set_root(nd);
e518ddb7b   Andreas Mohr   [PATCH] fs/namei....
644

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

2a7378711   Al Viro   Cache root in nam...
648
649
  		if (nd->path.dentry == nd->root.dentry &&
  		    nd->path.mnt == nd->root.mnt) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650
651
  			break;
  		}
4ac913785   Jan Blunck   Embed a struct pa...
652
  		if (nd->path.dentry != nd->path.mnt->mnt_root) {
3088dd708   Al Viro   Clean follow_dotd...
653
654
  			/* rare case of legitimate dget_parent()... */
  			nd->path.dentry = dget_parent(nd->path.dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
655
656
657
  			dput(old);
  			break;
  		}
3088dd708   Al Viro   Clean follow_dotd...
658
  		if (!follow_up(&nd->path))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
659
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
660
  	}
79ed02261   Al Viro   switch follow_mou...
661
  	follow_mount(&nd->path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
663
  /*
baa038907   Nick Piggin   fs: dentry alloca...
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
   * 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
693
694
695
696
697
698
699
   *  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,
  		     struct path *path)
  {
4ac913785   Jan Blunck   Embed a struct pa...
700
  	struct vfsmount *mnt = nd->path.mnt;
6e6b1bd1e   Al Viro   Kill cached_looku...
701
702
  	struct dentry *dentry, *parent;
  	struct inode *dir;
3cac260ad   Al Viro   Take hash recalcu...
703
704
705
706
707
708
709
710
711
  	/*
  	 * See if the low-level filesystem might want
  	 * to use its own hash..
  	 */
  	if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) {
  		int err = nd->path.dentry->d_op->d_hash(nd->path.dentry, name);
  		if (err < 0)
  			return err;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
712

b04f784e5   Nick Piggin   fs: remove extra ...
713
714
715
716
717
  	/*
  	 * 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.
  	 */
3cac260ad   Al Viro   Take hash recalcu...
718
  	dentry = __d_lookup(nd->path.dentry, name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
719
720
  	if (!dentry)
  		goto need_lookup;
2e2e88ea8   Nick Piggin   fs: fix do_lookup...
721
  found:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
722
723
724
725
726
  	if (dentry->d_op && dentry->d_op->d_revalidate)
  		goto need_revalidate;
  done:
  	path->mnt = mnt;
  	path->dentry = dentry;
634ee7017   Al Viro   [PATCH] namei fix...
727
  	__follow_mount(path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
728
729
730
  	return 0;
  
  need_lookup:
6e6b1bd1e   Al Viro   Kill cached_looku...
731
732
733
734
735
736
  	parent = nd->path.dentry;
  	dir = parent->d_inode;
  
  	mutex_lock(&dir->i_mutex);
  	/*
  	 * First re-do the cached lookup just in case it was created
b04f784e5   Nick Piggin   fs: remove extra ...
737
738
  	 * while we waited for the directory semaphore, or the first
  	 * lookup failed due to an unrelated rename.
6e6b1bd1e   Al Viro   Kill cached_looku...
739
  	 *
b04f784e5   Nick Piggin   fs: remove extra ...
740
741
742
743
  	 * This could use version numbering or similar to avoid unnecessary
  	 * cache lookups, but then we'd have to do the first lookup in the
  	 * non-racy way. However in the common case here, everything should
  	 * be hot in cache, so would it be a big win?
6e6b1bd1e   Al Viro   Kill cached_looku...
744
745
  	 */
  	dentry = d_lookup(parent, name);
baa038907   Nick Piggin   fs: dentry alloca...
746
747
  	if (likely(!dentry)) {
  		dentry = d_alloc_and_lookup(parent, name, nd);
6e6b1bd1e   Al Viro   Kill cached_looku...
748
749
750
751
752
  		mutex_unlock(&dir->i_mutex);
  		if (IS_ERR(dentry))
  			goto fail;
  		goto done;
  	}
6e6b1bd1e   Al Viro   Kill cached_looku...
753
754
755
756
757
  	/*
  	 * Uhhuh! Nasty case: the cache was re-populated while
  	 * we waited on the semaphore. Need to revalidate.
  	 */
  	mutex_unlock(&dir->i_mutex);
2e2e88ea8   Nick Piggin   fs: fix do_lookup...
758
  	goto found;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
759
760
  
  need_revalidate:
bcdc5e019   Ian Kent   [PATCH] autofs4 n...
761
762
763
764
765
766
  	dentry = do_revalidate(dentry, nd);
  	if (!dentry)
  		goto need_lookup;
  	if (IS_ERR(dentry))
  		goto fail;
  	goto done;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
767
768
769
770
771
772
  
  fail:
  	return PTR_ERR(dentry);
  }
  
  /*
ac278a9c5   Al Viro   fix LOOKUP_FOLLOW...
773
774
775
776
777
778
779
780
781
782
783
   * This is a temporary kludge to deal with "automount" symlinks; proper
   * solution is to trigger them on follow_mount(), so that do_lookup()
   * would DTRT.  To be killed before 2.6.34-final.
   */
  static inline int follow_on_final(struct inode *inode, unsigned lookup_flags)
  {
  	return inode && unlikely(inode->i_op->follow_link) &&
  		((lookup_flags & LOOKUP_FOLLOW) || S_ISDIR(inode->i_mode));
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
784
   * Name resolution.
ea3834d9f   Prasanna Meda   namei: add audit_...
785
786
   * 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
787
   *
ea3834d9f   Prasanna Meda   namei: add audit_...
788
789
   * 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
790
   */
6de88d729   Al Viro   kill __link_path_...
791
  static int link_path_walk(const char *name, struct nameidata *nd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
792
793
794
795
796
797
798
799
800
801
  {
  	struct path next;
  	struct inode *inode;
  	int err;
  	unsigned int lookup_flags = nd->flags;
  	
  	while (*name=='/')
  		name++;
  	if (!*name)
  		goto return_reval;
4ac913785   Jan Blunck   Embed a struct pa...
802
  	inode = nd->path.dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
803
  	if (nd->depth)
f55eab822   Trond Myklebust   [PATCH] VFS: Ensu...
804
  		lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
805
806
807
808
809
810
  
  	/* At this point we know we have a real path component. */
  	for(;;) {
  		unsigned long hash;
  		struct qstr this;
  		unsigned int c;
cdce5d6b9   Trond Myklebust   VFS: Make link_pa...
811
  		nd->flags |= LOOKUP_CONTINUE;
b75b5086b   Al Viro   Sanitize exec_per...
812
  		err = exec_permission(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
   		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);
  
  		/* remove trailing slashes? */
  		if (!c)
  			goto last_component;
  		while (*++name == '/');
  		if (!*name)
  			goto last_with_slashes;
  
  		/*
  		 * "." and ".." are special - ".." especially so because it has
  		 * to be able to know about the current root directory and
  		 * parent relationships.
  		 */
  		if (this.name[0] == '.') switch (this.len) {
  			default:
  				break;
  			case 2:	
  				if (this.name[1] != '.')
  					break;
58c465eba   Al Viro   [PATCH] namei fix...
846
  				follow_dotdot(nd);
4ac913785   Jan Blunck   Embed a struct pa...
847
  				inode = nd->path.dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
848
849
850
851
  				/* fallthrough */
  			case 1:
  				continue;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
852
853
854
855
  		/* This does the actual lookups.. */
  		err = do_lookup(nd, &this, &next);
  		if (err)
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
856
857
858
859
860
  
  		err = -ENOENT;
  		inode = next.dentry->d_inode;
  		if (!inode)
  			goto out_dput;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
861
862
  
  		if (inode->i_op->follow_link) {
90ebe5654   Al Viro   [PATCH] namei fixes
863
  			err = do_follow_link(&next, nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
864
865
866
  			if (err)
  				goto return_err;
  			err = -ENOENT;
4ac913785   Jan Blunck   Embed a struct pa...
867
  			inode = nd->path.dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
868
869
  			if (!inode)
  				break;
09dd17d3e   Miklos Szeredi   [PATCH] namei cle...
870
871
  		} else
  			path_to_nameidata(&next, nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
872
873
874
875
876
877
878
879
880
  		err = -ENOTDIR; 
  		if (!inode->i_op->lookup)
  			break;
  		continue;
  		/* here ends the main loop */
  
  last_with_slashes:
  		lookup_flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
  last_component:
f55eab822   Trond Myklebust   [PATCH] VFS: Ensu...
881
882
  		/* Clear LOOKUP_CONTINUE iff it was previously unset */
  		nd->flags &= lookup_flags | ~LOOKUP_CONTINUE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
883
884
885
886
887
888
889
890
  		if (lookup_flags & LOOKUP_PARENT)
  			goto lookup_parent;
  		if (this.name[0] == '.') switch (this.len) {
  			default:
  				break;
  			case 2:	
  				if (this.name[1] != '.')
  					break;
58c465eba   Al Viro   [PATCH] namei fix...
891
  				follow_dotdot(nd);
4ac913785   Jan Blunck   Embed a struct pa...
892
  				inode = nd->path.dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
893
894
895
896
  				/* fallthrough */
  			case 1:
  				goto return_reval;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
897
898
899
  		err = do_lookup(nd, &this, &next);
  		if (err)
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
900
  		inode = next.dentry->d_inode;
ac278a9c5   Al Viro   fix LOOKUP_FOLLOW...
901
  		if (follow_on_final(inode, lookup_flags)) {
90ebe5654   Al Viro   [PATCH] namei fixes
902
  			err = do_follow_link(&next, nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
903
904
  			if (err)
  				goto return_err;
4ac913785   Jan Blunck   Embed a struct pa...
905
  			inode = nd->path.dentry->d_inode;
09dd17d3e   Miklos Szeredi   [PATCH] namei cle...
906
907
  		} else
  			path_to_nameidata(&next, nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
908
909
910
911
912
  		err = -ENOENT;
  		if (!inode)
  			break;
  		if (lookup_flags & LOOKUP_DIRECTORY) {
  			err = -ENOTDIR; 
acfa4380e   Al Viro   inode->i_op is ne...
913
  			if (!inode->i_op->lookup)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
  				break;
  		}
  		goto return_base;
  lookup_parent:
  		nd->last = this;
  		nd->last_type = LAST_NORM;
  		if (this.name[0] != '.')
  			goto return_base;
  		if (this.len == 1)
  			nd->last_type = LAST_DOT;
  		else if (this.len == 2 && this.name[1] == '.')
  			nd->last_type = LAST_DOTDOT;
  		else
  			goto return_base;
  return_reval:
  		/*
  		 * We bypassed the ordinary revalidation routines.
  		 * We may need to check the cached dentry for staleness.
  		 */
4ac913785   Jan Blunck   Embed a struct pa...
933
934
  		if (nd->path.dentry && nd->path.dentry->d_sb &&
  		    (nd->path.dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
935
936
  			err = -ESTALE;
  			/* Note: we do not d_invalidate() */
4ac913785   Jan Blunck   Embed a struct pa...
937
938
  			if (!nd->path.dentry->d_op->d_revalidate(
  					nd->path.dentry, nd))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
939
940
941
942
943
  				break;
  		}
  return_base:
  		return 0;
  out_dput:
1d957f9bf   Jan Blunck   Introduce path_put()
944
  		path_put_conditional(&next, nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
945
946
  		break;
  	}
1d957f9bf   Jan Blunck   Introduce path_put()
947
  	path_put(&nd->path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
948
949
950
  return_err:
  	return err;
  }
fc9b52cd8   Harvey Harrison   fs: remove fastca...
951
  static int path_walk(const char *name, struct nameidata *nd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
952
  {
6de88d729   Al Viro   kill __link_path_...
953
954
  	struct path save = nd->path;
  	int result;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
955
  	current->total_link_count = 0;
6de88d729   Al Viro   kill __link_path_...
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
  
  	/* make sure the stuff we saved doesn't go away */
  	path_get(&save);
  
  	result = link_path_walk(name, nd);
  	if (result == -ESTALE) {
  		/* nd->path had been dropped */
  		current->total_link_count = 0;
  		nd->path = save;
  		path_get(&nd->path);
  		nd->flags |= LOOKUP_REVAL;
  		result = link_path_walk(name, nd);
  	}
  
  	path_put(&save);
  
  	return result;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
973
  }
9b4a9b14a   Al Viro   Preparations to c...
974
  static int path_init(int dfd, const char *name, unsigned int flags, struct nameidata *nd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
975
  {
ea3834d9f   Prasanna Meda   namei: add audit_...
976
  	int retval = 0;
170aa3d02   Ulrich Drepper   [PATCH] namei.c: ...
977
978
  	int fput_needed;
  	struct file *file;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
979
980
981
982
  
  	nd->last_type = LAST_ROOT; /* if there are only slashes... */
  	nd->flags = flags;
  	nd->depth = 0;
2a7378711   Al Viro   Cache root in nam...
983
  	nd->root.mnt = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
984

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
985
  	if (*name=='/') {
2a7378711   Al Viro   Cache root in nam...
986
987
988
  		set_root(nd);
  		nd->path = nd->root;
  		path_get(&nd->root);
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
989
  	} else if (dfd == AT_FDCWD) {
f7ad3c6be   Miklos Szeredi   vfs: add helpers ...
990
  		get_fs_pwd(current->fs, &nd->path);
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
991
  	} else {
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
992
993
994
  		struct dentry *dentry;
  
  		file = fget_light(dfd, &fput_needed);
170aa3d02   Ulrich Drepper   [PATCH] namei.c: ...
995
996
  		retval = -EBADF;
  		if (!file)
6d09bb627   Trond Myklebust   [PATCH] fs/namei....
997
  			goto out_fail;
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
998

0f7fc9e4d   Josef "Jeff" Sipek   [PATCH] VFS: chan...
999
  		dentry = file->f_path.dentry;
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
1000

170aa3d02   Ulrich Drepper   [PATCH] namei.c: ...
1001
1002
  		retval = -ENOTDIR;
  		if (!S_ISDIR(dentry->d_inode->i_mode))
6d09bb627   Trond Myklebust   [PATCH] fs/namei....
1003
  			goto fput_fail;
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
1004
1005
  
  		retval = file_permission(file, MAY_EXEC);
170aa3d02   Ulrich Drepper   [PATCH] namei.c: ...
1006
  		if (retval)
6d09bb627   Trond Myklebust   [PATCH] fs/namei....
1007
  			goto fput_fail;
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
1008

5dd784d04   Jan Blunck   Introduce path_get()
1009
1010
  		nd->path = file->f_path;
  		path_get(&file->f_path);
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
1011
1012
  
  		fput_light(file, fput_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1013
  	}
9b4a9b14a   Al Viro   Preparations to c...
1014
  	return 0;
2dfdd266b   Josef 'Jeff' Sipek   fs: use path_walk...
1015

9b4a9b14a   Al Viro   Preparations to c...
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
  fput_fail:
  	fput_light(file, fput_needed);
  out_fail:
  	return retval;
  }
  
  /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
  static int do_path_lookup(int dfd, const char *name,
  				unsigned int flags, struct nameidata *nd)
  {
  	int retval = path_init(dfd, name, flags, nd);
  	if (!retval)
  		retval = path_walk(name, nd);
4ac913785   Jan Blunck   Embed a struct pa...
1029
1030
1031
  	if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
  				nd->path.dentry->d_inode))
  		audit_inode(name, nd->path.dentry);
2a7378711   Al Viro   Cache root in nam...
1032
1033
1034
1035
  	if (nd->root.mnt) {
  		path_put(&nd->root);
  		nd->root.mnt = NULL;
  	}
170aa3d02   Ulrich Drepper   [PATCH] namei.c: ...
1036
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1037
  }
fc9b52cd8   Harvey Harrison   fs: remove fastca...
1038
  int path_lookup(const char *name, unsigned int flags,
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
1039
1040
1041
1042
  			struct nameidata *nd)
  {
  	return do_path_lookup(AT_FDCWD, name, flags, nd);
  }
d18114657   Al Viro   [PATCH] new helpe...
1043
1044
1045
1046
1047
1048
1049
1050
  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...
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
  /**
   * 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)
  {
  	int retval;
  
  	/* same as do_path_lookup */
  	nd->last_type = LAST_ROOT;
  	nd->flags = flags;
  	nd->depth = 0;
c8e7f449b   Jan Blunck   [patch 1/4] vfs: ...
1069
1070
1071
  	nd->path.dentry = dentry;
  	nd->path.mnt = mnt;
  	path_get(&nd->path);
5b8571195   Al Viro   Make vfs_path_loo...
1072
1073
  	nd->root = nd->path;
  	path_get(&nd->root);
16f182002   Josef 'Jeff' Sipek   fs: introduce vfs...
1074
1075
  
  	retval = path_walk(name, nd);
4ac913785   Jan Blunck   Embed a struct pa...
1076
1077
1078
  	if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
  				nd->path.dentry->d_inode))
  		audit_inode(name, nd->path.dentry);
16f182002   Josef 'Jeff' Sipek   fs: introduce vfs...
1079

5b8571195   Al Viro   Make vfs_path_loo...
1080
1081
  	path_put(&nd->root);
  	nd->root.mnt = NULL;
16f182002   Josef 'Jeff' Sipek   fs: introduce vfs...
1082

2a7378711   Al Viro   Cache root in nam...
1083
  	return retval;
16f182002   Josef 'Jeff' Sipek   fs: introduce vfs...
1084
  }
eead19115   Christoph Hellwig   partially fix up ...
1085
1086
  static struct dentry *__lookup_hash(struct qstr *name,
  		struct dentry *base, struct nameidata *nd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1087
  {
057f6c019   James Morris   security: prevent...
1088
  	struct dentry *dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1089
1090
1091
1092
  	struct inode *inode;
  	int err;
  
  	inode = base->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
  
  	/*
  	 * See if the low-level filesystem might want
  	 * to use its own hash..
  	 */
  	if (base->d_op && base->d_op->d_hash) {
  		err = base->d_op->d_hash(base, name);
  		dentry = ERR_PTR(err);
  		if (err < 0)
  			goto out;
  	}
b04f784e5   Nick Piggin   fs: remove extra ...
1104
1105
1106
1107
  	/*
  	 * 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...
1108
  	 */
b04f784e5   Nick Piggin   fs: remove extra ...
1109
  	dentry = d_lookup(base, name);
6e6b1bd1e   Al Viro   Kill cached_looku...
1110
1111
1112
  
  	if (dentry && dentry->d_op && dentry->d_op->d_revalidate)
  		dentry = do_revalidate(dentry, nd);
baa038907   Nick Piggin   fs: dentry alloca...
1113
1114
  	if (!dentry)
  		dentry = d_alloc_and_lookup(base, name, nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1115
1116
1117
  out:
  	return dentry;
  }
057f6c019   James Morris   security: prevent...
1118
1119
1120
1121
1122
  /*
   * 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 ...
1123
  static struct dentry *lookup_hash(struct nameidata *nd)
057f6c019   James Morris   security: prevent...
1124
  {
057f6c019   James Morris   security: prevent...
1125
  	int err;
b75b5086b   Al Viro   Sanitize exec_per...
1126
  	err = exec_permission(nd->path.dentry->d_inode);
057f6c019   James Morris   security: prevent...
1127
  	if (err)
eead19115   Christoph Hellwig   partially fix up ...
1128
  		return ERR_PTR(err);
4ac913785   Jan Blunck   Embed a struct pa...
1129
  	return __lookup_hash(&nd->last, nd->path.dentry, nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1130
  }
eead19115   Christoph Hellwig   partially fix up ...
1131
1132
  static int __lookup_one_len(const char *name, struct qstr *this,
  		struct dentry *base, int len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1133
1134
  {
  	unsigned long hash;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1135
  	unsigned int c;
057f6c019   James Morris   security: prevent...
1136
1137
  	this->name = name;
  	this->len = len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1138
  	if (!len)
057f6c019   James Morris   security: prevent...
1139
  		return -EACCES;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1140
1141
1142
1143
1144
  
  	hash = init_name_hash();
  	while (len--) {
  		c = *(const unsigned char *)name++;
  		if (c == '/' || c == '\0')
057f6c019   James Morris   security: prevent...
1145
  			return -EACCES;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1146
1147
  		hash = partial_name_hash(c, hash);
  	}
057f6c019   James Morris   security: prevent...
1148
1149
1150
  	this->hash = end_name_hash(hash);
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1151

eead19115   Christoph Hellwig   partially fix up ...
1152
  /**
a6b91919e   Randy Dunlap   fs: fix kernel-do...
1153
   * lookup_one_len - filesystem helper to lookup single pathname component
eead19115   Christoph Hellwig   partially fix up ...
1154
1155
1156
1157
   * @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...
1158
1159
   * 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 ...
1160
1161
1162
   * 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...
1163
1164
1165
1166
  struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
  {
  	int err;
  	struct qstr this;
2f9092e10   David Woodhouse   Fix i_mutex vs. r...
1167
  	WARN_ON_ONCE(!mutex_is_locked(&base->d_inode->i_mutex));
057f6c019   James Morris   security: prevent...
1168
1169
1170
  	err = __lookup_one_len(name, &this, base, len);
  	if (err)
  		return ERR_PTR(err);
eead19115   Christoph Hellwig   partially fix up ...
1171

b75b5086b   Al Viro   Sanitize exec_per...
1172
  	err = exec_permission(base->d_inode);
eead19115   Christoph Hellwig   partially fix up ...
1173
1174
  	if (err)
  		return ERR_PTR(err);
49705b774   Christoph Hellwig   [PATCH] sanitize ...
1175
  	return __lookup_hash(&this, base, NULL);
057f6c019   James Morris   security: prevent...
1176
  }
2d8f30380   Al Viro   [PATCH] sanitize ...
1177
1178
  int user_path_at(int dfd, const char __user *name, unsigned flags,
  		 struct path *path)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1179
  {
2d8f30380   Al Viro   [PATCH] sanitize ...
1180
  	struct nameidata nd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1181
1182
  	char *tmp = getname(name);
  	int err = PTR_ERR(tmp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1183
  	if (!IS_ERR(tmp)) {
2d8f30380   Al Viro   [PATCH] sanitize ...
1184
1185
1186
1187
  
  		BUG_ON(flags & LOOKUP_PARENT);
  
  		err = do_path_lookup(dfd, tmp, flags, &nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1188
  		putname(tmp);
2d8f30380   Al Viro   [PATCH] sanitize ...
1189
1190
  		if (!err)
  			*path = nd.path;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1191
1192
1193
  	}
  	return err;
  }
2ad94ae65   Al Viro   [PATCH] new (loca...
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
  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
1211
1212
1213
1214
1215
1216
  /*
   * 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...
1217
  	uid_t fsuid = current_fsuid();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1218
1219
  	if (!(dir->i_mode & S_ISVTX))
  		return 0;
da9592ede   David Howells   CRED: Wrap task c...
1220
  	if (inode->i_uid == fsuid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1221
  		return 0;
da9592ede   David Howells   CRED: Wrap task c...
1222
  	if (dir->i_uid == fsuid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
  		return 0;
  	return !capable(CAP_FOWNER);
  }
  
  /*
   *	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...
1246
  static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1247
1248
1249
1250
1251
1252
1253
  {
  	int error;
  
  	if (!victim->d_inode)
  		return -ENOENT;
  
  	BUG_ON(victim->d_parent->d_inode != dir);
cccc6bba3   Al Viro   Lose the first ar...
1254
  	audit_inode_child(victim, dir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1255

f419a2e3b   Al Viro   [PATCH] kill name...
1256
  	error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1257
1258
1259
1260
1261
  	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...
1262
  	    IS_IMMUTABLE(victim->d_inode) || IS_SWAPFILE(victim->d_inode))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
  		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: ...
1286
  static inline int may_create(struct inode *dir, struct dentry *child)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1287
1288
1289
1290
1291
  {
  	if (child->d_inode)
  		return -EEXIST;
  	if (IS_DEADDIR(dir))
  		return -ENOENT;
f419a2e3b   Al Viro   [PATCH] kill name...
1292
  	return inode_permission(dir, MAY_WRITE | MAY_EXEC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1293
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1294
1295
1296
1297
1298
1299
1300
1301
  /*
   * 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: ...
1302
  		mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1303
1304
  		return NULL;
  	}
a11f3a057   Arjan van de Ven   [PATCH] sem2mutex...
1305
  	mutex_lock(&p1->d_inode->i_sb->s_vfs_rename_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1306

e2761a116   OGAWA Hirofumi   [PATCH vfs-2.6 2/...
1307
1308
1309
1310
1311
  	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
1312
  	}
e2761a116   OGAWA Hirofumi   [PATCH vfs-2.6 2/...
1313
1314
1315
1316
1317
  	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
1318
  	}
f2eace23e   Ingo Molnar   [PATCH] lockdep: ...
1319
1320
  	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
1321
1322
1323
1324
1325
  	return NULL;
  }
  
  void unlock_rename(struct dentry *p1, struct dentry *p2)
  {
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
1326
  	mutex_unlock(&p1->d_inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1327
  	if (p1 != p2) {
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
1328
  		mutex_unlock(&p2->d_inode->i_mutex);
a11f3a057   Arjan van de Ven   [PATCH] sem2mutex...
1329
  		mutex_unlock(&p1->d_inode->i_sb->s_vfs_rename_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1330
1331
1332
1333
1334
1335
  	}
  }
  
  int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
  		struct nameidata *nd)
  {
a95164d97   Miklos Szeredi   [patch 3/4] vfs: ...
1336
  	int error = may_create(dir, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1337
1338
1339
  
  	if (error)
  		return error;
acfa4380e   Al Viro   inode->i_op is ne...
1340
  	if (!dir->i_op->create)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1341
1342
1343
1344
1345
1346
  		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
1347
  	error = dir->i_op->create(dir, dentry, mode, nd);
a74574aaf   Stephen Smalley   [PATCH] Remove se...
1348
  	if (!error)
f38aa9422   Amy Griffis   [PATCH] Pass dent...
1349
  		fsnotify_create(dir, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1350
1351
  	return error;
  }
3fb64190a   Christoph Hellwig   pass a struct pat...
1352
  int may_open(struct path *path, int acc_mode, int flag)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1353
  {
3fb64190a   Christoph Hellwig   pass a struct pat...
1354
  	struct dentry *dentry = path->dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1355
1356
1357
1358
1359
  	struct inode *inode = dentry->d_inode;
  	int error;
  
  	if (!inode)
  		return -ENOENT;
c8fe8f30c   Christoph Hellwig   cleanup may_open
1360
1361
  	switch (inode->i_mode & S_IFMT) {
  	case S_IFLNK:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1362
  		return -ELOOP;
c8fe8f30c   Christoph Hellwig   cleanup may_open
1363
1364
1365
1366
1367
1368
  	case S_IFDIR:
  		if (acc_mode & MAY_WRITE)
  			return -EISDIR;
  		break;
  	case S_IFBLK:
  	case S_IFCHR:
3fb64190a   Christoph Hellwig   pass a struct pat...
1369
  		if (path->mnt->mnt_flags & MNT_NODEV)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1370
  			return -EACCES;
c8fe8f30c   Christoph Hellwig   cleanup may_open
1371
1372
1373
  		/*FALLTHRU*/
  	case S_IFIFO:
  	case S_IFSOCK:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1374
  		flag &= ~O_TRUNC;
c8fe8f30c   Christoph Hellwig   cleanup may_open
1375
  		break;
4a3fd211c   Dave Hansen   [PATCH] r/o bind ...
1376
  	}
b41572e92   Dave Hansen   r/o bind mounts: ...
1377

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1382
1383
1384
1385
  	/*
  	 * An append-only file must be opened in append mode for writing.
  	 */
  	if (IS_APPEND(inode)) {
8737c9305   Al Viro   Switch may_open()...
1386
  		if  ((flag & O_ACCMODE) != O_RDONLY && !(flag & O_APPEND))
7715b5212   Al Viro   O_TRUNC open shou...
1387
  			return -EPERM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1388
  		if (flag & O_TRUNC)
7715b5212   Al Viro   O_TRUNC open shou...
1389
  			return -EPERM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1390
1391
1392
  	}
  
  	/* O_NOATIME can only be set by the owner or superuser */
7715b5212   Al Viro   O_TRUNC open shou...
1393
1394
  	if (flag & O_NOATIME && !is_owner_or_cap(inode))
  		return -EPERM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1395
1396
1397
1398
  
  	/*
  	 * Ensure there are no outstanding leases on the file.
  	 */
b65a9cfc2   Al Viro   Untangling ima me...
1399
  	return break_lease(inode, flag);
7715b5212   Al Viro   O_TRUNC open shou...
1400
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1401

7715b5212   Al Viro   O_TRUNC open shou...
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
  static int handle_truncate(struct path *path)
  {
  	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...
1413
  		error = security_path_truncate(path);
7715b5212   Al Viro   O_TRUNC open shou...
1414
1415
1416
1417
1418
1419
  	if (!error) {
  		error = do_truncate(path->dentry, 0,
  				    ATTR_MTIME|ATTR_CTIME|ATTR_OPEN,
  				    NULL);
  	}
  	put_write_access(inode);
acd0c9351   Mimi Zohar   IMA: update ima_c...
1420
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1421
  }
d57999e15   Dave Hansen   [PATCH] do namei_...
1422
1423
1424
1425
1426
1427
  /*
   * Be careful about ever adding any more callers of this
   * function.  Its flags must be in the namei format, not
   * what get passed to sys_open().
   */
  static int __open_namei_create(struct nameidata *nd, struct path *path,
8737c9305   Al Viro   Switch may_open()...
1428
  				int open_flag, int mode)
aab520e2f   Dave Hansen   [PATCH] r/o bind ...
1429
1430
  {
  	int error;
4ac913785   Jan Blunck   Embed a struct pa...
1431
  	struct dentry *dir = nd->path.dentry;
aab520e2f   Dave Hansen   [PATCH] r/o bind ...
1432
1433
  
  	if (!IS_POSIXACL(dir->d_inode))
ce3b0f8d5   Al Viro   New helper - curr...
1434
  		mode &= ~current_umask();
be6d3e56a   Kentaro Takeda   introduce new LSM...
1435
1436
1437
  	error = security_path_mknod(&nd->path, path->dentry, mode, 0);
  	if (error)
  		goto out_unlock;
aab520e2f   Dave Hansen   [PATCH] r/o bind ...
1438
  	error = vfs_create(dir->d_inode, path->dentry, mode, nd);
be6d3e56a   Kentaro Takeda   introduce new LSM...
1439
  out_unlock:
aab520e2f   Dave Hansen   [PATCH] r/o bind ...
1440
  	mutex_unlock(&dir->d_inode->i_mutex);
4ac913785   Jan Blunck   Embed a struct pa...
1441
1442
  	dput(nd->path.dentry);
  	nd->path.dentry = path->dentry;
aab520e2f   Dave Hansen   [PATCH] r/o bind ...
1443
1444
1445
  	if (error)
  		return error;
  	/* Don't check for write permission, don't truncate */
8737c9305   Al Viro   Switch may_open()...
1446
  	return may_open(&nd->path, 0, open_flag & ~O_TRUNC);
aab520e2f   Dave Hansen   [PATCH] r/o bind ...
1447
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1448
  /*
d57999e15   Dave Hansen   [PATCH] do namei_...
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
   * 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;
  }
7715b5212   Al Viro   O_TRUNC open shou...
1471
  static int open_will_truncate(int flag, struct inode *inode)
4a3fd211c   Dave Hansen   [PATCH] r/o bind ...
1472
1473
1474
1475
1476
1477
1478
1479
1480
  {
  	/*
  	 * We'll never write to the fs underlying
  	 * a device file.
  	 */
  	if (special_file(inode->i_mode))
  		return 0;
  	return (flag & O_TRUNC);
  }
648fa8611   Al Viro   beginning to unta...
1481
  static struct file *finish_open(struct nameidata *nd,
9a66179e1   Al Viro   Don't pass mangle...
1482
  				int open_flag, int acc_mode)
648fa8611   Al Viro   beginning to unta...
1483
1484
1485
1486
  {
  	struct file *filp;
  	int will_truncate;
  	int error;
9a66179e1   Al Viro   Don't pass mangle...
1487
  	will_truncate = open_will_truncate(open_flag, nd->path.dentry->d_inode);
648fa8611   Al Viro   beginning to unta...
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
  	if (will_truncate) {
  		error = mnt_want_write(nd->path.mnt);
  		if (error)
  			goto exit;
  	}
  	error = may_open(&nd->path, acc_mode, open_flag);
  	if (error) {
  		if (will_truncate)
  			mnt_drop_write(nd->path.mnt);
  		goto exit;
  	}
  	filp = nameidata_to_filp(nd);
  	if (!IS_ERR(filp)) {
  		error = ima_file_check(filp, acc_mode);
  		if (error) {
  			fput(filp);
  			filp = ERR_PTR(error);
  		}
  	}
  	if (!IS_ERR(filp)) {
648fa8611   Al Viro   beginning to unta...
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
  		if (will_truncate) {
  			error = handle_truncate(&nd->path);
  			if (error) {
  				fput(filp);
  				filp = ERR_PTR(error);
  			}
  		}
  	}
  	/*
  	 * It is now safe to drop the mnt write
  	 * because the filp has had a write taken
  	 * on its behalf.
  	 */
  	if (will_truncate)
  		mnt_drop_write(nd->path.mnt);
  	return filp;
  
  exit:
  	if (!IS_ERR(nd->intent.open.file))
  		release_open_intent(nd);
  	path_put(&nd->path);
  	return ERR_PTR(error);
  }
fb1cc555d   Al Viro   gut do_filp_open(...
1531
  static struct file *do_last(struct nameidata *nd, struct path *path,
5b369df82   Al Viro   Get rid of passin...
1532
  			    int open_flag, int acc_mode,
3e297b613   Al Viro   Restore LOOKUP_DI...
1533
  			    int mode, const char *pathname)
fb1cc555d   Al Viro   gut do_filp_open(...
1534
  {
a1e28038d   Al Viro   pull the common p...
1535
  	struct dentry *dir = nd->path.dentry;
fb1cc555d   Al Viro   gut do_filp_open(...
1536
  	struct file *filp;
1f36f774b   Al Viro   Switch !O_CREAT c...
1537
1538
1539
1540
1541
1542
  	int error = -EISDIR;
  
  	switch (nd->last_type) {
  	case LAST_DOTDOT:
  		follow_dotdot(nd);
  		dir = nd->path.dentry;
176306f59   Neil Brown   VFS: fix recent b...
1543
  	case LAST_DOT:
1f36f774b   Al Viro   Switch !O_CREAT c...
1544
1545
1546
1547
1548
1549
1550
  		if (nd->path.mnt->mnt_sb->s_type->fs_flags & FS_REVAL_DOT) {
  			if (!dir->d_op->d_revalidate(dir, nd)) {
  				error = -ESTALE;
  				goto exit;
  			}
  		}
  		/* fallthrough */
1f36f774b   Al Viro   Switch !O_CREAT c...
1551
1552
1553
1554
1555
1556
  	case LAST_ROOT:
  		if (open_flag & O_CREAT)
  			goto exit;
  		/* fallthrough */
  	case LAST_BIND:
  		audit_inode(pathname, dir);
67ee3ad21   Al Viro   Pull handling of ...
1557
  		goto ok;
1f36f774b   Al Viro   Switch !O_CREAT c...
1558
  	}
67ee3ad21   Al Viro   Pull handling of ...
1559

1f36f774b   Al Viro   Switch !O_CREAT c...
1560
1561
1562
1563
  	/* trailing slashes? */
  	if (nd->last.name[nd->last.len]) {
  		if (open_flag & O_CREAT)
  			goto exit;
002baeecf   Jan Kara   vfs: Fix O_NOFOLL...
1564
  		nd->flags |= LOOKUP_DIRECTORY | LOOKUP_FOLLOW;
1f36f774b   Al Viro   Switch !O_CREAT c...
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
  	}
  
  	/* just plain open? */
  	if (!(open_flag & O_CREAT)) {
  		error = do_lookup(nd, &nd->last, path);
  		if (error)
  			goto exit;
  		error = -ENOENT;
  		if (!path->dentry->d_inode)
  			goto exit_dput;
  		if (path->dentry->d_inode->i_op->follow_link)
  			return NULL;
  		error = -ENOTDIR;
3e297b613   Al Viro   Restore LOOKUP_DI...
1578
1579
1580
1581
  		if (nd->flags & LOOKUP_DIRECTORY) {
  			if (!path->dentry->d_inode->i_op->lookup)
  				goto exit_dput;
  		}
1f36f774b   Al Viro   Switch !O_CREAT c...
1582
1583
1584
1585
  		path_to_nameidata(path, nd);
  		audit_inode(pathname, nd->path.dentry);
  		goto ok;
  	}
a2c36b450   Al Viro   pull more into do...
1586

1f36f774b   Al Viro   Switch !O_CREAT c...
1587
  	/* OK, it's O_CREAT */
a1e28038d   Al Viro   pull the common p...
1588
1589
1590
1591
  	mutex_lock(&dir->d_inode->i_mutex);
  
  	path->dentry = lookup_hash(nd);
  	path->mnt = nd->path.mnt;
fb1cc555d   Al Viro   gut do_filp_open(...
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
  	error = PTR_ERR(path->dentry);
  	if (IS_ERR(path->dentry)) {
  		mutex_unlock(&dir->d_inode->i_mutex);
  		goto exit;
  	}
  
  	if (IS_ERR(nd->intent.open.file)) {
  		error = PTR_ERR(nd->intent.open.file);
  		goto exit_mutex_unlock;
  	}
  
  	/* Negative dentry, just create the file */
  	if (!path->dentry->d_inode) {
  		/*
  		 * This write is needed to ensure that a
  		 * ro->rw transition does not occur between
  		 * 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;
  		error = __open_namei_create(nd, path, open_flag, mode);
  		if (error) {
  			mnt_drop_write(nd->path.mnt);
  			goto exit;
  		}
  		filp = nameidata_to_filp(nd);
  		mnt_drop_write(nd->path.mnt);
fb1cc555d   Al Viro   gut do_filp_open(...
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
  		if (!IS_ERR(filp)) {
  			error = ima_file_check(filp, acc_mode);
  			if (error) {
  				fput(filp);
  				filp = ERR_PTR(error);
  			}
  		}
  		return filp;
  	}
  
  	/*
  	 * It already exists.
  	 */
  	mutex_unlock(&dir->d_inode->i_mutex);
  	audit_inode(pathname, path->dentry);
  
  	error = -EEXIST;
5b369df82   Al Viro   Get rid of passin...
1639
  	if (open_flag & O_EXCL)
fb1cc555d   Al Viro   gut do_filp_open(...
1640
1641
1642
1643
  		goto exit_dput;
  
  	if (__follow_mount(path)) {
  		error = -ELOOP;
5b369df82   Al Viro   Get rid of passin...
1644
  		if (open_flag & O_NOFOLLOW)
fb1cc555d   Al Viro   gut do_filp_open(...
1645
1646
1647
1648
1649
1650
  			goto exit_dput;
  	}
  
  	error = -ENOENT;
  	if (!path->dentry->d_inode)
  		goto exit_dput;
9e67f3616   Al Viro   Kill is_link argu...
1651
1652
  
  	if (path->dentry->d_inode->i_op->follow_link)
fb1cc555d   Al Viro   gut do_filp_open(...
1653
  		return NULL;
fb1cc555d   Al Viro   gut do_filp_open(...
1654
1655
1656
1657
1658
  
  	path_to_nameidata(path, nd);
  	error = -EISDIR;
  	if (S_ISDIR(path->dentry->d_inode->i_mode))
  		goto exit;
67ee3ad21   Al Viro   Pull handling of ...
1659
  ok:
9a66179e1   Al Viro   Don't pass mangle...
1660
  	filp = finish_open(nd, open_flag, acc_mode);
fb1cc555d   Al Viro   gut do_filp_open(...
1661
1662
1663
1664
1665
1666
1667
1668
1669
  	return filp;
  
  exit_mutex_unlock:
  	mutex_unlock(&dir->d_inode->i_mutex);
  exit_dput:
  	path_put_conditional(path, nd);
  exit:
  	if (!IS_ERR(nd->intent.open.file))
  		release_open_intent(nd);
fb1cc555d   Al Viro   gut do_filp_open(...
1670
1671
1672
  	path_put(&nd->path);
  	return ERR_PTR(error);
  }
d57999e15   Dave Hansen   [PATCH] do namei_...
1673
  /*
4a3fd211c   Dave Hansen   [PATCH] r/o bind ...
1674
1675
1676
   * Note that the low bits of the passed in "open_flag"
   * are not the same as in the local variable "flag". See
   * open_to_namei_flags() for more details.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1677
   */
a70e65df8   Christoph Hellwig   [PATCH] merge ope...
1678
  struct file *do_filp_open(int dfd, const char *pathname,
6e8341a11   Al Viro   Switch open_exec(...
1679
  		int open_flag, int mode, int acc_mode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1680
  {
4a3fd211c   Dave Hansen   [PATCH] r/o bind ...
1681
  	struct file *filp;
a70e65df8   Christoph Hellwig   [PATCH] merge ope...
1682
  	struct nameidata nd;
6e8341a11   Al Viro   Switch open_exec(...
1683
  	int error;
9850c0565   Al Viro   Fix the -ESTALE h...
1684
  	struct path path;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1685
  	int count = 0;
d57999e15   Dave Hansen   [PATCH] do namei_...
1686
  	int flag = open_to_namei_flags(open_flag);
9850c0565   Al Viro   Fix the -ESTALE h...
1687
  	int force_reval = 0;
1f36f774b   Al Viro   Switch !O_CREAT c...
1688
1689
1690
  
  	if (!(open_flag & O_CREAT))
  		mode = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1691

6b2f3d1f7   Christoph Hellwig   vfs: Implement pr...
1692
1693
1694
1695
1696
1697
1698
1699
  	/*
  	 * O_SYNC is implemented as __O_SYNC|O_DSYNC.  As many places only
  	 * check for O_DSYNC if the need any syncing at all we enforce it's
  	 * always set instead of having to deal with possibly weird behaviour
  	 * for malicious applications setting only __O_SYNC.
  	 */
  	if (open_flag & __O_SYNC)
  		open_flag |= O_DSYNC;
6e8341a11   Al Viro   Switch open_exec(...
1700
  	if (!acc_mode)
6d125529c   Al Viro   Fix ACC_MODE() fo...
1701
  		acc_mode = MAY_OPEN | ACC_MODE(open_flag);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1702

834f2a4a1   Trond Myklebust   VFS: Allow the fi...
1703
  	/* O_TRUNC implies we need access checks for write permissions */
4296e2cbf   Al Viro   Leave mangled fla...
1704
  	if (open_flag & O_TRUNC)
834f2a4a1   Trond Myklebust   VFS: Allow the fi...
1705
  		acc_mode |= MAY_WRITE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1706
1707
  	/* Allow the LSM permission hook to distinguish append 
  	   access from general write access. */
4296e2cbf   Al Viro   Leave mangled fla...
1708
  	if (open_flag & O_APPEND)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1709
  		acc_mode |= MAY_APPEND;
1f36f774b   Al Viro   Switch !O_CREAT c...
1710
  	/* find the parent */
9850c0565   Al Viro   Fix the -ESTALE h...
1711
  reval:
9b4a9b14a   Al Viro   Preparations to c...
1712
  	error = path_init(dfd, pathname, LOOKUP_PARENT, &nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1713
  	if (error)
a70e65df8   Christoph Hellwig   [PATCH] merge ope...
1714
  		return ERR_PTR(error);
9850c0565   Al Viro   Fix the -ESTALE h...
1715
1716
  	if (force_reval)
  		nd.flags |= LOOKUP_REVAL;
3866248e5   Al Viro   Finish pulling of...
1717
1718
1719
  
  	current->total_link_count = 0;
  	error = link_path_walk(pathname, &nd);
654f562c5   J. R. Okajima   vfs: fix nd->root...
1720
  	if (error) {
10fa8e62f   Al Viro   Unify exits in O_...
1721
1722
  		filp = ERR_PTR(error);
  		goto out;
654f562c5   J. R. Okajima   vfs: fix nd->root...
1723
  	}
1f36f774b   Al Viro   Switch !O_CREAT c...
1724
  	if (unlikely(!audit_dummy_context()) && (open_flag & O_CREAT))
9b4a9b14a   Al Viro   Preparations to c...
1725
  		audit_inode(pathname, nd.path.dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1726
1727
  
  	/*
a2c36b450   Al Viro   pull more into do...
1728
  	 * We have the parent and last component.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1729
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1730

8737f3a1b   Al Viro   [PATCH] get rid o...
1731
1732
1733
1734
1735
  	error = -ENFILE;
  	filp = get_empty_filp();
  	if (filp == NULL)
  		goto exit_parent;
  	nd.intent.open.file = filp;
482928d59   Al Viro   Fix f_flags/f_mod...
1736
  	filp->f_flags = open_flag;
8737f3a1b   Al Viro   [PATCH] get rid o...
1737
1738
  	nd.intent.open.flags = flag;
  	nd.intent.open.create_mode = mode;
a70e65df8   Christoph Hellwig   [PATCH] merge ope...
1739
  	nd.flags &= ~LOOKUP_PARENT;
1f36f774b   Al Viro   Switch !O_CREAT c...
1740
1741
1742
1743
1744
1745
  	nd.flags |= LOOKUP_OPEN;
  	if (open_flag & O_CREAT) {
  		nd.flags |= LOOKUP_CREATE;
  		if (open_flag & O_EXCL)
  			nd.flags |= LOOKUP_EXCL;
  	}
3e297b613   Al Viro   Restore LOOKUP_DI...
1746
1747
  	if (open_flag & O_DIRECTORY)
  		nd.flags |= LOOKUP_DIRECTORY;
002baeecf   Jan Kara   vfs: Fix O_NOFOLL...
1748
1749
  	if (!(open_flag & O_NOFOLLOW))
  		nd.flags |= LOOKUP_FOLLOW;
3e297b613   Al Viro   Restore LOOKUP_DI...
1750
  	filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname);
806b681cb   Al Viro   Turn do_link spag...
1751
  	while (unlikely(!filp)) { /* trailing symlink */
def4af30c   Al Viro   Get rid of symlin...
1752
  		struct path holder;
1f36f774b   Al Viro   Switch !O_CREAT c...
1753
  		struct inode *inode = path.dentry->d_inode;
def4af30c   Al Viro   Get rid of symlin...
1754
  		void *cookie;
806b681cb   Al Viro   Turn do_link spag...
1755
  		error = -ELOOP;
1f36f774b   Al Viro   Switch !O_CREAT c...
1756
  		/* S_ISDIR part is a temporary automount kludge */
002baeecf   Jan Kara   vfs: Fix O_NOFOLL...
1757
  		if (!(nd.flags & LOOKUP_FOLLOW) && !S_ISDIR(inode->i_mode))
1f36f774b   Al Viro   Switch !O_CREAT c...
1758
1759
  			goto exit_dput;
  		if (count++ == 32)
806b681cb   Al Viro   Turn do_link spag...
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
  			goto exit_dput;
  		/*
  		 * This is subtle. Instead of calling do_follow_link() we do
  		 * the thing by hands. The reason is that this way we have zero
  		 * link_count and path_walk() (called from ->follow_link)
  		 * honoring LOOKUP_PARENT.  After that we have the parent and
  		 * last component, i.e. we are in the same situation as after
  		 * the first path_walk().  Well, almost - if the last component
  		 * is normal we get its copy stored in nd->last.name and we will
  		 * have to putname() it when we are done. Procfs-like symlinks
  		 * just set LAST_BIND.
  		 */
  		nd.flags |= LOOKUP_PARENT;
  		error = security_inode_follow_link(path.dentry, &nd);
  		if (error)
  			goto exit_dput;
def4af30c   Al Viro   Get rid of symlin...
1776
1777
  		error = __do_follow_link(&path, &nd, &cookie);
  		if (unlikely(error)) {
806b681cb   Al Viro   Turn do_link spag...
1778
  			/* nd.path had been dropped */
def4af30c   Al Viro   Get rid of symlin...
1779
1780
1781
  			if (!IS_ERR(cookie) && inode->i_op->put_link)
  				inode->i_op->put_link(path.dentry, &nd, cookie);
  			path_put(&path);
806b681cb   Al Viro   Turn do_link spag...
1782
1783
1784
1785
  			release_open_intent(&nd);
  			filp = ERR_PTR(error);
  			goto out;
  		}
def4af30c   Al Viro   Get rid of symlin...
1786
  		holder = path;
806b681cb   Al Viro   Turn do_link spag...
1787
  		nd.flags &= ~LOOKUP_PARENT;
3e297b613   Al Viro   Restore LOOKUP_DI...
1788
  		filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname);
def4af30c   Al Viro   Get rid of symlin...
1789
1790
1791
  		if (inode->i_op->put_link)
  			inode->i_op->put_link(holder.dentry, &nd, cookie);
  		path_put(&holder);
806b681cb   Al Viro   Turn do_link spag...
1792
  	}
10fa8e62f   Al Viro   Unify exits in O_...
1793
  out:
2a7378711   Al Viro   Cache root in nam...
1794
1795
  	if (nd.root.mnt)
  		path_put(&nd.root);
10fa8e62f   Al Viro   Unify exits in O_...
1796
1797
1798
1799
1800
  	if (filp == ERR_PTR(-ESTALE) && !force_reval) {
  		force_reval = 1;
  		goto reval;
  	}
  	return filp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1801

806b681cb   Al Viro   Turn do_link spag...
1802
1803
1804
  exit_dput:
  	path_put_conditional(&path, &nd);
  	if (!IS_ERR(nd.intent.open.file))
a70e65df8   Christoph Hellwig   [PATCH] merge ope...
1805
  		release_open_intent(&nd);
806b681cb   Al Viro   Turn do_link spag...
1806
1807
1808
  exit_parent:
  	path_put(&nd.path);
  	filp = ERR_PTR(error);
10fa8e62f   Al Viro   Unify exits in O_...
1809
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1810
1811
1812
  }
  
  /**
a70e65df8   Christoph Hellwig   [PATCH] merge ope...
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
   * filp_open - open file and return file pointer
   *
   * @filename:	path to open
   * @flags:	open flags as per the open(2) second argument
   * @mode:	mode for the new file if O_CREAT is set, else ignored
   *
   * This is the helper to open a file from kernelspace if you really
   * have to.  But in generally you should not do this, so please move
   * along, nothing to see here..
   */
  struct file *filp_open(const char *filename, int flags, int mode)
  {
6e8341a11   Al Viro   Switch open_exec(...
1825
  	return do_filp_open(AT_FDCWD, filename, flags, mode, 0);
a70e65df8   Christoph Hellwig   [PATCH] merge ope...
1826
1827
1828
1829
  }
  EXPORT_SYMBOL(filp_open);
  
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1830
1831
1832
1833
1834
1835
   * 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 ...
1836
   *
4ac913785   Jan Blunck   Embed a struct pa...
1837
   * Returns with nd->path.dentry->d_inode->i_mutex locked.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1838
1839
1840
   */
  struct dentry *lookup_create(struct nameidata *nd, int is_dir)
  {
c663e5d80   Christoph Hellwig   [PATCH] add some ...
1841
  	struct dentry *dentry = ERR_PTR(-EEXIST);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1842

4ac913785   Jan Blunck   Embed a struct pa...
1843
  	mutex_lock_nested(&nd->path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
c663e5d80   Christoph Hellwig   [PATCH] add some ...
1844
1845
1846
1847
  	/*
  	 * Yucky last component or no last component at all?
  	 * (foo/., foo/.., /////)
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1848
1849
1850
  	if (nd->last_type != LAST_NORM)
  		goto fail;
  	nd->flags &= ~LOOKUP_PARENT;
3516586a4   Al Viro   [PATCH] make O_EX...
1851
  	nd->flags |= LOOKUP_CREATE | LOOKUP_EXCL;
a634904a7   ASANO Masahiro   VFS: add lookup h...
1852
  	nd->intent.open.flags = O_EXCL;
c663e5d80   Christoph Hellwig   [PATCH] add some ...
1853
1854
1855
1856
  
  	/*
  	 * Do the final lookup.
  	 */
49705b774   Christoph Hellwig   [PATCH] sanitize ...
1857
  	dentry = lookup_hash(nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1858
1859
  	if (IS_ERR(dentry))
  		goto fail;
c663e5d80   Christoph Hellwig   [PATCH] add some ...
1860

e9baf6e59   Al Viro   [PATCH] return to...
1861
1862
  	if (dentry->d_inode)
  		goto eexist;
c663e5d80   Christoph Hellwig   [PATCH] add some ...
1863
1864
1865
1866
1867
1868
  	/*
  	 * 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...
1869
1870
1871
1872
  	if (unlikely(!is_dir && nd->last.name[nd->last.len])) {
  		dput(dentry);
  		dentry = ERR_PTR(-ENOENT);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1873
  	return dentry;
e9baf6e59   Al Viro   [PATCH] return to...
1874
  eexist:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1875
  	dput(dentry);
e9baf6e59   Al Viro   [PATCH] return to...
1876
  	dentry = ERR_PTR(-EEXIST);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1877
1878
1879
  fail:
  	return dentry;
  }
f81a0bffa   Christoph Hellwig   [AF_UNIX]: Use lo...
1880
  EXPORT_SYMBOL_GPL(lookup_create);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1881
1882
1883
  
  int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
  {
a95164d97   Miklos Szeredi   [patch 3/4] vfs: ...
1884
  	int error = may_create(dir, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1885
1886
1887
1888
1889
1890
  
  	if (error)
  		return error;
  
  	if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD))
  		return -EPERM;
acfa4380e   Al Viro   inode->i_op is ne...
1891
  	if (!dir->i_op->mknod)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1892
  		return -EPERM;
08ce5f16e   Serge E. Hallyn   cgroups: implemen...
1893
1894
1895
  	error = devcgroup_inode_mknod(mode, dev);
  	if (error)
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1896
1897
1898
  	error = security_inode_mknod(dir, dentry, mode, dev);
  	if (error)
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1899
  	error = dir->i_op->mknod(dir, dentry, mode, dev);
a74574aaf   Stephen Smalley   [PATCH] Remove se...
1900
  	if (!error)
f38aa9422   Amy Griffis   [PATCH] Pass dent...
1901
  		fsnotify_create(dir, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1902
1903
  	return error;
  }
463c31972   Dave Hansen   [PATCH] r/o bind ...
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
  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...
1920
1921
  SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode,
  		unsigned, dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1922
  {
2ad94ae65   Al Viro   [PATCH] new (loca...
1923
1924
1925
  	int error;
  	char *tmp;
  	struct dentry *dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1926
1927
1928
1929
  	struct nameidata nd;
  
  	if (S_ISDIR(mode))
  		return -EPERM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1930

2ad94ae65   Al Viro   [PATCH] new (loca...
1931
  	error = user_path_parent(dfd, filename, &nd, &tmp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1932
  	if (error)
2ad94ae65   Al Viro   [PATCH] new (loca...
1933
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1934
  	dentry = lookup_create(&nd, 0);
463c31972   Dave Hansen   [PATCH] r/o bind ...
1935
1936
1937
1938
  	if (IS_ERR(dentry)) {
  		error = PTR_ERR(dentry);
  		goto out_unlock;
  	}
4ac913785   Jan Blunck   Embed a struct pa...
1939
  	if (!IS_POSIXACL(nd.path.dentry->d_inode))
ce3b0f8d5   Al Viro   New helper - curr...
1940
  		mode &= ~current_umask();
463c31972   Dave Hansen   [PATCH] r/o bind ...
1941
1942
1943
1944
1945
1946
  	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...
1947
1948
1949
  	error = security_path_mknod(&nd.path, dentry, mode, dev);
  	if (error)
  		goto out_drop_write;
463c31972   Dave Hansen   [PATCH] r/o bind ...
1950
  	switch (mode & S_IFMT) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1951
  		case 0: case S_IFREG:
4ac913785   Jan Blunck   Embed a struct pa...
1952
  			error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1953
1954
  			break;
  		case S_IFCHR: case S_IFBLK:
4ac913785   Jan Blunck   Embed a struct pa...
1955
  			error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1956
1957
1958
  					new_decode_dev(dev));
  			break;
  		case S_IFIFO: case S_IFSOCK:
4ac913785   Jan Blunck   Embed a struct pa...
1959
  			error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1960
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1961
  	}
be6d3e56a   Kentaro Takeda   introduce new LSM...
1962
  out_drop_write:
463c31972   Dave Hansen   [PATCH] r/o bind ...
1963
1964
1965
1966
  	mnt_drop_write(nd.path.mnt);
  out_dput:
  	dput(dentry);
  out_unlock:
4ac913785   Jan Blunck   Embed a struct pa...
1967
  	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
1d957f9bf   Jan Blunck   Introduce path_put()
1968
  	path_put(&nd.path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1969
1970
1971
1972
  	putname(tmp);
  
  	return error;
  }
3480b2574   Heiko Carstens   [CVE-2009-0029] S...
1973
  SYSCALL_DEFINE3(mknod, const char __user *, filename, int, mode, unsigned, dev)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
1974
1975
1976
  {
  	return sys_mknodat(AT_FDCWD, filename, mode, dev);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1977
1978
  int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
  {
a95164d97   Miklos Szeredi   [patch 3/4] vfs: ...
1979
  	int error = may_create(dir, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1980
1981
1982
  
  	if (error)
  		return error;
acfa4380e   Al Viro   inode->i_op is ne...
1983
  	if (!dir->i_op->mkdir)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1984
1985
1986
1987
1988
1989
  		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
1990
  	error = dir->i_op->mkdir(dir, dentry, mode);
a74574aaf   Stephen Smalley   [PATCH] Remove se...
1991
  	if (!error)
f38aa9422   Amy Griffis   [PATCH] Pass dent...
1992
  		fsnotify_mkdir(dir, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1993
1994
  	return error;
  }
2e4d0924e   Heiko Carstens   [CVE-2009-0029] S...
1995
  SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1996
1997
1998
  {
  	int error = 0;
  	char * tmp;
6902d925d   Dave Hansen   [PATCH] r/o bind ...
1999
2000
  	struct dentry *dentry;
  	struct nameidata nd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2001

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

6902d925d   Dave Hansen   [PATCH] r/o bind ...
2006
2007
2008
2009
  	dentry = lookup_create(&nd, 1);
  	error = PTR_ERR(dentry);
  	if (IS_ERR(dentry))
  		goto out_unlock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2010

4ac913785   Jan Blunck   Embed a struct pa...
2011
  	if (!IS_POSIXACL(nd.path.dentry->d_inode))
ce3b0f8d5   Al Viro   New helper - curr...
2012
  		mode &= ~current_umask();
463c31972   Dave Hansen   [PATCH] r/o bind ...
2013
2014
2015
  	error = mnt_want_write(nd.path.mnt);
  	if (error)
  		goto out_dput;
be6d3e56a   Kentaro Takeda   introduce new LSM...
2016
2017
2018
  	error = security_path_mkdir(&nd.path, dentry, mode);
  	if (error)
  		goto out_drop_write;
4ac913785   Jan Blunck   Embed a struct pa...
2019
  	error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
be6d3e56a   Kentaro Takeda   introduce new LSM...
2020
  out_drop_write:
463c31972   Dave Hansen   [PATCH] r/o bind ...
2021
2022
  	mnt_drop_write(nd.path.mnt);
  out_dput:
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2023
2024
  	dput(dentry);
  out_unlock:
4ac913785   Jan Blunck   Embed a struct pa...
2025
  	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
1d957f9bf   Jan Blunck   Introduce path_put()
2026
  	path_put(&nd.path);
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2027
2028
  	putname(tmp);
  out_err:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2029
2030
  	return error;
  }
3cdad4288   Heiko Carstens   [CVE-2009-0029] S...
2031
  SYSCALL_DEFINE2(mkdir, const char __user *, pathname, int, mode)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2032
2033
2034
  {
  	return sys_mkdirat(AT_FDCWD, pathname, mode);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
  /*
   * We 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.
   *
   * 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)
  {
  	dget(dentry);
dc168427e   Vasily Averin   [PATCH] VFS: extr...
2053
  	shrink_dcache_parent(dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
  	spin_lock(&dcache_lock);
  	spin_lock(&dentry->d_lock);
  	if (atomic_read(&dentry->d_count) == 2)
  		__d_drop(dentry);
  	spin_unlock(&dentry->d_lock);
  	spin_unlock(&dcache_lock);
  }
  
  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...
2068
  	if (!dir->i_op->rmdir)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2069
  		return -EPERM;
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2070
  	mutex_lock(&dentry->d_inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2071
2072
2073
2074
2075
2076
2077
  	dentry_unhash(dentry);
  	if (d_mountpoint(dentry))
  		error = -EBUSY;
  	else {
  		error = security_inode_rmdir(dir, dentry);
  		if (!error) {
  			error = dir->i_op->rmdir(dir, dentry);
d83c49f3e   Al Viro   Fix the regressio...
2078
  			if (!error) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2079
  				dentry->d_inode->i_flags |= S_DEAD;
d83c49f3e   Al Viro   Fix the regressio...
2080
2081
  				dont_mount(dentry);
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2082
2083
  		}
  	}
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2084
  	mutex_unlock(&dentry->d_inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2085
  	if (!error) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2086
2087
2088
2089
2090
2091
  		d_delete(dentry);
  	}
  	dput(dentry);
  
  	return error;
  }
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2092
  static long do_rmdir(int dfd, const char __user *pathname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2093
2094
2095
2096
2097
  {
  	int error = 0;
  	char * name;
  	struct dentry *dentry;
  	struct nameidata nd;
2ad94ae65   Al Viro   [PATCH] new (loca...
2098
  	error = user_path_parent(dfd, pathname, &nd, &name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2099
  	if (error)
2ad94ae65   Al Viro   [PATCH] new (loca...
2100
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2101
2102
  
  	switch(nd.last_type) {
0612d9fb2   OGAWA Hirofumi   [PATCH vfs-2.6 5/...
2103
2104
2105
2106
2107
2108
2109
2110
2111
  	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
2112
  	}
0612d9fb2   OGAWA Hirofumi   [PATCH vfs-2.6 5/...
2113
2114
  
  	nd.flags &= ~LOOKUP_PARENT;
4ac913785   Jan Blunck   Embed a struct pa...
2115
  	mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
49705b774   Christoph Hellwig   [PATCH] sanitize ...
2116
  	dentry = lookup_hash(&nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2117
  	error = PTR_ERR(dentry);
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2118
2119
  	if (IS_ERR(dentry))
  		goto exit2;
0622753b8   Dave Hansen   [PATCH] r/o bind ...
2120
2121
2122
  	error = mnt_want_write(nd.path.mnt);
  	if (error)
  		goto exit3;
be6d3e56a   Kentaro Takeda   introduce new LSM...
2123
2124
2125
  	error = security_path_rmdir(&nd.path, dentry);
  	if (error)
  		goto exit4;
4ac913785   Jan Blunck   Embed a struct pa...
2126
  	error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
be6d3e56a   Kentaro Takeda   introduce new LSM...
2127
  exit4:
0622753b8   Dave Hansen   [PATCH] r/o bind ...
2128
2129
  	mnt_drop_write(nd.path.mnt);
  exit3:
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2130
2131
  	dput(dentry);
  exit2:
4ac913785   Jan Blunck   Embed a struct pa...
2132
  	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2133
  exit1:
1d957f9bf   Jan Blunck   Introduce path_put()
2134
  	path_put(&nd.path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2135
2136
2137
  	putname(name);
  	return error;
  }
3cdad4288   Heiko Carstens   [CVE-2009-0029] S...
2138
  SYSCALL_DEFINE1(rmdir, const char __user *, pathname)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2139
2140
2141
  {
  	return do_rmdir(AT_FDCWD, pathname);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2142
2143
2144
2145
2146
2147
  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...
2148
  	if (!dir->i_op->unlink)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2149
  		return -EPERM;
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2150
  	mutex_lock(&dentry->d_inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2151
2152
2153
2154
  	if (d_mountpoint(dentry))
  		error = -EBUSY;
  	else {
  		error = security_inode_unlink(dir, dentry);
bec1052e5   Al Viro   set S_DEAD on unl...
2155
  		if (!error) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2156
  			error = dir->i_op->unlink(dir, dentry);
bec1052e5   Al Viro   set S_DEAD on unl...
2157
  			if (!error)
d83c49f3e   Al Viro   Fix the regressio...
2158
  				dont_mount(dentry);
bec1052e5   Al Viro   set S_DEAD on unl...
2159
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2160
  	}
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2161
  	mutex_unlock(&dentry->d_inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2162
2163
2164
  
  	/* 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_...
2165
  		fsnotify_link_count(dentry->d_inode);
e234f35c5   John McCutchan   [PATCH] inotify d...
2166
  		d_delete(dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2167
  	}
0eeca2830   Robert Love   [PATCH] inotify
2168

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2169
2170
2171
2172
2173
  	return error;
  }
  
  /*
   * Make sure that the actual truncation of the file will occur outside its
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2174
   * directory's i_mutex.  Truncate can take a long time if there is a lot of
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2175
2176
2177
   * 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 ...
2178
  static long do_unlinkat(int dfd, const char __user *pathname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2179
  {
2ad94ae65   Al Viro   [PATCH] new (loca...
2180
2181
  	int error;
  	char *name;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2182
2183
2184
  	struct dentry *dentry;
  	struct nameidata nd;
  	struct inode *inode = NULL;
2ad94ae65   Al Viro   [PATCH] new (loca...
2185
  	error = user_path_parent(dfd, pathname, &nd, &name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2186
  	if (error)
2ad94ae65   Al Viro   [PATCH] new (loca...
2187
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2188
2189
2190
  	error = -EISDIR;
  	if (nd.last_type != LAST_NORM)
  		goto exit1;
0612d9fb2   OGAWA Hirofumi   [PATCH vfs-2.6 5/...
2191
2192
  
  	nd.flags &= ~LOOKUP_PARENT;
4ac913785   Jan Blunck   Embed a struct pa...
2193
  	mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
49705b774   Christoph Hellwig   [PATCH] sanitize ...
2194
  	dentry = lookup_hash(&nd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2195
2196
2197
2198
2199
2200
2201
2202
  	error = PTR_ERR(dentry);
  	if (!IS_ERR(dentry)) {
  		/* Why not before? Because we want correct error value */
  		if (nd.last.name[nd.last.len])
  			goto slashes;
  		inode = dentry->d_inode;
  		if (inode)
  			atomic_inc(&inode->i_count);
0622753b8   Dave Hansen   [PATCH] r/o bind ...
2203
2204
2205
  		error = mnt_want_write(nd.path.mnt);
  		if (error)
  			goto exit2;
be6d3e56a   Kentaro Takeda   introduce new LSM...
2206
2207
2208
  		error = security_path_unlink(&nd.path, dentry);
  		if (error)
  			goto exit3;
4ac913785   Jan Blunck   Embed a struct pa...
2209
  		error = vfs_unlink(nd.path.dentry->d_inode, dentry);
be6d3e56a   Kentaro Takeda   introduce new LSM...
2210
  exit3:
0622753b8   Dave Hansen   [PATCH] r/o bind ...
2211
  		mnt_drop_write(nd.path.mnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2212
2213
2214
  	exit2:
  		dput(dentry);
  	}
4ac913785   Jan Blunck   Embed a struct pa...
2215
  	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2216
2217
2218
  	if (inode)
  		iput(inode);	/* truncate the inode here */
  exit1:
1d957f9bf   Jan Blunck   Introduce path_put()
2219
  	path_put(&nd.path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2220
2221
2222
2223
2224
2225
2226
2227
  	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...
2228
  SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2229
2230
2231
2232
2233
2234
2235
2236
2237
  {
  	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...
2238
  SYSCALL_DEFINE1(unlink, const char __user *, pathname)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2239
2240
2241
  {
  	return do_unlinkat(AT_FDCWD, pathname);
  }
db2e747b1   Miklos Szeredi   [patch 5/5] vfs: ...
2242
  int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2243
  {
a95164d97   Miklos Szeredi   [patch 3/4] vfs: ...
2244
  	int error = may_create(dir, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2245
2246
2247
  
  	if (error)
  		return error;
acfa4380e   Al Viro   inode->i_op is ne...
2248
  	if (!dir->i_op->symlink)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2249
2250
2251
2252
2253
  		return -EPERM;
  
  	error = security_inode_symlink(dir, dentry, oldname);
  	if (error)
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2254
  	error = dir->i_op->symlink(dir, dentry, oldname);
a74574aaf   Stephen Smalley   [PATCH] Remove se...
2255
  	if (!error)
f38aa9422   Amy Griffis   [PATCH] Pass dent...
2256
  		fsnotify_create(dir, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2257
2258
  	return error;
  }
2e4d0924e   Heiko Carstens   [CVE-2009-0029] S...
2259
2260
  SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
  		int, newdfd, const char __user *, newname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2261
  {
2ad94ae65   Al Viro   [PATCH] new (loca...
2262
2263
2264
  	int error;
  	char *from;
  	char *to;
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2265
2266
  	struct dentry *dentry;
  	struct nameidata nd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2267
2268
  
  	from = getname(oldname);
2ad94ae65   Al Viro   [PATCH] new (loca...
2269
  	if (IS_ERR(from))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2270
  		return PTR_ERR(from);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2271

2ad94ae65   Al Viro   [PATCH] new (loca...
2272
  	error = user_path_parent(newdfd, newname, &nd, &to);
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2273
  	if (error)
2ad94ae65   Al Viro   [PATCH] new (loca...
2274
  		goto out_putname;
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2275
2276
2277
2278
  	dentry = lookup_create(&nd, 0);
  	error = PTR_ERR(dentry);
  	if (IS_ERR(dentry))
  		goto out_unlock;
75c3f29de   Dave Hansen   [PATCH] r/o bind ...
2279
2280
2281
  	error = mnt_want_write(nd.path.mnt);
  	if (error)
  		goto out_dput;
be6d3e56a   Kentaro Takeda   introduce new LSM...
2282
2283
2284
  	error = security_path_symlink(&nd.path, dentry, from);
  	if (error)
  		goto out_drop_write;
db2e747b1   Miklos Szeredi   [patch 5/5] vfs: ...
2285
  	error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
be6d3e56a   Kentaro Takeda   introduce new LSM...
2286
  out_drop_write:
75c3f29de   Dave Hansen   [PATCH] r/o bind ...
2287
2288
  	mnt_drop_write(nd.path.mnt);
  out_dput:
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2289
2290
  	dput(dentry);
  out_unlock:
4ac913785   Jan Blunck   Embed a struct pa...
2291
  	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
1d957f9bf   Jan Blunck   Introduce path_put()
2292
  	path_put(&nd.path);
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2293
2294
  	putname(to);
  out_putname:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2295
2296
2297
  	putname(from);
  	return error;
  }
3480b2574   Heiko Carstens   [CVE-2009-0029] S...
2298
  SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newname)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2299
2300
2301
  {
  	return sys_symlinkat(oldname, AT_FDCWD, newname);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2302
2303
2304
2305
2306
2307
2308
  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: ...
2309
  	error = may_create(dir, new_dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
  	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...
2321
  	if (!dir->i_op->link)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2322
  		return -EPERM;
7e79eedb3   Tetsuo Handa   [patch 4/5] vfs: ...
2323
  	if (S_ISDIR(inode->i_mode))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2324
2325
2326
2327
2328
  		return -EPERM;
  
  	error = security_inode_link(old_dentry, dir, new_dentry);
  	if (error)
  		return error;
7e79eedb3   Tetsuo Handa   [patch 4/5] vfs: ...
2329
  	mutex_lock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2330
  	error = dir->i_op->link(old_dentry, dir, new_dentry);
7e79eedb3   Tetsuo Handa   [patch 4/5] vfs: ...
2331
  	mutex_unlock(&inode->i_mutex);
e31e14ec3   Stephen Smalley   [PATCH] remove th...
2332
  	if (!error)
7e79eedb3   Tetsuo Handa   [patch 4/5] vfs: ...
2333
  		fsnotify_link(dir, inode, new_dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
  	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...
2346
2347
  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
2348
2349
  {
  	struct dentry *new_dentry;
2d8f30380   Al Viro   [PATCH] sanitize ...
2350
2351
  	struct nameidata nd;
  	struct path old_path;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2352
  	int error;
2ad94ae65   Al Viro   [PATCH] new (loca...
2353
  	char *to;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2354

45c9b11a1   Ulrich Drepper   [PATCH] Implement...
2355
  	if ((flags & ~AT_SYMLINK_FOLLOW) != 0)
c04030e16   Ulrich Drepper   [PATCH] flags par...
2356
  		return -EINVAL;
2d8f30380   Al Viro   [PATCH] sanitize ...
2357
2358
2359
  	error = user_path_at(olddfd, oldname,
  			     flags & AT_SYMLINK_FOLLOW ? LOOKUP_FOLLOW : 0,
  			     &old_path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2360
  	if (error)
2ad94ae65   Al Viro   [PATCH] new (loca...
2361
2362
2363
  		return error;
  
  	error = user_path_parent(newdfd, newname, &nd, &to);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2364
2365
2366
  	if (error)
  		goto out;
  	error = -EXDEV;
2d8f30380   Al Viro   [PATCH] sanitize ...
2367
  	if (old_path.mnt != nd.path.mnt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2368
2369
2370
  		goto out_release;
  	new_dentry = lookup_create(&nd, 0);
  	error = PTR_ERR(new_dentry);
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2371
2372
  	if (IS_ERR(new_dentry))
  		goto out_unlock;
75c3f29de   Dave Hansen   [PATCH] r/o bind ...
2373
2374
2375
  	error = mnt_want_write(nd.path.mnt);
  	if (error)
  		goto out_dput;
be6d3e56a   Kentaro Takeda   introduce new LSM...
2376
2377
2378
  	error = security_path_link(old_path.dentry, &nd.path, new_dentry);
  	if (error)
  		goto out_drop_write;
2d8f30380   Al Viro   [PATCH] sanitize ...
2379
  	error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
be6d3e56a   Kentaro Takeda   introduce new LSM...
2380
  out_drop_write:
75c3f29de   Dave Hansen   [PATCH] r/o bind ...
2381
2382
  	mnt_drop_write(nd.path.mnt);
  out_dput:
6902d925d   Dave Hansen   [PATCH] r/o bind ...
2383
2384
  	dput(new_dentry);
  out_unlock:
4ac913785   Jan Blunck   Embed a struct pa...
2385
  	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2386
  out_release:
1d957f9bf   Jan Blunck   Introduce path_put()
2387
  	path_put(&nd.path);
2ad94ae65   Al Viro   [PATCH] new (loca...
2388
  	putname(to);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2389
  out:
2d8f30380   Al Viro   [PATCH] sanitize ...
2390
  	path_put(&old_path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2391
2392
2393
  
  	return error;
  }
3480b2574   Heiko Carstens   [CVE-2009-0029] S...
2394
  SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2395
  {
c04030e16   Ulrich Drepper   [PATCH] flags par...
2396
  	return sys_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2397
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2398
2399
2400
2401
2402
2403
2404
  /*
   * 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...
2405
   *	   sb->s_vfs_rename_mutex. We might be more accurate, but that's another
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2406
2407
   *	   story.
   *	c) we have to lock _three_ objects - parents and victim (if it exists).
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2408
   *	   And that - after we got ->i_mutex on parents (until then we don't know
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2409
2410
   *	   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...
2411
   *	   only under ->s_vfs_rename_mutex _and_ that parent of the object we
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2412
2413
2414
   *	   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...
2415
   *	   lock child" and rename is under ->s_vfs_rename_mutex.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2416
2417
2418
2419
2420
2421
2422
2423
2424
   *	   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.
   *	d) some filesystems don't support opened-but-unlinked directories,
   *	   either because of layout or because they are not ready to deal with
   *	   all cases correctly. The latter will be fixed (taking this sort of
   *	   stuff into VFS), but the former is not going away. Solution: the same
   *	   trick as in rmdir().
   *	e) conversion from fhandle to dentry may come in the wrong moment - when
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2425
   *	   we are removing the target. Solution: we will have to grab ->i_mutex
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2426
   *	   in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on
c41b20e72   Adam Buchbinder   Fix misspellings ...
2427
   *	   ->i_mutex on parents, which works but leads to some truly excessive
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2428
2429
   *	   locking].
   */
75c96f858   Adrian Bunk   [PATCH] make some...
2430
2431
  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
2432
2433
2434
2435
2436
2437
2438
2439
2440
  {
  	int error = 0;
  	struct inode *target;
  
  	/*
  	 * 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...
2441
  		error = inode_permission(old_dentry->d_inode, MAY_WRITE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2442
2443
2444
2445
2446
2447
2448
2449
2450
  		if (error)
  			return error;
  	}
  
  	error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry);
  	if (error)
  		return error;
  
  	target = new_dentry->d_inode;
d83c49f3e   Al Viro   Fix the regressio...
2451
  	if (target)
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2452
  		mutex_lock(&target->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2453
2454
  	if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
  		error = -EBUSY;
d83c49f3e   Al Viro   Fix the regressio...
2455
2456
2457
  	else {
  		if (target)
  			dentry_unhash(new_dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2458
  		error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
d83c49f3e   Al Viro   Fix the regressio...
2459
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2460
  	if (target) {
d83c49f3e   Al Viro   Fix the regressio...
2461
  		if (!error) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2462
  			target->i_flags |= S_DEAD;
d83c49f3e   Al Viro   Fix the regressio...
2463
2464
  			dont_mount(new_dentry);
  		}
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2465
  		mutex_unlock(&target->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2466
2467
2468
2469
  		if (d_unhashed(new_dentry))
  			d_rehash(new_dentry);
  		dput(new_dentry);
  	}
e31e14ec3   Stephen Smalley   [PATCH] remove th...
2470
  	if (!error)
349457ccf   Mark Fasheh   [PATCH] Allow fil...
2471
2472
  		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
2473
2474
  	return error;
  }
75c96f858   Adrian Bunk   [PATCH] make some...
2475
2476
  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
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
  {
  	struct inode *target;
  	int error;
  
  	error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry);
  	if (error)
  		return error;
  
  	dget(new_dentry);
  	target = new_dentry->d_inode;
  	if (target)
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2488
  		mutex_lock(&target->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2489
2490
2491
2492
2493
  	if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
  		error = -EBUSY;
  	else
  		error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
  	if (!error) {
bec1052e5   Al Viro   set S_DEAD on unl...
2494
  		if (target)
d83c49f3e   Al Viro   Fix the regressio...
2495
  			dont_mount(new_dentry);
349457ccf   Mark Fasheh   [PATCH] Allow fil...
2496
  		if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2497
  			d_move(old_dentry, new_dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2498
2499
  	}
  	if (target)
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
2500
  		mutex_unlock(&target->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2501
2502
2503
2504
2505
2506
2507
2508
2509
  	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...
2510
  	const unsigned char *old_name;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2511
2512
2513
2514
2515
2516
2517
2518
2519
  
  	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: ...
2520
  		error = may_create(new_dir, new_dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2521
2522
2523
2524
  	else
  		error = may_delete(new_dir, new_dentry, is_dir);
  	if (error)
  		return error;
acfa4380e   Al Viro   inode->i_op is ne...
2525
  	if (!old_dir->i_op->rename)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2526
  		return -EPERM;
0eeca2830   Robert Love   [PATCH] inotify
2527
  	old_name = fsnotify_oldname_init(old_dentry->d_name.name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2528
2529
2530
2531
  	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...
2532
2533
  	if (!error)
  		fsnotify_move(old_dir, new_dir, old_name, is_dir,
5a190ae69   Al Viro   [PATCH] pass dent...
2534
  			      new_dentry->d_inode, old_dentry);
0eeca2830   Robert Love   [PATCH] inotify
2535
  	fsnotify_oldname_free(old_name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2536
2537
  	return error;
  }
2e4d0924e   Heiko Carstens   [CVE-2009-0029] S...
2538
2539
  SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
  		int, newdfd, const char __user *, newname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2540
  {
2ad94ae65   Al Viro   [PATCH] new (loca...
2541
2542
2543
  	struct dentry *old_dir, *new_dir;
  	struct dentry *old_dentry, *new_dentry;
  	struct dentry *trap;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2544
  	struct nameidata oldnd, newnd;
2ad94ae65   Al Viro   [PATCH] new (loca...
2545
2546
2547
  	char *from;
  	char *to;
  	int error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2548

2ad94ae65   Al Viro   [PATCH] new (loca...
2549
  	error = user_path_parent(olddfd, oldname, &oldnd, &from);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2550
2551
  	if (error)
  		goto exit;
2ad94ae65   Al Viro   [PATCH] new (loca...
2552
  	error = user_path_parent(newdfd, newname, &newnd, &to);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2553
2554
2555
2556
  	if (error)
  		goto exit1;
  
  	error = -EXDEV;
4ac913785   Jan Blunck   Embed a struct pa...
2557
  	if (oldnd.path.mnt != newnd.path.mnt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2558
  		goto exit2;
4ac913785   Jan Blunck   Embed a struct pa...
2559
  	old_dir = oldnd.path.dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2560
2561
2562
  	error = -EBUSY;
  	if (oldnd.last_type != LAST_NORM)
  		goto exit2;
4ac913785   Jan Blunck   Embed a struct pa...
2563
  	new_dir = newnd.path.dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2564
2565
  	if (newnd.last_type != LAST_NORM)
  		goto exit2;
0612d9fb2   OGAWA Hirofumi   [PATCH vfs-2.6 5/...
2566
2567
  	oldnd.flags &= ~LOOKUP_PARENT;
  	newnd.flags &= ~LOOKUP_PARENT;
4e9ed2f85   OGAWA Hirofumi   [PATCH vfs-2.6 6/...
2568
  	newnd.flags |= LOOKUP_RENAME_TARGET;
0612d9fb2   OGAWA Hirofumi   [PATCH vfs-2.6 5/...
2569

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2570
  	trap = lock_rename(new_dir, old_dir);
49705b774   Christoph Hellwig   [PATCH] sanitize ...
2571
  	old_dentry = lookup_hash(&oldnd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
  	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 ...
2591
  	new_dentry = lookup_hash(&newnd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2592
2593
2594
2595
2596
2597
2598
  	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 ...
2599
2600
2601
  	error = mnt_want_write(oldnd.path.mnt);
  	if (error)
  		goto exit5;
be6d3e56a   Kentaro Takeda   introduce new LSM...
2602
2603
2604
2605
  	error = security_path_rename(&oldnd.path, old_dentry,
  				     &newnd.path, new_dentry);
  	if (error)
  		goto exit6;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2606
2607
  	error = vfs_rename(old_dir->d_inode, old_dentry,
  				   new_dir->d_inode, new_dentry);
be6d3e56a   Kentaro Takeda   introduce new LSM...
2608
  exit6:
9079b1eb1   Dave Hansen   [PATCH] r/o bind ...
2609
  	mnt_drop_write(oldnd.path.mnt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2610
2611
2612
2613
2614
2615
2616
  exit5:
  	dput(new_dentry);
  exit4:
  	dput(old_dentry);
  exit3:
  	unlock_rename(new_dir, old_dir);
  exit2:
1d957f9bf   Jan Blunck   Introduce path_put()
2617
  	path_put(&newnd.path);
2ad94ae65   Al Viro   [PATCH] new (loca...
2618
  	putname(to);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2619
  exit1:
1d957f9bf   Jan Blunck   Introduce path_put()
2620
  	path_put(&oldnd.path);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2621
  	putname(from);
2ad94ae65   Al Viro   [PATCH] new (loca...
2622
  exit:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2623
2624
  	return error;
  }
a26eab240   Heiko Carstens   [CVE-2009-0029] S...
2625
  SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newname)
5590ff0d5   Ulrich Drepper   [PATCH] vfs: *at ...
2626
2627
2628
  {
  	return sys_renameat(AT_FDCWD, oldname, AT_FDCWD, newname);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
  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...
2654
  	void *cookie;
694a1764d   Marcin Slusarz   [patch 3/4] vfs: ...
2655
  	int res;
cc314eef0   Linus Torvalds   Fix nasty ncpfs s...
2656

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2657
  	nd.depth = 0;
cc314eef0   Linus Torvalds   Fix nasty ncpfs s...
2658
  	cookie = dentry->d_inode->i_op->follow_link(dentry, &nd);
694a1764d   Marcin Slusarz   [patch 3/4] vfs: ...
2659
2660
2661
2662
2663
2664
2665
  	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
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
  }
  
  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 ...
2676
2677
  	char *kaddr;
  	struct page *page;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2678
  	struct address_space *mapping = dentry->d_inode->i_mapping;
090d2b185   Pekka Enberg   [PATCH] read_mapp...
2679
  	page = read_mapping_page(mapping, 0, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2680
  	if (IS_ERR(page))
6fe6900e1   Nick Piggin   mm: make read_cac...
2681
  		return (char*)page;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2682
  	*ppage = page;
ebd09abbd   Duane Griffin   vfs: ensure page ...
2683
2684
2685
  	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
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
  }
  
  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...
2699
  void *page_follow_link_light(struct dentry *dentry, struct nameidata *nd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2700
  {
cc314eef0   Linus Torvalds   Fix nasty ncpfs s...
2701
  	struct page *page = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2702
  	nd_set_link(nd, page_getlink(dentry, &page));
cc314eef0   Linus Torvalds   Fix nasty ncpfs s...
2703
  	return page;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2704
  }
cc314eef0   Linus Torvalds   Fix nasty ncpfs s...
2705
  void page_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2706
  {
cc314eef0   Linus Torvalds   Fix nasty ncpfs s...
2707
2708
2709
  	struct page *page = cookie;
  
  	if (page) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2710
2711
  		kunmap(page);
  		page_cache_release(page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2712
2713
  	}
  }
54566b2c1   Nick Piggin   fs: symlink write...
2714
2715
2716
2717
  /*
   * 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
2718
2719
  {
  	struct address_space *mapping = inode->i_mapping;
0adb25d2e   Kirill Korotaev   [PATCH] ext3: ext...
2720
  	struct page *page;
afddba49d   Nick Piggin   fs: introduce wri...
2721
  	void *fsdata;
beb497ab4   Dmitriy Monakhov   [PATCH] __page_sy...
2722
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2723
  	char *kaddr;
54566b2c1   Nick Piggin   fs: symlink write...
2724
2725
2726
  	unsigned int flags = AOP_FLAG_UNINTERRUPTIBLE;
  	if (nofs)
  		flags |= AOP_FLAG_NOFS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2727

7e53cac41   NeilBrown   [PATCH] Honour AO...
2728
  retry:
afddba49d   Nick Piggin   fs: introduce wri...
2729
  	err = pagecache_write_begin(NULL, mapping, 0, len-1,
54566b2c1   Nick Piggin   fs: symlink write...
2730
  				flags, &page, &fsdata);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2731
  	if (err)
afddba49d   Nick Piggin   fs: introduce wri...
2732
  		goto fail;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2733
2734
2735
  	kaddr = kmap_atomic(page, KM_USER0);
  	memcpy(kaddr, symname, len-1);
  	kunmap_atomic(kaddr, KM_USER0);
afddba49d   Nick Piggin   fs: introduce wri...
2736
2737
2738
  
  	err = pagecache_write_end(NULL, mapping, 0, len-1, len-1,
  							page, fsdata);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2739
2740
  	if (err < 0)
  		goto fail;
afddba49d   Nick Piggin   fs: introduce wri...
2741
2742
  	if (err < len-1)
  		goto retry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2743
2744
  	mark_inode_dirty(inode);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2745
2746
2747
  fail:
  	return err;
  }
0adb25d2e   Kirill Korotaev   [PATCH] ext3: ext...
2748
2749
2750
  int page_symlink(struct inode *inode, const char *symname, int len)
  {
  	return __page_symlink(inode, symname, len,
54566b2c1   Nick Piggin   fs: symlink write...
2751
  			!(mapping_gfp_mask(inode->i_mapping) & __GFP_FS));
0adb25d2e   Kirill Korotaev   [PATCH] ext3: ext...
2752
  }
92e1d5be9   Arjan van de Ven   [PATCH] mark stru...
2753
  const struct inode_operations page_symlink_inode_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2754
2755
2756
2757
  	.readlink	= generic_readlink,
  	.follow_link	= page_follow_link_light,
  	.put_link	= page_put_link,
  };
2d8f30380   Al Viro   [PATCH] sanitize ...
2758
  EXPORT_SYMBOL(user_path_at);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2759
2760
2761
2762
2763
  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
2764
2765
2766
2767
  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...
2768
  EXPORT_SYMBOL(__page_symlink);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2769
2770
2771
  EXPORT_SYMBOL(page_symlink);
  EXPORT_SYMBOL(page_symlink_inode_operations);
  EXPORT_SYMBOL(path_lookup);
d18114657   Al Viro   [PATCH] new helpe...
2772
  EXPORT_SYMBOL(kern_path);
16f182002   Josef 'Jeff' Sipek   fs: introduce vfs...
2773
  EXPORT_SYMBOL(vfs_path_lookup);
f419a2e3b   Al Viro   [PATCH] kill name...
2774
  EXPORT_SYMBOL(inode_permission);
8c744fb83   Christoph Hellwig   [PATCH] add a fil...
2775
  EXPORT_SYMBOL(file_permission);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
  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);