*
* Virtual Server: File System Support
*
- * Copyright (C) 2004 Herbert Pötzl
+ * Copyright (C) 2004-2005 Herbert Pötzl
*
* V0.01 separated from vcontext V0.05
*
*/
-#include <linux/config.h>
#include <linux/sched.h>
#include <linux/vs_context.h>
-#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/devpts_fs.h>
#include <linux/namei.h>
#include <linux/mount.h>
#include <linux/parser.h>
+#include <linux/compat.h>
#include <linux/vserver/inode.h>
+#include <linux/vserver/inode_cmd.h>
#include <linux/vserver/xid.h>
#include <asm/errno.h>
case PROC_SUPER_MAGIC:
entry = PROC_I(in)->pde;
- // check for specific inodes ?
+ /* check for specific inodes? */
if (entry)
*mask |= IATTR_FLAGS;
if (entry)
&vc_data.xid, &vc_data.flags, &vc_data.mask);
path_release(&nd);
}
+ if (ret)
+ return ret;
if (copy_to_user (data, &vc_data, sizeof(vc_data)))
ret = -EFAULT;
return ret;
}
+#ifdef CONFIG_COMPAT
+
+int vc_get_iattr_x32(uint32_t id, void __user *data)
+{
+ struct nameidata nd;
+ struct vcmd_ctx_iattr_v1_x32 vc_data = { .xid = -1 };
+ int ret;
+
+ if (!vx_check(0, VX_ADMIN))
+ return -ENOSYS;
+ if (copy_from_user (&vc_data, data, sizeof(vc_data)))
+ return -EFAULT;
+
+ ret = user_path_walk_link(compat_ptr(vc_data.name_ptr), &nd);
+ if (!ret) {
+ ret = __vc_get_iattr(nd.dentry->d_inode,
+ &vc_data.xid, &vc_data.flags, &vc_data.mask);
+ path_release(&nd);
+ }
+ if (ret)
+ return ret;
+
+ if (copy_to_user (data, &vc_data, sizeof(vc_data)))
+ ret = -EFAULT;
+ return ret;
+}
+
+#endif /* CONFIG_COMPAT */
+
+
static int __vc_set_iattr(struct dentry *de, uint32_t *xid, uint32_t *flags, uint32_t *mask)
{
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;
return -EINVAL;
down(&in->i_sem);
- if (*mask & IATTR_XID)
- in->i_xid = *xid;
+ 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;
}
if (*mask & (IATTR_BARRIER | IATTR_IUNLINK | IATTR_IMMUTABLE)) {
- struct iattr attr;
- attr.ia_valid = ATTR_ATTR_FLAG;
+ attr.ia_valid |= ATTR_ATTR_FLAG;
attr.ia_attr_flags =
(IS_IMMUTABLE(in) ? ATTR_FLAG_IMMUTABLE : 0) |
(IS_IUNLINK(in) ? ATTR_FLAG_IUNLINK : 0) |
else
attr.ia_attr_flags &= ~ATTR_FLAG_BARRIER;
}
+ }
+
+ if (attr.ia_valid) {
if (in->i_op && in->i_op->setattr)
error = in->i_op->setattr(de, &attr);
else {
}
}
- mark_inode_dirty(in);
up(&in->i_sem);
return 0;
}
return ret;
}
+#ifdef CONFIG_COMPAT
+
+int vc_set_iattr_x32(uint32_t id, void __user *data)
+{
+ struct nameidata nd;
+ struct vcmd_ctx_iattr_v1_x32 vc_data;
+ int ret;
+
+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_LINUX_IMMUTABLE))
+ return -EPERM;
+ if (copy_from_user (&vc_data, data, sizeof(vc_data)))
+ return -EFAULT;
+
+ ret = user_path_walk_link(compat_ptr(vc_data.name_ptr), &nd);
+ if (!ret) {
+ ret = __vc_set_iattr(nd.dentry,
+ &vc_data.xid, &vc_data.flags, &vc_data.mask);
+ path_release(&nd);
+ }
+
+ if (copy_to_user (data, &vc_data, sizeof(vc_data)))
+ ret = -EFAULT;
+ return ret;
+}
+
+#endif /* CONFIG_COMPAT */
+
+/* required by PLK */
int vc_iattr_ioctl(struct dentry *de, unsigned int cmd, unsigned long arg)
{
void __user *data = (void __user *)arg;
return ret;
}
-
#ifdef CONFIG_VSERVER_LEGACY
#define PROC_DYNAMIC_FIRST 0xF0000000UL