VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / fs / open.c
index 66a77f5..4bd34f4 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
 #include <asm/uaccess.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
+#include <linux/vs_base.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)
 {
@@ -38,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;
 }
@@ -335,7 +343,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().
@@ -676,14 +684,15 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
        error = -EPERM;
        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
                goto out;
+
        newattrs.ia_valid =  ATTR_CTIME;
        if (user != (uid_t) -1) {
                newattrs.ia_valid |= ATTR_UID;
-               newattrs.ia_uid = user;
+               newattrs.ia_uid = vx_map_uid(user);
        }
        if (group != (gid_t) -1) {
                newattrs.ia_valid |= ATTR_GID;
-               newattrs.ia_gid = group;
+               newattrs.ia_gid = vx_map_gid(group);
        }
        if (!S_ISDIR(inode->i_mode))
                newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
@@ -779,7 +788,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);
@@ -788,7 +797,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;
@@ -802,12 +810,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);
                }
        }
 
@@ -878,6 +887,7 @@ repeat:
        FD_SET(fd, files->open_fds);
        FD_CLR(fd, files->close_on_exec);
        files->next_fd = fd + 1;
+       // vx_openfd_inc(fd);
 #if 1
        /* Sanity check */
        if (files->fd[fd] != NULL) {
@@ -899,6 +909,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)
@@ -1068,3 +1079,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);