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