File: /usr/src/linux/fs/open.c

1     /*
2      *  linux/fs/open.c
3      *
4      *  Copyright (C) 1991, 1992  Linus Torvalds
5      */
6     
7     #include <linux/string.h>
8     #include <linux/mm.h>
9     #include <linux/utime.h>
10     #include <linux/file.h>
11     #include <linux/smp_lock.h>
12     #include <linux/quotaops.h>
13     #include <linux/dnotify.h>
14     #include <linux/module.h>
15     #include <linux/slab.h>
16     #include <linux/tty.h>
17     #include <linux/iobuf.h>
18     
19     #include <asm/uaccess.h>
20     
21     #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
22     
23     int vfs_statfs(struct super_block *sb, struct statfs *buf)
24     {
25     	int retval = -ENODEV;
26     
27     	if (sb) {
28     		retval = -ENOSYS;
29     		if (sb->s_op && sb->s_op->statfs) {
30     			memset(buf, 0, sizeof(struct statfs));
31     			lock_kernel();
32     			retval = sb->s_op->statfs(sb, buf);
33     			unlock_kernel();
34     		}
35     	}
36     	return retval;
37     }
38     
39     
40     asmlinkage long sys_statfs(const char * path, struct statfs * buf)
41     {
42     	struct nameidata nd;
43     	int error;
44     
45     	error = user_path_walk(path, &nd);
46     	if (!error) {
47     		struct statfs tmp;
48     		error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp);
49     		if (!error && copy_to_user(buf, &tmp, sizeof(struct statfs)))
50     			error = -EFAULT;
51     		path_release(&nd);
52     	}
53     	return error;
54     }
55     
56     asmlinkage long sys_fstatfs(unsigned int fd, struct statfs * buf)
57     {
58     	struct file * file;
59     	struct statfs tmp;
60     	int error;
61     
62     	error = -EBADF;
63     	file = fget(fd);
64     	if (!file)
65     		goto out;
66     	error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp);
67     	if (!error && copy_to_user(buf, &tmp, sizeof(struct statfs)))
68     		error = -EFAULT;
69     	fput(file);
70     out:
71     	return error;
72     }
73     
74     int do_truncate(struct dentry *dentry, loff_t length)
75     {
76     	struct inode *inode = dentry->d_inode;
77     	int error;
78     	struct iattr newattrs;
79     
80     	/* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */
81     	if (length < 0)
82     		return -EINVAL;
83     
84     	down(&inode->i_sem);
85     	newattrs.ia_size = length;
86     	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
87     	error = notify_change(dentry, &newattrs);
88     	up(&inode->i_sem);
89     	return error;
90     }
91     
92     static inline long do_sys_truncate(const char * path, loff_t length)
93     {
94     	struct nameidata nd;
95     	struct inode * inode;
96     	int error;
97     
98     	error = -EINVAL;
99     	if (length < 0)	/* sorry, but loff_t says... */
100     		goto out;
101     
102     	error = user_path_walk(path, &nd);
103     	if (error)
104     		goto out;
105     	inode = nd.dentry->d_inode;
106     
107     	error = -EACCES;
108     	if (!S_ISREG(inode->i_mode))
109     		goto dput_and_out;
110     
111     	error = permission(inode,MAY_WRITE);
112     	if (error)
113     		goto dput_and_out;
114     
115     	error = -EROFS;
116     	if (IS_RDONLY(inode))
117     		goto dput_and_out;
118     
119     	error = -EPERM;
120     	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
121     		goto dput_and_out;
122     
123     	/*
124     	 * Make sure that there are no leases.
125     	 */
126     	error = get_lease(inode, FMODE_WRITE);
127     	if (error)
128     		goto dput_and_out;
129     
130     	error = get_write_access(inode);
131     	if (error)
132     		goto dput_and_out;
133     
134     	error = locks_verify_truncate(inode, NULL, length);
135     	if (!error) {
136     		DQUOT_INIT(inode);
137     		error = do_truncate(nd.dentry, length);
138     	}
139     	put_write_access(inode);
140     
141     dput_and_out:
142     	path_release(&nd);
143     out:
144     	return error;
145     }
146     
147     asmlinkage long sys_truncate(const char * path, unsigned long length)
148     {
149     	return do_sys_truncate(path, length);
150     }
151     
152     static inline long do_sys_ftruncate(unsigned int fd, loff_t length)
153     {
154     	struct inode * inode;
155     	struct dentry *dentry;
156     	struct file * file;
157     	int error;
158     
159     	error = -EINVAL;
160     	if (length < 0)
161     		goto out;
162     	error = -EBADF;
163     	file = fget(fd);
164     	if (!file)
165     		goto out;
166     	dentry = file->f_dentry;
167     	inode = dentry->d_inode;
168     	error = -EACCES;
169     	if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
170     		goto out_putf;
171     	error = -EPERM;
172     	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
173     		goto out_putf;
174     
175     	error = locks_verify_truncate(inode, file, length);
176     	if (!error)
177     		error = do_truncate(dentry, length);
178     out_putf:
179     	fput(file);
180     out:
181     	return error;
182     }
183     
184     asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length)
185     {
186     	return do_sys_ftruncate(fd, length);
187     }
188     
189     /* LFS versions of truncate are only needed on 32 bit machines */
190     #if BITS_PER_LONG == 32
191     asmlinkage long sys_truncate64(const char * path, loff_t length)
192     {
193     	return do_sys_truncate(path, length);
194     }
195     
196     asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length)
197     {
198     	return do_sys_ftruncate(fd, length);
199     }
200     #endif
201     
202     #if !(defined(__alpha__) || defined(__ia64__))
203     
204     /*
205      * sys_utime() can be implemented in user-level using sys_utimes().
206      * Is this for backwards compatibility?  If so, why not move it
207      * into the appropriate arch directory (for those architectures that
208      * need it).
209      */
210     
211     /* If times==NULL, set access and modification to current time,
212      * must be owner or have write permission.
213      * Else, update from *times, must be owner or super user.
214      */
215     asmlinkage long sys_utime(char * filename, struct utimbuf * times)
216     {
217     	int error;
218     	struct nameidata nd;
219     	struct inode * inode;
220     	struct iattr newattrs;
221     
222     	error = user_path_walk(filename, &nd);
223     	if (error)
224     		goto out;
225     	inode = nd.dentry->d_inode;
226     
227     	error = -EROFS;
228     	if (IS_RDONLY(inode))
229     		goto dput_and_out;
230     
231     	/* Don't worry, the checks are done in inode_change_ok() */
232     	newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
233     	if (times) {
234     		error = get_user(newattrs.ia_atime, &times->actime);
235     		if (!error) 
236     			error = get_user(newattrs.ia_mtime, &times->modtime);
237     		if (error)
238     			goto dput_and_out;
239     
240     		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
241     	} else {
242     		if (current->fsuid != inode->i_uid &&
243     		    (error = permission(inode,MAY_WRITE)) != 0)
244     			goto dput_and_out;
245     	}
246     	error = notify_change(nd.dentry, &newattrs);
247     dput_and_out:
248     	path_release(&nd);
249     out:
250     	return error;
251     }
252     
253     #endif
254     
255     /* If times==NULL, set access and modification to current time,
256      * must be owner or have write permission.
257      * Else, update from *times, must be owner or super user.
258      */
259     asmlinkage long sys_utimes(char * filename, struct timeval * utimes)
260     {
261     	int error;
262     	struct nameidata nd;
263     	struct inode * inode;
264     	struct iattr newattrs;
265     
266     	error = user_path_walk(filename, &nd);
267     
268     	if (error)
269     		goto out;
270     	inode = nd.dentry->d_inode;
271     
272     	error = -EROFS;
273     	if (IS_RDONLY(inode))
274     		goto dput_and_out;
275     
276     	/* Don't worry, the checks are done in inode_change_ok() */
277     	newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
278     	if (utimes) {
279     		struct timeval times[2];
280     		error = -EFAULT;
281     		if (copy_from_user(&times, utimes, sizeof(times)))
282     			goto dput_and_out;
283     		newattrs.ia_atime = times[0].tv_sec;
284     		newattrs.ia_mtime = times[1].tv_sec;
285     		newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
286     	} else {
287     		if ((error = permission(inode,MAY_WRITE)) != 0)
288     			goto dput_and_out;
289     	}
290     	error = notify_change(nd.dentry, &newattrs);
291     dput_and_out:
292     	path_release(&nd);
293     out:
294     	return error;
295     }
296     
297     /*
298      * access() needs to use the real uid/gid, not the effective uid/gid.
299      * We do this by temporarily clearing all FS-related capabilities and
300      * switching the fsuid/fsgid around to the real ones.
301      */
302     asmlinkage long sys_access(const char * filename, int mode)
303     {
304     	struct nameidata nd;
305     	int old_fsuid, old_fsgid;
306     	kernel_cap_t old_cap;
307     	int res;
308     
309     	if (mode & ~S_IRWXO)	/* where's F_OK, X_OK, W_OK, R_OK? */
310     		return -EINVAL;
311     
312     	old_fsuid = current->fsuid;
313     	old_fsgid = current->fsgid;
314     	old_cap = current->cap_effective;
315     
316     	current->fsuid = current->uid;
317     	current->fsgid = current->gid;
318     
319     	/* Clear the capabilities if we switch to a non-root user */
320     	if (current->uid)
321     		cap_clear(current->cap_effective);
322     	else
323     		current->cap_effective = current->cap_permitted;
324     
325     	res = user_path_walk(filename, &nd);
326     	if (!res) {
327     		res = permission(nd.dentry->d_inode, mode);
328     		/* SuS v2 requires we report a read only fs too */
329     		if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
330     		   && !special_file(nd.dentry->d_inode->i_mode))
331     			res = -EROFS;
332     		path_release(&nd);
333     	}
334     
335     	current->fsuid = old_fsuid;
336     	current->fsgid = old_fsgid;
337     	current->cap_effective = old_cap;
338     
339     	return res;
340     }
341     
342     asmlinkage long sys_chdir(const char * filename)
343     {
344     	int error;
345     	struct nameidata nd;
346     	char *name;
347     
348     	name = getname(filename);
349     	error = PTR_ERR(name);
350     	if (IS_ERR(name))
351     		goto out;
352     
353     	error = 0;
354     	if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
355     		error = path_walk(name, &nd);
356     	putname(name);
357     	if (error)
358     		goto out;
359     
360     	error = permission(nd.dentry->d_inode,MAY_EXEC);
361     	if (error)
362     		goto dput_and_out;
363     
364     	set_fs_pwd(current->fs, nd.mnt, nd.dentry);
365     
366     dput_and_out:
367     	path_release(&nd);
368     out:
369     	return error;
370     }
371     
372     asmlinkage long sys_fchdir(unsigned int fd)
373     {
374     	struct file *file;
375     	struct dentry *dentry;
376     	struct inode *inode;
377     	struct vfsmount *mnt;
378     	int error;
379     
380     	error = -EBADF;
381     	file = fget(fd);
382     	if (!file)
383     		goto out;
384     
385     	dentry = file->f_dentry;
386     	mnt = file->f_vfsmnt;
387     	inode = dentry->d_inode;
388     
389     	error = -ENOTDIR;
390     	if (!S_ISDIR(inode->i_mode))
391     		goto out_putf;
392     
393     	error = permission(inode, MAY_EXEC);
394     	if (!error)
395     		set_fs_pwd(current->fs, mnt, dentry);
396     out_putf:
397     	fput(file);
398     out:
399     	return error;
400     }
401     
402     asmlinkage long sys_chroot(const char * filename)
403     {
404     	int error;
405     	struct nameidata nd;
406     	char *name;
407     
408     	name = getname(filename);
409     	error = PTR_ERR(name);
410     	if (IS_ERR(name))
411     		goto out;
412     
413     	path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
414     		      LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
415     	error = path_walk(name, &nd);	
416     	putname(name);
417     	if (error)
418     		goto out;
419     
420     	error = permission(nd.dentry->d_inode,MAY_EXEC);
421     	if (error)
422     		goto dput_and_out;
423     
424     	error = -EPERM;
425     	if (!capable(CAP_SYS_CHROOT))
426     		goto dput_and_out;
427     
428     	set_fs_root(current->fs, nd.mnt, nd.dentry);
429     	set_fs_altroot();
430     	error = 0;
431     dput_and_out:
432     	path_release(&nd);
433     out:
434     	return error;
435     }
436     
437     asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
438     {
439     	struct inode * inode;
440     	struct dentry * dentry;
441     	struct file * file;
442     	int err = -EBADF;
443     	struct iattr newattrs;
444     
445     	file = fget(fd);
446     	if (!file)
447     		goto out;
448     
449     	dentry = file->f_dentry;
450     	inode = dentry->d_inode;
451     
452     	err = -EROFS;
453     	if (IS_RDONLY(inode))
454     		goto out_putf;
455     	err = -EPERM;
456     	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
457     		goto out_putf;
458     	if (mode == (mode_t) -1)
459     		mode = inode->i_mode;
460     	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
461     	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
462     	err = notify_change(dentry, &newattrs);
463     
464     out_putf:
465     	fput(file);
466     out:
467     	return err;
468     }
469     
470     asmlinkage long sys_chmod(const char * filename, mode_t mode)
471     {
472     	struct nameidata nd;
473     	struct inode * inode;
474     	int error;
475     	struct iattr newattrs;
476     
477     	error = user_path_walk(filename, &nd);
478     	if (error)
479     		goto out;
480     	inode = nd.dentry->d_inode;
481     
482     	error = -EROFS;
483     	if (IS_RDONLY(inode))
484     		goto dput_and_out;
485     
486     	error = -EPERM;
487     	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
488     		goto dput_and_out;
489     
490     	if (mode == (mode_t) -1)
491     		mode = inode->i_mode;
492     	newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
493     	newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
494     	error = notify_change(nd.dentry, &newattrs);
495     
496     dput_and_out:
497     	path_release(&nd);
498     out:
499     	return error;
500     }
501     
502     static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
503     {
504     	struct inode * inode;
505     	int error;
506     	struct iattr newattrs;
507     
508     	error = -ENOENT;
509     	if (!(inode = dentry->d_inode)) {
510     		printk("chown_common: NULL inode\n");
511     		goto out;
512     	}
513     	error = -EROFS;
514     	if (IS_RDONLY(inode))
515     		goto out;
516     	error = -EPERM;
517     	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
518     		goto out;
519     	if (user == (uid_t) -1)
520     		user = inode->i_uid;
521     	if (group == (gid_t) -1)
522     		group = inode->i_gid;
523     	newattrs.ia_mode = inode->i_mode;
524     	newattrs.ia_uid = user;
525     	newattrs.ia_gid = group;
526     	newattrs.ia_valid =  ATTR_UID | ATTR_GID | ATTR_CTIME;
527     	/*
528     	 * If the user or group of a non-directory has been changed by a
529     	 * non-root user, remove the setuid bit.
530     	 * 19981026	David C Niemi <niemi@tux.org>
531     	 *
532     	 * Changed this to apply to all users, including root, to avoid
533     	 * some races. This is the behavior we had in 2.0. The check for
534     	 * non-root was definitely wrong for 2.2 anyway, as it should
535     	 * have been using CAP_FSETID rather than fsuid -- 19990830 SD.
536     	 */
537     	if ((inode->i_mode & S_ISUID) == S_ISUID &&
538     		!S_ISDIR(inode->i_mode))
539     	{
540     		newattrs.ia_mode &= ~S_ISUID;
541     		newattrs.ia_valid |= ATTR_MODE;
542     	}
543     	/*
544     	 * Likewise, if the user or group of a non-directory has been changed
545     	 * by a non-root user, remove the setgid bit UNLESS there is no group
546     	 * execute bit (this would be a file marked for mandatory locking).
547     	 * 19981026	David C Niemi <niemi@tux.org>
548     	 *
549     	 * Removed the fsuid check (see the comment above) -- 19990830 SD.
550     	 */
551     	if (((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) 
552     		&& !S_ISDIR(inode->i_mode))
553     	{
554     		newattrs.ia_mode &= ~S_ISGID;
555     		newattrs.ia_valid |= ATTR_MODE;
556     	}
557     	error = DQUOT_TRANSFER(dentry, &newattrs);
558     out:
559     	return error;
560     }
561     
562     asmlinkage long sys_chown(const char * filename, uid_t user, gid_t group)
563     {
564     	struct nameidata nd;
565     	int error;
566     
567     	error = user_path_walk(filename, &nd);
568     	if (!error) {
569     		error = chown_common(nd.dentry, user, group);
570     		path_release(&nd);
571     	}
572     	return error;
573     }
574     
575     asmlinkage long sys_lchown(const char * filename, uid_t user, gid_t group)
576     {
577     	struct nameidata nd;
578     	int error;
579     
580     	error = user_path_walk_link(filename, &nd);
581     	if (!error) {
582     		error = chown_common(nd.dentry, user, group);
583     		path_release(&nd);
584     	}
585     	return error;
586     }
587     
588     
589     asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
590     {
591     	struct file * file;
592     	int error = -EBADF;
593     
594     	file = fget(fd);
595     	if (file) {
596     		error = chown_common(file->f_dentry, user, group);
597     		fput(file);
598     	}
599     	return error;
600     }
601     
602     /*
603      * Note that while the flag value (low two bits) for sys_open means:
604      *	00 - read-only
605      *	01 - write-only
606      *	10 - read-write
607      *	11 - special
608      * it is changed into
609      *	00 - no permissions needed
610      *	01 - read-permission
611      *	10 - write-permission
612      *	11 - read-write
613      * for the internal routines (ie open_namei()/follow_link() etc). 00 is
614      * used by symlinks.
615      */
616     struct file *filp_open(const char * filename, int flags, int mode)
617     {
618     	int namei_flags, error;
619     	struct nameidata nd;
620     
621     	namei_flags = flags;
622     	if ((namei_flags+1) & O_ACCMODE)
623     		namei_flags++;
624     	if (namei_flags & O_TRUNC)
625     		namei_flags |= 2;
626     
627     	error = open_namei(filename, namei_flags, mode, &nd);
628     	if (!error)
629     		return dentry_open(nd.dentry, nd.mnt, flags);
630     
631     	return ERR_PTR(error);
632     }
633     
634     struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
635     {
636     	struct file * f;
637     	struct inode *inode;
638     	static LIST_HEAD(kill_list);
639     	int error;
640     
641     	error = -ENFILE;
642     	f = get_empty_filp();
643     	if (!f)
644     		goto cleanup_dentry;
645     	f->f_flags = flags;
646     	f->f_mode = (flags+1) & O_ACCMODE;
647     	inode = dentry->d_inode;
648     	if (f->f_mode & FMODE_WRITE) {
649     		error = get_write_access(inode);
650     		if (error)
651     			goto cleanup_file;
652     	}
653     
654     	f->f_dentry = dentry;
655     	f->f_vfsmnt = mnt;
656     	f->f_pos = 0;
657     	f->f_reada = 0;
658     	f->f_op = fops_get(inode->i_fop);
659     	file_move(f, &inode->i_sb->s_files);
660     
661     	/* preallocate kiobuf for O_DIRECT */
662     	f->f_iobuf = NULL;
663     	f->f_iobuf_lock = 0;
664     	if (f->f_flags & O_DIRECT) {
665     		error = alloc_kiovec(1, &f->f_iobuf);
666     		if (error)
667     			goto cleanup_all;
668     	}
669     
670     	if (f->f_op && f->f_op->open) {
671     		error = f->f_op->open(inode,f);
672     		if (error)
673     			goto cleanup_all;
674     	}
675     	f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
676     
677     	return f;
678     
679     cleanup_all:
680     	if (f->f_iobuf)
681     		free_kiovec(1, &f->f_iobuf);
682     	fops_put(f->f_op);
683     	if (f->f_mode & FMODE_WRITE)
684     		put_write_access(inode);
685     	file_move(f, &kill_list); /* out of the way.. */
686     	f->f_dentry = NULL;
687     	f->f_vfsmnt = NULL;
688     cleanup_file:
689     	put_filp(f);
690     cleanup_dentry:
691     	dput(dentry);
692     	mntput(mnt);
693     	return ERR_PTR(error);
694     }
695     
696     /*
697      * Find an empty file descriptor entry, and mark it busy.
698      */
699     int get_unused_fd(void)
700     {
701     	struct files_struct * files = current->files;
702     	int fd, error;
703     
704       	error = -EMFILE;
705     	write_lock(&files->file_lock);
706     
707     repeat:
708      	fd = find_next_zero_bit(files->open_fds, 
709     				files->max_fdset, 
710     				files->next_fd);
711     
712     	/*
713     	 * N.B. For clone tasks sharing a files structure, this test
714     	 * will limit the total number of files that can be opened.
715     	 */
716     	if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
717     		goto out;
718     
719     	/* Do we need to expand the fdset array? */
720     	if (fd >= files->max_fdset) {
721     		error = expand_fdset(files, fd);
722     		if (!error) {
723     			error = -EMFILE;
724     			goto repeat;
725     		}
726     		goto out;
727     	}
728     	
729     	/* 
730     	 * Check whether we need to expand the fd array.
731     	 */
732     	if (fd >= files->max_fds) {
733     		error = expand_fd_array(files, fd);
734     		if (!error) {
735     			error = -EMFILE;
736     			goto repeat;
737     		}
738     		goto out;
739     	}
740     
741     	FD_SET(fd, files->open_fds);
742     	FD_CLR(fd, files->close_on_exec);
743     	files->next_fd = fd + 1;
744     #if 1
745     	/* Sanity check */
746     	if (files->fd[fd] != NULL) {
747     		printk("get_unused_fd: slot %d not NULL!\n", fd);
748     		files->fd[fd] = NULL;
749     	}
750     #endif
751     	error = fd;
752     
753     out:
754     	write_unlock(&files->file_lock);
755     	return error;
756     }
757     
758     asmlinkage long sys_open(const char * filename, int flags, int mode)
759     {
760     	char * tmp;
761     	int fd, error;
762     
763     #if BITS_PER_LONG != 32
764     	flags |= O_LARGEFILE;
765     #endif
766     	tmp = getname(filename);
767     	fd = PTR_ERR(tmp);
768     	if (!IS_ERR(tmp)) {
769     		fd = get_unused_fd();
770     		if (fd >= 0) {
771     			struct file *f = filp_open(tmp, flags, mode);
772     			error = PTR_ERR(f);
773     			if (IS_ERR(f))
774     				goto out_error;
775     			fd_install(fd, f);
776     		}
777     out:
778     		putname(tmp);
779     	}
780     	return fd;
781     
782     out_error:
783     	put_unused_fd(fd);
784     	fd = error;
785     	goto out;
786     }
787     
788     #ifndef __alpha__
789     
790     /*
791      * For backward compatibility?  Maybe this should be moved
792      * into arch/i386 instead?
793      */
794     asmlinkage long sys_creat(const char * pathname, int mode)
795     {
796     	return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
797     }
798     
799     #endif
800     
801     /*
802      * "id" is the POSIX thread ID. We use the
803      * files pointer for this..
804      */
805     int filp_close(struct file *filp, fl_owner_t id)
806     {
807     	int retval;
808     
809     	if (!file_count(filp)) {
810     		printk("VFS: Close: file count is 0\n");
811     		return 0;
812     	}
813     	retval = 0;
814     	if (filp->f_op && filp->f_op->flush) {
815     		lock_kernel();
816     		retval = filp->f_op->flush(filp);
817     		unlock_kernel();
818     	}
819     	fcntl_dirnotify(0, filp, 0);
820     	locks_remove_posix(filp, id);
821     	fput(filp);
822     	return retval;
823     }
824     
825     /*
826      * Careful here! We test whether the file pointer is NULL before
827      * releasing the fd. This ensures that one clone task can't release
828      * an fd while another clone is opening it.
829      */
830     asmlinkage long sys_close(unsigned int fd)
831     {
832     	struct file * filp;
833     	struct files_struct *files = current->files;
834     
835     	write_lock(&files->file_lock);
836     	if (fd >= files->max_fds)
837     		goto out_unlock;
838     	filp = files->fd[fd];
839     	if (!filp)
840     		goto out_unlock;
841     	files->fd[fd] = NULL;
842     	FD_CLR(fd, files->close_on_exec);
843     	__put_unused_fd(files, fd);
844     	write_unlock(&files->file_lock);
845     	return filp_close(filp, files);
846     
847     out_unlock:
848     	write_unlock(&files->file_lock);
849     	return -EBADF;
850     }
851     
852     /*
853      * This routine simulates a hangup on the tty, to arrange that users
854      * are given clean terminals at login time.
855      */
856     asmlinkage long sys_vhangup(void)
857     {
858     	if (capable(CAP_SYS_TTY_CONFIG)) {
859     		tty_vhangup(current->tty);
860     		return 0;
861     	}
862     	return -EPERM;
863     }
864     
865     /*
866      * Called when an inode is about to be open.
867      * We use this to disallow opening RW large files on 32bit systems if
868      * the caller didn't specify O_LARGEFILE.  On 64bit systems we force
869      * on this flag in sys_open.
870      */
871     int generic_file_open(struct inode * inode, struct file * filp)
872     {
873     	if (!(filp->f_flags & O_LARGEFILE) && inode->i_size > MAX_NON_LFS)
874     		return -EFBIG;
875     	return 0;
876     }
877     
878     EXPORT_SYMBOL(generic_file_open);
879