Editing
Delta-dmap-feat04.4.diff
From Linix VServer
Jump to navigation
Jump to search
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
--- linux-2.6.19.1-vs2.1.1.6/kernel/vserver/device.c 2006-12-13 16:27:31.000000000 +0100 +++ testing-2.6.19/kernel/vserver/device.c 2006-12-13 16:29:59.000000000 +0100 @@ -27,10 +27,6 @@ #define DMAP_HASH_BITS 4 -struct hlist_head dmap_main_hash[1 << DMAP_HASH_BITS]; - -static spinlock_t dmap_main_hash_lock = SPIN_LOCK_UNLOCKED; - struct vs_mapping { struct hlist_node dm_hlist; @@ -39,6 +35,19 @@ struct vs_mapping { int flags; }; +struct vs_device_map { + spinlock_t dmap_lock; + struct hlist_head dmap_hash[1 << DMAP_HASH_BITS]; + struct vs_mapping *dmap_def; + int dmap_bits; +}; + +static struct vs_device_map main_device_map = { + .dmap_lock = SPIN_LOCK_UNLOCKED, + .dmap_def = NULL, + .dmap_bits = DMAP_HASH_BITS; +}; + kmem_cache_t *dmap_cachep __read_mostly; @@ -65,17 +74,25 @@ static inline unsigned int __hashval(dev static inline void __hash_mapping(struct vx_info *vxi, struct vs_mapping *vdm) { - spinlock_t *hash_lock = &dmap_main_hash_lock; - struct hlist_head *head, *hash = dmap_main_hash; + struct vs_device_map *dmap = &main_device_map; + struct hlist_head *head; int device = vdm->device; - spin_lock(hash_lock); + spin_lock(&dmap->dmap_lock); vxdprintk(VXD_CBIT(misc, 8), "__hash_mapping: %p[#%d] %08x:%08x", vxi, vxi ? vxi->vx_id : 0, device, vdm->target); - head = &hash[__hashval(device, DMAP_HASH_BITS)]; - hlist_add_head(&vdm->dm_hlist, head); - spin_unlock(hash_lock); + if (!device) { + if (dmap->dmap_def) + kmem_cache_free(dmap_cachep, dmap->dmap_def); + dmap->dmap_def = vdm; + } + else { + head = &dmap->dmap_hash[__hashval(device, dmap->dmap_bits)]; + hlist_add_head(&vdm->dm_hlist, head); + } + + spin_unlock(&dmap->dmap_lock); } /* __unhash_mapping() @@ -84,15 +101,22 @@ static inline void __hash_mapping(struct static inline void __unhash_mapping(struct vx_info *vxi, struct vs_mapping *vdm) { - spinlock_t *hash_lock = &dmap_main_hash_lock; + struct vs_device_map *dmap = &main_device_map; int device = vdm->device; - spin_lock(hash_lock); + spin_lock(&dmap->dmap_lock); vxdprintk(VXD_CBIT(misc, 8), "__unhash_mapping: %p[#%d] %08x:%08x", vxi, vxi ? vxi->vx_id : 0, device, vdm->target); - hlist_del(&vdm->dm_hlist); - spin_unlock(hash_lock); + if (!device) { + if (dmap->dmap_def) + kmem_cache_free(dmap_cachep, dmap->dmap_def); + dmap->dmap_def = NULL; + } + else + hlist_del(&vdm->dm_hlist); + + spin_unlock(&dmap->dmap_lock); } @@ -100,14 +124,13 @@ static inline void __unhash_mapping(stru static inline int __lookup_mapping(struct vx_info *vxi, dev_t device, dev_t *target, int *flags, umode_t mode) { - spinlock_t *hash_lock = &dmap_main_hash_lock; - struct hlist_head *hash = dmap_main_hash; - struct hlist_head *head = &hash[__hashval(device, DMAP_HASH_BITS)]; + struct vs_device_map *dmap = &main_device_map; + struct hlist_head *head = &dmap->dmap_hash[__hashval(device, dmap->dmap_bits)]; struct hlist_node *pos; struct vs_mapping *vdm; int ret; - spin_lock(hash_lock); + spin_lock(&dmap->dmap_lock); hlist_for_each(pos, head) { vdm = hlist_entry(pos, struct vs_mapping, dm_hlist); @@ -115,20 +138,22 @@ static inline int __lookup_mapping(struc !((vdm->flags ^ mode) & S_IFMT)) goto found; } - ret = 0; - if (target) - *target = device; - if (flags) - *flags = DATTR_OPEN|DATTR_CREATE; - goto out; + if (dmap->dmap_def) + vdm = dmap->dmap_def; + else { + ret = 0; + goto out; + } found: - if (target) + if (target && vdm->flags & DATTR_REMAP) *target = vdm->target; + else if (target) + *target = device; if (flags) *flags = vdm->flags; ret = 1; out: - spin_unlock(hash_lock); + spin_unlock(&dmap->dmap_lock); return ret; } @@ -139,7 +164,7 @@ int vs_map_device(struct vx_info *vxi, d dev_t target = ~0; int ret, flags = 0; - if (!vxi && 0) + if (!vxi) return DATTR_MASK; ret = __lookup_mapping(vxi, *device, &target, &flags, mode); @@ -156,7 +181,7 @@ int vs_device_permission(struct vx_info { int ret, flags = 0; - if (!vxi && 0) + if (!vxi) return -1; ret = __lookup_mapping(vxi, device, NULL, &flags, mode); --- linux-2.6.19.1-vs2.1.1.6/fs/block_dev.c 2006-12-13 16:27:31.000000000 +0100 +++ testing-2.6.19/fs/block_dev.c 2006-12-12 01:48:57.000000000 +0100 @@ -377,6 +377,7 @@ struct block_device *bdget(dev_t dev) bdev->bd_invalidated = 0; inode->i_mode = S_IFBLK; inode->i_rdev = dev; + inode->i_mdev = dev; inode->i_bdev = bdev; inode->i_data.a_ops = &def_blk_aops; mapping_set_gfp_mask(&inode->i_data, GFP_USER); --- linux-2.6.19.1-vs2.1.1.6/fs/namei.c 2006-11-30 21:33:28.000000000 +0100 +++ testing-2.6.19/fs/namei.c 2006-12-12 01:08:35.000000000 +0100 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -1931,8 +1932,17 @@ int vfs_mknod(struct inode *dir, struct if (error) return error; - if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD)) - return -EPERM; + if (S_ISCHR(mode) || S_ISBLK(mode)) { + if (!cap_raised(current->cap_effective, CAP_MKNOD)) + return -EPERM; + + if (!vx_check(vx_current_xid(), VS_ADMIN)) { + if (S_ISCHR(mode) && vs_chrdev_permission(dev, DATTR_CREATE) <= 0) + return -EPERM; + else if (S_ISBLK(mode) && vs_blkdev_permission(dev, DATTR_CREATE) <= 0) + return -EPERM; + } + } if (!dir->i_op || !dir->i_op->mknod) return -EPERM; --- linux-2.6.19.1-vs2.1.1.6/include/linux/vs_device.h 2006-12-13 16:27:31.000000000 +0100 +++ testing-2.6.19/include/linux/vs_device.h 2006-12-13 16:33:14.000000000 +0100 @@ -8,17 +8,27 @@ int vs_map_device(struct vx_info *, dev_t *, umode_t); -#define vs_map_chrdev(d,p) \ +#ifdef CONFIG_VSERVER_DEVICE +# define vs_map_chrdev(d,p) \ ((vs_map_device(current_vx_info(), d, S_IFCHR) & (p)) == (p)) -#define vs_map_blkdev(d,p) \ +# define vs_map_blkdev(d,p) \ ((vs_map_device(current_vx_info(), d, S_IFBLK) & (p)) == (p)) +#else +# define vs_map_chrdev(d,p) 0 +# define vs_map_blkdev(d,p) 0 +#endif int vs_device_permission(struct vx_info *, dev_t, umode_t, int); -#define vs_chrdev_permission(d,p) \ +#ifdef CONFIG_VSERVER_DEVICE +# define vs_chrdev_permission(d,p) \ vs_device_permission(current_vx_info(), d, S_IFCHR, p) -#define vs_blkdev_permission(d,p) \ +# define vs_blkdev_permission(d,p) \ vs_device_permission(current_vx_info(), d, S_IFBLK, p) +#else +# define vs_chrdev_permission(d,p) 0 +# define vs_blkdev_permission(d,p) 0 +#endif #else
Summary:
Please note that all contributions to Linix VServer may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Linix VServer:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Navigation menu
Page actions
Page
Discussion
Read
Edit
History
Page actions
Page
Discussion
More
Tools
Personal tools
Not logged in
Talk
Contributions
Create account
Log in
About
Overview
Paper
News
Developers
Donations
Search
Getting Started
Downloads
FAQs
Documentation
Support
Participate
How to participate
Report a Bug
Communicate
Teams/Projects
Hall of Fame
Resources
Archives
Recent Wiki Changes
Pastebin
Related Projects
VServer Hosting
Happy VServer Users
Tools
What links here
Related changes
Special pages
Page information