Whamcloud - gitweb
LU-11085 lustre: remove interval-tree code
[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 "nodemap_internal.h"
38
39 static LIST_HEAD(nodemap_pde_list);
40
41 /**
42  * Reads and prints the idmap for the given nodemap.
43  *
44  * \param       m               seq file in proc fs
45  * \param       data            unused
46  * \retval      0               success
47  */
48 static int nodemap_idmap_show(struct seq_file *m, void *data)
49 {
50         struct lu_nodemap       *nodemap;
51         struct lu_idmap         *idmap;
52         struct rb_node          *node;
53         bool                    cont = 0;
54         int rc;
55
56         mutex_lock(&active_config_lock);
57         nodemap = nodemap_lookup(m->private);
58         mutex_unlock(&active_config_lock);
59         if (IS_ERR(nodemap)) {
60                 rc = PTR_ERR(nodemap);
61                 CERROR("cannot find nodemap '%s': rc = %d\n",
62                         (char *)m->private, rc);
63                 return rc;
64         }
65
66         seq_printf(m, "[\n");
67         down_read(&nodemap->nm_idmap_lock);
68         for (node = rb_first(&nodemap->nm_client_to_fs_uidmap); node;
69                                 node = rb_next(node)) {
70                 if (cont)
71                         seq_printf(m, ",\n");
72                 cont = 1;
73                 idmap = rb_entry(node, struct lu_idmap, id_client_to_fs);
74                 if (idmap != NULL)
75                         seq_printf(m, " { idtype: uid, client_id: %u, "
76                                    "fs_id: %u }", idmap->id_client,
77                                    idmap->id_fs);
78         }
79         for (node = rb_first(&nodemap->nm_client_to_fs_gidmap);
80                                 node; node = rb_next(node)) {
81                 if (cont)
82                         seq_printf(m, ",\n");
83                 idmap = rb_entry(node, struct lu_idmap, id_client_to_fs);
84                 if (idmap != NULL)
85                         seq_printf(m, " { idtype: gid, client_id: %u, "
86                                    "fs_id: %u }", idmap->id_client,
87                                    idmap->id_fs);
88         }
89         for (node = rb_first(&nodemap->nm_client_to_fs_projidmap);
90              node; node = rb_next(node)) {
91                 if (cont)
92                         seq_printf(m, ",\n");
93                 idmap = rb_entry(node, struct lu_idmap, id_client_to_fs);
94                 if (idmap != NULL)
95                         seq_printf(m,
96                                    " { idtype: projid, client_id: %u, fs_id: %u }",
97                                    idmap->id_client,
98                                    idmap->id_fs);
99         }
100         up_read(&nodemap->nm_idmap_lock);
101         seq_printf(m, "\n");
102         seq_printf(m, "]\n");
103
104         nodemap_putref(nodemap);
105         return 0;
106 }
107
108 /**
109  * Attaches nodemap_idmap_show to proc file.
110  *
111  * \param       inode           inode of seq file in proc fs
112  * \param       file            seq file
113  * \retval      0               success
114  */
115 static int nodemap_idmap_open(struct inode *inode, struct file *file)
116 {
117         return single_open(file, nodemap_idmap_show, pde_data(inode));
118 }
119
120 /**
121  * Reads and prints the NID ranges for the given nodemap.
122  *
123  * \param       m               seq file in proc fs
124  * \param       data            unused
125  * \retval      0               success
126  */
127 static int nodemap_ranges_show(struct seq_file *m, void *data)
128 {
129         struct lu_nodemap               *nodemap;
130         struct lu_nid_range             *range;
131         char                            start_nidstr[LNET_NIDSTR_SIZE];
132         char                            end_nidstr[LNET_NIDSTR_SIZE];
133         bool                            cont = false;
134         int rc;
135
136         mutex_lock(&active_config_lock);
137         nodemap = nodemap_lookup(m->private);
138         if (IS_ERR(nodemap)) {
139                 mutex_unlock(&active_config_lock);
140                 rc = PTR_ERR(nodemap);
141                 CERROR("cannot find nodemap '%s': rc = %d\n",
142                         (char *)m->private, rc);
143                 return rc;
144         }
145
146         seq_printf(m, "[\n");
147         down_read(&active_config->nmc_range_tree_lock);
148         list_for_each_entry(range, &nodemap->nm_ranges, rn_list) {
149                 if (cont)
150                         seq_printf(m, ",\n");
151                 cont = 1;
152                 libcfs_nidstr_r(&range->rn_start, start_nidstr, sizeof(start_nidstr));
153                 libcfs_nidstr_r(&range->rn_end, end_nidstr, sizeof(end_nidstr));
154                 seq_printf(m, " { id: %u, start_nid: %s, end_nid: %s }",
155                            range->rn_id, start_nidstr, end_nidstr);
156         }
157         up_read(&active_config->nmc_range_tree_lock);
158         mutex_unlock(&active_config_lock);
159         seq_printf(m, "\n");
160         seq_printf(m, "]\n");
161
162         nodemap_putref(nodemap);
163         return 0;
164 }
165
166 /**
167  * Connects nodemap_idmap_show to proc file.
168  *
169  * \param       inode           inode of seq file in proc fs
170  * \param       file            seq file
171  * \retval      0               success
172  */
173 static int nodemap_ranges_open(struct inode *inode, struct file *file)
174 {
175         return single_open(file, nodemap_ranges_show, pde_data(inode));
176 }
177
178 /**
179  * Reads and prints the fileset for the given nodemap.
180  *
181  * \param       m               seq file in proc fs
182  * \param       data            unused
183  * \retval      0               success
184  */
185 static int nodemap_fileset_seq_show(struct seq_file *m, void *data)
186 {
187         struct lu_nodemap *nodemap;
188         int rc = 0;
189
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);
197                 return rc;
198         }
199
200         seq_printf(m, "%s\n", nodemap->nm_fileset);
201         nodemap_putref(nodemap);
202         return rc;
203 }
204
205 /**
206  * Set a fileset on a nodemap.
207  *
208  * \param[in] file      proc file
209  * \param[in] buffer    string, "<fileset>"
210  * \param[in] count     \a buffer length
211  * \param[in] off       unused
212  * \retval              \a count on success
213  * \retval              negative number on error
214  */
215 static ssize_t
216 nodemap_fileset_seq_write(struct file *file,
217                                       const char __user *buffer,
218                                       size_t count, loff_t *off)
219 {
220         struct seq_file *m = file->private_data;
221         char *nm_fileset;
222         int rc = 0;
223         ENTRY;
224
225         if (count == 0)
226                 RETURN(0);
227
228         if (count > PATH_MAX)
229                 RETURN(-EINVAL);
230
231         OBD_ALLOC(nm_fileset, count + 1);
232         /* OBD_ALLOC zero-fills the buffer */
233         if (nm_fileset == NULL)
234                 RETURN(-ENOMEM);
235
236         if (copy_from_user(nm_fileset, buffer, count))
237                 GOTO(out, rc = -EFAULT);
238
239         rc = nodemap_set_fileset(m->private, nm_fileset);
240         if (rc != 0)
241                 GOTO(out, rc = -EINVAL);
242
243         rc = count;
244 out:
245         OBD_FREE(nm_fileset, count + 1);
246
247         return rc;
248 }
249 LPROC_SEQ_FOPS(nodemap_fileset);
250
251 /**
252  * Reads and prints the SELinux policy info for the given nodemap.
253  *
254  * \param       m               seq file in proc fs
255  * \param       data            unused
256  * \retval      0               success
257  */
258 static int nodemap_sepol_seq_show(struct seq_file *m, void *data)
259 {
260         struct lu_nodemap *nodemap;
261         int rc = 0;
262
263         mutex_lock(&active_config_lock);
264         nodemap = nodemap_lookup(m->private);
265         mutex_unlock(&active_config_lock);
266         if (IS_ERR(nodemap)) {
267                 rc = PTR_ERR(nodemap);
268                 CERROR("cannot find nodemap '%s': rc = %d\n",
269                         (char *)m->private, rc);
270                 return rc;
271         }
272
273         seq_printf(m, "%s\n", nodemap_get_sepol(nodemap));
274         nodemap_putref(nodemap);
275         return rc;
276 }
277
278 /**
279  * Set SELinux policy info on a nodemap.
280  *
281  * \param[in] file      proc file
282  * \param[in] buffer    string, "<sepol>"
283  * \param[in] count     \a buffer length
284  * \param[in] off       unused
285  * \retval              \a count on success
286  * \retval              negative number on error
287  */
288 static ssize_t
289 nodemap_sepol_seq_write(struct file *file,
290                         const char __user *buffer,
291                         size_t count, loff_t *off)
292 {
293         struct seq_file *m = file->private_data;
294         char sepol[LUSTRE_NODEMAP_SEPOL_LENGTH + 1];
295         int rc = 0;
296
297         BUILD_BUG_ON(sizeof(sepol) !=
298                      sizeof(((struct lu_nodemap *)0)->nm_sepol));
299
300         if (count > 0) {
301                 if (count >= sizeof(sepol))
302                         GOTO(out, rc = -ENAMETOOLONG);
303
304                 if (copy_from_user(sepol, buffer, count))
305                         GOTO(out, rc = -EFAULT);
306
307                 sepol[count] = '\0';
308
309                 rc = nodemap_set_sepol(m->private, sepol);
310         }
311
312 out:
313         if (rc != 0)
314                 return rc;
315
316         return count;
317 }
318 LPROC_SEQ_FOPS(nodemap_sepol);
319
320 /**
321  * Reads and prints the exports attached to the given nodemap.
322  *
323  * \param       m               seq file in proc fs, stores nodemap
324  * \param       data            unused
325  * \retval      0               success
326  */
327 static int nodemap_exports_show(struct seq_file *m, void *data)
328 {
329         struct lu_nodemap *nodemap;
330         struct obd_export *exp;
331         char nidstr[LNET_NIDSTR_SIZE] = "<unknown>";
332         int rc;
333
334         mutex_lock(&active_config_lock);
335         nodemap = nodemap_lookup(m->private);
336         mutex_unlock(&active_config_lock);
337         if (IS_ERR(nodemap)) {
338                 rc = PTR_ERR(nodemap);
339                 CERROR("cannot find nodemap '%s': rc = %d\n",
340                         (char *)m->private, rc);
341                 return rc;
342         }
343
344         seq_printf(m, "[\n");
345
346         mutex_lock(&nodemap->nm_member_list_lock);
347         list_for_each_entry(exp, &nodemap->nm_member_list,
348                             exp_target_data.ted_nodemap_member) {
349                 if (exp->exp_connection != NULL)
350                         libcfs_nidstr_r(&exp->exp_connection->c_peer.nid,
351                                           nidstr, sizeof(nidstr));
352
353                 seq_printf(m, " { nid: %s, uuid: %s },",
354                            nidstr, exp->exp_client_uuid.uuid);
355         }
356         mutex_unlock(&nodemap->nm_member_list_lock);
357
358         seq_printf(m, "\n");
359         seq_printf(m, "]\n");
360
361         nodemap_putref(nodemap);
362         return 0;
363 }
364
365 /**
366  * Attaches nodemap_idmap_show to proc file.
367  *
368  * \param       inode           inode of seq file in proc fs
369  * \param       file            seq file
370  * \retval      0               success
371  */
372 static int nodemap_exports_open(struct inode *inode, struct file *file)
373 {
374         return single_open(file, nodemap_exports_show, pde_data(inode));
375 }
376
377 /**
378  * Reads and prints the active flag for the given nodemap.
379  *
380  * \param       m               seq file in proc fs
381  * \param       data            unused
382  * \retval      0               success
383  */
384 static int nodemap_active_seq_show(struct seq_file *m, void *data)
385 {
386         seq_printf(m, "%u\n", (unsigned int)nodemap_active);
387         return 0;
388 }
389
390 /**
391  * Activate/deactivate nodemap.
392  *
393  * \param[in] file      proc file
394  * \param[in] buffer    string, "1" or "0" to activate/deactivate nodemap
395  * \param[in] count     \a buffer length
396  * \param[in] off       unused
397  * \retval              \a count on success
398  * \retval              negative number on error
399  */
400 static ssize_t
401 nodemap_active_seq_write(struct file *file, const char __user *buffer,
402                          size_t count, loff_t *off)
403 {
404         char                    active_string[NODEMAP_LPROC_FLAG_LEN + 1];
405         long unsigned int       active;
406         int                     rc;
407
408         if (count == 0)
409                 return 0;
410
411         if (count >= sizeof(active_string))
412                 return -EINVAL;
413
414         if (copy_from_user(active_string, buffer, count))
415                 return -EFAULT;
416
417         active_string[count] = '\0';
418         rc = kstrtoul(active_string, 10, &active);
419         if (rc != 0)
420                 return -EINVAL;
421
422         nodemap_activate(active);
423
424         return count;
425 }
426 LPROC_SEQ_FOPS(nodemap_active);
427
428 /**
429  * Reads and prints the nodemap ID for the given nodemap.
430  *
431  * \param       m               seq file in proc fs
432  * \param       data            unused
433  * \retval      0               success
434  */
435 static int nodemap_id_seq_show(struct seq_file *m, void *data)
436 {
437         struct lu_nodemap *nodemap;
438
439         mutex_lock(&active_config_lock);
440         nodemap = nodemap_lookup(m->private);
441         mutex_unlock(&active_config_lock);
442         if (IS_ERR(nodemap)) {
443                 int rc = PTR_ERR(nodemap);
444                 CERROR("cannot find nodemap '%s': rc = %d\n",
445                         (char *)m->private, rc);
446                 return rc;
447         }
448
449         seq_printf(m, "%u\n", nodemap->nm_id);
450         nodemap_putref(nodemap);
451         return 0;
452 }
453 LPROC_SEQ_FOPS_RO(nodemap_id);
454
455 /**
456  * Reads and prints the root squash UID for the given nodemap.
457  *
458  * \param       m               seq file in proc fs
459  * \param       data            unused
460  * \retval      0               success
461  */
462 static int nodemap_squash_uid_seq_show(struct seq_file *m, void *data)
463 {
464         struct lu_nodemap *nodemap;
465
466         mutex_lock(&active_config_lock);
467         nodemap = nodemap_lookup(m->private);
468         mutex_unlock(&active_config_lock);
469         if (IS_ERR(nodemap)) {
470                 int rc = PTR_ERR(nodemap);
471                 CERROR("cannot find nodemap '%s': rc = %d\n",
472                         (char *)m->private, rc);
473                 return rc;
474         }
475
476         seq_printf(m, "%u\n", nodemap->nm_squash_uid);
477         nodemap_putref(nodemap);
478         return 0;
479 }
480
481 /**
482  * Reads and prints the root squash GID for the given nodemap.
483  *
484  * \param       m               seq file in proc fs
485  * \param       data            unused
486  * \retval      0               success
487  */
488 static int nodemap_squash_gid_seq_show(struct seq_file *m, void *data)
489 {
490         struct lu_nodemap *nodemap;
491
492         mutex_lock(&active_config_lock);
493         nodemap = nodemap_lookup(m->private);
494         mutex_unlock(&active_config_lock);
495         if (IS_ERR(nodemap)) {
496                 int rc = PTR_ERR(nodemap);
497                 CERROR("cannot find nodemap '%s': rc = %d\n",
498                         (char *)m->private, rc);
499                 return rc;
500         }
501
502         seq_printf(m, "%u\n", nodemap->nm_squash_gid);
503         nodemap_putref(nodemap);
504         return 0;
505 }
506
507 /**
508  * Reads and prints the squash PROJID for the given nodemap.
509  *
510  * \param       m               seq file in proc fs
511  * \param       data            unused
512  * \retval      0               success
513  */
514 static int nodemap_squash_projid_seq_show(struct seq_file *m, void *data)
515 {
516         struct lu_nodemap *nodemap;
517
518         mutex_lock(&active_config_lock);
519         nodemap = nodemap_lookup(m->private);
520         mutex_unlock(&active_config_lock);
521         if (IS_ERR(nodemap)) {
522                 int rc = PTR_ERR(nodemap);
523
524                 CERROR("cannot find nodemap '%s': rc = %d\n",
525                        (char *)m->private, rc);
526                 return rc;
527         }
528
529         seq_printf(m, "%u\n", nodemap->nm_squash_projid);
530         nodemap_putref(nodemap);
531         return 0;
532 }
533
534 /**
535  * Reads and prints the trusted flag for the given nodemap.
536  *
537  * \param       m               seq file in proc fs
538  * \param       data            unused
539  * \retval      0               success
540  */
541 static int nodemap_trusted_seq_show(struct seq_file *m, void *data)
542 {
543         struct lu_nodemap *nodemap;
544
545         mutex_lock(&active_config_lock);
546         nodemap = nodemap_lookup(m->private);
547         mutex_unlock(&active_config_lock);
548         if (IS_ERR(nodemap)) {
549                 int rc = PTR_ERR(nodemap);
550
551                 CERROR("cannot find nodemap '%s': rc = %d\n",
552                         (char *)m->private, rc);
553                 return rc;
554         }
555
556         seq_printf(m, "%d\n", (int)nodemap->nmf_trust_client_ids);
557         nodemap_putref(nodemap);
558         return 0;
559 }
560
561 /**
562  * Reads and prints the admin flag for the given nodemap.
563  *
564  * \param       m               seq file in proc fs
565  * \param       data            unused
566  * \retval      0               success
567  */
568 static int nodemap_admin_seq_show(struct seq_file *m, void *data)
569 {
570         struct lu_nodemap *nodemap;
571         int rc;
572
573         mutex_lock(&active_config_lock);
574         nodemap = nodemap_lookup(m->private);
575         mutex_unlock(&active_config_lock);
576         if (IS_ERR(nodemap)) {
577                 rc = PTR_ERR(nodemap);
578                 CERROR("cannot find nodemap '%s': rc = %d\n",
579                         (char *)m->private, rc);
580                 return rc;
581         }
582
583         seq_printf(m, "%d\n", (int)nodemap->nmf_allow_root_access);
584         nodemap_putref(nodemap);
585         return 0;
586 }
587
588 /**
589  * Reads and prints the mapping mode for the given nodemap.
590  *
591  * \param       m               seq file in proc fs
592  * \param       data            unused
593  * \retval      0               success
594  */
595 static int nodemap_map_mode_seq_show(struct seq_file *m, void *data)
596 {
597         struct lu_nodemap *nodemap;
598         bool need_sep = false;
599         int rc;
600
601         mutex_lock(&active_config_lock);
602         nodemap = nodemap_lookup(m->private);
603         mutex_unlock(&active_config_lock);
604         if (IS_ERR(nodemap)) {
605                 rc = PTR_ERR(nodemap);
606                 CERROR("cannot find nodemap '%s': rc = %d\n",
607                         (char *)m->private, rc);
608                 return rc;
609         }
610
611         if (nodemap->nmf_map_mode == NODEMAP_MAP_ALL) {
612                 seq_puts(m, "all\n");
613         } else {
614                 if (nodemap->nmf_map_mode & NODEMAP_MAP_UID) {
615                         seq_puts(m, "uid");
616                         need_sep = true;
617                 }
618                 if (nodemap->nmf_map_mode & NODEMAP_MAP_GID) {
619                         seq_puts(m, need_sep ? ",gid" : "gid");
620                         need_sep = true;
621                 }
622                 if (nodemap->nmf_map_mode & NODEMAP_MAP_PROJID)
623                         seq_puts(m, need_sep ? ",projid" : "projid");
624                 seq_puts(m, "\n");
625         }
626
627         nodemap_putref(nodemap);
628         return 0;
629 }
630
631 /**
632  * Reads and prints the rbac for the given nodemap.
633  *
634  * \param       m               seq file in proc fs
635  * \param       data            unused
636  * \retval      0               success
637  */
638 static int nodemap_rbac_seq_show(struct seq_file *m, void *data)
639 {
640         struct lu_nodemap *nodemap;
641         char *sep = "";
642         int i, rc;
643
644         mutex_lock(&active_config_lock);
645         nodemap = nodemap_lookup(m->private);
646         mutex_unlock(&active_config_lock);
647         if (IS_ERR(nodemap)) {
648                 rc = PTR_ERR(nodemap);
649                 CERROR("cannot find nodemap '%s': rc = %d\n",
650                        (char *)m->private, rc);
651                 return rc;
652         }
653
654         if (nodemap->nmf_rbac == NODEMAP_RBAC_ALL) {
655                 for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names); i++)
656                         seq_printf(m, "%s%s", i == 0 ? "" : ",",
657                                    nodemap_rbac_names[i].nrn_name);
658                 seq_puts(m, "\n");
659         } else if (nodemap->nmf_rbac == NODEMAP_RBAC_NONE) {
660                 seq_puts(m, "none\n");
661         } else {
662                 for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names); i++) {
663                         if (nodemap->nmf_rbac &
664                             nodemap_rbac_names[i].nrn_mode) {
665                                 seq_printf(m, "%s%s", sep,
666                                            nodemap_rbac_names[i].nrn_name);
667                                 sep = ",";
668                         }
669                 }
670                 seq_puts(m, "\n");
671         }
672
673         nodemap_putref(nodemap);
674         return 0;
675 }
676
677 /**
678  * Reads and prints the deny_unknown flag for the given nodemap.
679  *
680  * \param       m               seq file in proc fs
681  * \param       data            unused
682  * \retval      0               success
683  */
684 static int nodemap_deny_unknown_seq_show(struct seq_file *m, void *data)
685 {
686         struct lu_nodemap *nodemap;
687         int rc;
688
689         mutex_lock(&active_config_lock);
690         nodemap = nodemap_lookup(m->private);
691         mutex_unlock(&active_config_lock);
692         if (IS_ERR(nodemap)) {
693                 rc = PTR_ERR(nodemap);
694                 CERROR("cannot find nodemap '%s': rc = %d\n",
695                         (char *)m->private, rc);
696                 return rc;
697         }
698
699         seq_printf(m, "%d\n", (int)nodemap->nmf_deny_unknown);
700         nodemap_putref(nodemap);
701         return 0;
702 }
703
704 /**
705  * Reads and prints the audit_mode flag for the given nodemap.
706  *
707  * \param       m               seq file in proc fs
708  * \param       data            unused
709  * \retval      0               success
710  */
711 static int nodemap_audit_mode_seq_show(struct seq_file *m, void *data)
712 {
713         struct lu_nodemap *nodemap;
714         int rc;
715
716         mutex_lock(&active_config_lock);
717         nodemap = nodemap_lookup(m->private);
718         mutex_unlock(&active_config_lock);
719         if (IS_ERR(nodemap)) {
720                 rc = PTR_ERR(nodemap);
721                 CERROR("cannot find nodemap '%s': rc = %d\n",
722                        (char *)m->private, rc);
723                 return rc;
724         }
725
726         seq_printf(m, "%d\n", (int)nodemap->nmf_enable_audit);
727         nodemap_putref(nodemap);
728         return 0;
729 }
730
731 /**
732  * Reads and prints the forbid_encryption flag for the given nodemap.
733  *
734  * \param       m               seq file in proc fs
735  * \param       data            unused
736  * \retval      0               success
737  */
738 static int nodemap_forbid_encryption_seq_show(struct seq_file *m, void *data)
739 {
740         struct lu_nodemap *nodemap;
741         int rc;
742
743         mutex_lock(&active_config_lock);
744         nodemap = nodemap_lookup(m->private);
745         mutex_unlock(&active_config_lock);
746         if (IS_ERR(nodemap)) {
747                 rc = PTR_ERR(nodemap);
748                 CERROR("cannot find nodemap '%s': rc = %d\n",
749                        (char *)m->private, rc);
750                 return rc;
751         }
752
753         seq_printf(m, "%d\n", (int)nodemap->nmf_forbid_encryption);
754         nodemap_putref(nodemap);
755         return 0;
756 }
757
758 /**
759  * Reads and prints the readonly_mount flag for the given nodemap.
760  *
761  * \param       m               seq file in proc fs
762  * \param       data            unused
763  * \retval      0               success
764  */
765 static int nodemap_readonly_mount_seq_show(struct seq_file *m, void *data)
766 {
767         struct lu_nodemap *nodemap;
768         int rc;
769
770         mutex_lock(&active_config_lock);
771         nodemap = nodemap_lookup(m->private);
772         mutex_unlock(&active_config_lock);
773         if (IS_ERR(nodemap)) {
774                 rc = PTR_ERR(nodemap);
775                 CERROR("cannot find nodemap '%s': rc = %d\n",
776                        (char *)m->private, rc);
777                 return rc;
778         }
779
780         seq_printf(m, "%d\n", (int)nodemap->nmf_readonly_mount);
781         nodemap_putref(nodemap);
782         return 0;
783 }
784
785 static struct lprocfs_vars lprocfs_nm_module_vars[] = {
786         {
787                 .name           = "active",
788                 .fops           = &nodemap_active_fops,
789         },
790         {
791                 NULL
792         }
793 };
794
795 LPROC_SEQ_FOPS_RO(nodemap_trusted);
796 LPROC_SEQ_FOPS_RO(nodemap_admin);
797 LPROC_SEQ_FOPS_RO(nodemap_squash_uid);
798 LPROC_SEQ_FOPS_RO(nodemap_squash_gid);
799 LPROC_SEQ_FOPS_RO(nodemap_squash_projid);
800
801 LPROC_SEQ_FOPS_RO(nodemap_deny_unknown);
802 LPROC_SEQ_FOPS_RO(nodemap_map_mode);
803 LPROC_SEQ_FOPS_RO(nodemap_rbac);
804 LPROC_SEQ_FOPS_RO(nodemap_audit_mode);
805 LPROC_SEQ_FOPS_RO(nodemap_forbid_encryption);
806 LPROC_SEQ_FOPS_RO(nodemap_readonly_mount);
807
808 static const struct proc_ops nodemap_ranges_fops = {
809         .proc_open              = nodemap_ranges_open,
810         .proc_read              = seq_read,
811         .proc_lseek             = seq_lseek,
812         .proc_release           = single_release
813 };
814
815 static const struct proc_ops nodemap_idmap_fops = {
816         .proc_open              = nodemap_idmap_open,
817         .proc_read              = seq_read,
818         .proc_lseek             = seq_lseek,
819         .proc_release           = single_release
820 };
821
822 static const struct proc_ops nodemap_exports_fops = {
823         .proc_open              = nodemap_exports_open,
824         .proc_read              = seq_read,
825         .proc_lseek             = seq_lseek,
826         .proc_release           = single_release
827 };
828
829 static struct lprocfs_vars lprocfs_nodemap_vars[] = {
830         /* in alphabetical order */
831         {
832                 .name           = "admin_nodemap",
833                 .fops           = &nodemap_admin_fops,
834         },
835         {
836                 .name           = "audit_mode",
837                 .fops           = &nodemap_audit_mode_fops,
838         },
839         {
840                 .name           = "deny_unknown",
841                 .fops           = &nodemap_deny_unknown_fops,
842         },
843         {
844                 .name           = "exports",
845                 .fops           = &nodemap_exports_fops,
846         },
847         {
848                 .name           = "fileset",
849                 .fops           = &nodemap_fileset_fops,
850         },
851         {
852                 .name           = "forbid_encryption",
853                 .fops           = &nodemap_forbid_encryption_fops,
854         },
855         {
856                 .name           = "id",
857                 .fops           = &nodemap_id_fops,
858         },
859         {
860                 .name           = "idmap",
861                 .fops           = &nodemap_idmap_fops,
862         },
863         {
864                 .name           = "map_mode",
865                 .fops           = &nodemap_map_mode_fops,
866         },
867         {
868                 .name           = "ranges",
869                 .fops           = &nodemap_ranges_fops,
870         },
871         {
872                 .name           = "rbac",
873                 .fops           = &nodemap_rbac_fops,
874         },
875         {
876                 .name           = "readonly_mount",
877                 .fops           = &nodemap_readonly_mount_fops,
878         },
879         {
880                 .name           = "sepol",
881                 .fops           = &nodemap_sepol_fops,
882         },
883         {
884                 .name           = "squash_gid",
885                 .fops           = &nodemap_squash_gid_fops,
886         },
887         {
888                 .name           = "squash_projid",
889                 .fops           = &nodemap_squash_projid_fops,
890         },
891         {
892                 .name           = "squash_uid",
893                 .fops           = &nodemap_squash_uid_fops,
894         },
895         {
896                 .name           = "trusted_nodemap",
897                 .fops           = &nodemap_trusted_fops,
898         },
899         {
900                 NULL
901         }
902 };
903
904 static struct lprocfs_vars lprocfs_default_nodemap_vars[] = {
905         /* in alphabetical order */
906         {
907                 .name           = "admin_nodemap",
908                 .fops           = &nodemap_admin_fops,
909         },
910         {
911                 .name           = "audit_mode",
912                 .fops           = &nodemap_audit_mode_fops,
913         },
914         {
915                 .name           = "deny_unknown",
916                 .fops           = &nodemap_deny_unknown_fops,
917         },
918         {
919                 .name           = "exports",
920                 .fops           = &nodemap_exports_fops,
921         },
922         {
923                 .name           = "fileset",
924                 .fops           = &nodemap_fileset_fops,
925         },
926         {
927                 .name           = "forbid_encryption",
928                 .fops           = &nodemap_forbid_encryption_fops,
929         },
930         {
931                 .name           = "id",
932                 .fops           = &nodemap_id_fops,
933         },
934         {
935                 .name           = "map_mode",
936                 .fops           = &nodemap_map_mode_fops,
937         },
938         {
939                 .name           = "readonly_mount",
940                 .fops           = &nodemap_readonly_mount_fops,
941         },
942         {
943                 .name           = "squash_gid",
944                 .fops           = &nodemap_squash_gid_fops,
945         },
946         {
947                 .name           = "squash_projid",
948                 .fops           = &nodemap_squash_projid_fops,
949         },
950         {
951                 .name           = "squash_uid",
952                 .fops           = &nodemap_squash_uid_fops,
953         },
954         {
955                 .name           = "trusted_nodemap",
956                 .fops           = &nodemap_trusted_fops,
957         },
958         {
959                 NULL
960         }
961 };
962
963 /**
964  * Initialize the nodemap procfs directory.
965  *
966  * \retval      0               success
967  */
968 int nodemap_procfs_init(void)
969 {
970         int rc = 0;
971
972         proc_lustre_nodemap_root = lprocfs_register(LUSTRE_NODEMAP_NAME,
973                                                     proc_lustre_root,
974                                                     lprocfs_nm_module_vars,
975                                                     NULL);
976         if (IS_ERR(proc_lustre_nodemap_root)) {
977                 rc = PTR_ERR(proc_lustre_nodemap_root);
978                 CERROR("cannot create 'nodemap' directory: rc = %d\n",
979                        rc);
980                 proc_lustre_nodemap_root = NULL;
981         }
982         return rc;
983 }
984
985 /**
986  * Cleanup nodemap proc entry data structures.
987  */
988 void nodemap_procfs_exit(void)
989 {
990         struct nodemap_pde *nm_pde;
991         struct nodemap_pde *tmp;
992
993         lprocfs_remove(&proc_lustre_nodemap_root);
994         list_for_each_entry_safe(nm_pde, tmp, &nodemap_pde_list,
995                                  npe_list_member) {
996                 list_del(&nm_pde->npe_list_member);
997                 OBD_FREE_PTR(nm_pde);
998         }
999 }
1000
1001 /**
1002  * Remove a nodemap's procfs entry and related data.
1003  */
1004 void lprocfs_nodemap_remove(struct nodemap_pde *nm_pde)
1005 {
1006         lprocfs_remove(&nm_pde->npe_proc_entry);
1007         list_del(&nm_pde->npe_list_member);
1008         OBD_FREE_PTR(nm_pde);
1009 }
1010
1011 /**
1012  * Register the proc directory for a nodemap
1013  *
1014  * \param       nodemap         nodemap to make the proc dir for
1015  * \param       is_default:     1 if default nodemap
1016  * \retval      0               success
1017  */
1018 int lprocfs_nodemap_register(struct lu_nodemap *nodemap, bool is_default)
1019 {
1020         struct nodemap_pde      *nm_entry;
1021         int                      rc = 0;
1022
1023         OBD_ALLOC_PTR(nm_entry);
1024         if (nm_entry == NULL)
1025                 GOTO(out, rc = -ENOMEM);
1026
1027         nm_entry->npe_proc_entry = proc_mkdir(nodemap->nm_name,
1028                                               proc_lustre_nodemap_root);
1029         if (IS_ERR(nm_entry->npe_proc_entry))
1030                 GOTO(out, rc = PTR_ERR(nm_entry->npe_proc_entry));
1031
1032         snprintf(nm_entry->npe_name, sizeof(nm_entry->npe_name), "%s",
1033                  nodemap->nm_name);
1034
1035         /* Use the nodemap name as stored on the PDE as the private data. This
1036          * is so a nodemap struct can be replaced without updating the proc
1037          * entries.
1038          */
1039         rc = lprocfs_add_vars(nm_entry->npe_proc_entry,
1040                               (is_default ? lprocfs_default_nodemap_vars :
1041                                             lprocfs_nodemap_vars),
1042                               nm_entry->npe_name);
1043         if (rc != 0)
1044                 lprocfs_remove(&nm_entry->npe_proc_entry);
1045         else
1046                 list_add(&nm_entry->npe_list_member, &nodemap_pde_list);
1047
1048 out:
1049         if (rc != 0) {
1050                 CERROR("cannot create 'nodemap/%s': rc = %d\n",
1051                        nodemap->nm_name, rc);
1052                 if (nm_entry != NULL) {
1053                         OBD_FREE_PTR(nm_entry);
1054                         nm_entry = NULL;
1055                 }
1056         }
1057
1058         nodemap->nm_pde_data = nm_entry;
1059
1060         return rc;
1061 }