浏览代码

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>
Martin Brandenburg 9 年之前
父节点
当前提交
482664ddba

+ 5 - 5
fs/orangefs/devorangefs-req.c

@@ -17,7 +17,7 @@
 
 
 /* this file implements the /dev/pvfs2-req device node */
 /* this file implements the /dev/pvfs2-req device node */
 
 
-uint32_t userspace_version;
+uint32_t orangefs_userspace_version;
 
 
 static int open_access_count;
 static int open_access_count;
 
 
@@ -389,9 +389,9 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
 		return -EPROTO;
 		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");
 		gossip_err("Error: userspace version changes\n");
 		return -EPROTO;
 		return -EPROTO;
 	}
 	}
@@ -536,7 +536,7 @@ static int orangefs_devreq_release(struct inode *inode, struct file *file)
 	gossip_debug(GOSSIP_DEV_DEBUG,
 	gossip_debug(GOSSIP_DEV_DEBUG,
 		     "pvfs2-client-core: device close complete\n");
 		     "pvfs2-client-core: device close complete\n");
 	open_access_count = 0;
 	open_access_count = 0;
-	userspace_version = 0;
+	orangefs_userspace_version = 0;
 	mutex_unlock(&devreq_mutex);
 	mutex_unlock(&devreq_mutex);
 	return 0;
 	return 0;
 }
 }

+ 6 - 0
fs/orangefs/downcall.h

@@ -101,6 +101,11 @@ struct orangefs_fs_key_response {
 	char fs_key[FS_KEY_BUF_SIZE];
 	char fs_key[FS_KEY_BUF_SIZE];
 };
 };
 
 
+/* 2.9.6 */
+struct orangefs_features_response {
+	__u64 features;
+};
+
 struct orangefs_downcall_s {
 struct orangefs_downcall_s {
 	__s32 type;
 	__s32 type;
 	__s32 status;
 	__s32 status;
@@ -122,6 +127,7 @@ struct orangefs_downcall_s {
 		struct orangefs_param_response param;
 		struct orangefs_param_response param;
 		struct orangefs_perf_count_response perf_count;
 		struct orangefs_perf_count_response perf_count;
 		struct orangefs_fs_key_response fs_key;
 		struct orangefs_fs_key_response fs_key;
+		struct orangefs_features_response features;
 	} resp;
 	} resp;
 };
 };
 
 

+ 2 - 0
fs/orangefs/orangefs-cache.c

@@ -97,6 +97,8 @@ char *get_opname_string(struct orangefs_kernel_op_s *new_op)
 			return "OP_FSYNC";
 			return "OP_FSYNC";
 		else if (type == ORANGEFS_VFS_OP_FSKEY)
 		else if (type == ORANGEFS_VFS_OP_FSKEY)
 			return "OP_FSKEY";
 			return "OP_FSKEY";
+		else if (type == ORANGEFS_VFS_OP_FEATURES)
+			return "OP_FEATURES";
 	}
 	}
 	return "OP_UNKNOWN?";
 	return "OP_UNKNOWN?";
 }
 }

+ 4 - 0
fs/orangefs/orangefs-dev-proto.h

@@ -41,6 +41,10 @@
 #define ORANGEFS_VFS_OP_FSYNC          0xFF00EE01
 #define ORANGEFS_VFS_OP_FSYNC          0xFF00EE01
 #define ORANGEFS_VFS_OP_FSKEY             0xFF00EE02
 #define ORANGEFS_VFS_OP_FSKEY             0xFF00EE02
 #define ORANGEFS_VFS_OP_READDIRPLUS       0xFF00EE03
 #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!
  * Misc constants. Please retain them as multiples of 8!

+ 3 - 1
fs/orangefs/orangefs-kernel.h

@@ -447,6 +447,8 @@ void purge_waiting_ops(void);
 /*
 /*
  * defined in super.c
  * defined in super.c
  */
  */
+extern uint64_t orangefs_features;
+
 struct dentry *orangefs_mount(struct file_system_type *fst,
 struct dentry *orangefs_mount(struct file_system_type *fst,
 			   int flags,
 			   int flags,
 			   const char *devname,
 			   const char *devname,
@@ -506,7 +508,7 @@ ssize_t orangefs_inode_read(struct inode *inode,
 /*
 /*
  * defined in devorangefs-req.c
  * defined in devorangefs-req.c
  */
  */
-extern uint32_t userspace_version;
+extern uint32_t orangefs_userspace_version;
 
 
 int orangefs_dev_init(void);
 int orangefs_dev_init(void);
 void orangefs_dev_cleanup(void);
 void orangefs_dev_cleanup(void);

+ 27 - 0
fs/orangefs/super.c

@@ -33,6 +33,7 @@ static const match_table_t tokens = {
 	{ Opt_err,	NULL }
 	{ Opt_err,	NULL }
 };
 };
 
 
+uint64_t orangefs_features;
 
 
 static int parse_mount_options(struct super_block *sb, char *options,
 static int parse_mount_options(struct super_block *sb, char *options,
 		int silent)
 		int silent)
@@ -249,6 +250,19 @@ int orangefs_remount(struct orangefs_sb_info_s *orangefs_sb)
 	}
 	}
 
 
 	op_release(new_op);
 	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;
 	return ret;
 }
 }
 
 
@@ -492,6 +506,19 @@ struct dentry *orangefs_mount(struct file_system_type *fst,
 	list_add_tail(&ORANGEFS_SB(sb)->list, &orangefs_superblocks);
 	list_add_tail(&ORANGEFS_SB(sb)->list, &orangefs_superblocks);
 	spin_unlock(&orangefs_superblocks_lock);
 	spin_unlock(&orangefs_superblocks_lock);
 	op_release(new_op);
 	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);
 	return dget(sb->s_root);
 
 
 free_op:
 free_op:

+ 6 - 0
fs/orangefs/upcall.h

@@ -210,6 +210,11 @@ struct orangefs_fs_key_request_s {
 	__s32 __pad1;
 	__s32 __pad1;
 };
 };
 
 
+/* 2.9.6 */
+struct orangefs_features_request_s {
+	__u64 features;
+};
+
 struct orangefs_upcall_s {
 struct orangefs_upcall_s {
 	__s32 type;
 	__s32 type;
 	__u32 uid;
 	__u32 uid;
@@ -246,6 +251,7 @@ struct orangefs_upcall_s {
 		struct orangefs_param_request_s param;
 		struct orangefs_param_request_s param;
 		struct orangefs_perf_count_request_s perf_count;
 		struct orangefs_perf_count_request_s perf_count;
 		struct orangefs_fs_key_request_s fs_key;
 		struct orangefs_fs_key_request_s fs_key;
+		struct orangefs_features_request_s features;
 	} req;
 	} req;
 };
 };