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, 2015, 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 read_lock(&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 read_unlock(&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);
224 if (nm_fileset == NULL)
227 if (copy_from_user(nm_fileset, buffer, count))
228 GOTO(out, rc = -EFAULT);
230 rc = nodemap_set_fileset(m->private, nm_fileset);
232 GOTO(out, rc = -EINVAL);
236 OBD_FREE(nm_fileset, count);
240 LPROC_SEQ_FOPS(nodemap_fileset);
243 * Reads and prints the exports attached to the given nodemap.
245 * \param m seq file in proc fs, stores nodemap
249 static int nodemap_exports_show(struct seq_file *m, void *data)
251 struct lu_nodemap *nodemap;
252 struct obd_export *exp;
253 char nidstr[LNET_NIDSTR_SIZE] = "<unknown>";
256 mutex_lock(&active_config_lock);
257 nodemap = nodemap_lookup(m->private);
258 mutex_unlock(&active_config_lock);
259 if (IS_ERR(nodemap)) {
260 rc = PTR_ERR(nodemap);
261 CERROR("cannot find nodemap '%s': rc = %d\n",
262 (char *)m->private, rc);
266 seq_printf(m, "[\n");
268 mutex_lock(&nodemap->nm_member_list_lock);
269 list_for_each_entry(exp, &nodemap->nm_member_list,
270 exp_target_data.ted_nodemap_member) {
271 if (exp->exp_connection != NULL)
272 libcfs_nid2str_r(exp->exp_connection->c_peer.nid,
273 nidstr, sizeof(nidstr));
275 seq_printf(m, " { nid: %s, uuid: %s },",
276 nidstr, exp->exp_client_uuid.uuid);
278 mutex_unlock(&nodemap->nm_member_list_lock);
281 seq_printf(m, "]\n");
283 nodemap_putref(nodemap);
288 * Attaches nodemap_idmap_show to proc file.
290 * \param inode inode of seq file in proc fs
291 * \param file seq file
294 static int nodemap_exports_open(struct inode *inode, struct file *file)
296 return single_open(file, nodemap_exports_show, PDE_DATA(inode));
300 * Reads and prints the active flag for the given nodemap.
302 * \param m seq file in proc fs
306 static int nodemap_active_seq_show(struct seq_file *m, void *data)
308 seq_printf(m, "%u\n", (unsigned int)nodemap_active);
313 * Activate/deactivate nodemap.
315 * \param[in] file proc file
316 * \param[in] buffer string, "1" or "0" to activate/deactivate nodemap
317 * \param[in] count \a buffer length
318 * \param[in] off unused
319 * \retval \a count on success
320 * \retval negative number on error
323 nodemap_active_seq_write(struct file *file, const char __user *buffer,
324 size_t count, loff_t *off)
326 char active_string[NODEMAP_LPROC_FLAG_LEN + 1];
327 long unsigned int active;
333 if (count >= sizeof(active_string))
336 if (copy_from_user(active_string, buffer, count))
339 active_string[count] = '\0';
340 rc = kstrtoul(active_string, 10, &active);
344 nodemap_activate(active);
348 LPROC_SEQ_FOPS(nodemap_active);
351 * Reads and prints the nodemap ID for the given nodemap.
353 * \param m seq file in proc fs
357 static int nodemap_id_seq_show(struct seq_file *m, void *data)
359 struct lu_nodemap *nodemap;
361 mutex_lock(&active_config_lock);
362 nodemap = nodemap_lookup(m->private);
363 mutex_unlock(&active_config_lock);
364 if (IS_ERR(nodemap)) {
365 int rc = PTR_ERR(nodemap);
366 CERROR("cannot find nodemap '%s': rc = %d\n",
367 (char *)m->private, rc);
371 seq_printf(m, "%u\n", nodemap->nm_id);
372 nodemap_putref(nodemap);
375 LPROC_SEQ_FOPS_RO(nodemap_id);
378 * Reads and prints the root squash UID for the given nodemap.
380 * \param m seq file in proc fs
384 static int nodemap_squash_uid_seq_show(struct seq_file *m, void *data)
386 struct lu_nodemap *nodemap;
388 mutex_lock(&active_config_lock);
389 nodemap = nodemap_lookup(m->private);
390 mutex_unlock(&active_config_lock);
391 if (IS_ERR(nodemap)) {
392 int rc = PTR_ERR(nodemap);
393 CERROR("cannot find nodemap '%s': rc = %d\n",
394 (char *)m->private, rc);
398 seq_printf(m, "%u\n", nodemap->nm_squash_uid);
399 nodemap_putref(nodemap);
404 * Reads and prints the root squash GID for the given nodemap.
406 * \param m seq file in proc fs
410 static int nodemap_squash_gid_seq_show(struct seq_file *m, void *data)
412 struct lu_nodemap *nodemap;
414 mutex_lock(&active_config_lock);
415 nodemap = nodemap_lookup(m->private);
416 mutex_unlock(&active_config_lock);
417 if (IS_ERR(nodemap)) {
418 int rc = PTR_ERR(nodemap);
419 CERROR("cannot find nodemap '%s': rc = %d\n",
420 (char *)m->private, rc);
424 seq_printf(m, "%u\n", nodemap->nm_squash_gid);
425 nodemap_putref(nodemap);
430 * Reads and prints the trusted flag for the given nodemap.
432 * \param m seq file in proc fs
436 static int nodemap_trusted_seq_show(struct seq_file *m, void *data)
438 struct lu_nodemap *nodemap;
440 mutex_lock(&active_config_lock);
441 nodemap = nodemap_lookup(m->private);
442 mutex_unlock(&active_config_lock);
443 if (IS_ERR(nodemap)) {
444 int rc = PTR_ERR(nodemap);
446 CERROR("cannot find nodemap '%s': rc = %d\n",
447 (char *)m->private, rc);
451 seq_printf(m, "%d\n", (int)nodemap->nmf_trust_client_ids);
452 nodemap_putref(nodemap);
457 * Reads and prints the admin flag for the given nodemap.
459 * \param m seq file in proc fs
463 static int nodemap_admin_seq_show(struct seq_file *m, void *data)
465 struct lu_nodemap *nodemap;
468 mutex_lock(&active_config_lock);
469 nodemap = nodemap_lookup(m->private);
470 mutex_unlock(&active_config_lock);
471 if (IS_ERR(nodemap)) {
472 rc = PTR_ERR(nodemap);
473 CERROR("cannot find nodemap '%s': rc = %d\n",
474 (char *)m->private, rc);
478 seq_printf(m, "%d\n", (int)nodemap->nmf_allow_root_access);
479 nodemap_putref(nodemap);
484 * Reads and prints the mapping mode for the given nodemap.
486 * \param m seq file in proc fs
490 static int nodemap_map_mode_seq_show(struct seq_file *m, void *data)
492 struct lu_nodemap *nodemap;
495 mutex_lock(&active_config_lock);
496 nodemap = nodemap_lookup(m->private);
497 mutex_unlock(&active_config_lock);
498 if (IS_ERR(nodemap)) {
499 rc = PTR_ERR(nodemap);
500 CERROR("cannot find nodemap '%s': rc = %d\n",
501 (char *)m->private, rc);
505 if (nodemap->nmf_map_uid_only)
506 seq_printf(m, "uid_only\n");
507 else if (nodemap->nmf_map_gid_only)
508 seq_printf(m, "gid_only\n");
510 seq_printf(m, "both\n");
512 nodemap_putref(nodemap);
517 * Reads and prints the deny_unknown flag for the given nodemap.
519 * \param m seq file in proc fs
523 static int nodemap_deny_unknown_seq_show(struct seq_file *m, void *data)
525 struct lu_nodemap *nodemap;
528 mutex_lock(&active_config_lock);
529 nodemap = nodemap_lookup(m->private);
530 mutex_unlock(&active_config_lock);
531 if (IS_ERR(nodemap)) {
532 rc = PTR_ERR(nodemap);
533 CERROR("cannot find nodemap '%s': rc = %d\n",
534 (char *)m->private, rc);
538 seq_printf(m, "%d\n", (int)nodemap->nmf_deny_unknown);
539 nodemap_putref(nodemap);
543 #ifdef NODEMAP_PROC_DEBUG
545 * Helper functions to set nodemap flags.
547 * \param[in] buffer string, which is "1" or "0" to set/unset flag
548 * \param[in] count \a buffer length
549 * \param[out] flag_p where to store flag value
550 * \retval \a count on success
551 * \retval negative number on error
553 static int nodemap_proc_read_flag(const char __user *buffer,
554 unsigned long count, unsigned int *flag_p)
556 char scratch[NODEMAP_LPROC_FLAG_LEN + 1];
557 long unsigned int flag_buf;
563 if (count >= sizeof(scratch))
566 if (copy_from_user(scratch, buffer, count))
569 scratch[count] = '\0';
570 rc = kstrtoul(scratch, 10, &flag_buf);
580 * Set the squash UID.
582 * \param[in] file proc file
583 * \param[in] buffer string representing squash UID to set
584 * \param[in] count \a buffer length
585 * \param[in] off unused
586 * \retval \a count on success
587 * \retval negative number on error
590 nodemap_squash_uid_seq_write(struct file *file, const char __user *buffer,
591 size_t count, loff_t *off)
593 char squash[NODEMAP_LPROC_ID_LEN + 1];
594 struct seq_file *m = file->private_data;
595 long unsigned int squash_uid;
601 if (count >= sizeof(squash))
604 if (copy_from_user(squash, buffer, count))
607 squash[count] = '\0';
608 rc = kstrtoul(squash, 10, &squash_uid);
612 rc = nodemap_set_squash_uid(m->private, squash_uid);
620 * Set the squash GID.
622 * \param[in] file proc file
623 * \param[in] buffer string representing squash GID to set
624 * \param[in] count \a buffer length
625 * \param[in] off unused
626 * \retval \a count on success
627 * \retval negative number on error
630 nodemap_squash_gid_seq_write(struct file *file, const char __user *buffer,
631 size_t count, loff_t *off)
633 char squash[NODEMAP_LPROC_ID_LEN + 1];
634 struct seq_file *m = file->private_data;
635 long unsigned int squash_gid;
641 if (count >= sizeof(squash))
644 if (copy_from_user(squash, buffer, count))
647 squash[count] = '\0';
648 rc = kstrtoul(squash, 10, &squash_gid);
652 rc = nodemap_set_squash_gid(m->private, squash_gid);
660 * Set/unset the trusted flag.
662 * \param[in] file proc file
663 * \param[in] buffer string, "1" or "0"
664 * \param[in] count \a buffer length
665 * \param[in] off unused
666 * \retval \a count on success
667 * \retval negative number on error
670 nodemap_trusted_seq_write(struct file *file, const char __user *buffer,
671 size_t count, loff_t *off)
673 struct seq_file *m = file->private_data;
677 rc = nodemap_proc_read_flag(buffer, count, &flags);
681 rc = nodemap_set_trust_client_ids(m->private, flags);
689 * Set/unset the admin flag.
691 * \param[in] file proc file
692 * \param[in] buffer string, "1" or "0"
693 * \param[in] count \a buffer length
694 * \param[in] off unused
695 * \retval \a count on success
696 * \retval negative number on error
699 nodemap_admin_seq_write(struct file *file, const char __user *buffer,
700 size_t count, loff_t *off)
702 struct seq_file *m = file->private_data;
706 rc = nodemap_proc_read_flag(buffer, count, &flags);
710 rc = nodemap_set_allow_root(m->private, flags);
720 * \param[in] file proc file
721 * \param[in] buffer string, name of the nodemap to add
722 * \param[in] count \a buffer length
723 * \param[in] off unused
724 * \retval \a count on success
725 * \retval negative number on error
728 lprocfs_add_nodemap_seq_write(struct file *file, const char __user *buffer,
729 size_t count, loff_t *off)
731 char nodemap_name[LUSTRE_NODEMAP_NAME_LENGTH + 1];
739 if (count >= sizeof(nodemap_name))
742 if (copy_from_user(nodemap_name, buffer, count))
745 nodemap_name[count] = '\0';
747 cpybuf = nodemap_name;
748 pos = strsep(&cpybuf, " \n");
752 rc = nodemap_add(nodemap_name);
758 LPROC_SEQ_FOPS_WO_TYPE(nodemap, add_nodemap);
763 * \param[in] file proc file
764 * \param[in] buffer string, name of the nodemap to delete
765 * \param[in] count \a buffer length
766 * \param[in] off unused
767 * \retval \a count on success
768 * \retval negative number on error
771 lprocfs_del_nodemap_seq_write(struct file *file, const char __user *buffer,
772 size_t count, loff_t *off)
774 char nodemap_name[LUSTRE_NODEMAP_NAME_LENGTH + 1];
782 if (count >= sizeof(nodemap_name))
785 if (copy_from_user(nodemap_name, buffer, count))
788 nodemap_name[count] = '\0';
790 cpybuf = nodemap_name;
791 pos = strsep(&cpybuf, " \n");
795 rc = nodemap_del(nodemap_name);
802 LPROC_SEQ_FOPS_WO_TYPE(nodemap, del_nodemap);
805 * Helper function to parse a NID string.
807 * \param[in] rangestr string representation of NIDs, see libcfs_str2nid()
808 * \param[out] nids array of two nids
809 * \retval 0 on success
810 * \retval negative number on error
812 static int parse_nids(char *rangestr, lnet_nid_t nids[2])
814 struct list_head nidlist;
815 char nidstr[2][LNET_NIDSTR_SIZE];
816 char nidrange_str[2 * LNET_NIDSTR_SIZE + 2];
819 INIT_LIST_HEAD(&nidlist);
821 if (cfs_parse_nidlist(rangestr, strlen(rangestr),
825 if (!cfs_nidrange_is_contiguous(&nidlist))
828 cfs_nidrange_find_min_max(&nidlist, nidstr[0], nidstr[1],
830 snprintf(nidrange_str, sizeof(nidrange_str), "%s:%s",
831 nidstr[0], nidstr[1]);
833 rc = nodemap_parse_range(nidrange_str, nids);
837 cfs_free_nidlist(&nidlist);
843 * Add a NID range to nodemap.
845 * \param[in] file proc file
846 * \param[in] buffer string, "<nodemap name> <nid range>"
847 * \param[in] count \a buffer length
848 * \param[in] off unused
849 * \retval \a count on success
850 * \retval negative number on error
853 lprocfs_add_nodemap_range_seq_write(struct file *file,
854 const char __user *buffer,
855 size_t count, loff_t *off)
857 char name_range[LUSTRE_NODEMAP_NAME_LENGTH +
858 LNET_NIDSTR_SIZE * 2 + 2];
861 char *rangestr = NULL;
868 if (count >= sizeof(name_range))
869 GOTO(out, rc = -EINVAL);
871 if (copy_from_user(name_range, buffer, count))
872 GOTO(out, rc = -EFAULT);
874 name_range[count] = '\0';
877 name = strsep(&cpybuf, " ");
879 GOTO(out, rc = -EINVAL);
881 rangestr = strsep(&cpybuf, " \n");
882 if (rangestr == NULL)
883 GOTO(out, rc = -EINVAL);
885 rc = parse_nids(rangestr, nids);
889 rc = nodemap_add_range(name, nids);
891 GOTO(out, rc = -EINVAL);
899 LPROC_SEQ_FOPS_WO_TYPE(nodemap, add_nodemap_range);
902 * Delete a NID range from nodemap.
904 * \param[in] file proc file
905 * \param[in] buffer string, "<nodemap name> <nid range>"
906 * \param[in] count \a buffer length
907 * \param[in] off unused
908 * \retval \a count on success
909 * \retval negative number on error
912 lprocfs_del_nodemap_range_seq_write(struct file *file,
913 const char __user *buffer,
914 size_t count, loff_t *off)
916 char name_range[LUSTRE_NODEMAP_NAME_LENGTH +
917 LNET_NIDSTR_SIZE * 2 + 2];
920 char *rangestr = NULL;
927 if (count >= sizeof(name_range))
928 GOTO(out, rc = -EINVAL);
930 if (copy_from_user(name_range, buffer, count))
931 GOTO(out, rc = -EFAULT);
933 name_range[count] = '\0';
936 name = strsep(&cpybuf, " ");
938 GOTO(out, rc = -EINVAL);
940 rangestr = strsep(&cpybuf, " \n");
941 if (rangestr == NULL)
942 GOTO(out, rc = -EINVAL);
944 rc = parse_nids(rangestr, nids);
948 rc = nodemap_del_range(name, nids);
950 GOTO(out, rc = -EINVAL);
958 LPROC_SEQ_FOPS_WO_TYPE(nodemap, del_nodemap_range);
961 * Add an idmap to nodemap.
963 * \param[in] file proc file
964 * \param[in] buffer string, "<nodemap name> <uid|gid> <idmap>"
965 * \param[in] count \a buffer length
966 * \param[in] off unused
967 * \retval \a count on success
968 * \retval negative number on error
971 lprocfs_add_nodemap_idmap_seq_write(struct file *file,
972 const char __user *buffer,
973 size_t count, loff_t *off)
975 char name_idmapstr[LUSTRE_NODEMAP_NAME_LENGTH + 16];
978 char *idtypestr = NULL;
979 char *idmapstr = NULL;
986 if (count >= sizeof(name_idmapstr))
987 GOTO(out, rc = -EINVAL);
989 if (copy_from_user(name_idmapstr, buffer, count))
990 GOTO(out, rc = -EFAULT);
992 name_idmapstr[count] = '\0';
994 cpybuf = name_idmapstr;
995 name = strsep(&cpybuf, " ");
997 GOTO(out, rc = -EINVAL);
999 idtypestr = strsep(&cpybuf, " ");
1000 if (idtypestr == NULL)
1001 GOTO(out, rc = -EINVAL);
1003 idmapstr = strsep(&cpybuf, " \n");
1004 if (idmapstr == NULL)
1005 GOTO(out, rc = -EINVAL);
1007 rc = nodemap_parse_idmap(idmapstr, idmap);
1009 GOTO(out, rc = -EINVAL);
1011 if (strcmp(idtypestr, "uid") == 0)
1012 rc = nodemap_add_idmap(name, NODEMAP_UID, idmap);
1013 else if (strcmp(idtypestr, "gid") == 0)
1014 rc = nodemap_add_idmap(name, NODEMAP_GID, idmap);
1016 GOTO(out, rc = -EINVAL);
1019 GOTO(out, rc = -EINVAL);
1027 LPROC_SEQ_FOPS_WO_TYPE(nodemap, add_nodemap_idmap);
1030 * Delete an idmap from nodemap.
1032 * \param[in] file proc file
1033 * \param[in] buffer string, "<nodemap name> <uid|gid> <idmap>"
1034 * \param[in] count \a buffer length
1035 * \param[in] off unused
1036 * \retval \a count on success
1037 * \retval negative number on error
1040 lprocfs_del_nodemap_idmap_seq_write(struct file *file,
1041 const char __user *buffer,
1042 size_t count, loff_t *off)
1044 char name_idmapstr[LUSTRE_NODEMAP_NAME_LENGTH + 16];
1045 char *cpybuf = NULL;
1047 char *idtypestr = NULL;
1048 char *idmapstr = NULL;
1055 if (count >= sizeof(name_idmapstr))
1056 GOTO(out, rc = -EINVAL);
1058 if (copy_from_user(name_idmapstr, buffer, count))
1059 GOTO(out, rc = -EFAULT);
1061 name_idmapstr[count] = '\0';
1063 cpybuf = name_idmapstr;
1064 name = strsep(&cpybuf, " ");
1066 GOTO(out, rc = -EINVAL);
1068 idtypestr = strsep(&cpybuf, " ");
1069 if (idtypestr == NULL)
1070 GOTO(out, rc = -EINVAL);
1072 idmapstr = strsep(&cpybuf, " \n");
1073 if (idmapstr == NULL)
1074 GOTO(out, rc = -EINVAL);
1076 rc = nodemap_parse_idmap(idmapstr, idmap);
1078 GOTO(out, rc = -EINVAL);
1080 if (strcmp(idtypestr, "uid") == 0)
1081 rc = nodemap_del_idmap(name, NODEMAP_UID, idmap);
1082 else if (strcmp(idtypestr, "gid") == 0)
1083 rc = nodemap_del_idmap(name, NODEMAP_GID, idmap);
1085 GOTO(out, rc = -EINVAL);
1088 GOTO(out, rc = -EINVAL);
1096 LPROC_SEQ_FOPS_WO_TYPE(nodemap, del_nodemap_idmap);
1097 #endif /* NODEMAP_PROC_DEBUG */
1099 static struct lprocfs_vars lprocfs_nm_module_vars[] = {
1102 .fops = &nodemap_active_fops,
1104 #ifdef NODEMAP_PROC_DEBUG
1106 .name = "add_nodemap",
1107 .fops = &nodemap_add_nodemap_fops,
1110 .name = "remove_nodemap",
1111 .fops = &nodemap_del_nodemap_fops,
1114 .name = "add_nodemap_range",
1115 .fops = &nodemap_add_nodemap_range_fops,
1118 .name = "del_nodemap_range",
1119 .fops = &nodemap_del_nodemap_range_fops,
1122 .name = "add_nodemap_idmap",
1123 .fops = &nodemap_add_nodemap_idmap_fops,
1126 .name = "del_nodemap_idmap",
1127 .fops = &nodemap_del_nodemap_idmap_fops,
1129 #endif /* NODEMAP_PROC_DEBUG */
1135 #ifdef NODEMAP_PROC_DEBUG
1136 LPROC_SEQ_FOPS(nodemap_trusted);
1137 LPROC_SEQ_FOPS(nodemap_admin);
1138 LPROC_SEQ_FOPS(nodemap_squash_uid);
1139 LPROC_SEQ_FOPS(nodemap_squash_gid);
1141 LPROC_SEQ_FOPS_RO(nodemap_trusted);
1142 LPROC_SEQ_FOPS_RO(nodemap_admin);
1143 LPROC_SEQ_FOPS_RO(nodemap_squash_uid);
1144 LPROC_SEQ_FOPS_RO(nodemap_squash_gid);
1147 LPROC_SEQ_FOPS_RO(nodemap_deny_unknown);
1148 LPROC_SEQ_FOPS_RO(nodemap_map_mode);
1150 const struct file_operations nodemap_ranges_fops = {
1151 .open = nodemap_ranges_open,
1153 .llseek = seq_lseek,
1154 .release = single_release
1157 const struct file_operations nodemap_idmap_fops = {
1158 .open = nodemap_idmap_open,
1160 .llseek = seq_lseek,
1161 .release = single_release
1164 const struct file_operations nodemap_exports_fops = {
1165 .open = nodemap_exports_open,
1167 .llseek = seq_lseek,
1168 .release = single_release
1171 static struct lprocfs_vars lprocfs_nodemap_vars[] = {
1174 .fops = &nodemap_id_fops,
1177 .name = "trusted_nodemap",
1178 .fops = &nodemap_trusted_fops,
1181 .name = "admin_nodemap",
1182 .fops = &nodemap_admin_fops,
1185 .name = "deny_unknown",
1186 .fops = &nodemap_deny_unknown_fops,
1190 .fops = &nodemap_map_mode_fops,
1193 .name = "squash_uid",
1194 .fops = &nodemap_squash_uid_fops,
1197 .name = "squash_gid",
1198 .fops = &nodemap_squash_gid_fops,
1202 .fops = &nodemap_ranges_fops,
1206 .fops = &nodemap_fileset_fops,
1210 .fops = &nodemap_exports_fops,
1214 .fops = &nodemap_idmap_fops,
1221 static struct lprocfs_vars lprocfs_default_nodemap_vars[] = {
1224 .fops = &nodemap_id_fops,
1227 .name = "trusted_nodemap",
1228 .fops = &nodemap_trusted_fops,
1231 .name = "admin_nodemap",
1232 .fops = &nodemap_admin_fops,
1235 .name = "squash_uid",
1236 .fops = &nodemap_squash_uid_fops,
1239 .name = "squash_gid",
1240 .fops = &nodemap_squash_gid_fops,
1244 .fops = &nodemap_exports_fops,
1252 * Initialize the nodemap procfs directory.
1256 int nodemap_procfs_init(void)
1260 proc_lustre_nodemap_root = lprocfs_register(LUSTRE_NODEMAP_NAME,
1262 lprocfs_nm_module_vars,
1264 if (IS_ERR(proc_lustre_nodemap_root)) {
1265 rc = PTR_ERR(proc_lustre_nodemap_root);
1266 CERROR("cannot create 'nodemap' directory: rc = %d\n",
1268 proc_lustre_nodemap_root = NULL;
1274 * Cleanup nodemap proc entry data structures.
1276 void nodemap_procfs_exit(void)
1278 struct nodemap_pde *nm_pde;
1279 struct nodemap_pde *tmp;
1281 lprocfs_remove(&proc_lustre_nodemap_root);
1282 list_for_each_entry_safe(nm_pde, tmp, &nodemap_pde_list,
1284 list_del(&nm_pde->npe_list_member);
1285 OBD_FREE_PTR(nm_pde);
1290 * Remove a nodemap's procfs entry and related data.
1292 void lprocfs_nodemap_remove(struct nodemap_pde *nm_pde)
1294 lprocfs_remove(&nm_pde->npe_proc_entry);
1295 list_del(&nm_pde->npe_list_member);
1296 OBD_FREE_PTR(nm_pde);
1300 * Register the proc directory for a nodemap
1302 * \param nodemap nodemap to make the proc dir for
1303 * \param is_default: 1 if default nodemap
1306 int lprocfs_nodemap_register(struct lu_nodemap *nodemap, bool is_default)
1308 struct nodemap_pde *nm_entry;
1311 OBD_ALLOC_PTR(nm_entry);
1312 if (nm_entry == NULL)
1313 GOTO(out, rc = -ENOMEM);
1315 nm_entry->npe_proc_entry = proc_mkdir(nodemap->nm_name,
1316 proc_lustre_nodemap_root);
1317 if (IS_ERR(nm_entry->npe_proc_entry))
1318 GOTO(out, rc = PTR_ERR(nm_entry->npe_proc_entry));
1320 snprintf(nm_entry->npe_name, sizeof(nm_entry->npe_name), "%s",
1323 /* Use the nodemap name as stored on the PDE as the private data. This
1324 * is so a nodemap struct can be replaced without updating the proc
1327 rc = lprocfs_add_vars(nm_entry->npe_proc_entry,
1328 (is_default ? lprocfs_default_nodemap_vars :
1329 lprocfs_nodemap_vars),
1330 nm_entry->npe_name);
1332 lprocfs_remove(&nm_entry->npe_proc_entry);
1334 list_add(&nm_entry->npe_list_member, &nodemap_pde_list);
1338 CERROR("cannot create 'nodemap/%s': rc = %d\n",
1339 nodemap->nm_name, rc);
1340 if (nm_entry != NULL) {
1341 OBD_FREE_PTR(nm_entry);
1346 nodemap->nm_pde_data = nm_entry;