@@ -339,6 +339,8 @@ struct client_obd {
u32 cl_supp_cksum_types;
/* checksum algorithm to be used */
enum cksum_type cl_cksum_type;
+ /* preferred checksum algorithm to be used */
+ enum cksum_type cl_preferred_cksum_type;
/* also protected by the poorly named _loi_list_lock lock above */
struct osc_async_rc cl_ar;
@@ -109,10 +109,17 @@ static inline enum cksum_type obd_cksum_types_supported_client(void)
* Caution is advised, however, since what is fastest on a single client may
* not be the fastest or most efficient algorithm on the server.
*/
-static inline enum cksum_type
-obd_cksum_type_select(const char *obd_name, enum cksum_type cksum_types)
+static inline
+enum cksum_type obd_cksum_type_select(const char *obd_name,
+ enum cksum_type cksum_types,
+ enum cksum_type preferred)
{
- u32 flag = obd_cksum_type_pack(obd_name, cksum_types);
+ u32 flag;
+
+ if (preferred & cksum_types)
+ return preferred;
+
+ flag = obd_cksum_type_pack(obd_name, cksum_types);
return obd_cksum_type_unpack(flag);
}
@@ -364,6 +364,7 @@ int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg)
atomic_set(&cli->cl_destroy_in_flight, 0);
cli->cl_supp_cksum_types = OBD_CKSUM_CRC32;
+ cli->cl_preferred_cksum_type = 0;
/* Turn on checksumming by default. */
cli->cl_checksum = 1;
/*
@@ -415,6 +415,7 @@ static ssize_t osc_checksum_type_seq_write(struct file *file,
DECLARE_CKSUM_NAME;
char kernbuf[10];
int i;
+ int rc = -EINVAL;
if (!obd)
return 0;
@@ -423,22 +424,26 @@ static ssize_t osc_checksum_type_seq_write(struct file *file,
return -EINVAL;
if (copy_from_user(kernbuf, buffer, count))
return -EFAULT;
+
if (count > 0 && kernbuf[count - 1] == '\n')
kernbuf[count - 1] = '\0';
else
kernbuf[count] = '\0';
for (i = 0; i < ARRAY_SIZE(cksum_name); i++) {
- if (((1 << i) & obd->u.cli.cl_supp_cksum_types) == 0)
- continue;
- if (!strcmp(kernbuf, cksum_name[i])) {
- obd->u.cli.cl_cksum_type = 1 << i;
- return count;
+ if (strcmp(kernbuf, cksum_name[i]) == 0) {
+ obd->u.cli.cl_preferred_cksum_type = BIT(i);
+ if (obd->u.cli.cl_supp_cksum_types & BIT(i)) {
+ obd->u.cli.cl_cksum_type = BIT(i);
+ rc = count;
+ } else {
+ rc = -ENOTSUPP;
+ }
+ break;
}
}
- return -EINVAL;
+ return rc;
}
-
LPROC_SEQ_FOPS(osc_checksum_type);
static ssize_t resend_count_show(struct kobject *kobj,
@@ -846,7 +846,8 @@ static int ptlrpc_connect_set_flags(struct obd_import *imp,
cli->cl_supp_cksum_types = OBD_CKSUM_ADLER;
}
cli->cl_cksum_type = obd_cksum_type_select(imp->imp_obd->obd_name,
- cli->cl_supp_cksum_types);
+ cli->cl_supp_cksum_types,
+ cli->cl_preferred_cksum_type);
if (ocd->ocd_connect_flags & OBD_CONNECT_BRW_SIZE)
cli->cl_max_pages_per_rpc =