orangefs: add features op
This is a new userspace operation, which will be done if the client-core version is greater than or equal to 2.9.6. This will provide a way to implement optional features and to determine which features are supported by the client-core. If the client-core version is older than 2.9.6, no optional features are supported and the op will not be done. The intent is to allow protocol extensions without relying on the client-core's current behavior of ignoring what it doesn't understand. Signed-off-by: Martin Brandenburg <martin@omnibond.com>
This commit is contained in:
parent
f2ee3b7595
commit
482664ddba
7 changed files with 53 additions and 6 deletions
|
@ -17,7 +17,7 @@
|
|||
|
||||
/* this file implements the /dev/pvfs2-req device node */
|
||||
|
||||
uint32_t userspace_version;
|
||||
uint32_t orangefs_userspace_version;
|
||||
|
||||
static int open_access_count;
|
||||
|
||||
|
@ -389,9 +389,9 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
|
|||
return -EPROTO;
|
||||
}
|
||||
|
||||
if (!userspace_version) {
|
||||
userspace_version = head.version;
|
||||
} else if (userspace_version != head.version) {
|
||||
if (!orangefs_userspace_version) {
|
||||
orangefs_userspace_version = head.version;
|
||||
} else if (orangefs_userspace_version != head.version) {
|
||||
gossip_err("Error: userspace version changes\n");
|
||||
return -EPROTO;
|
||||
}
|
||||
|
@ -536,7 +536,7 @@ static int orangefs_devreq_release(struct inode *inode, struct file *file)
|
|||
gossip_debug(GOSSIP_DEV_DEBUG,
|
||||
"pvfs2-client-core: device close complete\n");
|
||||
open_access_count = 0;
|
||||
userspace_version = 0;
|
||||
orangefs_userspace_version = 0;
|
||||
mutex_unlock(&devreq_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -101,6 +101,11 @@ struct orangefs_fs_key_response {
|
|||
char fs_key[FS_KEY_BUF_SIZE];
|
||||
};
|
||||
|
||||
/* 2.9.6 */
|
||||
struct orangefs_features_response {
|
||||
__u64 features;
|
||||
};
|
||||
|
||||
struct orangefs_downcall_s {
|
||||
__s32 type;
|
||||
__s32 status;
|
||||
|
@ -122,6 +127,7 @@ struct orangefs_downcall_s {
|
|||
struct orangefs_param_response param;
|
||||
struct orangefs_perf_count_response perf_count;
|
||||
struct orangefs_fs_key_response fs_key;
|
||||
struct orangefs_features_response features;
|
||||
} resp;
|
||||
};
|
||||
|
||||
|
|
|
@ -97,6 +97,8 @@ char *get_opname_string(struct orangefs_kernel_op_s *new_op)
|
|||
return "OP_FSYNC";
|
||||
else if (type == ORANGEFS_VFS_OP_FSKEY)
|
||||
return "OP_FSKEY";
|
||||
else if (type == ORANGEFS_VFS_OP_FEATURES)
|
||||
return "OP_FEATURES";
|
||||
}
|
||||
return "OP_UNKNOWN?";
|
||||
}
|
||||
|
|
|
@ -41,6 +41,10 @@
|
|||
#define ORANGEFS_VFS_OP_FSYNC 0xFF00EE01
|
||||
#define ORANGEFS_VFS_OP_FSKEY 0xFF00EE02
|
||||
#define ORANGEFS_VFS_OP_READDIRPLUS 0xFF00EE03
|
||||
#define ORANGEFS_VFS_OP_FEATURES 0xFF00EE05 /* 2.9.6 */
|
||||
|
||||
/* features is a 64-bit unsigned bitmask */
|
||||
#define ORANGEFS_FEATURE_READAHEAD 1
|
||||
|
||||
/*
|
||||
* Misc constants. Please retain them as multiples of 8!
|
||||
|
|
|
@ -447,6 +447,8 @@ void purge_waiting_ops(void);
|
|||
/*
|
||||
* defined in super.c
|
||||
*/
|
||||
extern uint64_t orangefs_features;
|
||||
|
||||
struct dentry *orangefs_mount(struct file_system_type *fst,
|
||||
int flags,
|
||||
const char *devname,
|
||||
|
@ -506,7 +508,7 @@ ssize_t orangefs_inode_read(struct inode *inode,
|
|||
/*
|
||||
* defined in devorangefs-req.c
|
||||
*/
|
||||
extern uint32_t userspace_version;
|
||||
extern uint32_t orangefs_userspace_version;
|
||||
|
||||
int orangefs_dev_init(void);
|
||||
void orangefs_dev_cleanup(void);
|
||||
|
|
|
@ -33,6 +33,7 @@ static const match_table_t tokens = {
|
|||
{ Opt_err, NULL }
|
||||
};
|
||||
|
||||
uint64_t orangefs_features;
|
||||
|
||||
static int parse_mount_options(struct super_block *sb, char *options,
|
||||
int silent)
|
||||
|
@ -249,6 +250,19 @@ int orangefs_remount(struct orangefs_sb_info_s *orangefs_sb)
|
|||
}
|
||||
|
||||
op_release(new_op);
|
||||
|
||||
if (orangefs_userspace_version >= 20906) {
|
||||
new_op = op_alloc(ORANGEFS_VFS_OP_FEATURES);
|
||||
if (!new_op)
|
||||
return -ENOMEM;
|
||||
new_op->upcall.req.features.features = 0;
|
||||
ret = service_operation(new_op, "orangefs_features", 0);
|
||||
orangefs_features = new_op->downcall.resp.features.features;
|
||||
op_release(new_op);
|
||||
} else {
|
||||
orangefs_features = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -492,6 +506,19 @@ struct dentry *orangefs_mount(struct file_system_type *fst,
|
|||
list_add_tail(&ORANGEFS_SB(sb)->list, &orangefs_superblocks);
|
||||
spin_unlock(&orangefs_superblocks_lock);
|
||||
op_release(new_op);
|
||||
|
||||
if (orangefs_userspace_version >= 20906) {
|
||||
new_op = op_alloc(ORANGEFS_VFS_OP_FEATURES);
|
||||
if (!new_op)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
new_op->upcall.req.features.features = 0;
|
||||
ret = service_operation(new_op, "orangefs_features", 0);
|
||||
orangefs_features = new_op->downcall.resp.features.features;
|
||||
op_release(new_op);
|
||||
} else {
|
||||
orangefs_features = 0;
|
||||
}
|
||||
|
||||
return dget(sb->s_root);
|
||||
|
||||
free_op:
|
||||
|
|
|
@ -210,6 +210,11 @@ struct orangefs_fs_key_request_s {
|
|||
__s32 __pad1;
|
||||
};
|
||||
|
||||
/* 2.9.6 */
|
||||
struct orangefs_features_request_s {
|
||||
__u64 features;
|
||||
};
|
||||
|
||||
struct orangefs_upcall_s {
|
||||
__s32 type;
|
||||
__u32 uid;
|
||||
|
@ -246,6 +251,7 @@ struct orangefs_upcall_s {
|
|||
struct orangefs_param_request_s param;
|
||||
struct orangefs_perf_count_request_s perf_count;
|
||||
struct orangefs_fs_key_request_s fs_key;
|
||||
struct orangefs_features_request_s features;
|
||||
} req;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue