X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fopen.c;h=e3dfda3bf6a8c9a8b2c2e023b17a8f04e7a0caa3;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=1ded0f7984a98fd2749b6fe8fe010321a63b0388;hpb=a8e794ca871505c8ea96cc102f4ad555c5231d7f;p=linux-2.6.git diff --git a/fs/open.c b/fs/open.c index 1ded0f798..e3dfda3bf 100644 --- a/fs/open.c +++ b/fs/open.c @@ -22,8 +22,13 @@ #include #include #include +#include +#include +#include #include +#include + int vfs_statfs(struct super_block *sb, struct kstatfs *buf) { int retval = -ENODEV; @@ -39,6 +44,8 @@ int vfs_statfs(struct super_block *sb, struct kstatfs *buf) if (retval == 0 && buf->f_frsize == 0) buf->f_frsize = buf->f_bsize; } + if (!vx_check(0, VX_ADMIN|VX_WATCH)) + vx_vsi_statfs(sb, buf); } return retval; } @@ -201,10 +208,9 @@ int do_truncate(struct dentry *dentry, loff_t length) newattrs.ia_size = length; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; + down(&dentry->d_inode->i_sem); - down_write(&dentry->d_inode->i_alloc_sem); err = notify_change(dentry, &newattrs); - up_write(&dentry->d_inode->i_alloc_sem); up(&dentry->d_inode->i_sem); return err; } @@ -336,7 +342,7 @@ asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length) } #endif -#if !(defined(__alpha__) || defined(__ia64__)) +#ifdef __ARCH_WANT_SYS_UTIME /* * sys_utime() can be implemented in user-level using sys_utimes(). @@ -606,9 +612,6 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) dentry = file->f_dentry; inode = dentry->d_inode; - err = -EPERM; - if (IS_BARRIER(inode) && !vx_check(0, VX_ADMIN)) - goto out_putf; err = -EROFS; if (IS_RDONLY(inode)) goto out_putf; @@ -641,10 +644,6 @@ asmlinkage long sys_chmod(const char __user * filename, mode_t mode) goto out; inode = nd.dentry->d_inode; - error = -EPERM; - if (IS_BARRIER(inode) && !vx_check(0, VX_ADMIN)) - goto dput_and_out; - error = -EROFS; if (IS_RDONLY(inode)) goto dput_and_out; @@ -788,7 +787,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) if (!f) goto cleanup_dentry; f->f_flags = flags; - f->f_mode = (flags+1) & O_ACCMODE; + f->f_mode = ((flags+1) & O_ACCMODE) | FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE; inode = dentry->d_inode; if (f->f_mode & FMODE_WRITE) { error = get_write_access(inode); @@ -797,7 +796,6 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) } f->f_mapping = inode->i_mapping; - file_ra_state_init(&f->f_ra, f->f_mapping); f->f_dentry = dentry; f->f_vfsmnt = mnt; f->f_pos = 0; @@ -811,12 +809,13 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) } f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); + file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); + /* NB: we're sure to have correct a_ops only after f_op->open */ if (f->f_flags & O_DIRECT) { - if (!f->f_mapping || !f->f_mapping->a_ops || - !f->f_mapping->a_ops->direct_IO) { - fput(f); - f = ERR_PTR(-EINVAL); + if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO) { + fput(f); + f = ERR_PTR(-EINVAL); } } @@ -859,29 +858,21 @@ repeat: * N.B. For clone tasks sharing a files structure, this test * will limit the total number of files that can be opened. */ - if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur) + if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) goto out; - /* Do we need to expand the fdset array? */ - if (fd >= files->max_fdset) { - error = expand_fdset(files, fd); - if (!error) { - error = -EMFILE; - goto repeat; - } - goto out; - } - - /* - * Check whether we need to expand the fd array. - */ - if (fd >= files->max_fds) { - error = expand_fd_array(files, fd); - if (!error) { - error = -EMFILE; - goto repeat; - } + /* Do we need to expand the fd array or fd set? */ + error = expand_files(files, fd); + if (error < 0) goto out; + + if (error) { + /* + * If we needed to expand the fs array we + * might have blocked - try again. + */ + error = -EMFILE; + goto repeat; } FD_SET(fd, files->open_fds); @@ -909,6 +900,7 @@ static inline void __put_unused_fd(struct files_struct *files, unsigned int fd) __FD_CLR(fd, files->open_fds); if (fd < files->next_fd) files->next_fd = fd; + vx_openfd_dec(fd); } void fastcall put_unused_fd(unsigned int fd) @@ -1042,7 +1034,6 @@ asmlinkage long sys_close(unsigned int fd) FD_CLR(fd, files->close_on_exec); __put_unused_fd(files, fd); spin_unlock(&files->file_lock); - vx_openfd_dec(fd); return filp_close(filp, files); out_unlock: @@ -1079,3 +1070,15 @@ int generic_file_open(struct inode * inode, struct file * filp) } EXPORT_SYMBOL(generic_file_open); + +/* + * This is used by subsystems that don't want seekable + * file descriptors + */ +int nonseekable_open(struct inode *inode, struct file *filp) +{ + filp->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE); + return 0; +} + +EXPORT_SYMBOL(nonseekable_open);