+ seq_printf(m, "unknown\n");
+
+ RETURN(0);
+}
+
+static int
+mdt_hsm_request_mask_show(struct seq_file *m, __u64 mask)
+{
+ int i, rc = 0;
+ ENTRY;
+
+ for (i = 0; i < 8 * sizeof(mask); i++) {
+ if (mask & (1UL << i))
+ rc += seq_printf(m, "%s%s", rc == 0 ? "" : " ",
+ hsm_copytool_action2name(i));
+ }
+ rc += seq_printf(m, "\n");
+
+ RETURN(rc);
+}
+
+static int
+mdt_hsm_user_request_mask_seq_show(struct seq_file *m, void *data)
+{
+ struct mdt_device *mdt = m->private;
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+
+ return mdt_hsm_request_mask_show(m, cdt->cdt_user_request_mask);
+}
+
+static int
+mdt_hsm_group_request_mask_seq_show(struct seq_file *m, void *data)
+{
+ struct mdt_device *mdt = m->private;
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+
+ return mdt_hsm_request_mask_show(m, cdt->cdt_group_request_mask);
+}
+
+static int
+mdt_hsm_other_request_mask_seq_show(struct seq_file *m, void *data)
+{
+ struct mdt_device *mdt = m->private;
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+
+ return mdt_hsm_request_mask_show(m, cdt->cdt_other_request_mask);
+}
+
+static inline enum hsm_copytool_action
+hsm_copytool_name2action(const char *name)
+{
+ if (strcasecmp(name, "NOOP") == 0)
+ return HSMA_NONE;
+ else if (strcasecmp(name, "ARCHIVE") == 0)
+ return HSMA_ARCHIVE;
+ else if (strcasecmp(name, "RESTORE") == 0)
+ return HSMA_RESTORE;
+ else if (strcasecmp(name, "REMOVE") == 0)
+ return HSMA_REMOVE;
+ else if (strcasecmp(name, "CANCEL") == 0)
+ return HSMA_CANCEL;
+ else
+ return -1;
+}
+
+static ssize_t
+mdt_write_hsm_request_mask(struct file *file, const char __user *user_buf,
+ size_t user_count, __u64 *mask)
+{
+ char *buf, *pos, *name;
+ size_t buf_size;
+ __u64 new_mask = 0;
+ int rc;
+ ENTRY;
+
+ if (!(user_count < 4096))
+ RETURN(-ENOMEM);
+
+ buf_size = user_count + 1;
+
+ OBD_ALLOC(buf, buf_size);
+ if (buf == NULL)
+ RETURN(-ENOMEM);
+
+ if (copy_from_user(buf, user_buf, buf_size - 1))
+ GOTO(out, rc = -EFAULT);
+
+ buf[buf_size - 1] = '\0';
+
+ pos = buf;
+ while ((name = strsep(&pos, " \t\v\n")) != NULL) {
+ int action;
+
+ if (*name == '\0')
+ continue;
+
+ action = hsm_copytool_name2action(name);
+ if (action < 0)
+ GOTO(out, rc = -EINVAL);
+
+ new_mask |= (1UL << action);
+ }
+
+ *mask = new_mask;
+ rc = user_count;
+out:
+ OBD_FREE(buf, buf_size);
+
+ RETURN(rc);
+}
+
+static ssize_t
+mdt_hsm_user_request_mask_seq_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *off)
+{
+ struct seq_file *m = file->private_data;
+ struct mdt_device *mdt = m->private;
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+
+ return mdt_write_hsm_request_mask(file, buf, count,
+ &cdt->cdt_user_request_mask);
+}
+
+static ssize_t
+mdt_hsm_group_request_mask_seq_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *off)
+{
+ struct seq_file *m = file->private_data;
+ struct mdt_device *mdt = m->private;
+ struct coordinator *cdt = &mdt->mdt_coordinator;
+
+ return mdt_write_hsm_request_mask(file, buf, count,
+ &cdt->cdt_group_request_mask);
+}
+
+static ssize_t
+mdt_hsm_other_request_mask_seq_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *off)
+{
+ struct seq_file *m = file->private_data;
+ struct mdt_device *mdt = m->private;
+ struct coordinator *cdt = &mdt->mdt_coordinator;