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