diff options
author | Martin Brandenburg <martin@omnibond.com> | 2016-08-12 12:02:31 -0400 |
---|---|---|
committer | Martin Brandenburg <martin@omnibond.com> | 2016-08-12 15:12:54 -0400 |
commit | 482664ddba81b3a5404fd083bb9697dfffc0b6a4 (patch) | |
tree | f4dd0268a8cf58fd898f73dd7b26a0a9ef5d2eff | |
parent | f2ee3b759593c184f1249e03d613a84b4b69db2b (diff) |
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>
-rw-r--r-- | fs/orangefs/devorangefs-req.c | 10 | ||||
-rw-r--r-- | fs/orangefs/downcall.h | 6 | ||||
-rw-r--r-- | fs/orangefs/orangefs-cache.c | 2 | ||||
-rw-r--r-- | fs/orangefs/orangefs-dev-proto.h | 4 | ||||
-rw-r--r-- | fs/orangefs/orangefs-kernel.h | 4 | ||||
-rw-r--r-- | fs/orangefs/super.c | 27 | ||||
-rw-r--r-- | fs/orangefs/upcall.h | 6 |
7 files changed, 53 insertions, 6 deletions
diff --git a/fs/orangefs/devorangefs-req.c b/fs/orangefs/devorangefs-req.c index 7c40e653e526..ec1a5ff1d843 100644 --- a/fs/orangefs/devorangefs-req.c +++ b/fs/orangefs/devorangefs-req.c | |||
@@ -17,7 +17,7 @@ | |||
17 | 17 | ||
18 | /* this file implements the /dev/pvfs2-req device node */ | 18 | /* this file implements the /dev/pvfs2-req device node */ |
19 | 19 | ||
20 | uint32_t userspace_version; | 20 | uint32_t orangefs_userspace_version; |
21 | 21 | ||
22 | static int open_access_count; | 22 | static int open_access_count; |
23 | 23 | ||
@@ -389,9 +389,9 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, | |||
389 | return -EPROTO; | 389 | return -EPROTO; |
390 | } | 390 | } |
391 | 391 | ||
392 | if (!userspace_version) { | 392 | if (!orangefs_userspace_version) { |
393 | userspace_version = head.version; | 393 | orangefs_userspace_version = head.version; |
394 | } else if (userspace_version != head.version) { | 394 | } else if (orangefs_userspace_version != head.version) { |
395 | gossip_err("Error: userspace version changes\n"); | 395 | gossip_err("Error: userspace version changes\n"); |
396 | return -EPROTO; | 396 | return -EPROTO; |
397 | } | 397 | } |
@@ -536,7 +536,7 @@ static int orangefs_devreq_release(struct inode *inode, struct file *file) | |||
536 | gossip_debug(GOSSIP_DEV_DEBUG, | 536 | gossip_debug(GOSSIP_DEV_DEBUG, |
537 | "pvfs2-client-core: device close complete\n"); | 537 | "pvfs2-client-core: device close complete\n"); |
538 | open_access_count = 0; | 538 | open_access_count = 0; |
539 | userspace_version = 0; | 539 | orangefs_userspace_version = 0; |
540 | mutex_unlock(&devreq_mutex); | 540 | mutex_unlock(&devreq_mutex); |
541 | return 0; | 541 | return 0; |
542 | } | 542 | } |
diff --git a/fs/orangefs/downcall.h b/fs/orangefs/downcall.h index db6e8722a89e..3b8923f8bf21 100644 --- a/fs/orangefs/downcall.h +++ b/fs/orangefs/downcall.h | |||
@@ -101,6 +101,11 @@ struct orangefs_fs_key_response { | |||
101 | char fs_key[FS_KEY_BUF_SIZE]; | 101 | char fs_key[FS_KEY_BUF_SIZE]; |
102 | }; | 102 | }; |
103 | 103 | ||
104 | /* 2.9.6 */ | ||
105 | struct orangefs_features_response { | ||
106 | __u64 features; | ||
107 | }; | ||
108 | |||
104 | struct orangefs_downcall_s { | 109 | struct orangefs_downcall_s { |
105 | __s32 type; | 110 | __s32 type; |
106 | __s32 status; | 111 | __s32 status; |
@@ -122,6 +127,7 @@ struct orangefs_downcall_s { | |||
122 | struct orangefs_param_response param; | 127 | struct orangefs_param_response param; |
123 | struct orangefs_perf_count_response perf_count; | 128 | struct orangefs_perf_count_response perf_count; |
124 | struct orangefs_fs_key_response fs_key; | 129 | struct orangefs_fs_key_response fs_key; |
130 | struct orangefs_features_response features; | ||
125 | } resp; | 131 | } resp; |
126 | }; | 132 | }; |
127 | 133 | ||
diff --git a/fs/orangefs/orangefs-cache.c b/fs/orangefs/orangefs-cache.c index eb0b6e00b519..aa3830b741c7 100644 --- a/fs/orangefs/orangefs-cache.c +++ b/fs/orangefs/orangefs-cache.c | |||
@@ -97,6 +97,8 @@ char *get_opname_string(struct orangefs_kernel_op_s *new_op) | |||
97 | return "OP_FSYNC"; | 97 | return "OP_FSYNC"; |
98 | else if (type == ORANGEFS_VFS_OP_FSKEY) | 98 | else if (type == ORANGEFS_VFS_OP_FSKEY) |
99 | return "OP_FSKEY"; | 99 | return "OP_FSKEY"; |
100 | else if (type == ORANGEFS_VFS_OP_FEATURES) | ||
101 | return "OP_FEATURES"; | ||
100 | } | 102 | } |
101 | return "OP_UNKNOWN?"; | 103 | return "OP_UNKNOWN?"; |
102 | } | 104 | } |
diff --git a/fs/orangefs/orangefs-dev-proto.h b/fs/orangefs/orangefs-dev-proto.h index 71902899b1da..a3d84ffee905 100644 --- a/fs/orangefs/orangefs-dev-proto.h +++ b/fs/orangefs/orangefs-dev-proto.h | |||
@@ -41,6 +41,10 @@ | |||
41 | #define ORANGEFS_VFS_OP_FSYNC 0xFF00EE01 | 41 | #define ORANGEFS_VFS_OP_FSYNC 0xFF00EE01 |
42 | #define ORANGEFS_VFS_OP_FSKEY 0xFF00EE02 | 42 | #define ORANGEFS_VFS_OP_FSKEY 0xFF00EE02 |
43 | #define ORANGEFS_VFS_OP_READDIRPLUS 0xFF00EE03 | 43 | #define ORANGEFS_VFS_OP_READDIRPLUS 0xFF00EE03 |
44 | #define ORANGEFS_VFS_OP_FEATURES 0xFF00EE05 /* 2.9.6 */ | ||
45 | |||
46 | /* features is a 64-bit unsigned bitmask */ | ||
47 | #define ORANGEFS_FEATURE_READAHEAD 1 | ||
44 | 48 | ||
45 | /* | 49 | /* |
46 | * Misc constants. Please retain them as multiples of 8! | 50 | * Misc constants. Please retain them as multiples of 8! |
diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index ff3566a8388f..6cf3f467fd89 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h | |||
@@ -447,6 +447,8 @@ void purge_waiting_ops(void); | |||
447 | /* | 447 | /* |
448 | * defined in super.c | 448 | * defined in super.c |
449 | */ | 449 | */ |
450 | extern uint64_t orangefs_features; | ||
451 | |||
450 | struct dentry *orangefs_mount(struct file_system_type *fst, | 452 | struct dentry *orangefs_mount(struct file_system_type *fst, |
451 | int flags, | 453 | int flags, |
452 | const char *devname, | 454 | const char *devname, |
@@ -506,7 +508,7 @@ ssize_t orangefs_inode_read(struct inode *inode, | |||
506 | /* | 508 | /* |
507 | * defined in devorangefs-req.c | 509 | * defined in devorangefs-req.c |
508 | */ | 510 | */ |
509 | extern uint32_t userspace_version; | 511 | extern uint32_t orangefs_userspace_version; |
510 | 512 | ||
511 | int orangefs_dev_init(void); | 513 | int orangefs_dev_init(void); |
512 | void orangefs_dev_cleanup(void); | 514 | void orangefs_dev_cleanup(void); |
diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c index b9da9a0281c9..3e484a667340 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c | |||
@@ -33,6 +33,7 @@ static const match_table_t tokens = { | |||
33 | { Opt_err, NULL } | 33 | { Opt_err, NULL } |
34 | }; | 34 | }; |
35 | 35 | ||
36 | uint64_t orangefs_features; | ||
36 | 37 | ||
37 | static int parse_mount_options(struct super_block *sb, char *options, | 38 | static int parse_mount_options(struct super_block *sb, char *options, |
38 | int silent) | 39 | int silent) |
@@ -249,6 +250,19 @@ int orangefs_remount(struct orangefs_sb_info_s *orangefs_sb) | |||
249 | } | 250 | } |
250 | 251 | ||
251 | op_release(new_op); | 252 | op_release(new_op); |
253 | |||
254 | if (orangefs_userspace_version >= 20906) { | ||
255 | new_op = op_alloc(ORANGEFS_VFS_OP_FEATURES); | ||
256 | if (!new_op) | ||
257 | return -ENOMEM; | ||
258 | new_op->upcall.req.features.features = 0; | ||
259 | ret = service_operation(new_op, "orangefs_features", 0); | ||
260 | orangefs_features = new_op->downcall.resp.features.features; | ||
261 | op_release(new_op); | ||
262 | } else { | ||
263 | orangefs_features = 0; | ||
264 | } | ||
265 | |||
252 | return ret; | 266 | return ret; |
253 | } | 267 | } |
254 | 268 | ||
@@ -492,6 +506,19 @@ struct dentry *orangefs_mount(struct file_system_type *fst, | |||
492 | list_add_tail(&ORANGEFS_SB(sb)->list, &orangefs_superblocks); | 506 | list_add_tail(&ORANGEFS_SB(sb)->list, &orangefs_superblocks); |
493 | spin_unlock(&orangefs_superblocks_lock); | 507 | spin_unlock(&orangefs_superblocks_lock); |
494 | op_release(new_op); | 508 | op_release(new_op); |
509 | |||
510 | if (orangefs_userspace_version >= 20906) { | ||
511 | new_op = op_alloc(ORANGEFS_VFS_OP_FEATURES); | ||
512 | if (!new_op) | ||
513 | return ERR_PTR(-ENOMEM); | ||
514 | new_op->upcall.req.features.features = 0; | ||
515 | ret = service_operation(new_op, "orangefs_features", 0); | ||
516 | orangefs_features = new_op->downcall.resp.features.features; | ||
517 | op_release(new_op); | ||
518 | } else { | ||
519 | orangefs_features = 0; | ||
520 | } | ||
521 | |||
495 | return dget(sb->s_root); | 522 | return dget(sb->s_root); |
496 | 523 | ||
497 | free_op: | 524 | free_op: |
diff --git a/fs/orangefs/upcall.h b/fs/orangefs/upcall.h index 7c29fdf08ec5..af0b0e36d559 100644 --- a/fs/orangefs/upcall.h +++ b/fs/orangefs/upcall.h | |||
@@ -210,6 +210,11 @@ struct orangefs_fs_key_request_s { | |||
210 | __s32 __pad1; | 210 | __s32 __pad1; |
211 | }; | 211 | }; |
212 | 212 | ||
213 | /* 2.9.6 */ | ||
214 | struct orangefs_features_request_s { | ||
215 | __u64 features; | ||
216 | }; | ||
217 | |||
213 | struct orangefs_upcall_s { | 218 | struct orangefs_upcall_s { |
214 | __s32 type; | 219 | __s32 type; |
215 | __u32 uid; | 220 | __u32 uid; |
@@ -246,6 +251,7 @@ struct orangefs_upcall_s { | |||
246 | struct orangefs_param_request_s param; | 251 | struct orangefs_param_request_s param; |
247 | struct orangefs_perf_count_request_s perf_count; | 252 | struct orangefs_perf_count_request_s perf_count; |
248 | struct orangefs_fs_key_request_s fs_key; | 253 | struct orangefs_fs_key_request_s fs_key; |
254 | struct orangefs_features_request_s features; | ||
249 | } req; | 255 | } req; |
250 | }; | 256 | }; |
251 | 257 | ||