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 /* Turn on proc debug interface to allow OSS and
41 * MDS nodes to configure nodemap independently of
42 * MGS (since the nodemap distribution is not written
44 #define NODEMAP_PROC_DEBUG 1
46 static LIST_HEAD(nodemap_pde_list);
49 * Reads and prints the idmap for the given nodemap.
51 * \param m seq file in proc fs
55 static int nodemap_idmap_show(struct seq_file *m, void *data)
57 struct lu_nodemap *nodemap;
58 struct lu_idmap *idmap;
63 mutex_lock(&active_config_lock);
64 nodemap = nodemap_lookup(m->private);
65 mutex_unlock(&active_config_lock);
66 if (IS_ERR(nodemap)) {
67 rc = PTR_ERR(nodemap);
68 CERROR("cannot find nodemap '%s': rc = %d\n",
69 (char *)m->private, rc);
74 read_lock(&nodemap->nm_idmap_lock);
75 for (node = rb_first(&nodemap->nm_client_to_fs_uidmap); node;
76 node = rb_next(node)) {
80 idmap = rb_entry(node, struct lu_idmap, id_client_to_fs);
82 seq_printf(m, " { idtype: uid, client_id: %u, "
83 "fs_id: %u }", idmap->id_client,
86 for (node = rb_first(&nodemap->nm_client_to_fs_gidmap);
87 node; node = rb_next(node)) {
90 idmap = rb_entry(node, struct lu_idmap, id_client_to_fs);
92 seq_printf(m, " { idtype: gid, client_id: %u, "
93 "fs_id: %u }", idmap->id_client,
96 read_unlock(&nodemap->nm_idmap_lock);
100 nodemap_putref(nodemap);
105 * Attaches nodemap_idmap_show to proc file.
107 * \param inode inode of seq file in proc fs
108 * \param file seq file
111 static int nodemap_idmap_open(struct inode *inode, struct file *file)
113 return single_open(file, nodemap_idmap_show, PDE_DATA(inode));
117 * Reads and prints the NID ranges for the given nodemap.
119 * \param m seq file in proc fs
123 static int nodemap_ranges_show(struct seq_file *m, void *data)
125 struct lu_nodemap *nodemap;
126 struct lu_nid_range *range;
127 struct interval_node_extent ext;
128 char start_nidstr[LNET_NIDSTR_SIZE];
129 char end_nidstr[LNET_NIDSTR_SIZE];
133 mutex_lock(&active_config_lock);
134 nodemap = nodemap_lookup(m->private);
135 if (IS_ERR(nodemap)) {
136 mutex_unlock(&active_config_lock);
137 rc = PTR_ERR(nodemap);
138 CERROR("cannot find nodemap '%s': rc = %d\n",
139 (char *)m->private, rc);
143 seq_printf(m, "[\n");
144 down_read(&active_config->nmc_range_tree_lock);
145 list_for_each_entry(range, &nodemap->nm_ranges, rn_list) {
147 seq_printf(m, ",\n");
149 ext = range->rn_node.in_extent;
150 libcfs_nid2str_r(ext.start, start_nidstr, sizeof(start_nidstr));
151 libcfs_nid2str_r(ext.end, end_nidstr, sizeof(end_nidstr));
152 seq_printf(m, " { id: %u, start_nid: %s, end_nid: %s }",
153 range->rn_id, start_nidstr, end_nidstr);
155 up_read(&active_config->nmc_range_tree_lock);
156 mutex_unlock(&active_config_lock);
158 seq_printf(m, "]\n");
160 nodemap_putref(nodemap);
165 * Connects nodemap_idmap_show to proc file.
167 * \param inode inode of seq file in proc fs
168 * \param file seq file
171 static int nodemap_ranges_open(struct inode *inode, struct file *file)
173 return single_open(file, nodemap_ranges_show, PDE_DATA(inode));
177 * Reads and prints the exports attached to the given nodemap.
179 * \param m seq file in proc fs, stores nodemap
183 static int nodemap_exports_show(struct seq_file *m, void *data)
185 struct lu_nodemap *nodemap;
186 struct obd_export *exp;
187 char nidstr[LNET_NIDSTR_SIZE] = "<unknown>";
190 mutex_lock(&active_config_lock);
191 nodemap = nodemap_lookup(m->private);
192 mutex_unlock(&active_config_lock);
193 if (IS_ERR(nodemap)) {
194 rc = PTR_ERR(nodemap);
195 CERROR("cannot find nodemap '%s': rc = %d\n",
196 (char *)m->private, rc);
200 seq_printf(m, "[\n");
202 mutex_lock(&nodemap->nm_member_list_lock);
203 list_for_each_entry(exp, &nodemap->nm_member_list,
204 exp_target_data.ted_nodemap_member) {
205 if (exp->exp_connection != NULL)
206 libcfs_nid2str_r(exp->exp_connection->c_peer.nid,
207 nidstr, sizeof(nidstr));
209 seq_printf(m, " { nid: %s, uuid: %s },",
210 nidstr, exp->exp_client_uuid.uuid);
212 mutex_unlock(&nodemap->nm_member_list_lock);
215 seq_printf(m, "]\n");
217 nodemap_putref(nodemap);
222 * Attaches nodemap_idmap_show to proc file.
224 * \param inode inode of seq file in proc fs
225 * \param file seq file
228 static int nodemap_exports_open(struct inode *inode, struct file *file)
230 return single_open(file, nodemap_exports_show, PDE_DATA(inode));
234 * Reads and prints the active flag for the given nodemap.
236 * \param m seq file in proc fs
240 static int nodemap_active_seq_show(struct seq_file *m, void *data)
242 return seq_printf(m, "%u\n", (unsigned int)nodemap_active);
246 * Activate/deactivate nodemap.
248 * \param[in] file proc file
249 * \param[in] buffer string, "1" or "0" to activate/deactivate nodemap
250 * \param[in] count \a buffer length
251 * \param[in] off unused
252 * \retval \a count on success
253 * \retval negative number on error
256 nodemap_active_seq_write(struct file *file, const char __user *buffer,
257 size_t count, loff_t *off)
259 char active_string[NODEMAP_LPROC_FLAG_LEN + 1];
260 long unsigned int active;
266 if (count >= sizeof(active_string))
269 if (copy_from_user(active_string, buffer, count))
272 active_string[count] = '\0';
273 rc = kstrtoul(active_string, 10, &active);
277 nodemap_activate(active);
281 LPROC_SEQ_FOPS(nodemap_active);
284 * Reads and prints the nodemap ID for the given nodemap.
286 * \param m seq file in proc fs
290 static int nodemap_id_seq_show(struct seq_file *m, void *data)
292 struct lu_nodemap *nodemap;
295 mutex_lock(&active_config_lock);
296 nodemap = nodemap_lookup(m->private);
297 mutex_unlock(&active_config_lock);
298 if (IS_ERR(nodemap)) {
299 rc = PTR_ERR(nodemap);
300 CERROR("cannot find nodemap '%s': rc = %d\n",
301 (char *)m->private, rc);
305 rc = seq_printf(m, "%u\n", nodemap->nm_id);
306 nodemap_putref(nodemap);
309 LPROC_SEQ_FOPS_RO(nodemap_id);
312 * Reads and prints the root squash UID for the given nodemap.
314 * \param m seq file in proc fs
318 static int nodemap_squash_uid_seq_show(struct seq_file *m, void *data)
320 struct lu_nodemap *nodemap;
323 mutex_lock(&active_config_lock);
324 nodemap = nodemap_lookup(m->private);
325 mutex_unlock(&active_config_lock);
326 if (IS_ERR(nodemap)) {
327 rc = PTR_ERR(nodemap);
328 CERROR("cannot find nodemap '%s': rc = %d\n",
329 (char *)m->private, rc);
333 rc = seq_printf(m, "%u\n", nodemap->nm_squash_uid);
334 nodemap_putref(nodemap);
339 * Reads and prints the root squash GID for the given nodemap.
341 * \param m seq file in proc fs
345 static int nodemap_squash_gid_seq_show(struct seq_file *m, void *data)
347 struct lu_nodemap *nodemap;
350 mutex_lock(&active_config_lock);
351 nodemap = nodemap_lookup(m->private);
352 mutex_unlock(&active_config_lock);
353 if (IS_ERR(nodemap)) {
354 rc = PTR_ERR(nodemap);
355 CERROR("cannot find nodemap '%s': rc = %d\n",
356 (char *)m->private, rc);
360 rc = seq_printf(m, "%u\n", nodemap->nm_squash_gid);
361 nodemap_putref(nodemap);
366 * Reads and prints the trusted flag for the given nodemap.
368 * \param m seq file in proc fs
372 static int nodemap_trusted_seq_show(struct seq_file *m, void *data)
374 struct lu_nodemap *nodemap;
377 mutex_lock(&active_config_lock);
378 nodemap = nodemap_lookup(m->private);
379 mutex_unlock(&active_config_lock);
380 if (IS_ERR(nodemap)) {
381 rc = PTR_ERR(nodemap);
382 CERROR("cannot find nodemap '%s': rc = %d\n",
383 (char *)m->private, rc);
387 rc = seq_printf(m, "%d\n", (int)nodemap->nmf_trust_client_ids);
388 nodemap_putref(nodemap);
393 * Reads and prints the admin flag for the given nodemap.
395 * \param m seq file in proc fs
399 static int nodemap_admin_seq_show(struct seq_file *m, void *data)
401 struct lu_nodemap *nodemap;
404 mutex_lock(&active_config_lock);
405 nodemap = nodemap_lookup(m->private);
406 mutex_unlock(&active_config_lock);
407 if (IS_ERR(nodemap)) {
408 rc = PTR_ERR(nodemap);
409 CERROR("cannot find nodemap '%s': rc = %d\n",
410 (char *)m->private, rc);
414 rc = seq_printf(m, "%d\n", (int)nodemap->nmf_allow_root_access);
415 nodemap_putref(nodemap);
419 #ifdef NODEMAP_PROC_DEBUG
421 * Helper functions to set nodemap flags.
423 * \param[in] buffer string, which is "1" or "0" to set/unset flag
424 * \param[in] count \a buffer length
425 * \param[out] flag_p where to store flag value
426 * \retval \a count on success
427 * \retval negative number on error
429 static int nodemap_proc_read_flag(const char __user *buffer,
430 unsigned long count, unsigned int *flag_p)
432 char scratch[NODEMAP_LPROC_FLAG_LEN + 1];
433 long unsigned int flag_buf;
439 if (count >= sizeof(scratch))
442 if (copy_from_user(scratch, buffer, count))
445 scratch[count] = '\0';
446 rc = kstrtoul(scratch, 10, &flag_buf);
456 * Set the squash UID.
458 * \param[in] file proc file
459 * \param[in] buffer string representing squash UID to set
460 * \param[in] count \a buffer length
461 * \param[in] off unused
462 * \retval \a count on success
463 * \retval negative number on error
466 nodemap_squash_uid_seq_write(struct file *file, const char __user *buffer,
467 size_t count, loff_t *off)
469 char squash[NODEMAP_LPROC_ID_LEN + 1];
470 struct seq_file *m = file->private_data;
471 long unsigned int squash_uid;
477 if (count >= sizeof(squash))
480 if (copy_from_user(squash, buffer, count))
483 squash[count] = '\0';
484 rc = kstrtoul(squash, 10, &squash_uid);
488 rc = nodemap_set_squash_uid(m->private, squash_uid);
496 * Set the squash GID.
498 * \param[in] file proc file
499 * \param[in] buffer string representing squash GID to set
500 * \param[in] count \a buffer length
501 * \param[in] off unused
502 * \retval \a count on success
503 * \retval negative number on error
506 nodemap_squash_gid_seq_write(struct file *file, const char __user *buffer,
507 size_t count, loff_t *off)
509 char squash[NODEMAP_LPROC_ID_LEN + 1];
510 struct seq_file *m = file->private_data;
511 long unsigned int squash_gid;
517 if (count >= sizeof(squash))
520 if (copy_from_user(squash, buffer, count))
523 squash[count] = '\0';
524 rc = kstrtoul(squash, 10, &squash_gid);
528 rc = nodemap_set_squash_gid(m->private, squash_gid);
536 * Set/unset the trusted flag.
538 * \param[in] file proc file
539 * \param[in] buffer string, "1" or "0"
540 * \param[in] count \a buffer length
541 * \param[in] off unused
542 * \retval \a count on success
543 * \retval negative number on error
546 nodemap_trusted_seq_write(struct file *file, const char __user *buffer,
547 size_t count, loff_t *off)
549 struct seq_file *m = file->private_data;
553 rc = nodemap_proc_read_flag(buffer, count, &flags);
557 rc = nodemap_set_trust_client_ids(m->private, flags);
565 * Set/unset the admin flag.
567 * \param[in] file proc file
568 * \param[in] buffer string, "1" or "0"
569 * \param[in] count \a buffer length
570 * \param[in] off unused
571 * \retval \a count on success
572 * \retval negative number on error
575 nodemap_admin_seq_write(struct file *file, const char __user *buffer,
576 size_t count, loff_t *off)
578 struct seq_file *m = file->private_data;
582 rc = nodemap_proc_read_flag(buffer, count, &flags);
586 rc = nodemap_set_allow_root(m->private, flags);
596 * \param[in] file proc file
597 * \param[in] buffer string, name of the nodemap to add
598 * \param[in] count \a buffer length
599 * \param[in] off unused
600 * \retval \a count on success
601 * \retval negative number on error
604 lprocfs_add_nodemap_seq_write(struct file *file, const char __user *buffer,
605 size_t count, loff_t *off)
607 char nodemap_name[LUSTRE_NODEMAP_NAME_LENGTH + 1];
615 if (count >= sizeof(nodemap_name))
618 if (copy_from_user(nodemap_name, buffer, count))
621 nodemap_name[count] = '\0';
623 cpybuf = nodemap_name;
624 pos = strsep(&cpybuf, " \n");
628 rc = nodemap_add(nodemap_name);
634 LPROC_SEQ_FOPS_WO_TYPE(nodemap, add_nodemap);
639 * \param[in] file proc file
640 * \param[in] buffer string, name of the nodemap to delete
641 * \param[in] count \a buffer length
642 * \param[in] off unused
643 * \retval \a count on success
644 * \retval negative number on error
647 lprocfs_del_nodemap_seq_write(struct file *file, const char __user *buffer,
648 size_t count, loff_t *off)
650 char nodemap_name[LUSTRE_NODEMAP_NAME_LENGTH + 1];
658 if (count >= sizeof(nodemap_name))
661 if (copy_from_user(nodemap_name, buffer, count))
664 nodemap_name[count] = '\0';
666 cpybuf = nodemap_name;
667 pos = strsep(&cpybuf, " \n");
671 rc = nodemap_del(nodemap_name);
678 LPROC_SEQ_FOPS_WO_TYPE(nodemap, del_nodemap);
681 * Helper function to parse a NID string.
683 * \param[in] rangestr string representation of NIDs, see libcfs_str2nid()
684 * \param[out] nids array of two nids
685 * \retval 0 on success
686 * \retval negative number on error
688 static int parse_nids(char *rangestr, lnet_nid_t nids[2])
690 struct list_head nidlist;
691 char nidstr[2][LNET_NIDSTR_SIZE];
692 char nidrange_str[2 * LNET_NIDSTR_SIZE + 2];
695 INIT_LIST_HEAD(&nidlist);
697 if (cfs_parse_nidlist(rangestr, strlen(rangestr),
701 if (!cfs_nidrange_is_contiguous(&nidlist))
704 cfs_nidrange_find_min_max(&nidlist, nidstr[0], nidstr[1],
706 snprintf(nidrange_str, sizeof(nidrange_str), "%s:%s",
707 nidstr[0], nidstr[1]);
709 rc = nodemap_parse_range(nidrange_str, nids);
713 cfs_free_nidlist(&nidlist);
719 * Add a NID range to nodemap.
721 * \param[in] file proc file
722 * \param[in] buffer string, "<nodemap name> <nid range>"
723 * \param[in] count \a buffer length
724 * \param[in] off unused
725 * \retval \a count on success
726 * \retval negative number on error
729 lprocfs_add_nodemap_range_seq_write(struct file *file,
730 const char __user *buffer,
731 size_t count, loff_t *off)
733 char name_range[LUSTRE_NODEMAP_NAME_LENGTH +
734 LNET_NIDSTR_SIZE * 2 + 2];
737 char *rangestr = NULL;
744 if (count >= sizeof(name_range))
745 GOTO(out, rc = -EINVAL);
747 if (copy_from_user(name_range, buffer, count))
748 GOTO(out, rc = -EFAULT);
750 name_range[count] = '\0';
753 name = strsep(&cpybuf, " ");
755 GOTO(out, rc = -EINVAL);
757 rangestr = strsep(&cpybuf, " \n");
758 if (rangestr == NULL)
759 GOTO(out, rc = -EINVAL);
761 rc = parse_nids(rangestr, nids);
765 rc = nodemap_add_range(name, nids);
767 GOTO(out, rc = -EINVAL);
775 LPROC_SEQ_FOPS_WO_TYPE(nodemap, add_nodemap_range);
778 * Delete a NID range from nodemap.
780 * \param[in] file proc file
781 * \param[in] buffer string, "<nodemap name> <nid range>"
782 * \param[in] count \a buffer length
783 * \param[in] off unused
784 * \retval \a count on success
785 * \retval negative number on error
788 lprocfs_del_nodemap_range_seq_write(struct file *file,
789 const char __user *buffer,
790 size_t count, loff_t *off)
792 char name_range[LUSTRE_NODEMAP_NAME_LENGTH +
793 LNET_NIDSTR_SIZE * 2 + 2];
796 char *rangestr = NULL;
803 if (count >= sizeof(name_range))
804 GOTO(out, rc = -EINVAL);
806 if (copy_from_user(name_range, buffer, count))
807 GOTO(out, rc = -EFAULT);
809 name_range[count] = '\0';
812 name = strsep(&cpybuf, " ");
814 GOTO(out, rc = -EINVAL);
816 rangestr = strsep(&cpybuf, " \n");
817 if (rangestr == NULL)
818 GOTO(out, rc = -EINVAL);
820 rc = parse_nids(rangestr, nids);
824 rc = nodemap_del_range(name, nids);
826 GOTO(out, rc = -EINVAL);
834 LPROC_SEQ_FOPS_WO_TYPE(nodemap, del_nodemap_range);
837 * Add an idmap to nodemap.
839 * \param[in] file proc file
840 * \param[in] buffer string, "<nodemap name> <uid|gid> <idmap>"
841 * \param[in] count \a buffer length
842 * \param[in] off unused
843 * \retval \a count on success
844 * \retval negative number on error
847 lprocfs_add_nodemap_idmap_seq_write(struct file *file,
848 const char __user *buffer,
849 size_t count, loff_t *off)
851 char name_idmapstr[LUSTRE_NODEMAP_NAME_LENGTH + 16];
854 char *idtypestr = NULL;
855 char *idmapstr = NULL;
862 if (count >= sizeof(name_idmapstr))
863 GOTO(out, rc = -EINVAL);
865 if (copy_from_user(name_idmapstr, buffer, count))
866 GOTO(out, rc = -EFAULT);
868 name_idmapstr[count] = '\0';
870 cpybuf = name_idmapstr;
871 name = strsep(&cpybuf, " ");
873 GOTO(out, rc = -EINVAL);
875 idtypestr = strsep(&cpybuf, " ");
876 if (idtypestr == NULL)
877 GOTO(out, rc = -EINVAL);
879 idmapstr = strsep(&cpybuf, " \n");
880 if (idmapstr == NULL)
881 GOTO(out, rc = -EINVAL);
883 rc = nodemap_parse_idmap(idmapstr, idmap);
885 GOTO(out, rc = -EINVAL);
887 if (strcmp(idtypestr, "uid") == 0)
888 rc = nodemap_add_idmap(name, NODEMAP_UID, idmap);
889 else if (strcmp(idtypestr, "gid") == 0)
890 rc = nodemap_add_idmap(name, NODEMAP_GID, idmap);
892 GOTO(out, rc = -EINVAL);
895 GOTO(out, rc = -EINVAL);
903 LPROC_SEQ_FOPS_WO_TYPE(nodemap, add_nodemap_idmap);
906 * Delete an idmap from nodemap.
908 * \param[in] file proc file
909 * \param[in] buffer string, "<nodemap name> <uid|gid> <idmap>"
910 * \param[in] count \a buffer length
911 * \param[in] off unused
912 * \retval \a count on success
913 * \retval negative number on error
916 lprocfs_del_nodemap_idmap_seq_write(struct file *file,
917 const char __user *buffer,
918 size_t count, loff_t *off)
920 char name_idmapstr[LUSTRE_NODEMAP_NAME_LENGTH + 16];
923 char *idtypestr = NULL;
924 char *idmapstr = NULL;
931 if (count >= sizeof(name_idmapstr))
932 GOTO(out, rc = -EINVAL);
934 if (copy_from_user(name_idmapstr, buffer, count))
935 GOTO(out, rc = -EFAULT);
937 name_idmapstr[count] = '\0';
939 cpybuf = name_idmapstr;
940 name = strsep(&cpybuf, " ");
942 GOTO(out, rc = -EINVAL);
944 idtypestr = strsep(&cpybuf, " ");
945 if (idtypestr == NULL)
946 GOTO(out, rc = -EINVAL);
948 idmapstr = strsep(&cpybuf, " \n");
949 if (idmapstr == NULL)
950 GOTO(out, rc = -EINVAL);
952 rc = nodemap_parse_idmap(idmapstr, idmap);
954 GOTO(out, rc = -EINVAL);
956 if (strcmp(idtypestr, "uid") == 0)
957 rc = nodemap_del_idmap(name, NODEMAP_UID, idmap);
958 else if (strcmp(idtypestr, "gid") == 0)
959 rc = nodemap_del_idmap(name, NODEMAP_GID, idmap);
961 GOTO(out, rc = -EINVAL);
964 GOTO(out, rc = -EINVAL);
972 LPROC_SEQ_FOPS_WO_TYPE(nodemap, del_nodemap_idmap);
973 #endif /* NODEMAP_PROC_DEBUG */
975 static struct lprocfs_vars lprocfs_nm_module_vars[] = {
978 .fops = &nodemap_active_fops,
980 #ifdef NODEMAP_PROC_DEBUG
982 .name = "add_nodemap",
983 .fops = &nodemap_add_nodemap_fops,
986 .name = "remove_nodemap",
987 .fops = &nodemap_del_nodemap_fops,
990 .name = "add_nodemap_range",
991 .fops = &nodemap_add_nodemap_range_fops,
994 .name = "del_nodemap_range",
995 .fops = &nodemap_del_nodemap_range_fops,
998 .name = "add_nodemap_idmap",
999 .fops = &nodemap_add_nodemap_idmap_fops,
1002 .name = "del_nodemap_idmap",
1003 .fops = &nodemap_del_nodemap_idmap_fops,
1005 #endif /* NODEMAP_PROC_DEBUG */
1011 #ifdef NODEMAP_PROC_DEBUG
1012 LPROC_SEQ_FOPS(nodemap_trusted);
1013 LPROC_SEQ_FOPS(nodemap_admin);
1014 LPROC_SEQ_FOPS(nodemap_squash_uid);
1015 LPROC_SEQ_FOPS(nodemap_squash_gid);
1017 LPROC_SEQ_FOPS_RO(nodemap_trusted);
1018 LPROC_SEQ_FOPS_RO(nodemap_admin);
1019 LPROC_SEQ_FOPS_RO(nodemap_squash_uid);
1020 LPROC_SEQ_FOPS_RO(nodemap_squash_gid);
1023 const struct file_operations nodemap_ranges_fops = {
1024 .open = nodemap_ranges_open,
1026 .llseek = seq_lseek,
1027 .release = single_release
1030 const struct file_operations nodemap_idmap_fops = {
1031 .open = nodemap_idmap_open,
1033 .llseek = seq_lseek,
1034 .release = single_release
1037 const struct file_operations nodemap_exports_fops = {
1038 .open = nodemap_exports_open,
1040 .llseek = seq_lseek,
1041 .release = single_release
1044 static struct lprocfs_vars lprocfs_nodemap_vars[] = {
1047 .fops = &nodemap_id_fops,
1050 .name = "trusted_nodemap",
1051 .fops = &nodemap_trusted_fops,
1054 .name = "admin_nodemap",
1055 .fops = &nodemap_admin_fops,
1058 .name = "squash_uid",
1059 .fops = &nodemap_squash_uid_fops,
1062 .name = "squash_gid",
1063 .fops = &nodemap_squash_gid_fops,
1067 .fops = &nodemap_ranges_fops,
1071 .fops = &nodemap_exports_fops,
1075 .fops = &nodemap_idmap_fops,
1082 static struct lprocfs_vars lprocfs_default_nodemap_vars[] = {
1085 .fops = &nodemap_id_fops,
1088 .name = "trusted_nodemap",
1089 .fops = &nodemap_trusted_fops,
1092 .name = "admin_nodemap",
1093 .fops = &nodemap_admin_fops,
1096 .name = "squash_uid",
1097 .fops = &nodemap_squash_uid_fops,
1100 .name = "squash_gid",
1101 .fops = &nodemap_squash_gid_fops,
1105 .fops = &nodemap_exports_fops,
1113 * Initialize the nodemap procfs directory.
1117 int nodemap_procfs_init(void)
1121 proc_lustre_nodemap_root = lprocfs_register(LUSTRE_NODEMAP_NAME,
1123 lprocfs_nm_module_vars,
1125 if (IS_ERR(proc_lustre_nodemap_root)) {
1126 rc = PTR_ERR(proc_lustre_nodemap_root);
1127 CERROR("cannot create 'nodemap' directory: rc = %d\n",
1129 proc_lustre_nodemap_root = NULL;
1135 * Cleanup nodemap proc entry data structures.
1137 void nodemap_procfs_exit(void)
1139 struct nodemap_pde *nm_pde;
1140 struct nodemap_pde *tmp;
1142 lprocfs_remove(&proc_lustre_nodemap_root);
1143 list_for_each_entry_safe(nm_pde, tmp, &nodemap_pde_list,
1145 list_del(&nm_pde->npe_list_member);
1146 OBD_FREE_PTR(nm_pde);
1151 * Remove a nodemap's procfs entry and related data.
1153 void lprocfs_nodemap_remove(struct nodemap_pde *nm_pde)
1155 lprocfs_remove(&nm_pde->npe_proc_entry);
1156 list_del(&nm_pde->npe_list_member);
1157 OBD_FREE_PTR(nm_pde);
1161 * Register the proc directory for a nodemap
1163 * \param nodemap nodemap to make the proc dir for
1164 * \param is_default: 1 if default nodemap
1167 int lprocfs_nodemap_register(struct lu_nodemap *nodemap, bool is_default)
1169 struct nodemap_pde *nm_entry;
1172 OBD_ALLOC_PTR(nm_entry);
1173 if (nm_entry == NULL)
1174 GOTO(out, rc = -ENOMEM);
1176 nm_entry->npe_proc_entry = proc_mkdir(nodemap->nm_name,
1177 proc_lustre_nodemap_root);
1178 if (IS_ERR(nm_entry->npe_proc_entry))
1179 GOTO(out, rc = PTR_ERR(nm_entry->npe_proc_entry));
1181 snprintf(nm_entry->npe_name, sizeof(nm_entry->npe_name), "%s",
1184 /* Use the nodemap name as stored on the PDE as the private data. This
1185 * is so a nodemap struct can be replaced without updating the proc
1188 rc = lprocfs_add_vars(nm_entry->npe_proc_entry,
1189 (is_default ? lprocfs_default_nodemap_vars :
1190 lprocfs_nodemap_vars),
1191 nm_entry->npe_name);
1193 lprocfs_remove(&nm_entry->npe_proc_entry);
1195 list_add(&nm_entry->npe_list_member, &nodemap_pde_list);
1199 CERROR("cannot create 'nodemap/%s': rc = %d\n",
1200 nodemap->nm_name, rc);
1201 if (nm_entry != NULL) {
1202 OBD_FREE_PTR(nm_entry);
1207 nodemap->nm_pde_data = nm_entry;