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 exports attached to the given nodemap.
173 * \param m seq file in proc fs, stores nodemap
177 static int nodemap_exports_show(struct seq_file *m, void *data)
179 struct lu_nodemap *nodemap;
180 struct obd_export *exp;
181 char nidstr[LNET_NIDSTR_SIZE] = "<unknown>";
184 mutex_lock(&active_config_lock);
185 nodemap = nodemap_lookup(m->private);
186 mutex_unlock(&active_config_lock);
187 if (IS_ERR(nodemap)) {
188 rc = PTR_ERR(nodemap);
189 CERROR("cannot find nodemap '%s': rc = %d\n",
190 (char *)m->private, rc);
194 seq_printf(m, "[\n");
196 mutex_lock(&nodemap->nm_member_list_lock);
197 list_for_each_entry(exp, &nodemap->nm_member_list,
198 exp_target_data.ted_nodemap_member) {
199 if (exp->exp_connection != NULL)
200 libcfs_nid2str_r(exp->exp_connection->c_peer.nid,
201 nidstr, sizeof(nidstr));
203 seq_printf(m, " { nid: %s, uuid: %s },",
204 nidstr, exp->exp_client_uuid.uuid);
206 mutex_unlock(&nodemap->nm_member_list_lock);
209 seq_printf(m, "]\n");
211 nodemap_putref(nodemap);
216 * Attaches nodemap_idmap_show to proc file.
218 * \param inode inode of seq file in proc fs
219 * \param file seq file
222 static int nodemap_exports_open(struct inode *inode, struct file *file)
224 return single_open(file, nodemap_exports_show, PDE_DATA(inode));
228 * Reads and prints the active flag for the given nodemap.
230 * \param m seq file in proc fs
234 static int nodemap_active_seq_show(struct seq_file *m, void *data)
236 seq_printf(m, "%u\n", (unsigned int)nodemap_active);
241 * Activate/deactivate nodemap.
243 * \param[in] file proc file
244 * \param[in] buffer string, "1" or "0" to activate/deactivate nodemap
245 * \param[in] count \a buffer length
246 * \param[in] off unused
247 * \retval \a count on success
248 * \retval negative number on error
251 nodemap_active_seq_write(struct file *file, const char __user *buffer,
252 size_t count, loff_t *off)
254 char active_string[NODEMAP_LPROC_FLAG_LEN + 1];
255 long unsigned int active;
261 if (count >= sizeof(active_string))
264 if (copy_from_user(active_string, buffer, count))
267 active_string[count] = '\0';
268 rc = kstrtoul(active_string, 10, &active);
272 nodemap_activate(active);
276 LPROC_SEQ_FOPS(nodemap_active);
279 * Reads and prints the nodemap ID for the given nodemap.
281 * \param m seq file in proc fs
285 static int nodemap_id_seq_show(struct seq_file *m, void *data)
287 struct lu_nodemap *nodemap;
289 mutex_lock(&active_config_lock);
290 nodemap = nodemap_lookup(m->private);
291 mutex_unlock(&active_config_lock);
292 if (IS_ERR(nodemap)) {
293 int rc = PTR_ERR(nodemap);
294 CERROR("cannot find nodemap '%s': rc = %d\n",
295 (char *)m->private, rc);
299 seq_printf(m, "%u\n", nodemap->nm_id);
300 nodemap_putref(nodemap);
303 LPROC_SEQ_FOPS_RO(nodemap_id);
306 * Reads and prints the root squash UID for the given nodemap.
308 * \param m seq file in proc fs
312 static int nodemap_squash_uid_seq_show(struct seq_file *m, void *data)
314 struct lu_nodemap *nodemap;
316 mutex_lock(&active_config_lock);
317 nodemap = nodemap_lookup(m->private);
318 mutex_unlock(&active_config_lock);
319 if (IS_ERR(nodemap)) {
320 int rc = PTR_ERR(nodemap);
321 CERROR("cannot find nodemap '%s': rc = %d\n",
322 (char *)m->private, rc);
326 seq_printf(m, "%u\n", nodemap->nm_squash_uid);
327 nodemap_putref(nodemap);
332 * Reads and prints the root squash GID for the given nodemap.
334 * \param m seq file in proc fs
338 static int nodemap_squash_gid_seq_show(struct seq_file *m, void *data)
340 struct lu_nodemap *nodemap;
342 mutex_lock(&active_config_lock);
343 nodemap = nodemap_lookup(m->private);
344 mutex_unlock(&active_config_lock);
345 if (IS_ERR(nodemap)) {
346 int rc = PTR_ERR(nodemap);
347 CERROR("cannot find nodemap '%s': rc = %d\n",
348 (char *)m->private, rc);
352 seq_printf(m, "%u\n", nodemap->nm_squash_gid);
353 nodemap_putref(nodemap);
358 * Reads and prints the trusted flag for the given nodemap.
360 * \param m seq file in proc fs
364 static int nodemap_trusted_seq_show(struct seq_file *m, void *data)
366 struct lu_nodemap *nodemap;
368 mutex_lock(&active_config_lock);
369 nodemap = nodemap_lookup(m->private);
370 mutex_unlock(&active_config_lock);
371 if (IS_ERR(nodemap)) {
372 int rc = PTR_ERR(nodemap);
374 CERROR("cannot find nodemap '%s': rc = %d\n",
375 (char *)m->private, rc);
379 seq_printf(m, "%d\n", (int)nodemap->nmf_trust_client_ids);
380 nodemap_putref(nodemap);
385 * Reads and prints the admin flag for the given nodemap.
387 * \param m seq file in proc fs
391 static int nodemap_admin_seq_show(struct seq_file *m, void *data)
393 struct lu_nodemap *nodemap;
396 mutex_lock(&active_config_lock);
397 nodemap = nodemap_lookup(m->private);
398 mutex_unlock(&active_config_lock);
399 if (IS_ERR(nodemap)) {
400 rc = PTR_ERR(nodemap);
401 CERROR("cannot find nodemap '%s': rc = %d\n",
402 (char *)m->private, rc);
406 seq_printf(m, "%d\n", (int)nodemap->nmf_allow_root_access);
407 nodemap_putref(nodemap);
411 #ifdef NODEMAP_PROC_DEBUG
413 * Helper functions to set nodemap flags.
415 * \param[in] buffer string, which is "1" or "0" to set/unset flag
416 * \param[in] count \a buffer length
417 * \param[out] flag_p where to store flag value
418 * \retval \a count on success
419 * \retval negative number on error
421 static int nodemap_proc_read_flag(const char __user *buffer,
422 unsigned long count, unsigned int *flag_p)
424 char scratch[NODEMAP_LPROC_FLAG_LEN + 1];
425 long unsigned int flag_buf;
431 if (count >= sizeof(scratch))
434 if (copy_from_user(scratch, buffer, count))
437 scratch[count] = '\0';
438 rc = kstrtoul(scratch, 10, &flag_buf);
448 * Set the squash UID.
450 * \param[in] file proc file
451 * \param[in] buffer string representing squash UID to set
452 * \param[in] count \a buffer length
453 * \param[in] off unused
454 * \retval \a count on success
455 * \retval negative number on error
458 nodemap_squash_uid_seq_write(struct file *file, const char __user *buffer,
459 size_t count, loff_t *off)
461 char squash[NODEMAP_LPROC_ID_LEN + 1];
462 struct seq_file *m = file->private_data;
463 long unsigned int squash_uid;
469 if (count >= sizeof(squash))
472 if (copy_from_user(squash, buffer, count))
475 squash[count] = '\0';
476 rc = kstrtoul(squash, 10, &squash_uid);
480 rc = nodemap_set_squash_uid(m->private, squash_uid);
488 * Set the squash GID.
490 * \param[in] file proc file
491 * \param[in] buffer string representing squash GID to set
492 * \param[in] count \a buffer length
493 * \param[in] off unused
494 * \retval \a count on success
495 * \retval negative number on error
498 nodemap_squash_gid_seq_write(struct file *file, const char __user *buffer,
499 size_t count, loff_t *off)
501 char squash[NODEMAP_LPROC_ID_LEN + 1];
502 struct seq_file *m = file->private_data;
503 long unsigned int squash_gid;
509 if (count >= sizeof(squash))
512 if (copy_from_user(squash, buffer, count))
515 squash[count] = '\0';
516 rc = kstrtoul(squash, 10, &squash_gid);
520 rc = nodemap_set_squash_gid(m->private, squash_gid);
528 * Set/unset the trusted flag.
530 * \param[in] file proc file
531 * \param[in] buffer string, "1" or "0"
532 * \param[in] count \a buffer length
533 * \param[in] off unused
534 * \retval \a count on success
535 * \retval negative number on error
538 nodemap_trusted_seq_write(struct file *file, const char __user *buffer,
539 size_t count, loff_t *off)
541 struct seq_file *m = file->private_data;
545 rc = nodemap_proc_read_flag(buffer, count, &flags);
549 rc = nodemap_set_trust_client_ids(m->private, flags);
557 * Set/unset the admin flag.
559 * \param[in] file proc file
560 * \param[in] buffer string, "1" or "0"
561 * \param[in] count \a buffer length
562 * \param[in] off unused
563 * \retval \a count on success
564 * \retval negative number on error
567 nodemap_admin_seq_write(struct file *file, const char __user *buffer,
568 size_t count, loff_t *off)
570 struct seq_file *m = file->private_data;
574 rc = nodemap_proc_read_flag(buffer, count, &flags);
578 rc = nodemap_set_allow_root(m->private, flags);
588 * \param[in] file proc file
589 * \param[in] buffer string, name of the nodemap to add
590 * \param[in] count \a buffer length
591 * \param[in] off unused
592 * \retval \a count on success
593 * \retval negative number on error
596 lprocfs_add_nodemap_seq_write(struct file *file, const char __user *buffer,
597 size_t count, loff_t *off)
599 char nodemap_name[LUSTRE_NODEMAP_NAME_LENGTH + 1];
607 if (count >= sizeof(nodemap_name))
610 if (copy_from_user(nodemap_name, buffer, count))
613 nodemap_name[count] = '\0';
615 cpybuf = nodemap_name;
616 pos = strsep(&cpybuf, " \n");
620 rc = nodemap_add(nodemap_name);
626 LPROC_SEQ_FOPS_WO_TYPE(nodemap, add_nodemap);
631 * \param[in] file proc file
632 * \param[in] buffer string, name of the nodemap to delete
633 * \param[in] count \a buffer length
634 * \param[in] off unused
635 * \retval \a count on success
636 * \retval negative number on error
639 lprocfs_del_nodemap_seq_write(struct file *file, const char __user *buffer,
640 size_t count, loff_t *off)
642 char nodemap_name[LUSTRE_NODEMAP_NAME_LENGTH + 1];
650 if (count >= sizeof(nodemap_name))
653 if (copy_from_user(nodemap_name, buffer, count))
656 nodemap_name[count] = '\0';
658 cpybuf = nodemap_name;
659 pos = strsep(&cpybuf, " \n");
663 rc = nodemap_del(nodemap_name);
670 LPROC_SEQ_FOPS_WO_TYPE(nodemap, del_nodemap);
673 * Helper function to parse a NID string.
675 * \param[in] rangestr string representation of NIDs, see libcfs_str2nid()
676 * \param[out] nids array of two nids
677 * \retval 0 on success
678 * \retval negative number on error
680 static int parse_nids(char *rangestr, lnet_nid_t nids[2])
682 struct list_head nidlist;
683 char nidstr[2][LNET_NIDSTR_SIZE];
684 char nidrange_str[2 * LNET_NIDSTR_SIZE + 2];
687 INIT_LIST_HEAD(&nidlist);
689 if (cfs_parse_nidlist(rangestr, strlen(rangestr),
693 if (!cfs_nidrange_is_contiguous(&nidlist))
696 cfs_nidrange_find_min_max(&nidlist, nidstr[0], nidstr[1],
698 snprintf(nidrange_str, sizeof(nidrange_str), "%s:%s",
699 nidstr[0], nidstr[1]);
701 rc = nodemap_parse_range(nidrange_str, nids);
705 cfs_free_nidlist(&nidlist);
711 * Add a NID range to nodemap.
713 * \param[in] file proc file
714 * \param[in] buffer string, "<nodemap name> <nid range>"
715 * \param[in] count \a buffer length
716 * \param[in] off unused
717 * \retval \a count on success
718 * \retval negative number on error
721 lprocfs_add_nodemap_range_seq_write(struct file *file,
722 const char __user *buffer,
723 size_t count, loff_t *off)
725 char name_range[LUSTRE_NODEMAP_NAME_LENGTH +
726 LNET_NIDSTR_SIZE * 2 + 2];
729 char *rangestr = NULL;
736 if (count >= sizeof(name_range))
737 GOTO(out, rc = -EINVAL);
739 if (copy_from_user(name_range, buffer, count))
740 GOTO(out, rc = -EFAULT);
742 name_range[count] = '\0';
745 name = strsep(&cpybuf, " ");
747 GOTO(out, rc = -EINVAL);
749 rangestr = strsep(&cpybuf, " \n");
750 if (rangestr == NULL)
751 GOTO(out, rc = -EINVAL);
753 rc = parse_nids(rangestr, nids);
757 rc = nodemap_add_range(name, nids);
759 GOTO(out, rc = -EINVAL);
767 LPROC_SEQ_FOPS_WO_TYPE(nodemap, add_nodemap_range);
770 * Delete a NID range from nodemap.
772 * \param[in] file proc file
773 * \param[in] buffer string, "<nodemap name> <nid range>"
774 * \param[in] count \a buffer length
775 * \param[in] off unused
776 * \retval \a count on success
777 * \retval negative number on error
780 lprocfs_del_nodemap_range_seq_write(struct file *file,
781 const char __user *buffer,
782 size_t count, loff_t *off)
784 char name_range[LUSTRE_NODEMAP_NAME_LENGTH +
785 LNET_NIDSTR_SIZE * 2 + 2];
788 char *rangestr = NULL;
795 if (count >= sizeof(name_range))
796 GOTO(out, rc = -EINVAL);
798 if (copy_from_user(name_range, buffer, count))
799 GOTO(out, rc = -EFAULT);
801 name_range[count] = '\0';
804 name = strsep(&cpybuf, " ");
806 GOTO(out, rc = -EINVAL);
808 rangestr = strsep(&cpybuf, " \n");
809 if (rangestr == NULL)
810 GOTO(out, rc = -EINVAL);
812 rc = parse_nids(rangestr, nids);
816 rc = nodemap_del_range(name, nids);
818 GOTO(out, rc = -EINVAL);
826 LPROC_SEQ_FOPS_WO_TYPE(nodemap, del_nodemap_range);
829 * Add an idmap to nodemap.
831 * \param[in] file proc file
832 * \param[in] buffer string, "<nodemap name> <uid|gid> <idmap>"
833 * \param[in] count \a buffer length
834 * \param[in] off unused
835 * \retval \a count on success
836 * \retval negative number on error
839 lprocfs_add_nodemap_idmap_seq_write(struct file *file,
840 const char __user *buffer,
841 size_t count, loff_t *off)
843 char name_idmapstr[LUSTRE_NODEMAP_NAME_LENGTH + 16];
846 char *idtypestr = NULL;
847 char *idmapstr = NULL;
854 if (count >= sizeof(name_idmapstr))
855 GOTO(out, rc = -EINVAL);
857 if (copy_from_user(name_idmapstr, buffer, count))
858 GOTO(out, rc = -EFAULT);
860 name_idmapstr[count] = '\0';
862 cpybuf = name_idmapstr;
863 name = strsep(&cpybuf, " ");
865 GOTO(out, rc = -EINVAL);
867 idtypestr = strsep(&cpybuf, " ");
868 if (idtypestr == NULL)
869 GOTO(out, rc = -EINVAL);
871 idmapstr = strsep(&cpybuf, " \n");
872 if (idmapstr == NULL)
873 GOTO(out, rc = -EINVAL);
875 rc = nodemap_parse_idmap(idmapstr, idmap);
877 GOTO(out, rc = -EINVAL);
879 if (strcmp(idtypestr, "uid") == 0)
880 rc = nodemap_add_idmap(name, NODEMAP_UID, idmap);
881 else if (strcmp(idtypestr, "gid") == 0)
882 rc = nodemap_add_idmap(name, NODEMAP_GID, idmap);
884 GOTO(out, rc = -EINVAL);
887 GOTO(out, rc = -EINVAL);
895 LPROC_SEQ_FOPS_WO_TYPE(nodemap, add_nodemap_idmap);
898 * Delete an idmap from nodemap.
900 * \param[in] file proc file
901 * \param[in] buffer string, "<nodemap name> <uid|gid> <idmap>"
902 * \param[in] count \a buffer length
903 * \param[in] off unused
904 * \retval \a count on success
905 * \retval negative number on error
908 lprocfs_del_nodemap_idmap_seq_write(struct file *file,
909 const char __user *buffer,
910 size_t count, loff_t *off)
912 char name_idmapstr[LUSTRE_NODEMAP_NAME_LENGTH + 16];
915 char *idtypestr = NULL;
916 char *idmapstr = NULL;
923 if (count >= sizeof(name_idmapstr))
924 GOTO(out, rc = -EINVAL);
926 if (copy_from_user(name_idmapstr, buffer, count))
927 GOTO(out, rc = -EFAULT);
929 name_idmapstr[count] = '\0';
931 cpybuf = name_idmapstr;
932 name = strsep(&cpybuf, " ");
934 GOTO(out, rc = -EINVAL);
936 idtypestr = strsep(&cpybuf, " ");
937 if (idtypestr == NULL)
938 GOTO(out, rc = -EINVAL);
940 idmapstr = strsep(&cpybuf, " \n");
941 if (idmapstr == NULL)
942 GOTO(out, rc = -EINVAL);
944 rc = nodemap_parse_idmap(idmapstr, idmap);
946 GOTO(out, rc = -EINVAL);
948 if (strcmp(idtypestr, "uid") == 0)
949 rc = nodemap_del_idmap(name, NODEMAP_UID, idmap);
950 else if (strcmp(idtypestr, "gid") == 0)
951 rc = nodemap_del_idmap(name, NODEMAP_GID, idmap);
953 GOTO(out, rc = -EINVAL);
956 GOTO(out, rc = -EINVAL);
964 LPROC_SEQ_FOPS_WO_TYPE(nodemap, del_nodemap_idmap);
965 #endif /* NODEMAP_PROC_DEBUG */
967 static struct lprocfs_vars lprocfs_nm_module_vars[] = {
970 .fops = &nodemap_active_fops,
972 #ifdef NODEMAP_PROC_DEBUG
974 .name = "add_nodemap",
975 .fops = &nodemap_add_nodemap_fops,
978 .name = "remove_nodemap",
979 .fops = &nodemap_del_nodemap_fops,
982 .name = "add_nodemap_range",
983 .fops = &nodemap_add_nodemap_range_fops,
986 .name = "del_nodemap_range",
987 .fops = &nodemap_del_nodemap_range_fops,
990 .name = "add_nodemap_idmap",
991 .fops = &nodemap_add_nodemap_idmap_fops,
994 .name = "del_nodemap_idmap",
995 .fops = &nodemap_del_nodemap_idmap_fops,
997 #endif /* NODEMAP_PROC_DEBUG */
1003 #ifdef NODEMAP_PROC_DEBUG
1004 LPROC_SEQ_FOPS(nodemap_trusted);
1005 LPROC_SEQ_FOPS(nodemap_admin);
1006 LPROC_SEQ_FOPS(nodemap_squash_uid);
1007 LPROC_SEQ_FOPS(nodemap_squash_gid);
1009 LPROC_SEQ_FOPS_RO(nodemap_trusted);
1010 LPROC_SEQ_FOPS_RO(nodemap_admin);
1011 LPROC_SEQ_FOPS_RO(nodemap_squash_uid);
1012 LPROC_SEQ_FOPS_RO(nodemap_squash_gid);
1015 const struct file_operations nodemap_ranges_fops = {
1016 .open = nodemap_ranges_open,
1018 .llseek = seq_lseek,
1019 .release = single_release
1022 const struct file_operations nodemap_idmap_fops = {
1023 .open = nodemap_idmap_open,
1025 .llseek = seq_lseek,
1026 .release = single_release
1029 const struct file_operations nodemap_exports_fops = {
1030 .open = nodemap_exports_open,
1032 .llseek = seq_lseek,
1033 .release = single_release
1036 static struct lprocfs_vars lprocfs_nodemap_vars[] = {
1039 .fops = &nodemap_id_fops,
1042 .name = "trusted_nodemap",
1043 .fops = &nodemap_trusted_fops,
1046 .name = "admin_nodemap",
1047 .fops = &nodemap_admin_fops,
1050 .name = "squash_uid",
1051 .fops = &nodemap_squash_uid_fops,
1054 .name = "squash_gid",
1055 .fops = &nodemap_squash_gid_fops,
1059 .fops = &nodemap_ranges_fops,
1063 .fops = &nodemap_exports_fops,
1067 .fops = &nodemap_idmap_fops,
1074 static struct lprocfs_vars lprocfs_default_nodemap_vars[] = {
1077 .fops = &nodemap_id_fops,
1080 .name = "trusted_nodemap",
1081 .fops = &nodemap_trusted_fops,
1084 .name = "admin_nodemap",
1085 .fops = &nodemap_admin_fops,
1088 .name = "squash_uid",
1089 .fops = &nodemap_squash_uid_fops,
1092 .name = "squash_gid",
1093 .fops = &nodemap_squash_gid_fops,
1097 .fops = &nodemap_exports_fops,
1105 * Initialize the nodemap procfs directory.
1109 int nodemap_procfs_init(void)
1113 proc_lustre_nodemap_root = lprocfs_register(LUSTRE_NODEMAP_NAME,
1115 lprocfs_nm_module_vars,
1117 if (IS_ERR(proc_lustre_nodemap_root)) {
1118 rc = PTR_ERR(proc_lustre_nodemap_root);
1119 CERROR("cannot create 'nodemap' directory: rc = %d\n",
1121 proc_lustre_nodemap_root = NULL;
1127 * Cleanup nodemap proc entry data structures.
1129 void nodemap_procfs_exit(void)
1131 struct nodemap_pde *nm_pde;
1132 struct nodemap_pde *tmp;
1134 lprocfs_remove(&proc_lustre_nodemap_root);
1135 list_for_each_entry_safe(nm_pde, tmp, &nodemap_pde_list,
1137 list_del(&nm_pde->npe_list_member);
1138 OBD_FREE_PTR(nm_pde);
1143 * Remove a nodemap's procfs entry and related data.
1145 void lprocfs_nodemap_remove(struct nodemap_pde *nm_pde)
1147 lprocfs_remove(&nm_pde->npe_proc_entry);
1148 list_del(&nm_pde->npe_list_member);
1149 OBD_FREE_PTR(nm_pde);
1153 * Register the proc directory for a nodemap
1155 * \param nodemap nodemap to make the proc dir for
1156 * \param is_default: 1 if default nodemap
1159 int lprocfs_nodemap_register(struct lu_nodemap *nodemap, bool is_default)
1161 struct nodemap_pde *nm_entry;
1164 OBD_ALLOC_PTR(nm_entry);
1165 if (nm_entry == NULL)
1166 GOTO(out, rc = -ENOMEM);
1168 nm_entry->npe_proc_entry = proc_mkdir(nodemap->nm_name,
1169 proc_lustre_nodemap_root);
1170 if (IS_ERR(nm_entry->npe_proc_entry))
1171 GOTO(out, rc = PTR_ERR(nm_entry->npe_proc_entry));
1173 snprintf(nm_entry->npe_name, sizeof(nm_entry->npe_name), "%s",
1176 /* Use the nodemap name as stored on the PDE as the private data. This
1177 * is so a nodemap struct can be replaced without updating the proc
1180 rc = lprocfs_add_vars(nm_entry->npe_proc_entry,
1181 (is_default ? lprocfs_default_nodemap_vars :
1182 lprocfs_nodemap_vars),
1183 nm_entry->npe_name);
1185 lprocfs_remove(&nm_entry->npe_proc_entry);
1187 list_add(&nm_entry->npe_list_member, &nodemap_pde_list);
1191 CERROR("cannot create 'nodemap/%s': rc = %d\n",
1192 nodemap->nm_name, rc);
1193 if (nm_entry != NULL) {
1194 OBD_FREE_PTR(nm_entry);
1199 nodemap->nm_pde_data = nm_entry;