Delta-dmap-feat04.4.diff

From Linix VServer
Revision as of 00:11, 11 November 2025 by 192.168.65.1 (talk) (Restored content from Wayback Machine)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

--- 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