orangefs: add features op
authorMartin Brandenburg <martin@omnibond.com>
Fri, 12 Aug 2016 16:02:31 +0000 (12:02 -0400)
committerMartin Brandenburg <martin@omnibond.com>
Fri, 12 Aug 2016 19:12:54 +0000 (15:12 -0400)
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>
fs/orangefs/devorangefs-req.c
fs/orangefs/downcall.h
fs/orangefs/orangefs-cache.c
fs/orangefs/orangefs-dev-proto.h
fs/orangefs/orangefs-kernel.h
fs/orangefs/super.c
fs/orangefs/upcall.h

index 7c40e65..ec1a5ff 100644 (file)
@@ -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;
 }
index db6e872..3b8923f 100644 (file)
@@ -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;
 };
 
index eb0b6e0..aa3830b 100644 (file)
@@ -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?";
 }
index 7190289..a3d84ff 100644 (file)
 #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!
index ff3566a..6cf3f46 100644 (file)
@@ -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);
index b9da9a0..3e484a6 100644 (file)
@@ -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:
index 7c29fdf..af0b0e3 100644 (file)
@@ -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;
 };