4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2013, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/mdt/mdt_lproc.c
38 * Author: Lai Siyao <lsy@clusterfs.com>
39 * Author: Fan Yong <fanyong@clusterfs.com>
42 #define DEBUG_SUBSYSTEM S_MDS
44 #include <linux/version.h>
45 #include <asm/statfs.h>
47 #include <linux/module.h>
49 /* LUSTRE_VERSION_CODE */
50 #include <lustre_ver.h>
52 * struct OBD_{ALLOC,FREE}*()
55 #include <obd_support.h>
56 /* struct obd_export */
57 #include <lustre_export.h>
58 /* struct obd_device */
60 #include <obd_class.h>
61 #include <lustre_mds.h>
62 #include <lustre_mdt.h>
63 #include <lprocfs_status.h>
64 #include "mdt_internal.h"
65 #include <lnet/lib-lnet.h>
68 * The rename stats output would be YAML formats, like
70 * - snapshot_time: 1234567890.123456
72 * 4kB: { samples: 1230, pct: 33, cum_pct: 45 }
73 * 8kB: { samples: 1242, pct: 33, cum_pct: 78 }
74 * 16kB: { samples: 132, pct: 3, cum_pct: 81 }
76 * 4kB: { samples: 123, pct: 33, cum_pct: 45 }
77 * 8kB: { samples: 124, pct: 33, cum_pct: 78 }
78 * 16kB: { samples: 12, pct: 3, cum_pct: 81 }
80 * 4kB: { samples: 123, pct: 33, cum_pct: 45 }
81 * 8kB: { samples: 124, pct: 33, cum_pct: 78 }
82 * 16kB: { samples: 12, pct: 3, cum_pct: 81 }
85 #define pct(a, b) (b ? a * 100 / b : 0)
87 static void display_rename_stats(struct seq_file *seq, char *name,
88 struct obd_histogram *hist)
90 unsigned long tot, t, cum = 0;
93 tot = lprocfs_oh_sum(hist);
95 seq_printf(seq, "- %-15s\n", name);
96 /* dir size start from 4K, start i from 10(2^10) here */
97 for (i = 0; i < OBD_HIST_MAX; i++) {
98 t = hist->oh_buckets[i];
104 seq_printf(seq, "%6s%d%s", " ", 1<< i, "bytes:");
106 seq_printf(seq, "%6s%d%s", " ", 1<<(i-10), "KB:");
108 seq_printf(seq, "%6s%d%s", " ", 1<<(i-20), "MB:");
110 seq_printf(seq, " { sample: %3lu, pct: %3lu, cum_pct: %3lu }\n",
111 t, pct(t, tot), pct(cum, tot));
118 static void rename_stats_show(struct seq_file *seq,
119 struct rename_stats *rename_stats)
123 /* this sampling races with updates */
124 do_gettimeofday(&now);
125 seq_printf(seq, "rename_stats:\n");
126 seq_printf(seq, "- %-15s %lu.%lu\n", "snapshot_time:",
127 now.tv_sec, now.tv_usec);
129 display_rename_stats(seq, "same_dir",
130 &rename_stats->hist[RENAME_SAMEDIR_SIZE]);
131 display_rename_stats(seq, "crossdir_src",
132 &rename_stats->hist[RENAME_CROSSDIR_SRC_SIZE]);
133 display_rename_stats(seq, "crossdir_tgt",
134 &rename_stats->hist[RENAME_CROSSDIR_TGT_SIZE]);
139 static int mdt_rename_stats_seq_show(struct seq_file *seq, void *v)
141 struct mdt_device *mdt = seq->private;
143 rename_stats_show(seq, &mdt->mdt_rename_stats);
148 static ssize_t mdt_rename_stats_seq_write(struct file *file, const char *buf,
149 size_t len, loff_t *off)
151 struct seq_file *seq = file->private_data;
152 struct mdt_device *mdt = seq->private;
155 for (i = 0; i < RENAME_LAST; i++)
156 lprocfs_oh_clear(&mdt->mdt_rename_stats.hist[i]);
161 LPROC_SEQ_FOPS(mdt_rename_stats);
163 static int lproc_mdt_attach_rename_seqstat(struct mdt_device *mdt)
167 for (i = 0; i < RENAME_LAST; i++)
168 spin_lock_init(&mdt->mdt_rename_stats.hist[i].oh_lock);
170 return lprocfs_obd_seq_create(mdt2obd_dev(mdt), "rename_stats", 0644,
171 &mdt_rename_stats_fops, mdt);
174 void mdt_rename_counter_tally(struct mdt_thread_info *info,
175 struct mdt_device *mdt,
176 struct ptlrpc_request *req,
177 struct mdt_object *src,
178 struct mdt_object *tgt)
180 struct md_attr *ma = &info->mti_attr;
181 struct rename_stats *rstats = &mdt->mdt_rename_stats;
184 ma->ma_need = MA_INODE;
186 rc = mo_attr_get(info->mti_env, mdt_object_child(src), ma);
188 CERROR("%s: "DFID" attr_get, rc = %d\n",
189 mdt_obd_name(mdt), PFID(mdt_object_fid(src)), rc);
194 mdt_counter_incr(req, LPROC_MDT_SAMEDIR_RENAME);
195 lprocfs_oh_tally_log2(&rstats->hist[RENAME_SAMEDIR_SIZE],
196 (unsigned int)ma->ma_attr.la_size);
200 mdt_counter_incr(req, LPROC_MDT_CROSSDIR_RENAME);
201 lprocfs_oh_tally_log2(&rstats->hist[RENAME_CROSSDIR_SRC_SIZE],
202 (unsigned int)ma->ma_attr.la_size);
204 ma->ma_need = MA_INODE;
206 rc = mo_attr_get(info->mti_env, mdt_object_child(tgt), ma);
208 CERROR("%s: "DFID" attr_get, rc = %d\n",
209 mdt_obd_name(mdt), PFID(mdt_object_fid(tgt)), rc);
213 lprocfs_oh_tally_log2(&rstats->hist[RENAME_CROSSDIR_TGT_SIZE],
214 (unsigned int)ma->ma_attr.la_size);
217 int mdt_procfs_init(struct mdt_device *mdt, const char *name)
219 struct obd_device *obd = mdt2obd_dev(mdt);
220 struct lprocfs_static_vars lvars;
224 LASSERT(name != NULL);
226 lprocfs_mdt_init_vars(&lvars);
227 rc = lprocfs_obd_setup(obd, lvars.obd_vars);
229 CERROR("Can't init lprocfs, rc %d\n", rc);
232 ptlrpc_lprocfs_register_obd(obd);
234 obd->obd_proc_exports_entry = proc_mkdir("exports",
235 obd->obd_proc_entry);
236 if (obd->obd_proc_exports_entry)
237 lprocfs_add_simple(obd->obd_proc_exports_entry,
238 "clear", lprocfs_nid_stats_clear_read,
239 lprocfs_nid_stats_clear_write, obd, NULL);
240 rc = lprocfs_alloc_md_stats(obd, LPROC_MDT_LAST);
243 mdt_stats_counter_init(obd->md_stats);
245 rc = lprocfs_job_stats_init(obd, LPROC_MDT_LAST,
246 mdt_stats_counter_init);
248 rc = lproc_mdt_attach_rename_seqstat(mdt);
250 CERROR("%s: MDT can not create rename stats rc = %d\n",
251 mdt_obd_name(mdt), rc);
256 void mdt_procfs_fini(struct mdt_device *mdt)
258 struct obd_device *obd = mdt2obd_dev(mdt);
260 if (obd->obd_proc_exports_entry) {
261 lprocfs_remove_proc_entry("clear", obd->obd_proc_exports_entry);
262 obd->obd_proc_exports_entry = NULL;
264 lprocfs_free_per_client_stats(obd);
265 lprocfs_obd_cleanup(obd);
266 ptlrpc_lprocfs_unregister_obd(obd);
267 lprocfs_free_md_stats(obd);
268 lprocfs_free_obd_stats(obd);
269 lprocfs_job_stats_fini(obd);
272 static int lprocfs_rd_identity_expire(char *page, char **start, off_t off,
273 int count, int *eof, void *data)
275 struct obd_device *obd = data;
276 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
279 return snprintf(page, count, "%u\n",
280 mdt->mdt_identity_cache->uc_entry_expire);
283 static int lprocfs_wr_identity_expire(struct file *file, const char *buffer,
284 unsigned long count, void *data)
286 struct obd_device *obd = data;
287 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
290 rc = lprocfs_write_helper(buffer, count, &val);
294 mdt->mdt_identity_cache->uc_entry_expire = val;
298 static int lprocfs_rd_identity_acquire_expire(char *page, char **start,
299 off_t off, int count, int *eof,
302 struct obd_device *obd = data;
303 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
306 return snprintf(page, count, "%u\n",
307 mdt->mdt_identity_cache->uc_acquire_expire);
310 static int lprocfs_wr_identity_acquire_expire(struct file *file,
315 struct obd_device *obd = data;
316 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
319 rc = lprocfs_write_helper(buffer, count, &val);
323 mdt->mdt_identity_cache->uc_acquire_expire = val;
327 static int lprocfs_rd_identity_upcall(char *page, char **start, off_t off,
328 int count, int *eof, void *data)
330 struct obd_device *obd = data;
331 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
332 struct upcall_cache *hash = mdt->mdt_identity_cache;
336 read_lock(&hash->uc_upcall_rwlock);
337 len = snprintf(page, count, "%s\n", hash->uc_upcall);
338 read_unlock(&hash->uc_upcall_rwlock);
342 static int lprocfs_wr_identity_upcall(struct file *file, const char *buffer,
343 unsigned long count, void *data)
345 struct obd_device *obd = data;
346 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
347 struct upcall_cache *hash = mdt->mdt_identity_cache;
351 if (count >= UC_CACHE_UPCALL_MAXPATH) {
352 CERROR("%s: identity upcall too long\n", mdt_obd_name(mdt));
355 OBD_ALLOC(kernbuf, count + 1);
357 GOTO(failed, rc = -ENOMEM);
358 if (cfs_copy_from_user(kernbuf, buffer, count))
359 GOTO(failed, rc = -EFAULT);
361 /* Remove any extraneous bits from the upcall (e.g. linefeeds) */
362 write_lock(&hash->uc_upcall_rwlock);
363 sscanf(kernbuf, "%s", hash->uc_upcall);
364 write_unlock(&hash->uc_upcall_rwlock);
366 if (strcmp(hash->uc_name, mdt_obd_name(mdt)) != 0)
367 CWARN("%s: write to upcall name %s\n",
368 mdt_obd_name(mdt), hash->uc_upcall);
370 if (strcmp(hash->uc_upcall, "NONE") == 0 && mdt->mdt_opts.mo_acl)
371 CWARN("%s: disable \"identity_upcall\" with ACL enabled maybe "
372 "cause unexpected \"EACCESS\"\n", mdt_obd_name(mdt));
374 CDEBUG(D_CONFIG, "%s: identity upcall set to %s\n", mdt_obd_name(mdt),
376 OBD_FREE(kernbuf, count + 1);
381 OBD_FREE(kernbuf, count + 1);
385 static int lprocfs_wr_identity_flush(struct file *file, const char *buffer,
386 unsigned long count, void *data)
388 struct obd_device *obd = data;
389 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
392 rc = lprocfs_write_helper(buffer, count, &uid);
396 mdt_flush_identity(mdt->mdt_identity_cache, uid);
400 static int lprocfs_wr_identity_info(struct file *file, const char *buffer,
401 unsigned long count, void *data)
403 struct obd_device *obd = data;
404 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
405 struct identity_downcall_data *param;
406 int size = sizeof(*param), rc, checked = 0;
410 CERROR("%s: invalid data count = %lu, size = %d\n",
411 mdt_obd_name(mdt), count, size);
415 OBD_ALLOC(param, size);
419 if (cfs_copy_from_user(param, buffer, size)) {
420 CERROR("%s: bad identity data\n", mdt_obd_name(mdt));
421 GOTO(out, rc = -EFAULT);
426 if (param->idd_magic != IDENTITY_DOWNCALL_MAGIC) {
427 CERROR("%s: MDS identity downcall bad params\n",
429 GOTO(out, rc = -EINVAL);
432 if (param->idd_nperms > N_PERMS_MAX) {
433 CERROR("%s: perm count %d more than maximum %d\n",
434 mdt_obd_name(mdt), param->idd_nperms,
436 GOTO(out, rc = -EINVAL);
439 if (param->idd_ngroups > NGROUPS_MAX) {
440 CERROR("%s: group count %d more than maximum %d\n",
441 mdt_obd_name(mdt), param->idd_ngroups,
443 GOTO(out, rc = -EINVAL);
446 if (param->idd_ngroups) {
447 rc = param->idd_ngroups; /* save idd_ngroups */
448 OBD_FREE(param, size);
449 size = offsetof(struct identity_downcall_data,
455 rc = upcall_cache_downcall(mdt->mdt_identity_cache, param->idd_err,
456 param->idd_uid, param);
460 OBD_FREE(param, size);
462 return rc ? rc : count;
466 static int lprocfs_rd_capa(char *page, char **start, off_t off,
467 int count, int *eof, void *data)
469 struct obd_device *obd = data;
470 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
472 return snprintf(page, count, "capability on: %s %s\n",
473 mdt->mdt_opts.mo_oss_capa ? "oss" : "",
474 mdt->mdt_opts.mo_mds_capa ? "mds" : "");
477 static int lprocfs_wr_capa(struct file *file, const char *buffer,
478 unsigned long count, void *data)
480 struct obd_device *obd = data;
481 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
484 rc = lprocfs_write_helper(buffer, count, &val);
488 if (val < 0 || val > 3) {
489 CERROR("invalid capability mode, only 0/2/3 is accepted.\n"
490 " 0: disable fid capability\n"
491 " 2: enable MDS fid capability\n"
492 " 3: enable both MDS and OSS fid capability\n");
496 /* OSS fid capability needs enable both MDS and OSS fid capability on
499 CERROR("can't enable OSS fid capability only, you should use "
500 "'3' to enable both MDS and OSS fid capability.\n");
504 mdt->mdt_opts.mo_oss_capa = (val & 0x1);
505 mdt->mdt_opts.mo_mds_capa = !!(val & 0x2);
506 mdt->mdt_capa_conf = 1;
507 LCONSOLE_INFO("MDS %s %s MDS fid capability.\n",
509 mdt->mdt_opts.mo_mds_capa ? "enabled" : "disabled");
510 LCONSOLE_INFO("MDS %s %s OSS fid capability.\n",
512 mdt->mdt_opts.mo_oss_capa ? "enabled" : "disabled");
516 static int lprocfs_rd_capa_count(char *page, char **start, off_t off,
517 int count, int *eof, void *data)
519 return snprintf(page, count, "%d %d\n",
520 capa_count[CAPA_SITE_CLIENT],
521 capa_count[CAPA_SITE_SERVER]);
524 static int lprocfs_rd_site_stats(char *page, char **start, off_t off,
525 int count, int *eof, void *data)
527 struct obd_device *obd = data;
528 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
530 return lu_site_stats_print(mdt_lu_site(mdt), page, count);
533 static int lprocfs_rd_capa_timeout(char *page, char **start, off_t off,
534 int count, int *eof, void *data)
536 struct obd_device *obd = data;
537 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
539 return snprintf(page, count, "%lu\n", mdt->mdt_capa_timeout);
542 static int lprocfs_wr_capa_timeout(struct file *file, const char *buffer,
543 unsigned long count, void *data)
545 struct obd_device *obd = data;
546 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
549 rc = lprocfs_write_helper(buffer, count, &val);
553 mdt->mdt_capa_timeout = (unsigned long)val;
554 mdt->mdt_capa_conf = 1;
558 static int lprocfs_rd_ck_timeout(char *page, char **start, off_t off, int count,
559 int *eof, void *data)
561 struct obd_device *obd = data;
562 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
564 return snprintf(page, count, "%lu\n", mdt->mdt_ck_timeout);
567 static int lprocfs_wr_ck_timeout(struct file *file, const char *buffer,
568 unsigned long count, void *data)
570 struct obd_device *obd = data;
571 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
574 rc = lprocfs_write_helper(buffer, count, &val);
578 mdt->mdt_ck_timeout = (unsigned long)val;
579 mdt->mdt_capa_conf = 1;
583 #define BUFLEN (UUID_MAX + 4)
585 static int lprocfs_mdt_wr_evict_client(struct file *file, const char *buffer,
586 unsigned long count, void *data)
591 OBD_ALLOC(kbuf, BUFLEN);
596 * OBD_ALLOC() will zero kbuf, but we only copy BUFLEN - 1
597 * bytes into kbuf, to ensure that the string is NUL-terminated.
598 * UUID_MAX should include a trailing NUL already.
600 if (cfs_copy_from_user(kbuf, buffer,
601 min_t(unsigned long, BUFLEN - 1, count))) {
605 tmpbuf = cfs_firststr(kbuf, min_t(unsigned long, BUFLEN - 1, count));
607 if (strncmp(tmpbuf, "nid:", 4) != 0) {
608 count = lprocfs_wr_evict_client(file, buffer, count, data);
612 CERROR("NOT implement evict client by nid %s\n", tmpbuf);
615 OBD_FREE(kbuf, BUFLEN);
621 static int lprocfs_rd_sec_level(char *page, char **start, off_t off,
622 int count, int *eof, void *data)
624 struct obd_device *obd = data;
625 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
627 return snprintf(page, count, "%d\n", mdt->mdt_sec_level);
630 static int lprocfs_wr_sec_level(struct file *file, const char *buffer,
631 unsigned long count, void *data)
633 struct obd_device *obd = data;
634 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
637 rc = lprocfs_write_helper(buffer, count, &val);
641 if (val > LUSTRE_SEC_ALL || val < LUSTRE_SEC_NONE)
644 if (val == LUSTRE_SEC_SPECIFY) {
645 CWARN("security level %d will be supported in future.\n",
650 mdt->mdt_sec_level = val;
654 static int lprocfs_rd_cos(char *page, char **start, off_t off,
655 int count, int *eof, void *data)
657 struct obd_device *obd = data;
658 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
660 return snprintf(page, count, "%u\n", mdt_cos_is_enabled(mdt));
663 static int lprocfs_wr_cos(struct file *file, const char *buffer,
664 unsigned long count, void *data)
666 struct obd_device *obd = data;
667 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
670 rc = lprocfs_write_helper(buffer, count, &val);
673 mdt_enable_cos(mdt, val);
677 static int lprocfs_rd_root_squash(char *page, char **start, off_t off,
678 int count, int *eof, void *data)
680 struct obd_device *obd = data;
681 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
683 return snprintf(page, count, "%u:%u\n", mdt->mdt_squash_uid,
684 mdt->mdt_squash_gid);
687 static int safe_strtoul(const char *str, char **endp, unsigned long *res)
691 *res = simple_strtoul(str, endp, 0);
695 sprintf(n, "%lu", *res);
696 if (strncmp(n, str, *endp - str))
702 static int lprocfs_wr_root_squash(struct file *file, const char *buffer,
703 unsigned long count, void *data)
705 struct obd_device *obd = data;
706 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
708 char kernbuf[50], *tmp, *end, *errmsg;
709 unsigned long uid, gid;
713 if (count >= sizeof(kernbuf)) {
714 errmsg = "string too long";
715 GOTO(failed, rc = -EINVAL);
717 if (cfs_copy_from_user(kernbuf, buffer, count)) {
718 errmsg = "bad address";
719 GOTO(failed, rc = -EFAULT);
721 kernbuf[count] = '\0';
724 if (safe_strtoul(buffer, &tmp, &uid)) {
725 uid = mdt->mdt_squash_uid;
732 if (safe_strtoul(tmp, &end, &gid)) {
733 gid = mdt->mdt_squash_gid;
737 gid = mdt->mdt_squash_gid;
741 mdt->mdt_squash_uid = uid;
742 mdt->mdt_squash_gid = gid;
744 if (nouid && nogid) {
745 errmsg = "needs uid:gid format";
746 GOTO(failed, rc = -EINVAL);
749 LCONSOLE_INFO("%s: root_squash is set to %u:%u\n",
751 mdt->mdt_squash_uid, mdt->mdt_squash_gid);
755 CWARN("%s: failed to set root_squash to \"%s\", %s: rc %d\n",
756 mdt_obd_name(mdt), buffer, errmsg, rc);
760 static int lprocfs_rd_nosquash_nids(char *page, char **start, off_t off,
761 int count, int *eof, void *data)
763 struct obd_device *obd = data;
764 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
766 if (mdt->mdt_nosquash_str)
767 return snprintf(page, count, "%s\n", mdt->mdt_nosquash_str);
768 return snprintf(page, count, "NONE\n");
771 static int lprocfs_wr_nosquash_nids(struct file *file, const char *buffer,
772 unsigned long count, void *data)
774 struct obd_device *obd = data;
775 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
777 char *kernbuf, *errmsg;
781 OBD_ALLOC(kernbuf, count + 1);
782 if (kernbuf == NULL) {
783 errmsg = "no memory";
784 GOTO(failed, rc = -ENOMEM);
786 if (cfs_copy_from_user(kernbuf, buffer, count)) {
787 errmsg = "bad address";
788 GOTO(failed, rc = -EFAULT);
790 kernbuf[count] = '\0';
792 if (!strcmp(kernbuf, "NONE") || !strcmp(kernbuf, "clear")) {
793 /* empty string is special case */
794 down_write(&mdt->mdt_squash_sem);
795 if (!cfs_list_empty(&mdt->mdt_nosquash_nids)) {
796 cfs_free_nidlist(&mdt->mdt_nosquash_nids);
797 OBD_FREE(mdt->mdt_nosquash_str,
798 mdt->mdt_nosquash_strlen);
799 mdt->mdt_nosquash_str = NULL;
800 mdt->mdt_nosquash_strlen = 0;
802 up_write(&mdt->mdt_squash_sem);
803 LCONSOLE_INFO("%s: nosquash_nids is cleared\n",
805 OBD_FREE(kernbuf, count + 1);
809 CFS_INIT_LIST_HEAD(&tmp);
810 if (cfs_parse_nidlist(kernbuf, count, &tmp) <= 0) {
811 errmsg = "can't parse";
812 GOTO(failed, rc = -EINVAL);
815 down_write(&mdt->mdt_squash_sem);
816 if (!cfs_list_empty(&mdt->mdt_nosquash_nids)) {
817 cfs_free_nidlist(&mdt->mdt_nosquash_nids);
818 OBD_FREE(mdt->mdt_nosquash_str, mdt->mdt_nosquash_strlen);
820 mdt->mdt_nosquash_str = kernbuf;
821 mdt->mdt_nosquash_strlen = count + 1;
822 cfs_list_splice(&tmp, &mdt->mdt_nosquash_nids);
824 LCONSOLE_INFO("%s: nosquash_nids is set to %s\n",
825 mdt_obd_name(mdt), kernbuf);
826 up_write(&mdt->mdt_squash_sem);
830 CWARN("%s: failed to set nosquash_nids to \"%s\", %s: rc %d\n",
831 mdt_obd_name(mdt), kernbuf, errmsg, rc);
833 OBD_FREE(kernbuf, count + 1);
837 static int lprocfs_rd_mdt_som(char *page, char **start, off_t off,
838 int count, int *eof, void *data)
840 struct obd_device *obd = data;
841 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
843 return snprintf(page, count, "%sabled\n",
844 mdt->mdt_som_conf ? "en" : "dis");
847 static int lprocfs_wr_mdt_som(struct file *file, const char *buffer,
848 unsigned long count, void *data)
850 struct obd_export *exp;
851 struct obd_device *obd = data;
852 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
854 unsigned long val = 0;
856 if (count > (sizeof(kernbuf) - 1))
859 if (cfs_copy_from_user(kernbuf, buffer, count))
862 kernbuf[count] = '\0';
864 if (!strcmp(kernbuf, "enabled"))
866 else if (strcmp(kernbuf, "disabled"))
869 if (mdt->mdt_som_conf == val)
872 if (!obd->obd_process_conf) {
873 CERROR("Temporary SOM change is not supported, use lctl "
874 "conf_param for permanent setting\n");
878 /* 1 stands for self export. */
879 cfs_list_for_each_entry(exp, &obd->obd_exports, exp_obd_chain) {
880 if (exp == obd->obd_self_export)
882 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
884 /* Some clients are already connected, skip the change */
885 LCONSOLE_INFO("%s is already connected, SOM will be %s on "
886 "the next mount\n", exp->exp_client_uuid.uuid,
887 val ? "enabled" : "disabled");
891 mdt->mdt_som_conf = val;
892 LCONSOLE_INFO("Enabling SOM\n");
897 /* Temporary; for testing purposes only */
898 static int lprocfs_mdt_wr_mdc(struct file *file, const char *buffer,
899 unsigned long count, void *data)
901 struct obd_device *obd = data;
902 struct obd_export *exp = NULL;
903 struct obd_uuid *uuid;
907 OBD_ALLOC(kbuf, UUID_MAX);
912 * OBD_ALLOC() will zero kbuf, but we only copy UUID_MAX - 1
913 * bytes into kbuf, to ensure that the string is NUL-terminated.
914 * UUID_MAX should include a trailing NUL already.
916 if (cfs_copy_from_user(kbuf, buffer,
917 min_t(unsigned long, UUID_MAX - 1, count))) {
921 tmpbuf = cfs_firststr(kbuf, min_t(unsigned long, UUID_MAX - 1, count));
923 OBD_ALLOC(uuid, UUID_MAX);
929 obd_str2uuid(uuid, tmpbuf);
930 exp = cfs_hash_lookup(obd->obd_uuid_hash, uuid);
932 CERROR("%s: no export %s found\n",
933 obd->obd_name, obd_uuid2str(uuid));
935 mdt_hsm_copytool_send(exp);
936 class_export_put(exp);
939 OBD_FREE(uuid, UUID_MAX);
941 OBD_FREE(kbuf, UUID_MAX);
945 static int lprocfs_rd_enable_remote_dir(char *page, char **start, off_t off,
946 int count, int *eof, void *data)
948 struct obd_device *obd = data;
949 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
951 return snprintf(page, count, "%u\n", mdt->mdt_enable_remote_dir);
954 static int lprocfs_wr_enable_remote_dir(struct file *file, const char *buffer,
955 unsigned long count, void *data)
957 struct obd_device *obd = data;
958 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
962 rc = lprocfs_write_helper(buffer, count, &val);
966 if (val < 0 || val > 1)
969 mdt->mdt_enable_remote_dir = val;
973 static int lprocfs_rd_enable_remote_dir_gid(char *page, char **start, off_t off,
974 int count, int *eof, void *data)
976 struct obd_device *obd = data;
977 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
979 return snprintf(page, count, "%d\n",
980 (int)mdt->mdt_enable_remote_dir_gid);
983 static int lprocfs_wr_enable_remote_dir_gid(struct file *file,
985 unsigned long count, void *data)
987 struct obd_device *obd = data;
988 struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
992 rc = lprocfs_write_helper(buffer, count, &val);
996 mdt->mdt_enable_remote_dir_gid = val;
1000 static struct lprocfs_vars lprocfs_mdt_obd_vars[] = {
1001 { "uuid", lprocfs_rd_uuid, 0, 0 },
1002 { "recovery_status", lprocfs_obd_rd_recovery_status, 0, 0 },
1003 { "num_exports", lprocfs_rd_num_exports, 0, 0 },
1004 { "identity_expire", lprocfs_rd_identity_expire,
1005 lprocfs_wr_identity_expire, 0 },
1006 { "identity_acquire_expire", lprocfs_rd_identity_acquire_expire,
1007 lprocfs_wr_identity_acquire_expire, 0 },
1008 { "identity_upcall", lprocfs_rd_identity_upcall,
1009 lprocfs_wr_identity_upcall, 0 },
1010 { "identity_flush", 0, lprocfs_wr_identity_flush, 0 },
1011 { "identity_info", 0, lprocfs_wr_identity_info, 0 },
1012 { "capa", lprocfs_rd_capa,
1013 lprocfs_wr_capa, 0 },
1014 { "capa_timeout", lprocfs_rd_capa_timeout,
1015 lprocfs_wr_capa_timeout, 0 },
1016 { "capa_key_timeout", lprocfs_rd_ck_timeout,
1017 lprocfs_wr_ck_timeout, 0 },
1018 { "capa_count", lprocfs_rd_capa_count, 0, 0 },
1019 { "site_stats", lprocfs_rd_site_stats, 0, 0 },
1020 { "evict_client", 0, lprocfs_mdt_wr_evict_client, 0 },
1021 { "hash_stats", lprocfs_obd_rd_hash, 0, 0 },
1022 { "sec_level", lprocfs_rd_sec_level,
1023 lprocfs_wr_sec_level, 0 },
1024 { "commit_on_sharing", lprocfs_rd_cos, lprocfs_wr_cos, 0 },
1025 { "root_squash", lprocfs_rd_root_squash,
1026 lprocfs_wr_root_squash, 0 },
1027 { "nosquash_nids", lprocfs_rd_nosquash_nids,
1028 lprocfs_wr_nosquash_nids, 0 },
1029 { "som", lprocfs_rd_mdt_som,
1030 lprocfs_wr_mdt_som, 0 },
1031 { "mdccomm", 0, lprocfs_mdt_wr_mdc, 0 },
1032 { "instance", lprocfs_target_rd_instance, 0 },
1033 { "ir_factor", lprocfs_obd_rd_ir_factor,
1034 lprocfs_obd_wr_ir_factor, 0 },
1035 { "job_cleanup_interval", lprocfs_rd_job_interval,
1036 lprocfs_wr_job_interval, 0 },
1037 { "enable_remote_dir", lprocfs_rd_enable_remote_dir,
1038 lprocfs_wr_enable_remote_dir, 0},
1039 { "enable_remote_dir_gid", lprocfs_rd_enable_remote_dir_gid,
1040 lprocfs_wr_enable_remote_dir_gid, 0},
1044 static struct lprocfs_vars lprocfs_mdt_module_vars[] = {
1045 { "num_refs", lprocfs_rd_numrefs, 0, 0 },
1049 void lprocfs_mdt_init_vars(struct lprocfs_static_vars *lvars)
1051 lvars->module_vars = lprocfs_mdt_module_vars;
1052 lvars->obd_vars = lprocfs_mdt_obd_vars;
1055 struct lprocfs_vars lprocfs_mds_obd_vars[] = {
1056 { "uuid", lprocfs_rd_uuid, 0, 0 },
1060 struct lprocfs_vars lprocfs_mds_module_vars[] = {
1061 { "num_refs", lprocfs_rd_numrefs, 0, 0 },
1065 void mdt_counter_incr(struct ptlrpc_request *req, int opcode)
1067 struct obd_export *exp = req->rq_export;
1069 if (exp->exp_obd && exp->exp_obd->md_stats)
1070 lprocfs_counter_incr(exp->exp_obd->md_stats, opcode);
1071 if (exp->exp_nid_stats && exp->exp_nid_stats->nid_stats != NULL)
1072 lprocfs_counter_incr(exp->exp_nid_stats->nid_stats, opcode);
1073 if (exp->exp_obd && exp->exp_obd->u.obt.obt_jobstats.ojs_hash &&
1074 (exp_connect_flags(exp) & OBD_CONNECT_JOBSTATS))
1075 lprocfs_job_stats_log(exp->exp_obd,
1076 lustre_msg_get_jobid(req->rq_reqmsg),
1080 void mdt_stats_counter_init(struct lprocfs_stats *stats)
1082 lprocfs_counter_init(stats, LPROC_MDT_OPEN, 0, "open", "reqs");
1083 lprocfs_counter_init(stats, LPROC_MDT_CLOSE, 0, "close", "reqs");
1084 lprocfs_counter_init(stats, LPROC_MDT_MKNOD, 0, "mknod", "reqs");
1085 lprocfs_counter_init(stats, LPROC_MDT_LINK, 0, "link", "reqs");
1086 lprocfs_counter_init(stats, LPROC_MDT_UNLINK, 0, "unlink", "reqs");
1087 lprocfs_counter_init(stats, LPROC_MDT_MKDIR, 0, "mkdir", "reqs");
1088 lprocfs_counter_init(stats, LPROC_MDT_RMDIR, 0, "rmdir", "reqs");
1089 lprocfs_counter_init(stats, LPROC_MDT_RENAME, 0, "rename", "reqs");
1090 lprocfs_counter_init(stats, LPROC_MDT_GETATTR, 0, "getattr", "reqs");
1091 lprocfs_counter_init(stats, LPROC_MDT_SETATTR, 0, "setattr", "reqs");
1092 lprocfs_counter_init(stats, LPROC_MDT_GETXATTR, 0, "getxattr", "reqs");
1093 lprocfs_counter_init(stats, LPROC_MDT_SETXATTR, 0, "setxattr", "reqs");
1094 lprocfs_counter_init(stats, LPROC_MDT_STATFS, 0, "statfs", "reqs");
1095 lprocfs_counter_init(stats, LPROC_MDT_SYNC, 0, "sync", "reqs");
1096 lprocfs_counter_init(stats, LPROC_MDT_SAMEDIR_RENAME, 0,
1097 "samedir_rename", "reqs");
1098 lprocfs_counter_init(stats, LPROC_MDT_CROSSDIR_RENAME, 0,
1099 "crossdir_rename", "reqs");