[Oracleasm-commits] jlbec commits r380 - trunk/kernel
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Fri Jun 15 13:24:57 PDT 2007
Author: jlbec
Date: 2007-06-15 13:24:56 -0700 (Fri, 15 Jun 2007)
New Revision: 380
Modified:
trunk/kernel/oracleasm.c
Log:
oracleasm uses a pseudo-filesystem to back its disk objects. This allows
it to use the inode hash to convert a bdev pointer to an actual disk object.
However, the test/set functions for comparing disk objects were not smart
enough. A has collision on two different bdev pointers could cause an
incorrect lookup of a disk object. A duplicate handle is returned.
We make a smarter test/set with a find_actor() function, very similar to
ocfs2.
This fixes Bug #6135457.
Modified: trunk/kernel/oracleasm.c
===================================================================
--- trunk/kernel/oracleasm.c 2007-06-15 20:22:14 UTC (rev 379)
+++ trunk/kernel/oracleasm.c 2007-06-15 20:24:56 UTC (rev 380)
@@ -212,6 +212,12 @@
struct inode vfs_inode;
};
+/* Argument to iget5_locked()/ilookup5() to map bdev to disk_inode */
+struct asmdisk_find_inode_args {
+ unsigned long fa_handle;
+ struct asmfs_inode_info *fa_inode;
+};
+
static inline struct asm_disk_info *ASMDISK_I(struct inode *inode)
{
return container_of(inode, struct asm_disk_info, vfs_inode);
@@ -417,15 +423,23 @@
kmem_cache_destroy(asmdisk_cachep);
}
-
static int asmdisk_test(struct inode *inode, void *data)
{
- return ASMDISK_I(inode)->d_inode == (struct asmfs_inode_info *)data;
+ struct asmdisk_find_inode_args *args = data;
+ struct asm_disk_info *d = ASMDISK_I(inode);
+ unsigned long handle = (unsigned long)(d->d_bdev);
+
+ return (d->d_inode == args->fa_inode) && (handle == args->fa_handle);
}
static int asmdisk_set(struct inode *inode, void *data)
{
- ASMDISK_I(inode)->d_inode = (struct asmfs_inode_info *)data;
+ struct asmdisk_find_inode_args *args = data;
+ struct asm_disk_info *d = ASMDISK_I(inode);
+
+ d->d_bdev = (struct block_device *)(args->fa_handle);
+ d->d_inode = args->fa_inode;
+
return 0;
}
@@ -722,6 +736,7 @@
struct asm_disk_head *h;
struct inode *inode = ASMFS_F2I(file);
struct inode *disk_inode;
+ struct asmdisk_find_inode_args args;
mlog_entry("(0x%p, 0x%p)\n", file, bdev);
@@ -745,9 +760,11 @@
mlog(ML_DISK, "Looking up disk for bdev %p (dev %X)\n", bdev,
bdev->bd_dev);
+ args.fa_handle = (unsigned long)bdev;
+ args.fa_inode = ASMFS_I(inode);
disk_inode = iget5_locked(asmdisk_mnt->mnt_sb,
(unsigned long)bdev, asmdisk_test,
- asmdisk_set, ASMFS_I(inode));
+ asmdisk_set, &args);
if (!disk_inode)
goto out_head;
@@ -761,9 +778,12 @@
"Supposedly new disk 0x%p (dev %X) is live\n",
d, bdev->bd_dev);
+ mlog_bug_on_msg(d->d_bdev != bdev,
+ "New disk 0x%p has set bdev 0x%p but we were opening 0x%p\n",
+ d, d->d_bdev, bdev);
+
disk_inode->i_mapping->backing_dev_info =
&memory_backing_dev_info;
- d->d_bdev = bdev;
d->d_max_sectors = compute_max_sectors(bdev);
d->d_live = 1;
@@ -811,6 +831,7 @@
static int asm_close_disk(struct file *file, unsigned long handle)
{
struct inode *inode = ASMFS_F2I(file);
+ struct asmdisk_find_inode_args args;
struct asm_disk_info *d;
struct block_device *bdev;
struct inode *disk_inode;
@@ -824,8 +845,10 @@
mlog_bug_on_msg(!ASMFS_FILE(file) || !ASMFS_I(inode),
"Garbage arguments\n");
+ args.fa_handle = handle;
+ args.fa_inode = ASMFS_I(inode);
disk_inode = ilookup5(asmdisk_mnt->mnt_sb, handle,
- asmdisk_test, ASMFS_I(inode));
+ asmdisk_test, &args);
if (!disk_inode) {
mlog_exit(-EINVAL);
return -EINVAL;
@@ -1234,6 +1257,7 @@
{
int ret, rw = READ;
struct inode *inode = ASMFS_F2I(file);
+ struct asmdisk_find_inode_args args;
struct asm_request *r;
struct asm_disk_info *d;
struct inode *disk_inode;
@@ -1281,9 +1305,11 @@
spin_unlock_irq(&ASMFS_FILE(file)->f_lock);
ret = -ENODEV;
+ args.fa_handle = (unsigned long)ioc->disk_asm_ioc;
+ args.fa_inode = ASMFS_I(inode);
disk_inode = ilookup5(asmdisk_mnt->mnt_sb,
(unsigned long)ioc->disk_asm_ioc,
- asmdisk_test, ASMFS_I(inode));
+ asmdisk_test, &args);
if (!disk_inode)
goto out_error;
@@ -1425,6 +1451,7 @@
long ret;
u64 p;
struct asmfs_file_info *afi = ASMFS_FILE(file);
+ struct asmdisk_find_inode_args args;
struct asm_request *r;
struct task_struct *tsk = current;
DECLARE_WAITQUEUE(wait, tsk);
@@ -1479,10 +1506,11 @@
bdev = d->d_bdev;
spin_unlock_irq(&afi->f_lock);
+ args.fa_handle = (unsigned long)bdev;
+ args.fa_inode = ASMFS_I(ASMFS_F2I(file));
disk_inode = ilookup5(asmdisk_mnt->mnt_sb,
(unsigned long)bdev,
- asmdisk_test,
- ASMFS_I(ASMFS_F2I(file)));
+ asmdisk_test, &args);
if (disk_inode) {
d = ASMDISK_I(disk_inode);
if (d->d_bdev)
@@ -1616,6 +1644,7 @@
struct block_device *bdev;
struct asm_disk_info *d;
struct inode *disk_inode;
+ struct asmdisk_find_inode_args args;
ret = 0;
set_task_state(tsk, TASK_INTERRUPTIBLE);
@@ -1629,10 +1658,11 @@
bdev = find_io_bdev(file);
spin_unlock_irq(&afi->f_lock);
+ args.fa_handle = (unsigned long)bdev;
+ args.fa_inode = ASMFS_I(ASMFS_F2I(file));
disk_inode = ilookup5(asmdisk_mnt->mnt_sb,
(unsigned long)bdev,
- asmdisk_test,
- ASMFS_I(ASMFS_F2I(file)));
+ asmdisk_test, &args);
if (disk_inode) {
d = ASMDISK_I(disk_inode);
if (d->d_bdev)
@@ -2101,6 +2131,7 @@
struct block_device *bdev;
struct asm_disk_info *d;
struct inode *disk_inode;
+ struct asmdisk_find_inode_args args;
set_task_state(tsk, TASK_UNINTERRUPTIBLE);
@@ -2111,9 +2142,11 @@
bdev = find_io_bdev(file);
spin_unlock_irq(&afi->f_lock);
+ args.fa_handle = (unsigned long)bdev;
+ args.fa_inode = aii;
disk_inode = ilookup5(asmdisk_mnt->mnt_sb,
(unsigned long)bdev,
- asmdisk_test, aii);
+ asmdisk_test, &args);
if (disk_inode) {
d = ASMDISK_I(disk_inode);
if (d->d_bdev)
More information about the Oracleasm-commits
mailing list