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