Browse Source

Merge branch 'features' into for-next

Pull in an OrangeFS branch containing improvements which the userspace
component and the kernel to negotiate mutually supported features.
Martin Brandenburg 9 years ago
parent
commit
f808e138c0

+ 10 - 0
fs/orangefs/devorangefs-req.c

@@ -17,6 +17,8 @@
 
 /* this file implements the /dev/pvfs2-req device node */
 
+uint32_t orangefs_userspace_version;
+
 static int open_access_count;
 
 #define DUMP_DEVICE_ERROR()                                                   \
@@ -387,6 +389,13 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
 		return -EPROTO;
 	}
 
+	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;
+	}
+
 	/* remove the op from the in progress hash table */
 	op = orangefs_devreq_remove_op(head.tag);
 	if (!op) {
@@ -527,6 +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;
+	orangefs_userspace_version = 0;
 	mutex_unlock(&devreq_mutex);
 	return 0;
 }

+ 6 - 0
fs/orangefs/downcall.h

@@ -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;
 };
 

+ 8 - 5
fs/orangefs/file.c

@@ -624,11 +624,14 @@ static int orangefs_file_release(struct inode *inode, struct file *file)
 	if (file->f_path.dentry->d_inode &&
 	    file->f_path.dentry->d_inode->i_mapping &&
 	    mapping_nrpages(&file->f_path.dentry->d_inode->i_data)) {
-		gossip_debug(GOSSIP_INODE_DEBUG,
-		    "calling flush_racache on %pU\n",
-		    get_khandle_from_ino(inode));
-		flush_racache(inode);
-		gossip_debug(GOSSIP_INODE_DEBUG, "flush_racache finished\n");
+		if (orangefs_features & ORANGEFS_FEATURE_READAHEAD) {
+			gossip_debug(GOSSIP_INODE_DEBUG,
+			    "calling flush_racache on %pU\n",
+			    get_khandle_from_ino(inode));
+			flush_racache(inode);
+			gossip_debug(GOSSIP_INODE_DEBUG,
+			    "flush_racache finished\n");
+		}
 		truncate_inode_pages(file->f_path.dentry->d_inode->i_mapping,
 				     0);
 	}

+ 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";
 		else if (type == ORANGEFS_VFS_OP_FSKEY)
 			return "OP_FSKEY";
+		else if (type == ORANGEFS_VFS_OP_FEATURES)
+			return "OP_FEATURES";
 	}
 	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_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!

+ 4 - 0
fs/orangefs/orangefs-kernel.h

@@ -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,6 +508,8 @@ ssize_t orangefs_inode_read(struct inode *inode,
 /*
  * defined in devorangefs-req.c
  */
+extern uint32_t orangefs_userspace_version;
+
 int orangefs_dev_init(void);
 void orangefs_dev_cleanup(void);
 int is_daemon_in_service(void);

+ 19 - 0
fs/orangefs/orangefs-sysfs.c

@@ -842,6 +842,16 @@ static int sysfs_service_op_show(char *kobj_id, char *buf, void *attr)
 	if (!strcmp(kobj_id, ORANGEFS_KOBJ_ID)) {
 		orangefs_attr = (struct orangefs_attribute *)attr;
 
+		/* Drop unsupported requests first. */
+		if (!(orangefs_features & ORANGEFS_FEATURE_READAHEAD) &&
+		    (!strcmp(orangefs_attr->attr.name, "readahead_count") ||
+		    !strcmp(orangefs_attr->attr.name, "readahead_size") ||
+		    !strcmp(orangefs_attr->attr.name,
+		    "readahead_count_size"))) {
+			rc = -EINVAL;
+			goto out;
+		}
+
 		if (!strcmp(orangefs_attr->attr.name, "perf_history_size"))
 			new_op->upcall.req.param.op =
 				ORANGEFS_PARAM_REQUEST_OP_PERF_HISTORY_SIZE;
@@ -1133,6 +1143,15 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr)
 
 	if (!strcmp(kobj_id, ORANGEFS_KOBJ_ID)) {
 		orangefs_attr = (struct orangefs_attribute *)attr;
+		/* Drop unsupported requests first. */
+		if (!(orangefs_features & ORANGEFS_FEATURE_READAHEAD) &&
+		    (!strcmp(orangefs_attr->attr.name, "readahead_count") ||
+		    !strcmp(orangefs_attr->attr.name, "readahead_size") ||
+		    !strcmp(orangefs_attr->attr.name,
+		    "readahead_count_size"))) {
+			rc = -EINVAL;
+			goto out;
+		}
 
 		if (!strcmp(orangefs_attr->attr.name, "perf_history_size")) {
 			if (val > 0) {

+ 27 - 0
fs/orangefs/super.c

@@ -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 >= 20907) {
+		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 >= 20907) {
+		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:

+ 6 - 0
fs/orangefs/upcall.h

@@ -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;
 };