X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Fvserver%2Finode.c;h=bb41a144b7835eb67601b96bdeaa1ff1cc084e7e;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=8be58829e5fb33090f5f5ccdd961ce6a78b7dea8;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/kernel/vserver/inode.c b/kernel/vserver/inode.c index 8be58829e..bb41a144b 100644 --- a/kernel/vserver/inode.c +++ b/kernel/vserver/inode.c @@ -3,19 +3,23 @@ * * 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 -#include +#include #include -#include #include +#include #include +#include +#include #include +#include +#include #include #include @@ -23,6 +27,8 @@ static int __vc_get_iattr(struct inode *in, uint32_t *xid, uint32_t *flags, uint32_t *mask) { + struct proc_dir_entry *entry; + if (!in || !in->i_sb) return -ESRCH; @@ -40,8 +46,9 @@ static int __vc_get_iattr(struct inode *in, uint32_t *xid, uint32_t *flags, uint *mask |= IATTR_XID; } - if (in->i_sb->s_magic == PROC_SUPER_MAGIC) { - struct proc_dir_entry *entry = PROC_I(in)->pde; + switch (in->i_sb->s_magic) { + case PROC_SUPER_MAGIC: + entry = PROC_I(in)->pde; // check for specific inodes ? if (entry) @@ -50,6 +57,15 @@ static int __vc_get_iattr(struct inode *in, uint32_t *xid, uint32_t *flags, uint *flags |= (entry->vx_flags & IATTR_FLAGS); else *flags |= (PROC_I(in)->vx_flags & IATTR_FLAGS); + break; + + case DEVPTS_SUPER_MAGIC: + *xid = in->i_xid; + *mask |= IATTR_XID; + break; + + default: + break; } return 0; } @@ -57,7 +73,7 @@ static int __vc_get_iattr(struct inode *in, uint32_t *xid, uint32_t *flags, uint int vc_get_iattr(uint32_t id, void __user *data) { struct nameidata nd; - struct vcmd_ctx_iattr_v1 vc_data; + struct vcmd_ctx_iattr_v1 vc_data = { .xid = -1 }; int ret; if (!vx_check(0, VX_ADMIN)) @@ -80,7 +96,7 @@ int vc_get_iattr(uint32_t id, void __user *data) 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; + int error = 0, is_proc = 0, has_xid = 0; if (!in || !in->i_sb) return -ESRCH; @@ -88,7 +104,10 @@ static int __vc_set_iattr(struct dentry *de, uint32_t *xid, uint32_t *flags, uin is_proc = (in->i_sb->s_magic == PROC_SUPER_MAGIC); if ((*mask & IATTR_FLAGS) && !is_proc) return -EINVAL; - if ((*mask & IATTR_XID) && !(in->i_sb->s_flags & MS_TAGXID)) + + has_xid = (in->i_sb->s_flags & MS_TAGXID) || + (in->i_sb->s_magic == DEVPTS_SUPER_MAGIC); + if ((*mask & IATTR_XID) && !has_xid) return -EINVAL; down(&in->i_sem); @@ -172,7 +191,6 @@ int vc_set_iattr(uint32_t id, void __user *data) #ifdef CONFIG_VSERVER_LEGACY -#include #define PROC_DYNAMIC_FIRST 0xF0000000UL @@ -221,3 +239,69 @@ int vx_proc_ioctl(struct inode * inode, struct file * filp, } #endif + +int vx_parse_xid(char *string, xid_t *xid, int remove) +{ + static match_table_t tokens = { + {1, "xid=%u"}, + {0, NULL} + }; + substring_t args[MAX_OPT_ARGS]; + int token, option = 0; + + if (!string) + return 0; + + token = match_token(string, tokens, args); + if (token && xid && !match_int(args, &option)) + *xid = option; + + vxdprintk(VXD_CBIT(xid, 7), + "vx_parse_xid(»%s«): %d:#%d", + string, token, option); + + if (token && remove) { + char *p = strstr(string, "xid="); + char *q = p; + + if (p) { + while (*q != '\0' && *q != ',') + q++; + while (*q) + *p++ = *q++; + while (*p) + *p++ = '\0'; + } + } + return token; +} + +void vx_propagate_xid(struct nameidata *nd, struct inode *inode) +{ + xid_t new_xid = 0; + struct vfsmount *mnt; + int propagate; + + if (!nd) + return; + mnt = nd->mnt; + if (!mnt) + return; + + propagate = (mnt->mnt_flags & MNT_XID); + if (propagate) + new_xid = mnt->mnt_xid; + + vxdprintk(VXD_CBIT(xid, 7), + "vx_propagate_xid(%p[#%lu.%d]): %d,%d", + inode, inode->i_ino, inode->i_xid, + new_xid, (propagate)?1:0); + + if (propagate) + inode->i_xid = new_xid; +} + +#include + +EXPORT_SYMBOL_GPL(vx_propagate_xid); +