static ssize_t asmfs_svc_get_iid(struct file *file, char *buf, size_t size);
static ssize_t asmfs_svc_check_iid(struct file *file, char *buf, size_t size);
static ssize_t asmfs_svc_query_disk(struct file *file, char *buf, size_t size);
+static ssize_t asmfs_svc_query_handle(struct file *file, char *buf, size_t size);
static ssize_t asmfs_svc_open_disk(struct file *file, char *buf, size_t size);
static ssize_t asmfs_svc_close_disk(struct file *file, char *buf, size_t size);
static ssize_t asmfs_svc_io32(struct file *file, char *buf, size_t size);
#if BITS_PER_LONG == 64
[ASMOP_IO64] = {asmfs_svc_io64},
#endif
+ [ASMOP_QUERY_HANDLE] = {asmfs_svc_query_handle},
};
static struct inode *asmdisk_alloc_inode(struct super_block *sb)
return (d->d_inode == args->fa_inode) && (handle == args->fa_handle);
}
+static int asmdisk_test_noinode(struct inode *inode, void *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 handle == args->fa_handle;
+}
+
static int asmdisk_set(struct inode *inode, void *data)
{
struct asmdisk_find_inode_args *args = data;
#endif /* BITS_PER_LONG == 64 */
+static ssize_t asmfs_svc_query_handle(struct file *file, char *buf, size_t size)
+{
+ struct oracleasm_query_handle_v2 *qh_info;
+ struct asmdisk_find_inode_args args;
+ struct inode *disk_inode;
+ struct asm_disk_info *d;
+ struct block_device *bdev;
+ unsigned int lsecsz = 0;
+ int ret;
+
+ if (size != sizeof(struct oracleasm_query_handle_v2))
+ return -EINVAL;
+
+ qh_info = (struct oracleasm_query_handle_v2 *)buf;
+
+ ret = asmfs_verify_abi(&qh_info->qh_abi);
+ if (ret)
+ goto out;
+
+ ret = -EBADR;
+ if (qh_info->qh_abi.ai_size != sizeof(struct oracleasm_query_handle_v2))
+ goto out;
+
+ ret = -EBADRQC;
+ if (qh_info->qh_abi.ai_type != ASMOP_QUERY_HANDLE)
+ goto out;
+
+ args.fa_handle = (unsigned long)qh_info->qh_handle;
+ args.fa_inode = 0;
+ disk_inode = ilookup5(asmdisk_mnt->mnt_sb, qh_info->qh_handle,
+ asmdisk_test_noinode, &args);
+ if (!disk_inode) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ d = ASMDISK_I(disk_inode);
+ iput(disk_inode);
+ bdev = d->d_bdev;
+
+ qh_info->qh_max_sectors = compute_max_sectors(bdev);
+ qh_info->qh_hardsect_size = asm_block_size(bdev);
+ qh_info->qh_feature = asm_integrity_format(bdev) & ASM_INTEGRITY_QDF_MASK;
+ if (use_logical_block_size == false) {
+ lsecsz = ilog2(bdev_logical_block_size(bdev));
+ qh_info->qh_feature |= lsecsz << ASM_LSECSZ_SHIFT
+ & ASM_LSECSZ_MASK;
+ }
+
+ trace_queryhandle(bdev, qh_info);
+ ret = 0;
+
+out:
+ qh_info->qh_abi.ai_status = ret;
+ return size;
+}
+
+
/*
* Because each of these operations need to access the filp->private,
* we must multiplex.
ret = asmfs_svc_io64(file, (char *)buf, size);
break;
#endif /* BITS_PER_LONG == 64 */
+
+ case ASMOP_QUERY_HANDLE:
+ ret = asmfs_svc_query_handle(file, (char *)buf, size);
+ break;
}
return ret;
}
+
static struct file_operations asmfs_file_operations = {
.open = asmfs_file_open,
.release = asmfs_file_release,
goto out_genocide;
d_add(dentry, inode);
+ name.name = asm_operation_files[ASMOP_QUERY_HANDLE];
+ name.len = strlen(asm_operation_files[ASMOP_QUERY_HANDLE]);
+ name.hash = full_name_hash(name.name, name.len);
+ dentry = d_alloc(root, &name);
+ if (!dentry)
+ goto out_genocide;
+ inode = new_transaction_inode(sb, 0770,
+ &trans_contexts[ASMOP_QUERY_HANDLE]);
+ if (!inode)
+ goto out_genocide;
+ d_add(dentry, inode);
+
sb->s_root = root;
show_ifmt(__entry->integrity))
);
+TRACE_EVENT(queryhandle,
+
+ TP_PROTO(struct block_device *bdev, struct oracleasm_query_handle_v2 *qh),
+
+ TP_ARGS(bdev, qh),
+
+ TP_STRUCT__entry(
+ __field(void * , bdev )
+ __field(void * , qh )
+ __field(dev_t , dev )
+ __field(sector_t , max )
+ __field(unsigned int , pbs )
+ __field(unsigned int , lbs )
+ __field(unsigned char , integrity )
+ ),
+
+ TP_fast_assign(
+ __entry->bdev = bdev;
+ __entry->qh = qh;
+ __entry->dev = bdev->bd_dev ? bdev->bd_dev : 0;
+ __entry->max = qh->qh_max_sectors;
+ __entry->pbs = qh->qh_hardsect_size;
+ __entry->lbs = 1 << (qh->qh_feature >> ASM_LSECSZ_SHIFT);
+ __entry->integrity = qh->qh_feature & ASM_INTEGRITY_QDF_MASK;
+ ),
+
+ TP_printk(" dev=%u:%u max_blocks=%llu pbs=%u lbs=%u integrity=%s",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ (unsigned long long)__entry->max, __entry->pbs, __entry->lbs,
+ show_ifmt(__entry->integrity))
+);
+
TRACE_EVENT(integrity,
TP_PROTO(struct oracleasm_integrity_v2 *it,