X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Ffcntl.c;h=3d9a948667445f7ee197dbbe17ddbeccd1bb2bd8;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=abad0aa00d13d68984506683bbade3abec0169b6;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/fs/fcntl.c b/fs/fcntl.c index abad0aa00..3d9a94866 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -107,6 +108,8 @@ repeat: error = -EMFILE; if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur) goto out; + if (!vx_files_avail(1)) + goto out; error = expand_files(files, newfd); if (error < 0) @@ -139,6 +142,7 @@ static int dupfd(struct file *file, unsigned int start) FD_SET(fd, files->open_fds); FD_CLR(fd, files->close_on_exec); spin_unlock(&files->file_lock); + // vx_openfd_inc(fd); fd_install(fd, file); } else { spin_unlock(&files->file_lock); @@ -186,6 +190,7 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd) FD_SET(newfd, files->open_fds); FD_CLR(newfd, files->close_on_exec); spin_unlock(&files->file_lock); + // vx_openfd_inc(newfd); if (tofree) filp_close(tofree, files); @@ -212,7 +217,7 @@ asmlinkage long sys_dup(unsigned int fildes) return ret; } -#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC | O_DIRECT) +#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | FASYNC | O_DIRECT | O_NOATIME) static int setfl(int fd, struct file * filp, unsigned long arg) { @@ -223,6 +228,11 @@ static int setfl(int fd, struct file * filp, unsigned long arg) if (!(arg & O_APPEND) && IS_APPEND(inode)) return -EPERM; + /* O_NOATIME can only be set by the owner or superuser */ + if ((arg & O_NOATIME) && !(filp->f_flags & O_NOATIME)) + if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER)) + return -EPERM; + /* required for strict SunOS emulation */ if (O_NONBLOCK != O_NDELAY) if (arg & O_NDELAY) @@ -234,6 +244,11 @@ static int setfl(int fd, struct file * filp, unsigned long arg) return -EINVAL; } + if (filp->f_op && filp->f_op->check_flags) + error = filp->f_op->check_flags(arg); + if (error) + return error; + lock_kernel(); if ((arg ^ filp->f_flags) & FASYNC) { if (filp->f_op && filp->f_op->fasync) { @@ -282,8 +297,8 @@ void f_delown(struct file *filp) EXPORT_SYMBOL(f_delown); -long generic_file_fcntl(int fd, unsigned int cmd, - unsigned long arg, struct file *filp) +static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, + struct file *filp) { long err = -EINVAL; @@ -351,15 +366,6 @@ long generic_file_fcntl(int fd, unsigned int cmd, } return err; } -EXPORT_SYMBOL(generic_file_fcntl); - -static long do_fcntl(int fd, unsigned int cmd, - unsigned long arg, struct file *filp) -{ - if (filp->f_op && filp->f_op->fcntl) - return filp->f_op->fcntl(fd, cmd, arg, filp); - return generic_file_fcntl(fd, cmd, arg, filp); -} asmlinkage long sys_fcntl(int fd, unsigned int cmd, unsigned long arg) { @@ -627,15 +633,12 @@ void kill_fasync(struct fasync_struct **fp, int sig, int band) read_unlock(&fasync_lock); } } - EXPORT_SYMBOL(kill_fasync); static int __init fasync_init(void) { fasync_cache = kmem_cache_create("fasync_cache", - sizeof(struct fasync_struct), 0, 0, NULL, NULL); - if (!fasync_cache) - panic("cannot create fasync slab cache"); + sizeof(struct fasync_struct), 0, SLAB_PANIC, NULL, NULL); return 0; }