Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+53 -6
+5 -5
fs/orangefs/devorangefs-req.c
··· 17 17 18 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 22 static int open_access_count; 23 23 ··· 389 389 return -EPROTO; 390 390 } 391 391 392 - if (!userspace_version) { 393 - userspace_version = head.version; 394 - } else if (userspace_version != head.version) { 392 + if (!orangefs_userspace_version) { 393 + orangefs_userspace_version = head.version; 394 + } else if (orangefs_userspace_version != head.version) { 395 395 gossip_err("Error: userspace version changes\n"); 396 396 return -EPROTO; 397 397 } ··· 536 536 gossip_debug(GOSSIP_DEV_DEBUG, 537 537 "pvfs2-client-core: device close complete\n"); 538 538 open_access_count = 0; 539 - userspace_version = 0; 539 + orangefs_userspace_version = 0; 540 540 mutex_unlock(&devreq_mutex); 541 541 return 0; 542 542 }
+6
fs/orangefs/downcall.h
··· 101 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 109 struct orangefs_downcall_s { 105 110 __s32 type; 106 111 __s32 status; ··· 127 122 struct orangefs_param_response param; 128 123 struct orangefs_perf_count_response perf_count; 129 124 struct orangefs_fs_key_response fs_key; 125 + struct orangefs_features_response features; 130 126 } resp; 131 127 }; 132 128
+2
fs/orangefs/orangefs-cache.c
··· 97 97 return "OP_FSYNC"; 98 98 else if (type == ORANGEFS_VFS_OP_FSKEY) 99 99 return "OP_FSKEY"; 100 + else if (type == ORANGEFS_VFS_OP_FEATURES) 101 + return "OP_FEATURES"; 100 102 } 101 103 return "OP_UNKNOWN?"; 102 104 }
+4
fs/orangefs/orangefs-dev-proto.h
··· 41 41 #define ORANGEFS_VFS_OP_FSYNC 0xFF00EE01 42 42 #define ORANGEFS_VFS_OP_FSKEY 0xFF00EE02 43 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 50 * Misc constants. Please retain them as multiples of 8!
+3 -1
fs/orangefs/orangefs-kernel.h
··· 447 447 /* 448 448 * defined in super.c 449 449 */ 450 + extern uint64_t orangefs_features; 451 + 450 452 struct dentry *orangefs_mount(struct file_system_type *fst, 451 453 int flags, 452 454 const char *devname, ··· 508 506 /* 509 507 * defined in devorangefs-req.c 510 508 */ 511 - extern uint32_t userspace_version; 509 + extern uint32_t orangefs_userspace_version; 512 510 513 511 int orangefs_dev_init(void); 514 512 void orangefs_dev_cleanup(void);
+27
fs/orangefs/super.c
··· 33 33 { Opt_err, NULL } 34 34 }; 35 35 36 + uint64_t orangefs_features; 36 37 37 38 static int parse_mount_options(struct super_block *sb, char *options, 38 39 int silent) ··· 250 249 } 251 250 252 251 op_release(new_op); 252 + 253 + if (orangefs_userspace_version >= 20906) { 254 + new_op = op_alloc(ORANGEFS_VFS_OP_FEATURES); 255 + if (!new_op) 256 + return -ENOMEM; 257 + new_op->upcall.req.features.features = 0; 258 + ret = service_operation(new_op, "orangefs_features", 0); 259 + orangefs_features = new_op->downcall.resp.features.features; 260 + op_release(new_op); 261 + } else { 262 + orangefs_features = 0; 263 + } 264 + 253 265 return ret; 254 266 } 255 267 ··· 506 492 list_add_tail(&ORANGEFS_SB(sb)->list, &orangefs_superblocks); 507 493 spin_unlock(&orangefs_superblocks_lock); 508 494 op_release(new_op); 495 + 496 + if (orangefs_userspace_version >= 20906) { 497 + new_op = op_alloc(ORANGEFS_VFS_OP_FEATURES); 498 + if (!new_op) 499 + return ERR_PTR(-ENOMEM); 500 + new_op->upcall.req.features.features = 0; 501 + ret = service_operation(new_op, "orangefs_features", 0); 502 + orangefs_features = new_op->downcall.resp.features.features; 503 + op_release(new_op); 504 + } else { 505 + orangefs_features = 0; 506 + } 507 + 509 508 return dget(sb->s_root); 510 509 511 510 free_op:
+6
fs/orangefs/upcall.h
··· 210 210 __s32 __pad1; 211 211 }; 212 212 213 + /* 2.9.6 */ 214 + struct orangefs_features_request_s { 215 + __u64 features; 216 + }; 217 + 213 218 struct orangefs_upcall_s { 214 219 __s32 type; 215 220 __u32 uid; ··· 251 246 struct orangefs_param_request_s param; 252 247 struct orangefs_perf_count_request_s perf_count; 253 248 struct orangefs_fs_key_request_s fs_key; 249 + struct orangefs_features_request_s features; 254 250 } req; 255 251 }; 256 252