Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / kernel / vserver / inode.c
index dce77dd..39a26b7 100644 (file)
@@ -41,7 +41,7 @@ static int __vc_get_iattr(struct inode *in, uint32_t *xid, uint32_t *flags, uint
        if (S_ISDIR(in->i_mode))
                *mask |= IATTR_BARRIER;
 
-       if (in->i_sb->s_flags & MS_TAGXID) {
+       if (IS_TAGXID(in)) {
                *xid = in->i_xid;
                *mask |= IATTR_XID;
        }
@@ -50,7 +50,7 @@ static int __vc_get_iattr(struct inode *in, uint32_t *xid, uint32_t *flags, uint
        case PROC_SUPER_MAGIC:
                entry = PROC_I(in)->pde;
 
-               // check for specific inodes ?
+               /* check for specific inodes? */
                if (entry)
                        *mask |= IATTR_FLAGS;
                if (entry)
@@ -129,6 +129,7 @@ static int __vc_set_iattr(struct dentry *de, uint32_t *xid, uint32_t *flags, uin
 {
        struct inode *in = de->d_inode;
        int error = 0, is_proc = 0, has_xid = 0;
+       struct iattr attr = { 0 };
 
        if (!in || !in->i_sb)
                return -ESRCH;
@@ -137,14 +138,16 @@ static int __vc_set_iattr(struct dentry *de, uint32_t *xid, uint32_t *flags, uin
        if ((*mask & IATTR_FLAGS) && !is_proc)
                return -EINVAL;
 
-       has_xid = (in->i_sb->s_flags & MS_TAGXID) ||
+       has_xid = IS_TAGXID(in) ||
                (in->i_sb->s_magic == DEVPTS_SUPER_MAGIC);
        if ((*mask & IATTR_XID) && !has_xid)
                return -EINVAL;
 
-       down(&in->i_sem);
-       if (*mask & IATTR_XID)
-               in->i_xid = *xid;
+       mutex_lock(&in->i_mutex);
+       if (*mask & IATTR_XID) {
+               attr.ia_xid = *xid;
+               attr.ia_valid |= ATTR_XID;
+       }
 
        if (*mask & IATTR_FLAGS) {
                struct proc_dir_entry *entry = PROC_I(in)->pde;
@@ -158,32 +161,32 @@ static int __vc_set_iattr(struct dentry *de, uint32_t *xid, uint32_t *flags, uin
        }
 
        if (*mask & (IATTR_BARRIER | IATTR_IUNLINK | IATTR_IMMUTABLE)) {
-               struct iattr attr;
-
-               attr.ia_valid = ATTR_ATTR_FLAG;
-               attr.ia_attr_flags =
-                       (IS_IMMUTABLE(in) ? ATTR_FLAG_IMMUTABLE : 0) |
-                       (IS_IUNLINK(in) ? ATTR_FLAG_IUNLINK : 0) |
-                       (IS_BARRIER(in) ? ATTR_FLAG_BARRIER : 0);
-
                if (*mask & IATTR_IMMUTABLE) {
                        if (*flags & IATTR_IMMUTABLE)
-                               attr.ia_attr_flags |= ATTR_FLAG_IMMUTABLE;
+                               in->i_flags |= S_IMMUTABLE;
                        else
-                               attr.ia_attr_flags &= ~ATTR_FLAG_IMMUTABLE;
+                               in->i_flags &= ~S_IMMUTABLE;
                }
                if (*mask & IATTR_IUNLINK) {
                        if (*flags & IATTR_IUNLINK)
-                               attr.ia_attr_flags |= ATTR_FLAG_IUNLINK;
+                               in->i_flags |= S_IUNLINK;
                        else
-                               attr.ia_attr_flags &= ~ATTR_FLAG_IUNLINK;
+                               in->i_flags &= ~S_IUNLINK;
                }
                if (S_ISDIR(in->i_mode) && (*mask & IATTR_BARRIER)) {
                        if (*flags & IATTR_BARRIER)
-                               attr.ia_attr_flags |= ATTR_FLAG_BARRIER;
+                               in->i_flags |= S_BARRIER;
                        else
-                               attr.ia_attr_flags &= ~ATTR_FLAG_BARRIER;
+                               in->i_flags &= ~S_BARRIER;
+               }
+               if (in->i_op && in->i_op->sync_flags) {
+                       error = in->i_op->sync_flags(in);
+                       if (error)
+                               goto out;
                }
+       }
+
+       if (attr.ia_valid) {
                if (in->i_op && in->i_op->setattr)
                        error = in->i_op->setattr(de, &attr);
                else {
@@ -193,9 +196,9 @@ static int __vc_set_iattr(struct dentry *de, uint32_t *xid, uint32_t *flags, uin
                }
        }
 
-       mark_inode_dirty(in);
-       up(&in->i_sem);
-       return 0;
+out:
+       mutex_unlock(&in->i_mutex);
+       return error;
 }
 
 int vc_set_iattr(uint32_t id, void __user *data)
@@ -272,7 +275,7 @@ int vx_proc_ioctl(struct inode * inode, struct file * filp,
                error = -EPERM;
                flags = entry->vx_flags;
                if (capable(CAP_CONTEXT))
-                       error = put_user(flags, (int *) arg);
+                       error = put_user(flags, (int __user *) arg);
                break;
        }
        case FIOC_SETXFLG: {
@@ -284,7 +287,7 @@ int vx_proc_ioctl(struct inode * inode, struct file * filp,
                if (IS_RDONLY(inode))
                        break;
                error = -EFAULT;
-               if (get_user(flags, (int *) arg))
+               if (get_user(flags, (int __user *) arg))
                        break;
                error = 0;
                entry->vx_flags = flags;