From: Steve Muir <smuir@cs.princeton.edu>
Date: Thu, 18 Nov 2004 20:06:31 +0000 (+0000)
Subject: Need a way to manipulate vserver file attrs using a file descriptor
X-Git-Tag: before-enable-kexec-patch~12
X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=30f11a80b583e0a29ed545027a6f973f8cc96ba8;p=linux-2.6.git

Need a way to manipulate vserver file attrs using a file descriptor
---

diff --git a/fs/ioctl.c b/fs/ioctl.c
index 96a1b601e..6404b0c10 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -173,6 +173,19 @@ asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 				error = vx_proc_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
 			break;
 #endif
+		case FIOC_SETIATTR:
+		case FIOC_GETIATTR:
+			/*
+			 * Verify that this filp is a file object,
+			 * not (say) a socket.
+			 */
+			error = -ENOTTY;
+			if (S_ISREG(filp->f_dentry->d_inode->i_mode) ||
+			    S_ISDIR(filp->f_dentry->d_inode->i_mode))
+				error = vc_iattr_ioctl(filp->f_dentry,
+						       cmd, arg);
+			break;
+
 		default:
 			error = -ENOTTY;
 			if (S_ISREG(filp->f_dentry->d_inode->i_mode))
diff --git a/include/linux/vserver/inode.h b/include/linux/vserver/inode.h
index aa8852f43..e19632d08 100644
--- a/include/linux/vserver/inode.h
+++ b/include/linux/vserver/inode.h
@@ -39,7 +39,7 @@ struct  vcmd_ctx_iattr_v1 {
 #define IATTR_IMMUTABLE	0x00040000
 
 
-#ifdef	CONFIG_PROC_SECURE
+#ifdef	CONFIG_VSERVER_PROC_SECURE
 #define IATTR_PROC_DEFAULT	( IATTR_ADMIN | IATTR_HIDE )
 #define IATTR_PROC_SYMLINK	( IATTR_ADMIN )
 #else
@@ -57,6 +57,10 @@ extern int vc_set_iattr_v0(uint32_t, void __user *);
 extern int vc_get_iattr(uint32_t, void __user *);
 extern int vc_set_iattr(uint32_t, void __user *);
 
+extern int vc_iattr_ioctl(struct dentry *de,
+			  unsigned int cmd,
+			  unsigned long arg);
+
 #endif	/* __KERNEL__ */
 
 /* inode ioctls */
@@ -64,4 +68,7 @@ extern int vc_set_iattr(uint32_t, void __user *);
 #define FIOC_GETXFLG	_IOR('x', 5, long)
 #define FIOC_SETXFLG	_IOW('x', 6, long)
 
+#define FIOC_GETIATTR   _IOR('x', 7, long)
+#define FIOC_SETIATTR   _IOR('x', 8, long)
+
 #endif	/* _VX_INODE_H */
diff --git a/kernel/vserver/inode.c b/kernel/vserver/inode.c
index 87e2849f3..d28749b91 100644
--- a/kernel/vserver/inode.c
+++ b/kernel/vserver/inode.c
@@ -10,7 +10,8 @@
  */
 
 #include <linux/config.h>
-#include <linux/vinline.h>
+#include <linux/vs_base.h>
+#include <linux/vs_context.h>
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
 #include <linux/namei.h>
@@ -169,6 +170,37 @@ int vc_set_iattr(uint32_t id, void __user *data)
 	return ret;
 }
 
+int vc_iattr_ioctl(struct dentry *de, unsigned int cmd, unsigned long arg)
+{
+	void __user *data = (void __user *)arg;
+	struct vcmd_ctx_iattr_v1 vc_data;
+	int ret;
+
+	/*
+	 * I don't think we need any dget/dput pairs in here as long as
+	 * this function is always called from sys_ioctl i.e., the big
+	 * kernel lock is held.
+	 */
+	if (cmd == FIOC_SETIATTR) {
+		if (!capable(CAP_SYS_ADMIN) || !capable(CAP_LINUX_IMMUTABLE))
+			return -EPERM;
+		if (copy_from_user (&vc_data, data, sizeof(vc_data)))
+			return -EFAULT;
+		ret = __vc_set_iattr(de,
+			&vc_data.xid, &vc_data.flags, &vc_data.mask);
+	}
+	else {
+		if (!vx_check(0, VX_ADMIN))
+			return -ENOSYS;
+		ret = __vc_get_iattr(de->d_inode,
+			&vc_data.xid, &vc_data.flags, &vc_data.mask);
+	}
+
+	if (!ret && copy_to_user (data, &vc_data, sizeof(vc_data)))
+		ret = -EFAULT;
+	return ret;
+}
+
 
 #ifdef	CONFIG_VSERVER_LEGACY		
 #include <linux/proc_fs.h>