4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (C) 2013, Trustees of Indiana University
25 * Copyright (c) 2014, 2017, Intel Corporation.
27 * Author: Joshua Walgenbach <jjw@iu.edu>
30 #define NODEMAP_LPROC_ID_LEN 16
31 #define NODEMAP_LPROC_FLAG_LEN 2
33 #include <lprocfs_status.h>
34 #include <lustre_net.h>
35 #include <lustre_export.h>
36 #include <obd_class.h>
37 #include <interval_tree.h>
38 #include "nodemap_internal.h"
40 static LIST_HEAD(nodemap_pde_list);
43 * Reads and prints the idmap for the given nodemap.
45 * \param m seq file in proc fs
49 static int nodemap_idmap_show(struct seq_file *m, void *data)
51 struct lu_nodemap *nodemap;
52 struct lu_idmap *idmap;
57 mutex_lock(&active_config_lock);
58 nodemap = nodemap_lookup(m->private);
59 mutex_unlock(&active_config_lock);
60 if (IS_ERR(nodemap)) {
61 rc = PTR_ERR(nodemap);
62 CERROR("cannot find nodemap '%s': rc = %d\n",
63 (char *)m->private, rc);
68 down_read(&nodemap->nm_idmap_lock);
69 for (node = rb_first(&nodemap->nm_client_to_fs_uidmap); node;
70 node = rb_next(node)) {
74 idmap = rb_entry(node, struct lu_idmap, id_client_to_fs);
76 seq_printf(m, " { idtype: uid, client_id: %u, "
77 "fs_id: %u }", idmap->id_client,
80 for (node = rb_first(&nodemap->nm_client_to_fs_gidmap);
81 node; node = rb_next(node)) {
84 idmap = rb_entry(node, struct lu_idmap, id_client_to_fs);
86 seq_printf(m, " { idtype: gid, client_id: %u, "
87 "fs_id: %u }", idmap->id_client,
90 up_read(&nodemap->nm_idmap_lock);
94 nodemap_putref(nodemap);
99 * Attaches nodemap_idmap_show to proc file.
101 * \param inode inode of seq file in proc fs
102 * \param file seq file
105 static int nodemap_idmap_open(struct inode *inode, struct file *file)
107 return single_open(file, nodemap_idmap_show, PDE_DATA(inode));
111 * Reads and prints the NID ranges for the given nodemap.
113 * \param m seq file in proc fs
117 static int nodemap_ranges_show(struct seq_file *m, void *data)
119 struct lu_nodemap *nodemap;
120 struct lu_nid_range *range;
121 struct interval_node_extent ext;
122 char start_nidstr[LNET_NIDSTR_SIZE];
123 char end_nidstr[LNET_NIDSTR_SIZE];
127 mutex_lock(&active_config_lock);
128 nodemap = nodemap_lookup(m->private);
129 if (IS_ERR(nodemap)) {
130 mutex_unlock(&active_config_lock);
131 rc = PTR_ERR(nodemap);
132 CERROR("cannot find nodemap '%s': rc = %d\n",
133 (char *)m->private, rc);
137 seq_printf(m, "[\n");
138 down_read(&active_config->nmc_range_tree_lock);
139 list_for_each_entry(range, &nodemap->nm_ranges, rn_list) {
141 seq_printf(m, ",\n");
143 ext = range->rn_node.in_extent;
144 libcfs_nid2str_r(ext.start, start_nidstr, sizeof(start_nidstr));
145 libcfs_nid2str_r(ext.end, end_nidstr, sizeof(end_nidstr));
146 seq_printf(m, " { id: %u, start_nid: %s, end_nid: %s }",
147 range->rn_id, start_nidstr, end_nidstr);
149 up_read(&active_config->nmc_range_tree_lock);
150 mutex_unlock(&active_config_lock);
152 seq_printf(m, "]\n");
154 nodemap_putref(nodemap);
159 * Connects nodemap_idmap_show to proc file.
161 * \param inode inode of seq file in proc fs
162 * \param file seq file
165 static int nodemap_ranges_open(struct inode *inode, struct file *file)
167 return single_open(file, nodemap_ranges_show, PDE_DATA(inode));
171 * Reads and prints the fileset for the given nodemap.
173 * \param m seq file in proc fs
177 static int nodemap_fileset_seq_show(struct seq_file *m, void *data)
179 struct lu_nodemap *nodemap;
182 mutex_lock(&active_config_lock);
183 nodemap = nodemap_lookup(m->private);
184 mutex_unlock(&active_config_lock);
185 if (IS_ERR(nodemap)) {
186 rc = PTR_ERR(nodemap);
187 CERROR("cannot find nodemap '%s': rc = %d\n",
188 (char *)m->private, rc);
192 seq_printf(m, "%s\n", nodemap->nm_fileset);
193 nodemap_putref(nodemap);
198 * Set a fileset on a nodemap.
200 * \param[in] file proc file
201 * \param[in] buffer string, "<fileset>"
202 * \param[in] count \a buffer length
203 * \param[in] off unused
204 * \retval \a count on success
205 * \retval negative number on error
208 nodemap_fileset_seq_write(struct file *file,
209 const char __user *buffer,
210 size_t count, loff_t *off)
212 struct seq_file *m = file->private_data;
220 if (count > PATH_MAX)
223 OBD_ALLOC(nm_fileset, count + 1);
224 /* OBD_ALLOC zero-fills the buffer */
225 if (nm_fileset == NULL)
228 if (copy_from_user(nm_fileset, buffer, count))
229 GOTO(out, rc = -EFAULT);
231 rc = nodemap_set_fileset(m->private, nm_fileset);
233 GOTO(out, rc = -EINVAL);
237 OBD_FREE(nm_fileset, count + 1);
241 LPROC_SEQ_FOPS(nodemap_fileset);
244 * Reads and prints the exports attached to the given nodemap.
246 * \param m seq file in proc fs, stores nodemap
250 static int nodemap_exports_show(struct seq_file *m, void *data)
252 struct lu_nodemap *nodemap;
253 struct obd_export *exp;
254 char nidstr[LNET_NIDSTR_SIZE] = "<unknown>";
257 mutex_lock(&active_config_lock);
258 nodemap = nodemap_lookup(m->private);
259 mutex_unlock(&active_config_lock);
260 if (IS_ERR(nodemap)) {
261 rc = PTR_ERR(nodemap);
262 CERROR("cannot find nodemap '%s': rc = %d\n",
263 (char *)m->private, rc);
267 seq_printf(m, "[\n");
269 mutex_lock(&nodemap->nm_member_list_lock);
270 list_for_each_entry(exp, &nodemap->nm_member_list,
271 exp_target_data.ted_nodemap_member) {
272 if (exp->exp_connection != NULL)
273 libcfs_nid2str_r(exp->exp_connection->c_peer.nid,
274 nidstr, sizeof(nidstr));
276 seq_printf(m, " { nid: %s, uuid: %s },",
277 nidstr, exp->exp_client_uuid.uuid);
279 mutex_unlock(&nodemap->nm_member_list_lock);
282 seq_printf(m, "]\n");
284 nodemap_putref(nodemap);
289 * Attaches nodemap_idmap_show to proc file.
291 * \param inode inode of seq file in proc fs
292 * \param file seq file
295 static int nodemap_exports_open(struct inode *inode, struct file *file)
297 return single_open(file, nodemap_exports_show, PDE_DATA(inode));
301 * Reads and prints the active flag for the given nodemap.
303 * \param m seq file in proc fs
307 static int nodemap_active_seq_show(struct seq_file *m, void *data)
309 seq_printf(m, "%u\n", (unsigned int)nodemap_active);
314 * Activate/deactivate nodemap.
316 * \param[in] file proc file
317 * \param[in] buffer string, "1" or "0" to activate/deactivate nodemap
318 * \param[in] count \a buffer length
319 * \param[in] off unused
320 * \retval \a count on success
321 * \retval negative number on error
324 nodemap_active_seq_write(struct file *file, const char __user *buffer,
325 size_t count, loff_t *off)
327 char active_string[NODEMAP_LPROC_FLAG_LEN + 1];
328 long unsigned int active;
334 if (count >= sizeof(active_string))
337 if (copy_from_user(active_string, buffer, count))
340 active_string[count] = '\0';
341 rc = kstrtoul(active_string, 10, &active);
345 nodemap_activate(active);
349 LPROC_SEQ_FOPS(nodemap_active);
352 * Reads and prints the nodemap ID for the given nodemap.
354 * \param m seq file in proc fs
358 static int nodemap_id_seq_show(struct seq_file *m, void *data)
360 struct lu_nodemap *nodemap;
362 mutex_lock(&active_config_lock);
363 nodemap = nodemap_lookup(m->private);
364 mutex_unlock(&active_config_lock);
365 if (IS_ERR(nodemap)) {
366 int rc = PTR_ERR(nodemap);
367 CERROR("cannot find nodemap '%s': rc = %d\n",
368 (char *)m->private, rc);
372 seq_printf(m, "%u\n", nodemap->nm_id);
373 nodemap_putref(nodemap);
376 LPROC_SEQ_FOPS_RO(nodemap_id);
379 * Reads and prints the root squash UID for the given nodemap.
381 * \param m seq file in proc fs
385 static int nodemap_squash_uid_seq_show(struct seq_file *m, void *data)
387 struct lu_nodemap *nodemap;
389 mutex_lock(&active_config_lock);
390 nodemap = nodemap_lookup(m->private);
391 mutex_unlock(&active_config_lock);
392 if (IS_ERR(nodemap)) {
393 int rc = PTR_ERR(nodemap);
394 CERROR("cannot find nodemap '%s': rc = %d\n",
395 (char *)m->private, rc);
399 seq_printf(m, "%u\n", nodemap->nm_squash_uid);
400 nodemap_putref(nodemap);
405 * Reads and prints the root squash GID for the given nodemap.
407 * \param m seq file in proc fs
411 static int nodemap_squash_gid_seq_show(struct seq_file *m, void *data)
413 struct lu_nodemap *nodemap;
415 mutex_lock(&active_config_lock);
416 nodemap = nodemap_lookup(m->private);
417 mutex_unlock(&active_config_lock);
418 if (IS_ERR(nodemap)) {
419 int rc = PTR_ERR(nodemap);
420 CERROR("cannot find nodemap '%s': rc = %d\n",
421 (char *)m->private, rc);
425 seq_printf(m, "%u\n", nodemap->nm_squash_gid);
426 nodemap_putref(nodemap);
431 * Reads and prints the trusted flag for the given nodemap.
433 * \param m seq file in proc fs
437 static int nodemap_trusted_seq_show(struct seq_file *m, void *data)
439 struct lu_nodemap *nodemap;
441 mutex_lock(&active_config_lock);
442 nodemap = nodemap_lookup(m->private);
443 mutex_unlock(&active_config_lock);
444 if (IS_ERR(nodemap)) {
445 int rc = PTR_ERR(nodemap);
447 CERROR("cannot find nodemap '%s': rc = %d\n",
448 (char *)m->private, rc);
452 seq_printf(m, "%d\n", (int)nodemap->nmf_trust_client_ids);
453 nodemap_putref(nodemap);
458 * Reads and prints the admin flag for the given nodemap.
460 * \param m seq file in proc fs
464 static int nodemap_admin_seq_show(struct seq_file *m, void *data)
466 struct lu_nodemap *nodemap;
469 mutex_lock(&active_config_lock);
470 nodemap = nodemap_lookup(m->private);
471 mutex_unlock(&active_config_lock);
472 if (IS_ERR(nodemap)) {
473 rc = PTR_ERR(nodemap);
474 CERROR("cannot find nodemap '%s': rc = %d\n",
475 (char *)m->private, rc);
479 seq_printf(m, "%d\n", (int)nodemap->nmf_allow_root_access);
480 nodemap_putref(nodemap);
485 * Reads and prints the mapping mode for the given nodemap.
487 * \param m seq file in proc fs
491 static int nodemap_map_mode_seq_show(struct seq_file *m, void *data)
493 struct lu_nodemap *nodemap;
496 mutex_lock(&active_config_lock);
497 nodemap = nodemap_lookup(m->private);
498 mutex_unlock(&active_config_lock);
499 if (IS_ERR(nodemap)) {
500 rc = PTR_ERR(nodemap);
501 CERROR("cannot find nodemap '%s': rc = %d\n",
502 (char *)m->private, rc);
506 if (nodemap->nmf_map_uid_only)
507 seq_printf(m, "uid_only\n");
508 else if (nodemap->nmf_map_gid_only)
509 seq_printf(m, "gid_only\n");
511 seq_printf(m, "both\n");
513 nodemap_putref(nodemap);
518 * Reads and prints the deny_unknown flag for the given nodemap.
520 * \param m seq file in proc fs
524 static int nodemap_deny_unknown_seq_show(struct seq_file *m, void *data)
526 struct lu_nodemap *nodemap;
529 mutex_lock(&active_config_lock);
530 nodemap = nodemap_lookup(m->private);
531 mutex_unlock(&active_config_lock);
532 if (IS_ERR(nodemap)) {
533 rc = PTR_ERR(nodemap);
534 CERROR("cannot find nodemap '%s': rc = %d\n",
535 (char *)m->private, rc);
539 seq_printf(m, "%d\n", (int)nodemap->nmf_deny_unknown);
540 nodemap_putref(nodemap);
545 * Reads and prints the audit_mode flag for the given nodemap.
547 * \param m seq file in proc fs
551 static int nodemap_audit_mode_seq_show(struct seq_file *m, void *data)
553 struct lu_nodemap *nodemap;
556 mutex_lock(&active_config_lock);
557 nodemap = nodemap_lookup(m->private);
558 mutex_unlock(&active_config_lock);
559 if (IS_ERR(nodemap)) {
560 rc = PTR_ERR(nodemap);
561 CERROR("cannot find nodemap '%s': rc = %d\n",
562 (char *)m->private, rc);
566 seq_printf(m, "%d\n", (int)nodemap->nmf_enable_audit);
567 nodemap_putref(nodemap);
571 #ifdef NODEMAP_PROC_DEBUG
573 * Helper functions to set nodemap flags.
575 * \param[in] buffer string, which is "1" or "0" to set/unset flag
576 * \param[in] count \a buffer length
577 * \param[out] flag_p where to store flag value
578 * \retval \a count on success
579 * \retval negative number on error
581 static int nodemap_proc_read_flag(const char __user *buffer,
582 unsigned long count, unsigned int *flag_p)
584 char scratch[NODEMAP_LPROC_FLAG_LEN + 1];
585 long unsigned int flag_buf;
591 if (count >= sizeof(scratch))
594 if (copy_from_user(scratch, buffer, count))
597 scratch[count] = '\0';
598 rc = kstrtoul(scratch, 10, &flag_buf);
608 * Set the squash UID.
610 * \param[in] file proc file
611 * \param[in] buffer string representing squash UID to set
612 * \param[in] count \a buffer length
613 * \param[in] off unused
614 * \retval \a count on success
615 * \retval negative number on error
618 nodemap_squash_uid_seq_write(struct file *file, const char __user *buffer,
619 size_t count, loff_t *off)
621 char squash[NODEMAP_LPROC_ID_LEN + 1];
622 struct seq_file *m = file->private_data;
623 long unsigned int squash_uid;
629 if (count >= sizeof(squash))
632 if (copy_from_user(squash, buffer, count))
635 squash[count] = '\0';
636 rc = kstrtoul(squash, 10, &squash_uid);
640 rc = nodemap_set_squash_uid(m->private, squash_uid);
648 * Set the squash GID.
650 * \param[in] file proc file
651 * \param[in] buffer string representing squash GID to set
652 * \param[in] count \a buffer length
653 * \param[in] off unused
654 * \retval \a count on success
655 * \retval negative number on error
658 nodemap_squash_gid_seq_write(struct file *file, const char __user *buffer,
659 size_t count, loff_t *off)
661 char squash[NODEMAP_LPROC_ID_LEN + 1];
662 struct seq_file *m = file->private_data;
663 long unsigned int squash_gid;
669 if (count >= sizeof(squash))
672 if (copy_from_user(squash, buffer, count))
675 squash[count] = '\0';
676 rc = kstrtoul(squash, 10, &squash_gid);
680 rc = nodemap_set_squash_gid(m->private, squash_gid);
688 * Set/unset the trusted flag.
690 * \param[in] file proc file
691 * \param[in] buffer string, "1" or "0"
692 * \param[in] count \a buffer length
693 * \param[in] off unused
694 * \retval \a count on success
695 * \retval negative number on error
698 nodemap_trusted_seq_write(struct file *file, const char __user *buffer,
699 size_t count, loff_t *off)
701 struct seq_file *m = file->private_data;
705 rc = nodemap_proc_read_flag(buffer, count, &flags);
709 rc = nodemap_set_trust_client_ids(m->private, flags);
717 * Set/unset the admin flag.
719 * \param[in] file proc file
720 * \param[in] buffer string, "1" or "0"
721 * \param[in] count \a buffer length
722 * \param[in] off unused
723 * \retval \a count on success
724 * \retval negative number on error
727 nodemap_admin_seq_write(struct file *file, const char __user *buffer,
728 size_t count, loff_t *off)
730 struct seq_file *m = file->private_data;
734 rc = nodemap_proc_read_flag(buffer, count, &flags);
738 rc = nodemap_set_allow_root(m->private, flags);
748 * \param[in] file proc file
749 * \param[in] buffer string, name of the nodemap to add
750 * \param[in] count \a buffer length
751 * \param[in] off unused
752 * \retval \a count on success
753 * \retval negative number on error
756 lprocfs_add_nodemap_seq_write(struct file *file, const char __user *buffer,
757 size_t count, loff_t *off)
759 char nodemap_name[LUSTRE_NODEMAP_NAME_LENGTH + 1];
767 if (count >= sizeof(nodemap_name))
770 if (copy_from_user(nodemap_name, buffer, count))
773 nodemap_name[count] = '\0';
775 cpybuf = nodemap_name;
776 pos = strsep(&cpybuf, " \n");
780 rc = nodemap_add(nodemap_name);
786 LPROC_SEQ_FOPS_WR_ONLY(nodemap, add_nodemap);
791 * \param[in] file proc file
792 * \param[in] buffer string, name of the nodemap to delete
793 * \param[in] count \a buffer length
794 * \param[in] off unused
795 * \retval \a count on success
796 * \retval negative number on error
799 lprocfs_del_nodemap_seq_write(struct file *file, const char __user *buffer,
800 size_t count, loff_t *off)
802 char nodemap_name[LUSTRE_NODEMAP_NAME_LENGTH + 1];
810 if (count >= sizeof(nodemap_name))
813 if (copy_from_user(nodemap_name, buffer, count))
816 nodemap_name[count] = '\0';
818 cpybuf = nodemap_name;
819 pos = strsep(&cpybuf, " \n");
823 rc = nodemap_del(nodemap_name);
830 LPROC_SEQ_FOPS_WR_ONLY(nodemap, del_nodemap);
833 * Helper function to parse a NID string.
835 * \param[in] rangestr string representation of NIDs, see libcfs_str2nid()
836 * \param[out] nids array of two nids
837 * \retval 0 on success
838 * \retval negative number on error
840 static int parse_nids(char *rangestr, lnet_nid_t nids[2])
842 struct list_head nidlist;
843 char nidstr[2][LNET_NIDSTR_SIZE];
844 char nidrange_str[2 * LNET_NIDSTR_SIZE + 2];
847 INIT_LIST_HEAD(&nidlist);
849 if (cfs_parse_nidlist(rangestr, strlen(rangestr),
853 rc = cfs_nidrange_find_min_max(&nidlist, nidstr[0], nidstr[1],
858 snprintf(nidrange_str, sizeof(nidrange_str), "%s:%s",
859 nidstr[0], nidstr[1]);
861 rc = nodemap_parse_range(nidrange_str, nids);
865 cfs_free_nidlist(&nidlist);
871 * Add a NID range to nodemap.
873 * \param[in] file proc file
874 * \param[in] buffer string, "<nodemap name> <nid range>"
875 * \param[in] count \a buffer length
876 * \param[in] off unused
877 * \retval \a count on success
878 * \retval negative number on error
881 lprocfs_add_nodemap_range_seq_write(struct file *file,
882 const char __user *buffer,
883 size_t count, loff_t *off)
885 char name_range[LUSTRE_NODEMAP_NAME_LENGTH +
886 LNET_NIDSTR_SIZE * 2 + 2];
889 char *rangestr = NULL;
896 if (count >= sizeof(name_range))
897 GOTO(out, rc = -EINVAL);
899 if (copy_from_user(name_range, buffer, count))
900 GOTO(out, rc = -EFAULT);
902 name_range[count] = '\0';
905 name = strsep(&cpybuf, " ");
907 GOTO(out, rc = -EINVAL);
909 rangestr = strsep(&cpybuf, " \n");
910 if (rangestr == NULL)
911 GOTO(out, rc = -EINVAL);
913 rc = parse_nids(rangestr, nids);
917 rc = nodemap_add_range(name, nids);
919 GOTO(out, rc = -EINVAL);
927 LPROC_SEQ_FOPS_WR_ONLY(nodemap, add_nodemap_range);
930 * Delete a NID range from nodemap.
932 * \param[in] file proc file
933 * \param[in] buffer string, "<nodemap name> <nid range>"
934 * \param[in] count \a buffer length
935 * \param[in] off unused
936 * \retval \a count on success
937 * \retval negative number on error
940 lprocfs_del_nodemap_range_seq_write(struct file *file,
941 const char __user *buffer,
942 size_t count, loff_t *off)
944 char name_range[LUSTRE_NODEMAP_NAME_LENGTH +
945 LNET_NIDSTR_SIZE * 2 + 2];
948 char *rangestr = NULL;
955 if (count >= sizeof(name_range))
956 GOTO(out, rc = -EINVAL);
958 if (copy_from_user(name_range, buffer, count))
959 GOTO(out, rc = -EFAULT);
961 name_range[count] = '\0';
964 name = strsep(&cpybuf, " ");
966 GOTO(out, rc = -EINVAL);
968 rangestr = strsep(&cpybuf, " \n");
969 if (rangestr == NULL)
970 GOTO(out, rc = -EINVAL);
972 rc = parse_nids(rangestr, nids);
976 rc = nodemap_del_range(name, nids);
978 GOTO(out, rc = -EINVAL);
986 LPROC_SEQ_FOPS_WR_ONLY(nodemap, del_nodemap_range);
989 * Add an idmap to nodemap.
991 * \param[in] file proc file
992 * \param[in] buffer string, "<nodemap name> <uid|gid> <idmap>"
993 * \param[in] count \a buffer length
994 * \param[in] off unused
995 * \retval \a count on success
996 * \retval negative number on error
999 lprocfs_add_nodemap_idmap_seq_write(struct file *file,
1000 const char __user *buffer,
1001 size_t count, loff_t *off)
1003 char name_idmapstr[LUSTRE_NODEMAP_NAME_LENGTH + 16];
1004 char *cpybuf = NULL;
1006 char *idtypestr = NULL;
1007 char *idmapstr = NULL;
1014 if (count >= sizeof(name_idmapstr))
1015 GOTO(out, rc = -EINVAL);
1017 if (copy_from_user(name_idmapstr, buffer, count))
1018 GOTO(out, rc = -EFAULT);
1020 name_idmapstr[count] = '\0';
1022 cpybuf = name_idmapstr;
1023 name = strsep(&cpybuf, " ");
1025 GOTO(out, rc = -EINVAL);
1027 idtypestr = strsep(&cpybuf, " ");
1028 if (idtypestr == NULL)
1029 GOTO(out, rc = -EINVAL);
1031 idmapstr = strsep(&cpybuf, " \n");
1032 if (idmapstr == NULL)
1033 GOTO(out, rc = -EINVAL);
1035 rc = nodemap_parse_idmap(idmapstr, idmap);
1037 GOTO(out, rc = -EINVAL);
1039 if (strcmp(idtypestr, "uid") == 0)
1040 rc = nodemap_add_idmap(name, NODEMAP_UID, idmap);
1041 else if (strcmp(idtypestr, "gid") == 0)
1042 rc = nodemap_add_idmap(name, NODEMAP_GID, idmap);
1044 GOTO(out, rc = -EINVAL);
1047 GOTO(out, rc = -EINVAL);
1055 LPROC_SEQ_FOPS_WR_ONLY(nodemap, add_nodemap_idmap);
1058 * Delete an idmap from nodemap.
1060 * \param[in] file proc file
1061 * \param[in] buffer string, "<nodemap name> <uid|gid> <idmap>"
1062 * \param[in] count \a buffer length
1063 * \param[in] off unused
1064 * \retval \a count on success
1065 * \retval negative number on error
1068 lprocfs_del_nodemap_idmap_seq_write(struct file *file,
1069 const char __user *buffer,
1070 size_t count, loff_t *off)
1072 char name_idmapstr[LUSTRE_NODEMAP_NAME_LENGTH + 16];
1073 char *cpybuf = NULL;
1075 char *idtypestr = NULL;
1076 char *idmapstr = NULL;
1083 if (count >= sizeof(name_idmapstr))
1084 GOTO(out, rc = -EINVAL);
1086 if (copy_from_user(name_idmapstr, buffer, count))
1087 GOTO(out, rc = -EFAULT);
1089 name_idmapstr[count] = '\0';
1091 cpybuf = name_idmapstr;
1092 name = strsep(&cpybuf, " ");
1094 GOTO(out, rc = -EINVAL);
1096 idtypestr = strsep(&cpybuf, " ");
1097 if (idtypestr == NULL)
1098 GOTO(out, rc = -EINVAL);
1100 idmapstr = strsep(&cpybuf, " \n");
1101 if (idmapstr == NULL)
1102 GOTO(out, rc = -EINVAL);
1104 rc = nodemap_parse_idmap(idmapstr, idmap);
1106 GOTO(out, rc = -EINVAL);
1108 if (strcmp(idtypestr, "uid") == 0)
1109 rc = nodemap_del_idmap(name, NODEMAP_UID, idmap);
1110 else if (strcmp(idtypestr, "gid") == 0)
1111 rc = nodemap_del_idmap(name, NODEMAP_GID, idmap);
1113 GOTO(out, rc = -EINVAL);
1116 GOTO(out, rc = -EINVAL);
1124 LPROC_SEQ_FOPS_WR_ONLY(nodemap, del_nodemap_idmap);
1125 #endif /* NODEMAP_PROC_DEBUG */
1127 static struct lprocfs_vars lprocfs_nm_module_vars[] = {
1130 .fops = &nodemap_active_fops,
1132 #ifdef NODEMAP_PROC_DEBUG
1134 .name = "add_nodemap",
1135 .fops = &nodemap_add_nodemap_fops,
1138 .name = "remove_nodemap",
1139 .fops = &nodemap_del_nodemap_fops,
1142 .name = "add_nodemap_range",
1143 .fops = &nodemap_add_nodemap_range_fops,
1146 .name = "del_nodemap_range",
1147 .fops = &nodemap_del_nodemap_range_fops,
1150 .name = "add_nodemap_idmap",
1151 .fops = &nodemap_add_nodemap_idmap_fops,
1154 .name = "del_nodemap_idmap",
1155 .fops = &nodemap_del_nodemap_idmap_fops,
1157 #endif /* NODEMAP_PROC_DEBUG */
1163 #ifdef NODEMAP_PROC_DEBUG
1164 LPROC_SEQ_FOPS(nodemap_trusted);
1165 LPROC_SEQ_FOPS(nodemap_admin);
1166 LPROC_SEQ_FOPS(nodemap_squash_uid);
1167 LPROC_SEQ_FOPS(nodemap_squash_gid);
1169 LPROC_SEQ_FOPS_RO(nodemap_trusted);
1170 LPROC_SEQ_FOPS_RO(nodemap_admin);
1171 LPROC_SEQ_FOPS_RO(nodemap_squash_uid);
1172 LPROC_SEQ_FOPS_RO(nodemap_squash_gid);
1175 LPROC_SEQ_FOPS_RO(nodemap_deny_unknown);
1176 LPROC_SEQ_FOPS_RO(nodemap_map_mode);
1177 LPROC_SEQ_FOPS_RO(nodemap_audit_mode);
1179 const struct file_operations nodemap_ranges_fops = {
1180 .open = nodemap_ranges_open,
1182 .llseek = seq_lseek,
1183 .release = single_release
1186 const struct file_operations nodemap_idmap_fops = {
1187 .open = nodemap_idmap_open,
1189 .llseek = seq_lseek,
1190 .release = single_release
1193 const struct file_operations nodemap_exports_fops = {
1194 .open = nodemap_exports_open,
1196 .llseek = seq_lseek,
1197 .release = single_release
1200 static struct lprocfs_vars lprocfs_nodemap_vars[] = {
1203 .fops = &nodemap_id_fops,
1206 .name = "trusted_nodemap",
1207 .fops = &nodemap_trusted_fops,
1210 .name = "admin_nodemap",
1211 .fops = &nodemap_admin_fops,
1214 .name = "deny_unknown",
1215 .fops = &nodemap_deny_unknown_fops,
1219 .fops = &nodemap_map_mode_fops,
1222 .name = "audit_mode",
1223 .fops = &nodemap_audit_mode_fops,
1226 .name = "squash_uid",
1227 .fops = &nodemap_squash_uid_fops,
1230 .name = "squash_gid",
1231 .fops = &nodemap_squash_gid_fops,
1235 .fops = &nodemap_ranges_fops,
1239 .fops = &nodemap_fileset_fops,
1243 .fops = &nodemap_exports_fops,
1247 .fops = &nodemap_idmap_fops,
1254 static struct lprocfs_vars lprocfs_default_nodemap_vars[] = {
1257 .fops = &nodemap_id_fops,
1260 .name = "trusted_nodemap",
1261 .fops = &nodemap_trusted_fops,
1264 .name = "admin_nodemap",
1265 .fops = &nodemap_admin_fops,
1268 .name = "squash_uid",
1269 .fops = &nodemap_squash_uid_fops,
1272 .name = "squash_gid",
1273 .fops = &nodemap_squash_gid_fops,
1277 .fops = &nodemap_fileset_fops,
1281 .fops = &nodemap_exports_fops,
1284 .name = "audit_mode",
1285 .fops = &nodemap_audit_mode_fops,
1293 * Initialize the nodemap procfs directory.
1297 int nodemap_procfs_init(void)
1301 proc_lustre_nodemap_root = lprocfs_register(LUSTRE_NODEMAP_NAME,
1303 lprocfs_nm_module_vars,
1305 if (IS_ERR(proc_lustre_nodemap_root)) {
1306 rc = PTR_ERR(proc_lustre_nodemap_root);
1307 CERROR("cannot create 'nodemap' directory: rc = %d\n",
1309 proc_lustre_nodemap_root = NULL;
1315 * Cleanup nodemap proc entry data structures.
1317 void nodemap_procfs_exit(void)
1319 struct nodemap_pde *nm_pde;
1320 struct nodemap_pde *tmp;
1322 lprocfs_remove(&proc_lustre_nodemap_root);
1323 list_for_each_entry_safe(nm_pde, tmp, &nodemap_pde_list,
1325 list_del(&nm_pde->npe_list_member);
1326 OBD_FREE_PTR(nm_pde);
1331 * Remove a nodemap's procfs entry and related data.
1333 void lprocfs_nodemap_remove(struct nodemap_pde *nm_pde)
1335 lprocfs_remove(&nm_pde->npe_proc_entry);
1336 list_del(&nm_pde->npe_list_member);
1337 OBD_FREE_PTR(nm_pde);
1341 * Register the proc directory for a nodemap
1343 * \param nodemap nodemap to make the proc dir for
1344 * \param is_default: 1 if default nodemap
1347 int lprocfs_nodemap_register(struct lu_nodemap *nodemap, bool is_default)
1349 struct nodemap_pde *nm_entry;
1352 OBD_ALLOC_PTR(nm_entry);
1353 if (nm_entry == NULL)
1354 GOTO(out, rc = -ENOMEM);
1356 nm_entry->npe_proc_entry = proc_mkdir(nodemap->nm_name,
1357 proc_lustre_nodemap_root);
1358 if (IS_ERR(nm_entry->npe_proc_entry))
1359 GOTO(out, rc = PTR_ERR(nm_entry->npe_proc_entry));
1361 snprintf(nm_entry->npe_name, sizeof(nm_entry->npe_name), "%s",
1364 /* Use the nodemap name as stored on the PDE as the private data. This
1365 * is so a nodemap struct can be replaced without updating the proc
1368 rc = lprocfs_add_vars(nm_entry->npe_proc_entry,
1369 (is_default ? lprocfs_default_nodemap_vars :
1370 lprocfs_nodemap_vars),
1371 nm_entry->npe_name);
1373 lprocfs_remove(&nm_entry->npe_proc_entry);
1375 list_add(&nm_entry->npe_list_member, &nodemap_pde_list);
1379 CERROR("cannot create 'nodemap/%s': rc = %d\n",
1380 nodemap->nm_name, rc);
1381 if (nm_entry != NULL) {
1382 OBD_FREE_PTR(nm_entry);
1387 nodemap->nm_pde_data = nm_entry;