Whamcloud - gitweb
87feff4ef20dcddaa0a3fcba30d3f42d8679995f
[fs/lustre-release.git] / lustre / ptlrpc / nodemap_lproc.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
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.
9  *
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).
15  *
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
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (C) 2013, Trustees of Indiana University
24  *
25  * Copyright (c) 2014, 2017, Intel Corporation.
26  *
27  * Author: Joshua Walgenbach <jjw@iu.edu>
28  */
29
30 #define NODEMAP_LPROC_ID_LEN 16
31 #define NODEMAP_LPROC_FLAG_LEN 2
32
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"
39
40 static LIST_HEAD(nodemap_pde_list);
41
42 /**
43  * Reads and prints the idmap for the given nodemap.
44  *
45  * \param       m               seq file in proc fs
46  * \param       data            unused
47  * \retval      0               success
48  */
49 static int nodemap_idmap_show(struct seq_file *m, void *data)
50 {
51         struct lu_nodemap       *nodemap;
52         struct lu_idmap         *idmap;
53         struct rb_node          *node;
54         bool                    cont = 0;
55         int rc;
56
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);
64                 return rc;
65         }
66
67         seq_printf(m, "[\n");
68         down_read(&nodemap->nm_idmap_lock);
69         for (node = rb_first(&nodemap->nm_client_to_fs_uidmap); node;
70                                 node = rb_next(node)) {
71                 if (cont)
72                         seq_printf(m, ",\n");
73                 cont = 1;
74                 idmap = rb_entry(node, struct lu_idmap, id_client_to_fs);
75                 if (idmap != NULL)
76                         seq_printf(m, " { idtype: uid, client_id: %u, "
77                                    "fs_id: %u }", idmap->id_client,
78                                    idmap->id_fs);
79         }
80         for (node = rb_first(&nodemap->nm_client_to_fs_gidmap);
81                                 node; node = rb_next(node)) {
82                 if (cont)
83                         seq_printf(m, ",\n");
84                 idmap = rb_entry(node, struct lu_idmap, id_client_to_fs);
85                 if (idmap != NULL)
86                         seq_printf(m, " { idtype: gid, client_id: %u, "
87                                    "fs_id: %u }", idmap->id_client,
88                                    idmap->id_fs);
89         }
90         up_read(&nodemap->nm_idmap_lock);
91         seq_printf(m, "\n");
92         seq_printf(m, "]\n");
93
94         nodemap_putref(nodemap);
95         return 0;
96 }
97
98 /**
99  * Attaches nodemap_idmap_show to proc file.
100  *
101  * \param       inode           inode of seq file in proc fs
102  * \param       file            seq file
103  * \retval      0               success
104  */
105 static int nodemap_idmap_open(struct inode *inode, struct file *file)
106 {
107         return single_open(file, nodemap_idmap_show, PDE_DATA(inode));
108 }
109
110 /**
111  * Reads and prints the NID ranges for the given nodemap.
112  *
113  * \param       m               seq file in proc fs
114  * \param       data            unused
115  * \retval      0               success
116  */
117 static int nodemap_ranges_show(struct seq_file *m, void *data)
118 {
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];
124         bool                            cont = false;
125         int rc;
126
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);
134                 return rc;
135         }
136
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) {
140                 if (cont)
141                         seq_printf(m, ",\n");
142                 cont = 1;
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);
148         }
149         up_read(&active_config->nmc_range_tree_lock);
150         mutex_unlock(&active_config_lock);
151         seq_printf(m, "\n");
152         seq_printf(m, "]\n");
153
154         nodemap_putref(nodemap);
155         return 0;
156 }
157
158 /**
159  * Connects nodemap_idmap_show to proc file.
160  *
161  * \param       inode           inode of seq file in proc fs
162  * \param       file            seq file
163  * \retval      0               success
164  */
165 static int nodemap_ranges_open(struct inode *inode, struct file *file)
166 {
167         return single_open(file, nodemap_ranges_show, PDE_DATA(inode));
168 }
169
170 /**
171  * Reads and prints the fileset for the given nodemap.
172  *
173  * \param       m               seq file in proc fs
174  * \param       data            unused
175  * \retval      0               success
176  */
177 static int nodemap_fileset_seq_show(struct seq_file *m, void *data)
178 {
179         struct lu_nodemap *nodemap;
180         int rc = 0;
181
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);
189                 return rc;
190         }
191
192         seq_printf(m, "%s\n", nodemap->nm_fileset);
193         nodemap_putref(nodemap);
194         return rc;
195 }
196
197 /**
198  * Set a fileset on a nodemap.
199  *
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
206  */
207 static ssize_t
208 nodemap_fileset_seq_write(struct file *file,
209                                       const char __user *buffer,
210                                       size_t count, loff_t *off)
211 {
212         struct seq_file *m = file->private_data;
213         char *nm_fileset;
214         int rc = 0;
215         ENTRY;
216
217         if (count == 0)
218                 RETURN(0);
219
220         if (count > PATH_MAX)
221                 RETURN(-EINVAL);
222
223         OBD_ALLOC(nm_fileset, count + 1);
224         /* OBD_ALLOC zero-fills the buffer */
225         if (nm_fileset == NULL)
226                 RETURN(-ENOMEM);
227
228         if (copy_from_user(nm_fileset, buffer, count))
229                 GOTO(out, rc = -EFAULT);
230
231         rc = nodemap_set_fileset(m->private, nm_fileset);
232         if (rc != 0)
233                 GOTO(out, rc = -EINVAL);
234
235         rc = count;
236 out:
237         OBD_FREE(nm_fileset, count + 1);
238
239         return rc;
240 }
241 LPROC_SEQ_FOPS(nodemap_fileset);
242
243 /**
244  * Reads and prints the SELinux policy info for the given nodemap.
245  *
246  * \param       m               seq file in proc fs
247  * \param       data            unused
248  * \retval      0               success
249  */
250 static int nodemap_sepol_seq_show(struct seq_file *m, void *data)
251 {
252         struct lu_nodemap *nodemap;
253         int rc = 0;
254
255         mutex_lock(&active_config_lock);
256         nodemap = nodemap_lookup(m->private);
257         mutex_unlock(&active_config_lock);
258         if (IS_ERR(nodemap)) {
259                 rc = PTR_ERR(nodemap);
260                 CERROR("cannot find nodemap '%s': rc = %d\n",
261                         (char *)m->private, rc);
262                 return rc;
263         }
264
265         seq_printf(m, "%s\n", nodemap_get_sepol(nodemap));
266         nodemap_putref(nodemap);
267         return rc;
268 }
269
270 /**
271  * Set SELinux policy info on a nodemap.
272  *
273  * \param[in] file      proc file
274  * \param[in] buffer    string, "<sepol>"
275  * \param[in] count     \a buffer length
276  * \param[in] off       unused
277  * \retval              \a count on success
278  * \retval              negative number on error
279  */
280 static ssize_t
281 nodemap_sepol_seq_write(struct file *file,
282                         const char __user *buffer,
283                         size_t count, loff_t *off)
284 {
285         struct seq_file *m = file->private_data;
286         char sepol[LUSTRE_NODEMAP_SEPOL_LENGTH + 1];
287         int rc = 0;
288
289         BUILD_BUG_ON(sizeof(sepol) !=
290                      sizeof(((struct lu_nodemap *)0)->nm_sepol));
291
292         if (count > 0) {
293                 if (count >= sizeof(sepol))
294                         GOTO(out, rc = -ENAMETOOLONG);
295
296                 if (copy_from_user(sepol, buffer, count))
297                         GOTO(out, rc = -EFAULT);
298
299                 sepol[count] = '\0';
300
301                 rc = nodemap_set_sepol(m->private, sepol);
302         }
303
304 out:
305         if (rc != 0)
306                 return rc;
307
308         return count;
309 }
310 LPROC_SEQ_FOPS(nodemap_sepol);
311
312 /**
313  * Reads and prints the exports attached to the given nodemap.
314  *
315  * \param       m               seq file in proc fs, stores nodemap
316  * \param       data            unused
317  * \retval      0               success
318  */
319 static int nodemap_exports_show(struct seq_file *m, void *data)
320 {
321         struct lu_nodemap *nodemap;
322         struct obd_export *exp;
323         char nidstr[LNET_NIDSTR_SIZE] = "<unknown>";
324         int rc;
325
326         mutex_lock(&active_config_lock);
327         nodemap = nodemap_lookup(m->private);
328         mutex_unlock(&active_config_lock);
329         if (IS_ERR(nodemap)) {
330                 rc = PTR_ERR(nodemap);
331                 CERROR("cannot find nodemap '%s': rc = %d\n",
332                         (char *)m->private, rc);
333                 return rc;
334         }
335
336         seq_printf(m, "[\n");
337
338         mutex_lock(&nodemap->nm_member_list_lock);
339         list_for_each_entry(exp, &nodemap->nm_member_list,
340                             exp_target_data.ted_nodemap_member) {
341                 if (exp->exp_connection != NULL)
342                         libcfs_nid2str_r(exp->exp_connection->c_peer.nid,
343                                          nidstr, sizeof(nidstr));
344
345                 seq_printf(m, " { nid: %s, uuid: %s },",
346                            nidstr, exp->exp_client_uuid.uuid);
347         }
348         mutex_unlock(&nodemap->nm_member_list_lock);
349
350         seq_printf(m, "\n");
351         seq_printf(m, "]\n");
352
353         nodemap_putref(nodemap);
354         return 0;
355 }
356
357 /**
358  * Attaches nodemap_idmap_show to proc file.
359  *
360  * \param       inode           inode of seq file in proc fs
361  * \param       file            seq file
362  * \retval      0               success
363  */
364 static int nodemap_exports_open(struct inode *inode, struct file *file)
365 {
366         return single_open(file, nodemap_exports_show, PDE_DATA(inode));
367 }
368
369 /**
370  * Reads and prints the active flag for the given nodemap.
371  *
372  * \param       m               seq file in proc fs
373  * \param       data            unused
374  * \retval      0               success
375  */
376 static int nodemap_active_seq_show(struct seq_file *m, void *data)
377 {
378         seq_printf(m, "%u\n", (unsigned int)nodemap_active);
379         return 0;
380 }
381
382 /**
383  * Activate/deactivate nodemap.
384  *
385  * \param[in] file      proc file
386  * \param[in] buffer    string, "1" or "0" to activate/deactivate nodemap
387  * \param[in] count     \a buffer length
388  * \param[in] off       unused
389  * \retval              \a count on success
390  * \retval              negative number on error
391  */
392 static ssize_t
393 nodemap_active_seq_write(struct file *file, const char __user *buffer,
394                          size_t count, loff_t *off)
395 {
396         char                    active_string[NODEMAP_LPROC_FLAG_LEN + 1];
397         long unsigned int       active;
398         int                     rc;
399
400         if (count == 0)
401                 return 0;
402
403         if (count >= sizeof(active_string))
404                 return -EINVAL;
405
406         if (copy_from_user(active_string, buffer, count))
407                 return -EFAULT;
408
409         active_string[count] = '\0';
410         rc = kstrtoul(active_string, 10, &active);
411         if (rc != 0)
412                 return -EINVAL;
413
414         nodemap_activate(active);
415
416         return count;
417 }
418 LPROC_SEQ_FOPS(nodemap_active);
419
420 /**
421  * Reads and prints the nodemap ID for the given nodemap.
422  *
423  * \param       m               seq file in proc fs
424  * \param       data            unused
425  * \retval      0               success
426  */
427 static int nodemap_id_seq_show(struct seq_file *m, void *data)
428 {
429         struct lu_nodemap *nodemap;
430
431         mutex_lock(&active_config_lock);
432         nodemap = nodemap_lookup(m->private);
433         mutex_unlock(&active_config_lock);
434         if (IS_ERR(nodemap)) {
435                 int rc = PTR_ERR(nodemap);
436                 CERROR("cannot find nodemap '%s': rc = %d\n",
437                         (char *)m->private, rc);
438                 return rc;
439         }
440
441         seq_printf(m, "%u\n", nodemap->nm_id);
442         nodemap_putref(nodemap);
443         return 0;
444 }
445 LPROC_SEQ_FOPS_RO(nodemap_id);
446
447 /**
448  * Reads and prints the root squash UID for the given nodemap.
449  *
450  * \param       m               seq file in proc fs
451  * \param       data            unused
452  * \retval      0               success
453  */
454 static int nodemap_squash_uid_seq_show(struct seq_file *m, void *data)
455 {
456         struct lu_nodemap *nodemap;
457
458         mutex_lock(&active_config_lock);
459         nodemap = nodemap_lookup(m->private);
460         mutex_unlock(&active_config_lock);
461         if (IS_ERR(nodemap)) {
462                 int rc = PTR_ERR(nodemap);
463                 CERROR("cannot find nodemap '%s': rc = %d\n",
464                         (char *)m->private, rc);
465                 return rc;
466         }
467
468         seq_printf(m, "%u\n", nodemap->nm_squash_uid);
469         nodemap_putref(nodemap);
470         return 0;
471 }
472
473 /**
474  * Reads and prints the root squash GID for the given nodemap.
475  *
476  * \param       m               seq file in proc fs
477  * \param       data            unused
478  * \retval      0               success
479  */
480 static int nodemap_squash_gid_seq_show(struct seq_file *m, void *data)
481 {
482         struct lu_nodemap *nodemap;
483
484         mutex_lock(&active_config_lock);
485         nodemap = nodemap_lookup(m->private);
486         mutex_unlock(&active_config_lock);
487         if (IS_ERR(nodemap)) {
488                 int rc = PTR_ERR(nodemap);
489                 CERROR("cannot find nodemap '%s': rc = %d\n",
490                         (char *)m->private, rc);
491                 return rc;
492         }
493
494         seq_printf(m, "%u\n", nodemap->nm_squash_gid);
495         nodemap_putref(nodemap);
496         return 0;
497 }
498
499 /**
500  * Reads and prints the trusted flag for the given nodemap.
501  *
502  * \param       m               seq file in proc fs
503  * \param       data            unused
504  * \retval      0               success
505  */
506 static int nodemap_trusted_seq_show(struct seq_file *m, void *data)
507 {
508         struct lu_nodemap *nodemap;
509
510         mutex_lock(&active_config_lock);
511         nodemap = nodemap_lookup(m->private);
512         mutex_unlock(&active_config_lock);
513         if (IS_ERR(nodemap)) {
514                 int rc = PTR_ERR(nodemap);
515
516                 CERROR("cannot find nodemap '%s': rc = %d\n",
517                         (char *)m->private, rc);
518                 return rc;
519         }
520
521         seq_printf(m, "%d\n", (int)nodemap->nmf_trust_client_ids);
522         nodemap_putref(nodemap);
523         return 0;
524 }
525
526 /**
527  * Reads and prints the admin flag for the given nodemap.
528  *
529  * \param       m               seq file in proc fs
530  * \param       data            unused
531  * \retval      0               success
532  */
533 static int nodemap_admin_seq_show(struct seq_file *m, void *data)
534 {
535         struct lu_nodemap *nodemap;
536         int rc;
537
538         mutex_lock(&active_config_lock);
539         nodemap = nodemap_lookup(m->private);
540         mutex_unlock(&active_config_lock);
541         if (IS_ERR(nodemap)) {
542                 rc = PTR_ERR(nodemap);
543                 CERROR("cannot find nodemap '%s': rc = %d\n",
544                         (char *)m->private, rc);
545                 return rc;
546         }
547
548         seq_printf(m, "%d\n", (int)nodemap->nmf_allow_root_access);
549         nodemap_putref(nodemap);
550         return 0;
551 }
552
553 /**
554  * Reads and prints the mapping mode for the given nodemap.
555  *
556  * \param       m               seq file in proc fs
557  * \param       data            unused
558  * \retval      0               success
559  */
560 static int nodemap_map_mode_seq_show(struct seq_file *m, void *data)
561 {
562         struct lu_nodemap *nodemap;
563         int rc;
564
565         mutex_lock(&active_config_lock);
566         nodemap = nodemap_lookup(m->private);
567         mutex_unlock(&active_config_lock);
568         if (IS_ERR(nodemap)) {
569                 rc = PTR_ERR(nodemap);
570                 CERROR("cannot find nodemap '%s': rc = %d\n",
571                         (char *)m->private, rc);
572                 return rc;
573         }
574
575         if (nodemap->nmf_map_uid_only)
576                 seq_printf(m, "uid_only\n");
577         else if (nodemap->nmf_map_gid_only)
578                 seq_printf(m, "gid_only\n");
579         else
580                 seq_printf(m, "both\n");
581
582         nodemap_putref(nodemap);
583         return 0;
584 }
585
586 /**
587  * Reads and prints the deny_unknown flag for the given nodemap.
588  *
589  * \param       m               seq file in proc fs
590  * \param       data            unused
591  * \retval      0               success
592  */
593 static int nodemap_deny_unknown_seq_show(struct seq_file *m, void *data)
594 {
595         struct lu_nodemap *nodemap;
596         int rc;
597
598         mutex_lock(&active_config_lock);
599         nodemap = nodemap_lookup(m->private);
600         mutex_unlock(&active_config_lock);
601         if (IS_ERR(nodemap)) {
602                 rc = PTR_ERR(nodemap);
603                 CERROR("cannot find nodemap '%s': rc = %d\n",
604                         (char *)m->private, rc);
605                 return rc;
606         }
607
608         seq_printf(m, "%d\n", (int)nodemap->nmf_deny_unknown);
609         nodemap_putref(nodemap);
610         return 0;
611 }
612
613 /**
614  * Reads and prints the audit_mode flag for the given nodemap.
615  *
616  * \param       m               seq file in proc fs
617  * \param       data            unused
618  * \retval      0               success
619  */
620 static int nodemap_audit_mode_seq_show(struct seq_file *m, void *data)
621 {
622         struct lu_nodemap *nodemap;
623         int rc;
624
625         mutex_lock(&active_config_lock);
626         nodemap = nodemap_lookup(m->private);
627         mutex_unlock(&active_config_lock);
628         if (IS_ERR(nodemap)) {
629                 rc = PTR_ERR(nodemap);
630                 CERROR("cannot find nodemap '%s': rc = %d\n",
631                        (char *)m->private, rc);
632                 return rc;
633         }
634
635         seq_printf(m, "%d\n", (int)nodemap->nmf_enable_audit);
636         nodemap_putref(nodemap);
637         return 0;
638 }
639
640 /**
641  * Reads and prints the forbid_encryption flag for the given nodemap.
642  *
643  * \param       m               seq file in proc fs
644  * \param       data            unused
645  * \retval      0               success
646  */
647 static int nodemap_forbid_encryption_seq_show(struct seq_file *m, void *data)
648 {
649         struct lu_nodemap *nodemap;
650         int rc;
651
652         mutex_lock(&active_config_lock);
653         nodemap = nodemap_lookup(m->private);
654         mutex_unlock(&active_config_lock);
655         if (IS_ERR(nodemap)) {
656                 rc = PTR_ERR(nodemap);
657                 CERROR("cannot find nodemap '%s': rc = %d\n",
658                        (char *)m->private, rc);
659                 return rc;
660         }
661
662         seq_printf(m, "%d\n", (int)nodemap->nmf_forbid_encryption);
663         nodemap_putref(nodemap);
664         return 0;
665 }
666
667 static struct lprocfs_vars lprocfs_nm_module_vars[] = {
668         {
669                 .name           = "active",
670                 .fops           = &nodemap_active_fops,
671         },
672         {
673                 NULL
674         }
675 };
676
677 LPROC_SEQ_FOPS_RO(nodemap_trusted);
678 LPROC_SEQ_FOPS_RO(nodemap_admin);
679 LPROC_SEQ_FOPS_RO(nodemap_squash_uid);
680 LPROC_SEQ_FOPS_RO(nodemap_squash_gid);
681
682 LPROC_SEQ_FOPS_RO(nodemap_deny_unknown);
683 LPROC_SEQ_FOPS_RO(nodemap_map_mode);
684 LPROC_SEQ_FOPS_RO(nodemap_audit_mode);
685 LPROC_SEQ_FOPS_RO(nodemap_forbid_encryption);
686
687 static const struct file_operations nodemap_ranges_fops = {
688         .open                   = nodemap_ranges_open,
689         .read                   = seq_read,
690         .llseek                 = seq_lseek,
691         .release                = single_release
692 };
693
694 static const struct file_operations nodemap_idmap_fops = {
695         .open                   = nodemap_idmap_open,
696         .read                   = seq_read,
697         .llseek                 = seq_lseek,
698         .release                = single_release
699 };
700
701 static const struct file_operations nodemap_exports_fops = {
702         .open                   = nodemap_exports_open,
703         .read                   = seq_read,
704         .llseek                 = seq_lseek,
705         .release                = single_release
706 };
707
708 static struct lprocfs_vars lprocfs_nodemap_vars[] = {
709         {
710                 .name           = "id",
711                 .fops           = &nodemap_id_fops,
712         },
713         {
714                 .name           = "trusted_nodemap",
715                 .fops           = &nodemap_trusted_fops,
716         },
717         {
718                 .name           = "admin_nodemap",
719                 .fops           = &nodemap_admin_fops,
720         },
721         {
722                 .name           = "deny_unknown",
723                 .fops           = &nodemap_deny_unknown_fops,
724         },
725         {
726                 .name           = "map_mode",
727                 .fops           = &nodemap_map_mode_fops,
728         },
729         {
730                 .name           = "audit_mode",
731                 .fops           = &nodemap_audit_mode_fops,
732         },
733         {
734                 .name           = "forbid_encryption",
735                 .fops           = &nodemap_forbid_encryption_fops,
736         },
737         {
738                 .name           = "squash_uid",
739                 .fops           = &nodemap_squash_uid_fops,
740         },
741         {
742                 .name           = "squash_gid",
743                 .fops           = &nodemap_squash_gid_fops,
744         },
745         {
746                 .name           = "ranges",
747                 .fops           = &nodemap_ranges_fops,
748         },
749         {
750                 .name           = "fileset",
751                 .fops           = &nodemap_fileset_fops,
752         },
753         {
754                 .name           = "sepol",
755                 .fops           = &nodemap_sepol_fops,
756         },
757         {
758                 .name           = "exports",
759                 .fops           = &nodemap_exports_fops,
760         },
761         {
762                 .name           = "idmap",
763                 .fops           = &nodemap_idmap_fops,
764         },
765         {
766                 NULL
767         }
768 };
769
770 static struct lprocfs_vars lprocfs_default_nodemap_vars[] = {
771         {
772                 .name           = "id",
773                 .fops           = &nodemap_id_fops,
774         },
775         {
776                 .name           = "trusted_nodemap",
777                 .fops           = &nodemap_trusted_fops,
778         },
779         {
780                 .name           = "admin_nodemap",
781                 .fops           = &nodemap_admin_fops,
782         },
783         {
784                 .name           = "deny_unknown",
785                 .fops           = &nodemap_deny_unknown_fops,
786         },
787         {
788                 .name           = "squash_uid",
789                 .fops           = &nodemap_squash_uid_fops,
790         },
791         {
792                 .name           = "squash_gid",
793                 .fops           = &nodemap_squash_gid_fops,
794         },
795         {
796                 .name           = "fileset",
797                 .fops           = &nodemap_fileset_fops,
798         },
799         {
800                 .name           = "exports",
801                 .fops           = &nodemap_exports_fops,
802         },
803         {
804                 .name           = "audit_mode",
805                 .fops           = &nodemap_audit_mode_fops,
806         },
807         {
808                 .name           = "forbid_encryption",
809                 .fops           = &nodemap_forbid_encryption_fops,
810         },
811         {
812                 NULL
813         }
814 };
815
816 /**
817  * Initialize the nodemap procfs directory.
818  *
819  * \retval      0               success
820  */
821 int nodemap_procfs_init(void)
822 {
823         int rc = 0;
824
825         proc_lustre_nodemap_root = lprocfs_register(LUSTRE_NODEMAP_NAME,
826                                                     proc_lustre_root,
827                                                     lprocfs_nm_module_vars,
828                                                     NULL);
829         if (IS_ERR(proc_lustre_nodemap_root)) {
830                 rc = PTR_ERR(proc_lustre_nodemap_root);
831                 CERROR("cannot create 'nodemap' directory: rc = %d\n",
832                        rc);
833                 proc_lustre_nodemap_root = NULL;
834         }
835         return rc;
836 }
837
838 /**
839  * Cleanup nodemap proc entry data structures.
840  */
841 void nodemap_procfs_exit(void)
842 {
843         struct nodemap_pde *nm_pde;
844         struct nodemap_pde *tmp;
845
846         lprocfs_remove(&proc_lustre_nodemap_root);
847         list_for_each_entry_safe(nm_pde, tmp, &nodemap_pde_list,
848                                  npe_list_member) {
849                 list_del(&nm_pde->npe_list_member);
850                 OBD_FREE_PTR(nm_pde);
851         }
852 }
853
854 /**
855  * Remove a nodemap's procfs entry and related data.
856  */
857 void lprocfs_nodemap_remove(struct nodemap_pde *nm_pde)
858 {
859         lprocfs_remove(&nm_pde->npe_proc_entry);
860         list_del(&nm_pde->npe_list_member);
861         OBD_FREE_PTR(nm_pde);
862 }
863
864 /**
865  * Register the proc directory for a nodemap
866  *
867  * \param       nodemap         nodemap to make the proc dir for
868  * \param       is_default:     1 if default nodemap
869  * \retval      0               success
870  */
871 int lprocfs_nodemap_register(struct lu_nodemap *nodemap, bool is_default)
872 {
873         struct nodemap_pde      *nm_entry;
874         int                      rc = 0;
875
876         OBD_ALLOC_PTR(nm_entry);
877         if (nm_entry == NULL)
878                 GOTO(out, rc = -ENOMEM);
879
880         nm_entry->npe_proc_entry = proc_mkdir(nodemap->nm_name,
881                                               proc_lustre_nodemap_root);
882         if (IS_ERR(nm_entry->npe_proc_entry))
883                 GOTO(out, rc = PTR_ERR(nm_entry->npe_proc_entry));
884
885         snprintf(nm_entry->npe_name, sizeof(nm_entry->npe_name), "%s",
886                  nodemap->nm_name);
887
888         /* Use the nodemap name as stored on the PDE as the private data. This
889          * is so a nodemap struct can be replaced without updating the proc
890          * entries.
891          */
892         rc = lprocfs_add_vars(nm_entry->npe_proc_entry,
893                               (is_default ? lprocfs_default_nodemap_vars :
894                                             lprocfs_nodemap_vars),
895                               nm_entry->npe_name);
896         if (rc != 0)
897                 lprocfs_remove(&nm_entry->npe_proc_entry);
898         else
899                 list_add(&nm_entry->npe_list_member, &nodemap_pde_list);
900
901 out:
902         if (rc != 0) {
903                 CERROR("cannot create 'nodemap/%s': rc = %d\n",
904                        nodemap->nm_name, rc);
905                 if (nm_entry != NULL) {
906                         OBD_FREE_PTR(nm_entry);
907                         nm_entry = NULL;
908                 }
909         }
910
911         nodemap->nm_pde_data = nm_entry;
912
913         return rc;
914 }