#include <asm/uaccess.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
+#include <linux/syscalls.h>
+#include <linux/vs_limit.h>
+#include <linux/vs_dlimit.h>
#include <linux/vserver/xid.h>
+#include <asm/unistd.h>
+
int vfs_statfs(struct super_block *sb, struct kstatfs *buf)
{
int retval = -ENODEV;
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;
}
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;
}
}
#endif
-#if !(defined(__alpha__) || defined(__ia64__))
+#ifdef __ARCH_WANT_SYS_UTIME
/*
* sys_utime() can be implemented in user-level using sys_utimes().
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;
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;
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);
}
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;
}
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);
}
}
* 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);
__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)
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:
}
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);