Whamcloud - gitweb
6dfc11726ffb9749a28ebcda69844ca94d94ef60
[fs/lustre-release.git] / lustre / mdt / mdt_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) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2011, 2017, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  *
31  * lustre/mdt/mdt_lproc.c
32  *
33  * Author: Lai Siyao <lsy@clusterfs.com>
34  * Author: Fan Yong <fanyong@clusterfs.com>
35  */
36
37 #define DEBUG_SUBSYSTEM S_MDS
38
39 #include <linux/version.h>
40 #include <asm/statfs.h>
41
42 #include <linux/module.h>
43 #include <uapi/linux/lnet/nidstr.h>
44 /* LUSTRE_VERSION_CODE */
45 #include <uapi/linux/lustre/lustre_ver.h>
46 /*
47  * struct OBD_{ALLOC,FREE}*()
48  * MDT_FAIL_CHECK
49  */
50 #include <obd_support.h>
51 /* struct obd_export */
52 #include <lustre_export.h>
53 /* struct obd_device */
54 #include <obd.h>
55 #include <obd_class.h>
56 #include <lustre_mds.h>
57 #include <lprocfs_status.h>
58 #include "mdt_internal.h"
59 #include <obd_cksum.h>
60
61 /**
62  * The rename stats output would be YAML formats, like
63  * rename_stats:
64  * - snapshot_time: 1234567890.123456789
65  * - start_time:    1234567880.987654321
66  * - elapsed_time:  9.135802468
67  * - same_dir:
68  *     4kB: { samples: 1230, pct: 33, cum_pct: 45 }
69  *     8kB: { samples: 1242, pct: 33, cum_pct: 78 }
70  *     16kB: { samples: 132, pct: 3, cum_pct: 81 }
71  * - crossdir_src:
72  *     4kB: { samples: 123, pct: 33, cum_pct: 45 }
73  *     8kB: { samples: 124, pct: 33, cum_pct: 78 }
74  *     16kB: { samples: 12, pct: 3, cum_pct: 81 }
75  * - crossdir_tgt:
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 }
79  **/
80
81 static void display_rename_stats(struct seq_file *seq, char *name,
82                                  struct obd_histogram *rs_hist)
83 {
84         unsigned long tot, t, cum = 0;
85         int i;
86
87         tot = lprocfs_oh_sum(rs_hist);
88         if (tot > 0)
89                 seq_printf(seq, "- %s\n", name);
90
91         for (i = 0; i < OBD_HIST_MAX; i++) {
92                 t = rs_hist->oh_buckets[i];
93                 cum += t;
94                 if (cum == 0)
95                         continue;
96
97                 if (i < 10)
98                         seq_printf(seq, "%6s%d%s", " ", 1 << i, "bytes:");
99                 else if (i < 20)
100                         seq_printf(seq, "%6s%d%s", " ", 1 << (i - 10), "KB:");
101                 else
102                         seq_printf(seq, "%6s%d%s", " ", 1 << (i - 20), "MB:");
103
104                 seq_printf(seq, " { sample: %3lu, pct: %3u, cum_pct: %3u }\n",
105                            t, pct(t, tot), pct(cum, tot));
106
107                 if (cum == tot)
108                         break;
109         }
110 }
111
112 static void rename_stats_show(struct seq_file *seq,
113                               struct rename_stats *rename_stats)
114 {
115         /* this sampling races with updates */
116         seq_puts(seq, "rename_stats:\n- ");
117         lprocfs_stats_header(seq, ktime_get(), rename_stats->rs_init, 15, ":",
118                              false);
119
120         display_rename_stats(seq, "same_dir",
121                              &rename_stats->rs_hist[RENAME_SAMEDIR_SIZE]);
122         display_rename_stats(seq, "crossdir_src",
123                              &rename_stats->rs_hist[RENAME_CROSSDIR_SRC_SIZE]);
124         display_rename_stats(seq, "crossdir_tgt",
125                              &rename_stats->rs_hist[RENAME_CROSSDIR_TGT_SIZE]);
126 }
127
128 static int mdt_rename_stats_seq_show(struct seq_file *seq, void *v)
129 {
130         struct mdt_device *mdt = seq->private;
131
132         rename_stats_show(seq, &mdt->mdt_rename_stats);
133
134         return 0;
135 }
136
137 static ssize_t
138 mdt_rename_stats_seq_write(struct file *file, const char __user *buf,
139                            size_t len, loff_t *off)
140 {
141         struct seq_file *seq = file->private_data;
142         struct mdt_device *mdt = seq->private;
143         int i;
144
145         for (i = 0; i < RENAME_LAST; i++)
146                 lprocfs_oh_clear(&mdt->mdt_rename_stats.rs_hist[i]);
147         mdt->mdt_rename_stats.rs_init = ktime_get();
148
149         return len;
150 }
151 LPROC_SEQ_FOPS(mdt_rename_stats);
152
153 static int lproc_mdt_attach_rename_seqstat(struct mdt_device *mdt)
154 {
155         int i;
156
157         for (i = 0; i < RENAME_LAST; i++)
158                 spin_lock_init(&mdt->mdt_rename_stats.rs_hist[i].oh_lock);
159
160         return lprocfs_obd_seq_create(mdt2obd_dev(mdt), "rename_stats", 0644,
161                                       &mdt_rename_stats_fops, mdt);
162 }
163
164 void mdt_rename_counter_tally(struct mdt_thread_info *info,
165                               struct mdt_device *mdt,
166                               struct ptlrpc_request *req,
167                               struct mdt_object *src, struct mdt_object *tgt,
168                               enum mdt_stat_idx msi, s64 ktime_delta)
169 {
170         struct md_attr *ma = &info->mti_attr;
171         struct rename_stats *rstats = &mdt->mdt_rename_stats;
172         int rc;
173
174         mdt_counter_incr(req, LPROC_MDT_RENAME, ktime_delta);
175
176         ma->ma_need = MA_INODE;
177         ma->ma_valid = 0;
178         rc = mo_attr_get(info->mti_env, mdt_object_child(src), ma);
179         if (rc) {
180                 CERROR("%s: "DFID" attr_get, rc = %d\n",
181                        mdt_obd_name(mdt), PFID(mdt_object_fid(src)), rc);
182                 return;
183         }
184
185         if (src == tgt) {
186                 mdt_counter_incr(req, LPROC_MDT_RENAME_SAMEDIR, ktime_delta);
187                 if (msi) /* parallel rename type */
188                         mdt_counter_incr(req, msi, ktime_delta);
189                 lprocfs_oh_tally_log2(&rstats->rs_hist[RENAME_SAMEDIR_SIZE],
190                                       (unsigned int)ma->ma_attr.la_size);
191                 return;
192         }
193
194         mdt_counter_incr(req, LPROC_MDT_RENAME_CROSSDIR, ktime_delta);
195         lprocfs_oh_tally_log2(&rstats->rs_hist[RENAME_CROSSDIR_SRC_SIZE],
196                               (unsigned int)ma->ma_attr.la_size);
197
198         ma->ma_need = MA_INODE;
199         ma->ma_valid = 0;
200         rc = mo_attr_get(info->mti_env, mdt_object_child(tgt), ma);
201         if (rc) {
202                 CERROR("%s: "DFID" attr_get, rc = %d\n",
203                        mdt_obd_name(mdt), PFID(mdt_object_fid(tgt)), rc);
204                 return;
205         }
206
207         lprocfs_oh_tally_log2(&rstats->rs_hist[RENAME_CROSSDIR_TGT_SIZE],
208                               (unsigned int)ma->ma_attr.la_size);
209 }
210
211 static ssize_t identity_expire_show(struct kobject *kobj,
212                                     struct attribute *attr, char *buf)
213 {
214         struct obd_device *obd = container_of(kobj, struct obd_device,
215                                               obd_kset.kobj);
216         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
217
218         return scnprintf(buf, PAGE_SIZE, "%lld\n",
219                          mdt->mdt_identity_cache->uc_entry_expire);
220 }
221
222 static ssize_t identity_expire_store(struct kobject *kobj,
223                                      struct attribute *attr,
224                                      const char *buffer, size_t count)
225 {
226         struct obd_device *obd = container_of(kobj, struct obd_device,
227                                               obd_kset.kobj);
228         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
229         time64_t val;
230         int rc;
231
232         rc = kstrtoll(buffer, 10, &val);
233         if (rc)
234                 return rc;
235
236         if (val < 0)
237                 return -ERANGE;
238
239         mdt->mdt_identity_cache->uc_entry_expire = val;
240
241         return count;
242 }
243 LUSTRE_RW_ATTR(identity_expire);
244
245 static ssize_t identity_acquire_expire_show(struct kobject *kobj,
246                                             struct attribute *attr, char *buf)
247 {
248         struct obd_device *obd = container_of(kobj, struct obd_device,
249                                               obd_kset.kobj);
250         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
251
252         return scnprintf(buf, PAGE_SIZE, "%lld\n",
253                          mdt->mdt_identity_cache->uc_acquire_expire);
254 }
255
256 static ssize_t identity_acquire_expire_store(struct kobject *kobj,
257                                              struct attribute *attr,
258                                              const char *buffer, size_t count)
259 {
260         struct obd_device *obd = container_of(kobj, struct obd_device,
261                                               obd_kset.kobj);
262         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
263         time64_t val;
264         int rc;
265
266         rc = kstrtoll(buffer, 0, &val);
267         if (rc)
268                 return rc;
269
270         if (val < 0 || val > INT_MAX)
271                 return -ERANGE;
272
273         mdt->mdt_identity_cache->uc_acquire_expire = val;
274
275         return count;
276 }
277 LUSTRE_RW_ATTR(identity_acquire_expire);
278
279 static ssize_t identity_upcall_show(struct kobject *kobj,
280                                     struct attribute *attr, char *buf)
281 {
282         struct obd_device *obd = container_of(kobj, struct obd_device,
283                                               obd_kset.kobj);
284         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
285         struct upcall_cache *hash = mdt->mdt_identity_cache;
286         int rc;
287
288         down_read(&hash->uc_upcall_rwsem);
289         rc = scnprintf(buf, PAGE_SIZE, "%s\n", hash->uc_upcall);
290         up_read(&hash->uc_upcall_rwsem);
291         return rc;
292 }
293
294 static ssize_t identity_upcall_store(struct kobject *kobj,
295                                      struct attribute *attr,
296                                      const char *buffer, size_t count)
297 {
298         struct obd_device *obd = container_of(kobj, struct obd_device,
299                                               obd_kset.kobj);
300         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
301         struct upcall_cache *hash = mdt->mdt_identity_cache;
302
303         if (count >= UC_CACHE_UPCALL_MAXPATH) {
304                 CERROR("%s: identity upcall too long\n", mdt_obd_name(mdt));
305                 return -EINVAL;
306         }
307
308         /* Remove any extraneous bits from the upcall (e.g. linefeeds) */
309         down_write(&hash->uc_upcall_rwsem);
310         sscanf(buffer, "%s", hash->uc_upcall);
311         up_write(&hash->uc_upcall_rwsem);
312
313         if (strcmp(hash->uc_name, mdt_obd_name(mdt)) != 0)
314                 CWARN("%s: write to upcall name %s\n",
315                       mdt_obd_name(mdt), hash->uc_upcall);
316
317         if (strcmp(hash->uc_upcall, "NONE") == 0 && mdt->mdt_opts.mo_acl)
318                 CWARN("%s: disable \"identity_upcall\" with ACL enabled maybe "
319                       "cause unexpected \"EACCESS\"\n", mdt_obd_name(mdt));
320
321         CDEBUG(D_CONFIG, "%s: identity upcall set to %s\n", mdt_obd_name(mdt),
322                hash->uc_upcall);
323         RETURN(count);
324 }
325 LUSTRE_RW_ATTR(identity_upcall);
326
327 static ssize_t identity_flush_store(struct kobject *kobj,
328                                     struct attribute *attr,
329                                     const char *buffer, size_t count)
330 {
331         struct obd_device *obd = container_of(kobj, struct obd_device,
332                                               obd_kset.kobj);
333         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
334         int uid;
335         int rc;
336
337         rc = kstrtoint(buffer, 0, &uid);
338         if (rc)
339                 return rc;
340
341         mdt_flush_identity(mdt->mdt_identity_cache, uid);
342         return count;
343 }
344 LUSTRE_WO_ATTR(identity_flush);
345
346 static ssize_t
347 lprocfs_identity_info_seq_write(struct file *file, const char __user *buffer,
348                                 size_t count, void *data)
349 {
350         struct seq_file   *m = file->private_data;
351         struct obd_device *obd = m->private;
352         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
353         struct identity_downcall_data *param;
354         int size = sizeof(*param), rc, checked = 0;
355
356 again:
357         if (count < size) {
358                 CERROR("%s: invalid data count = %lu, size = %d\n",
359                        mdt_obd_name(mdt), (unsigned long) count, size);
360                 return -EINVAL;
361         }
362
363         OBD_ALLOC(param, size);
364         if (param == NULL)
365                 return -ENOMEM;
366
367         if (copy_from_user(param, buffer, size)) {
368                 CERROR("%s: bad identity data\n", mdt_obd_name(mdt));
369                 GOTO(out, rc = -EFAULT);
370         }
371
372         if (checked == 0) {
373                 checked = 1;
374                 if (param->idd_magic != IDENTITY_DOWNCALL_MAGIC) {
375                         CERROR("%s: MDS identity downcall bad params\n",
376                                mdt_obd_name(mdt));
377                         GOTO(out, rc = -EINVAL);
378                 }
379
380                 if (param->idd_nperms > N_PERMS_MAX) {
381                         CERROR("%s: perm count %d more than maximum %d\n",
382                                mdt_obd_name(mdt), param->idd_nperms,
383                                N_PERMS_MAX);
384                         GOTO(out, rc = -EINVAL);
385                 }
386
387                 if (param->idd_ngroups > NGROUPS_MAX) {
388                         CERROR("%s: group count %d more than maximum %d\n",
389                                mdt_obd_name(mdt), param->idd_ngroups,
390                                NGROUPS_MAX);
391                         GOTO(out, rc = -EINVAL);
392                 }
393
394                 if (param->idd_ngroups) {
395                         rc = param->idd_ngroups; /* save idd_ngroups */
396                         OBD_FREE(param, size);
397                         size = offsetof(struct identity_downcall_data,
398                                         idd_groups[rc]);
399                         goto again;
400                 }
401         }
402
403         rc = upcall_cache_downcall(mdt->mdt_identity_cache, param->idd_err,
404                                    param->idd_uid, param);
405
406 out:
407         if (param != NULL)
408                 OBD_FREE(param, size);
409
410         return rc ? rc : count;
411 }
412 LPROC_SEQ_FOPS_WR_ONLY(mdt, identity_info);
413
414 static int mdt_site_stats_seq_show(struct seq_file *m, void *data)
415 {
416         struct obd_device *obd = m->private;
417         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
418
419         return lu_site_stats_seq_print(mdt_lu_site(mdt), m);
420 }
421 LPROC_SEQ_FOPS_RO(mdt_site_stats);
422
423 #define BUFLEN (UUID_MAX + 4)
424
425 static ssize_t
426 lprocfs_mds_evict_client_seq_write(struct file *file, const char __user *buf,
427                                    size_t count, loff_t *off)
428 {
429         struct seq_file   *m = file->private_data;
430         struct obd_device *obd = m->private;
431         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
432         char *kbuf;
433         char *tmpbuf;
434         int rc = 0;
435
436         OBD_ALLOC(kbuf, BUFLEN);
437         if (kbuf == NULL)
438                 return -ENOMEM;
439
440         /*
441          * OBD_ALLOC() will zero kbuf, but we only copy BUFLEN - 1
442          * bytes into kbuf, to ensure that the string is NUL-terminated.
443          * UUID_MAX should include a trailing NUL already.
444          */
445         if (copy_from_user(kbuf, buf, min_t(unsigned long, BUFLEN - 1, count)))
446                 GOTO(out, rc = -EFAULT);
447         tmpbuf = skip_spaces(kbuf);
448         tmpbuf = strsep(&tmpbuf, " \t\n\f\v\r");
449
450         if (strncmp(tmpbuf, "nid:", 4) != 0) {
451                 count = lprocfs_evict_client_seq_write(file, buf, count, off);
452                 goto out;
453         }
454
455         if (mdt->mdt_opts.mo_evict_tgt_nids) {
456                 rc = obd_set_info_async(NULL, mdt->mdt_child_exp,
457                                         sizeof(KEY_EVICT_BY_NID),
458                                         KEY_EVICT_BY_NID,
459                                         strlen(tmpbuf + 4) + 1,
460                                         tmpbuf + 4, NULL);
461                 if (rc)
462                         CERROR("Failed to evict nid %s from OSTs: rc %d\n",
463                                tmpbuf + 4, rc);
464         }
465
466         /* See the comments in function lprocfs_wr_evict_client()
467          * in ptlrpc/lproc_ptlrpc.c for details. - jay */
468         class_incref(obd, __func__, current);
469         obd_export_evict_by_nid(obd, tmpbuf + 4);
470         class_decref(obd, __func__, current);
471
472
473 out:
474         OBD_FREE(kbuf, BUFLEN);
475         return rc < 0 ? rc : count;
476 }
477
478 #undef BUFLEN
479
480 static ssize_t evict_tgt_nids_show(struct kobject *kobj,
481                                    struct attribute *attr, char *buf)
482 {
483         struct obd_device *obd = container_of(kobj, struct obd_device,
484                                               obd_kset.kobj);
485         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
486
487         return scnprintf(buf, PAGE_SIZE, "%u\n",
488                          mdt->mdt_opts.mo_evict_tgt_nids);
489 }
490
491 static ssize_t evict_tgt_nids_store(struct kobject *kobj,
492                                     struct attribute *attr, const char *buffer,
493                                     size_t count)
494 {
495         struct obd_device *obd = container_of(kobj, struct obd_device,
496                                               obd_kset.kobj);
497         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
498         bool val;
499         int rc;
500
501         rc = kstrtobool(buffer, &val);
502         if (rc)
503                 return rc;
504
505         mdt->mdt_opts.mo_evict_tgt_nids = val;
506         return count;
507 }
508 LUSTRE_RW_ATTR(evict_tgt_nids);
509
510 static ssize_t commit_on_sharing_show(struct kobject *kobj,
511                                       struct attribute *attr, char *buf)
512 {
513         struct obd_device *obd = container_of(kobj, struct obd_device,
514                                               obd_kset.kobj);
515         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
516
517         return scnprintf(buf, PAGE_SIZE, "%u\n", mdt_cos_is_enabled(mdt));
518 }
519
520 static ssize_t commit_on_sharing_store(struct kobject *kobj,
521                                        struct attribute *attr,
522                                        const char *buffer, size_t count)
523 {
524         struct obd_device *obd = container_of(kobj, struct obd_device,
525                                               obd_kset.kobj);
526         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
527         bool val;
528         int rc;
529
530         rc = kstrtobool(buffer, &val);
531         if (rc)
532                 return rc;
533
534         mdt_enable_cos(mdt, val);
535         return count;
536 }
537 LUSTRE_RW_ATTR(commit_on_sharing);
538
539 static ssize_t local_recovery_show(struct kobject *kobj,
540                                       struct attribute *attr, char *buf)
541 {
542         struct obd_device *obd = container_of(kobj, struct obd_device,
543                                               obd_kset.kobj);
544
545         return scnprintf(buf, PAGE_SIZE, "%u\n",
546                          obd->u.obt.obt_lut->lut_local_recovery);
547 }
548
549 static ssize_t local_recovery_store(struct kobject *kobj,
550                                        struct attribute *attr,
551                                        const char *buffer, size_t count)
552 {
553         struct obd_device *obd = container_of(kobj, struct obd_device,
554                                               obd_kset.kobj);
555         bool val;
556         int rc;
557
558         rc = kstrtobool(buffer, &val);
559         if (rc)
560                 return rc;
561
562         obd->u.obt.obt_lut->lut_local_recovery = !!val;
563         return count;
564 }
565 LUSTRE_RW_ATTR(local_recovery);
566
567 static int mdt_root_squash_seq_show(struct seq_file *m, void *data)
568 {
569         struct obd_device *obd = m->private;
570         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
571         struct root_squash_info *squash = &mdt->mdt_squash;
572
573         seq_printf(m, "%u:%u\n", squash->rsi_uid,
574                    squash->rsi_gid);
575         return 0;
576 }
577
578 static ssize_t
579 mdt_root_squash_seq_write(struct file *file, const char __user *buffer,
580                           size_t count, loff_t *off)
581 {
582         struct seq_file   *m = file->private_data;
583         struct obd_device *obd = m->private;
584         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
585         struct root_squash_info *squash = &mdt->mdt_squash;
586
587         return lprocfs_wr_root_squash(buffer, count, squash,
588                                       mdt_obd_name(mdt));
589 }
590 LPROC_SEQ_FOPS(mdt_root_squash);
591
592 static int mdt_nosquash_nids_seq_show(struct seq_file *m, void *data)
593 {
594         struct obd_device *obd = m->private;
595         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
596         struct root_squash_info *squash = &mdt->mdt_squash;
597         int len = 0;
598
599         spin_lock(&squash->rsi_lock);
600         if (!list_empty(&squash->rsi_nosquash_nids)) {
601                 len = cfs_print_nidlist(m->buf + m->count, m->size - m->count,
602                                         &squash->rsi_nosquash_nids);
603                 m->count += len;
604                 seq_putc(m, '\n');
605         } else
606                 seq_puts(m, "NONE\n");
607         spin_unlock(&squash->rsi_lock);
608
609         return 0;
610 }
611
612 static ssize_t
613 mdt_nosquash_nids_seq_write(struct file *file, const char __user *buffer,
614                             size_t count, loff_t *off)
615 {
616         struct seq_file   *m = file->private_data;
617         struct obd_device *obd = m->private;
618         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
619         struct root_squash_info *squash = &mdt->mdt_squash;
620
621         return lprocfs_wr_nosquash_nids(buffer, count, squash,
622                                         mdt_obd_name(mdt));
623 }
624 LPROC_SEQ_FOPS(mdt_nosquash_nids);
625
626 static ssize_t enable_remote_dir_show(struct kobject *kobj,
627                                       struct attribute *attr, char *buf)
628 {
629         struct obd_device *obd = container_of(kobj, struct obd_device,
630                                               obd_kset.kobj);
631         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
632
633         return scnprintf(buf, PAGE_SIZE, "%u\n", mdt->mdt_enable_remote_dir);
634 }
635
636 static ssize_t enable_remote_dir_store(struct kobject *kobj,
637                                        struct attribute *attr,
638                                        const char *buffer, size_t count)
639 {
640         struct obd_device *obd = container_of(kobj, struct obd_device,
641                                               obd_kset.kobj);
642         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
643         bool val;
644         int rc;
645
646         rc = kstrtobool(buffer, &val);
647         if (rc)
648                 return rc;
649
650         mdt->mdt_enable_remote_dir = val;
651         return count;
652 }
653 LUSTRE_RW_ATTR(enable_remote_dir);
654
655 static ssize_t enable_remote_dir_gid_show(struct kobject *kobj,
656                                           struct attribute *attr, char *buf)
657 {
658         struct obd_device *obd = container_of(kobj, struct obd_device,
659                                               obd_kset.kobj);
660         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
661
662         return scnprintf(buf, PAGE_SIZE, "%d\n",
663                          (int)mdt->mdt_enable_remote_dir_gid);
664 }
665
666 static ssize_t enable_remote_dir_gid_store(struct kobject *kobj,
667                                            struct attribute *attr,
668                                            const char *buffer, size_t count)
669 {
670         struct obd_device *obd = container_of(kobj, struct obd_device,
671                                               obd_kset.kobj);
672         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
673         int val;
674         int rc;
675
676         rc = kstrtoint(buffer, 0, &val);
677         if (rc)
678                 return rc;
679
680         mdt->mdt_enable_remote_dir_gid = val;
681         return count;
682 }
683 LUSTRE_RW_ATTR(enable_remote_dir_gid);
684
685 static ssize_t enable_chprojid_gid_show(struct kobject *kobj,
686                                         struct attribute *attr, char *buf)
687 {
688         struct obd_device *obd = container_of(kobj, struct obd_device,
689                                               obd_kset.kobj);
690         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
691
692         return scnprintf(buf, PAGE_SIZE, "%d\n",
693                          (int)mdt->mdt_enable_chprojid_gid);
694 }
695
696 static ssize_t enable_chprojid_gid_store(struct kobject *kobj,
697                                          struct attribute *attr,
698                                          const char *buffer, size_t count)
699 {
700         struct obd_device *obd = container_of(kobj, struct obd_device,
701                                               obd_kset.kobj);
702         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
703         int val;
704         int rc;
705
706         rc = kstrtoint(buffer, 0, &val);
707         if (rc)
708                 return rc;
709
710         mdt->mdt_enable_chprojid_gid = val;
711         return count;
712 }
713 LUSTRE_RW_ATTR(enable_chprojid_gid);
714
715 static ssize_t enable_parallel_rename_dir_show(struct kobject *kobj,
716                                                struct attribute *attr,
717                                                char *buf)
718 {
719         struct obd_device *obd = container_of(kobj, struct obd_device,
720                                               obd_kset.kobj);
721         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
722
723         return scnprintf(buf, PAGE_SIZE, "%u\n",
724                          mdt->mdt_enable_parallel_rename_dir);
725 }
726
727 static ssize_t enable_parallel_rename_dir_store(struct kobject *kobj,
728                                                 struct attribute *attr,
729                                                 const char *buffer,
730                                                 size_t count)
731 {
732         struct obd_device *obd = container_of(kobj, struct obd_device,
733                                               obd_kset.kobj);
734         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
735         bool val;
736         int rc;
737
738         rc = kstrtobool(buffer, &val);
739         if (rc)
740                 return rc;
741
742         mdt->mdt_enable_parallel_rename_dir = val;
743
744         return count;
745 }
746 LUSTRE_RW_ATTR(enable_parallel_rename_dir);
747
748 static ssize_t enable_parallel_rename_file_show(struct kobject *kobj,
749                                                 struct attribute *attr,
750                                                 char *buf)
751 {
752         struct obd_device *obd = container_of(kobj, struct obd_device,
753                                               obd_kset.kobj);
754         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
755
756         return scnprintf(buf, PAGE_SIZE, "%u\n",
757                          mdt->mdt_enable_parallel_rename_file);
758 }
759
760 static ssize_t enable_parallel_rename_file_store(struct kobject *kobj,
761                                                  struct attribute *attr,
762                                                  const char *buffer,
763                                                  size_t count)
764 {
765         struct obd_device *obd = container_of(kobj, struct obd_device,
766                                               obd_kset.kobj);
767         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
768         bool val;
769         int rc;
770
771         rc = kstrtobool(buffer, &val);
772         if (rc)
773                 return rc;
774
775         mdt->mdt_enable_parallel_rename_file = val;
776
777         return count;
778 }
779 LUSTRE_RW_ATTR(enable_parallel_rename_file);
780
781 static ssize_t enable_striped_dir_show(struct kobject *kobj,
782                                        struct attribute *attr, char *buf)
783 {
784         struct obd_device *obd = container_of(kobj, struct obd_device,
785                                               obd_kset.kobj);
786         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
787
788         return scnprintf(buf, PAGE_SIZE, "%u\n", mdt->mdt_enable_striped_dir);
789 }
790
791 static ssize_t enable_striped_dir_store(struct kobject *kobj,
792                                         struct attribute *attr,
793                                         const char *buffer, size_t count)
794 {
795         struct obd_device *obd = container_of(kobj, struct obd_device,
796                                               obd_kset.kobj);
797         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
798         bool val;
799         int rc;
800
801         rc = kstrtobool(buffer, &val);
802         if (rc)
803                 return rc;
804
805         mdt->mdt_enable_striped_dir = val;
806         return count;
807 }
808 LUSTRE_RW_ATTR(enable_striped_dir);
809
810 static ssize_t enable_dir_migration_show(struct kobject *kobj,
811                                          struct attribute *attr, char *buf)
812 {
813         struct obd_device *obd = container_of(kobj, struct obd_device,
814                                               obd_kset.kobj);
815         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
816
817         return scnprintf(buf, PAGE_SIZE, "%u\n", mdt->mdt_enable_dir_migration);
818 }
819
820 static ssize_t enable_dir_migration_store(struct kobject *kobj,
821                                           struct attribute *attr,
822                                           const char *buffer, size_t count)
823 {
824         struct obd_device *obd = container_of(kobj, struct obd_device,
825                                               obd_kset.kobj);
826         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
827         bool val;
828         int rc;
829
830         rc = kstrtobool(buffer, &val);
831         if (rc)
832                 return rc;
833
834         mdt->mdt_enable_dir_migration = val;
835         return count;
836 }
837 LUSTRE_RW_ATTR(enable_dir_migration);
838
839 static ssize_t enable_dir_restripe_show(struct kobject *kobj,
840                                         struct attribute *attr, char *buf)
841 {
842         struct obd_device *obd = container_of(kobj, struct obd_device,
843                                               obd_kset.kobj);
844         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
845
846         return scnprintf(buf, PAGE_SIZE, "%u\n", mdt->mdt_enable_dir_restripe);
847 }
848
849 static ssize_t enable_dir_restripe_store(struct kobject *kobj,
850                                          struct attribute *attr,
851                                          const char *buffer, size_t count)
852 {
853         struct obd_device *obd = container_of(kobj, struct obd_device,
854                                               obd_kset.kobj);
855         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
856         bool val;
857         int rc;
858
859         rc = kstrtobool(buffer, &val);
860         if (rc)
861                 return rc;
862
863         mdt->mdt_enable_dir_restripe = val;
864         return count;
865 }
866 LUSTRE_RW_ATTR(enable_dir_restripe);
867
868 static ssize_t enable_dir_auto_split_show(struct kobject *kobj,
869                                           struct attribute *attr, char *buf)
870 {
871         struct obd_device *obd = container_of(kobj, struct obd_device,
872                                               obd_kset.kobj);
873         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
874
875         return scnprintf(buf, PAGE_SIZE, "%u\n",
876                          mdt->mdt_enable_dir_auto_split);
877 }
878
879 static ssize_t enable_dir_auto_split_store(struct kobject *kobj,
880                                            struct attribute *attr,
881                                            const char *buffer, size_t count)
882 {
883         struct obd_device *obd = container_of(kobj, struct obd_device,
884                                               obd_kset.kobj);
885         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
886         bool val;
887         int rc;
888
889         rc = kstrtobool(buffer, &val);
890         if (rc)
891                 return rc;
892
893         mdt->mdt_enable_dir_auto_split = val;
894         return count;
895 }
896 LUSTRE_RW_ATTR(enable_dir_auto_split);
897
898 /**
899  * Show MDT async commit count.
900  *
901  * @m           seq_file handle
902  * @data        unused for single entry
903  *
904  * Return:      0 on success
905  *              negative value on error
906  */
907 static ssize_t async_commit_count_show(struct kobject *kobj,
908                                        struct attribute *attr, char *buf)
909 {
910         struct obd_device *obd = container_of(kobj, struct obd_device,
911                                               obd_kset.kobj);
912         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
913
914         return scnprintf(buf, PAGE_SIZE, "%d\n",
915                          atomic_read(&mdt->mdt_async_commit_count));
916 }
917
918 static ssize_t async_commit_count_store(struct kobject *kobj,
919                                         struct attribute *attr,
920                                         const char *buffer, size_t count)
921 {
922         struct obd_device *obd = container_of(kobj, struct obd_device,
923                                               obd_kset.kobj);
924         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
925         int val;
926         int rc;
927
928         rc = kstrtoint(buffer, 10, &val);
929         if (rc)
930                 return rc;
931
932         atomic_set(&mdt->mdt_async_commit_count, val);
933
934         return count;
935 }
936 LUSTRE_RW_ATTR(async_commit_count);
937
938 /**
939  * Show MDT sync count.
940  *
941  * \param[in] m         seq_file handle
942  * \param[in] data      unused for single entry
943  *
944  * \retval              0 on success
945  * \retval              negative value on error
946  */
947 static ssize_t sync_count_show(struct kobject *kobj, struct attribute *attr,
948                                char *buf)
949 {
950         struct obd_device *obd = container_of(kobj, struct obd_device,
951                                               obd_kset.kobj);
952         struct lu_target *tgt = obd->u.obt.obt_lut;
953
954         return scnprintf(buf, PAGE_SIZE, "%d\n",
955                          atomic_read(&tgt->lut_sync_count));
956 }
957
958 static ssize_t sync_count_store(struct kobject *kobj, struct attribute *attr,
959                                 const char *buffer, size_t count)
960 {
961         struct obd_device *obd = container_of(kobj, struct obd_device,
962                                               obd_kset.kobj);
963         struct lu_target *tgt = obd->u.obt.obt_lut;
964         int val;
965         int rc;
966
967         rc = kstrtoint(buffer, 0, &val);
968         if (rc)
969                 return rc;
970
971         atomic_set(&tgt->lut_sync_count, val);
972
973         return count;
974 }
975 LUSTRE_RW_ATTR(sync_count);
976
977 static const char *dom_open_lock_modes[NUM_DOM_LOCK_ON_OPEN_MODES] = {
978         [NO_DOM_LOCK_ON_OPEN] = "never",
979         [TRYLOCK_DOM_ON_OPEN] = "trylock",
980         [ALWAYS_DOM_LOCK_ON_OPEN] = "always",
981 };
982
983 /* This must be longer than the longest string above */
984 #define DOM_LOCK_MODES_MAXLEN 16
985
986 /**
987  * Show MDT policy for data prefetch on open for DoM files..
988  *
989  * \param[in] m         seq_file handle
990  * \param[in] data      unused
991  *
992  * \retval              0 on success
993  * \retval              negative value on error
994  */
995 static ssize_t dom_lock_show(struct kobject *kobj, struct attribute *attr,
996                              char *buf)
997 {
998         struct obd_device *obd = container_of(kobj, struct obd_device,
999                                               obd_kset.kobj);
1000         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1001
1002         return scnprintf(buf, PAGE_SIZE, "%s\n",
1003                          dom_open_lock_modes[mdt->mdt_opts.mo_dom_lock]);
1004 }
1005
1006 /**
1007  * Change MDT policy for data prefetch on open for DoM files.
1008  *
1009  * This variable defines how DOM lock is taken at open enqueue.
1010  * There are three possible modes:
1011  * 1) never - never take DoM lock on open. DoM lock will be taken as separate
1012  *    IO lock with own enqueue.
1013  * 2) trylock - DoM lock will be taken only if non-blocked.
1014  * 3) always - DoM lock will be taken always even if it is blocking lock.
1015  *
1016  * If dom_read_open is enabled too then DoM lock is taken in PR mode and
1017  * is paired with LAYOUT lock when possible.
1018  *
1019  * \param[in] file      proc file
1020  * \param[in] buffer    string which represents policy
1021  * \param[in] count     \a buffer length
1022  * \param[in] off       unused for single entry
1023  *
1024  * \retval              \a count on success
1025  * \retval              negative number on error
1026  */
1027 static ssize_t dom_lock_store(struct kobject *kobj, struct attribute *attr,
1028                               const char *buffer, size_t count)
1029 {
1030         struct obd_device *obd = container_of(kobj, struct obd_device,
1031                                               obd_kset.kobj);
1032         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1033         int val = -1;
1034         int i, rc;
1035
1036         if (count == 0 || count >= DOM_LOCK_MODES_MAXLEN)
1037                 return -EINVAL;
1038
1039         for (i = 0 ; i < NUM_DOM_LOCK_ON_OPEN_MODES; i++) {
1040                 /* buffer might have '\n' but using strlen() avoids it */
1041                 if (strncmp(buffer, dom_open_lock_modes[i],
1042                             strlen(dom_open_lock_modes[i])) == 0) {
1043                         val = i;
1044                         break;
1045                 }
1046         }
1047
1048         /* Legacy numeric codes */
1049         if (val == -1) {
1050                 rc = kstrtoint(buffer, 0, &val);
1051                 if (rc)
1052                         return rc;
1053         }
1054
1055         if (val == ALWAYS_DOM_LOCK_ON_OPEN)
1056                 val = TRYLOCK_DOM_ON_OPEN;
1057
1058         if (val < 0 || val >= NUM_DOM_LOCK_ON_OPEN_MODES)
1059                 return -EINVAL;
1060
1061         mdt->mdt_opts.mo_dom_lock = val;
1062         return count;
1063 }
1064 LUSTRE_RW_ATTR(dom_lock);
1065
1066 /**
1067  * Show MDT policy for data prefetch on open for DoM files..
1068  *
1069  * \param[in] m         seq_file handle
1070  * \param[in] data      unused
1071  *
1072  * \retval              0 on success
1073  * \retval              negative value on error
1074  */
1075 static ssize_t dom_read_open_show(struct kobject *kobj,
1076                                   struct attribute *attr, char *buf)
1077 {
1078         struct obd_device *obd = container_of(kobj, struct obd_device,
1079                                               obd_kset.kobj);
1080         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1081
1082         return scnprintf(buf, PAGE_SIZE, "%u\n",
1083                          !!mdt->mdt_opts.mo_dom_read_open);
1084 }
1085
1086 /**
1087  * Modify MDT policy for data prefetch on open for DoM files.
1088  *
1089  * If enabled then Data-on-MDT file data may be read during open and
1090  * returned back in reply. It works only with mo_dom_lock enabled.
1091  *
1092  * \param[in] file      proc file
1093  * \param[in] buffer    string which represents policy
1094  * \param[in] count     \a buffer length
1095  * \param[in] off       unused for single entry
1096  *
1097  * \retval              \a count on success
1098  * \retval              negative number on error
1099  */
1100 static ssize_t dom_read_open_store(struct kobject *kobj,
1101                                    struct attribute *attr, const char *buffer,
1102                                    size_t count)
1103 {
1104         struct obd_device *obd = container_of(kobj, struct obd_device,
1105                                               obd_kset.kobj);
1106         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1107         bool val;
1108         int rc;
1109
1110         rc = kstrtobool(buffer, &val);
1111         if (rc)
1112                 return rc;
1113
1114         mdt->mdt_opts.mo_dom_read_open = !!val;
1115         return count;
1116 }
1117 LUSTRE_RW_ATTR(dom_read_open);
1118
1119 /**
1120  * Show policy for using strict SOM information for real size (stat size).
1121  *
1122  * \param[in] m         seq_file handle
1123  * \param[in] data      unused
1124  *
1125  * \retval              0 on success
1126  * \retval              negative value on error
1127  */
1128 static ssize_t enable_strict_som_show(struct kobject *kobj,
1129                                       struct attribute *attr, char *buf)
1130 {
1131         struct obd_device *obd = container_of(kobj, struct obd_device,
1132                                               obd_kset.kobj);
1133         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1134
1135         return scnprintf(buf, PAGE_SIZE, "%u\n",
1136                          !!mdt->mdt_opts.mo_enable_strict_som);
1137 }
1138
1139 /**
1140  * Modify policy for using strict SOM information for real size (stat size).
1141  *
1142  * If disabled, SOM is never used for stat.
1143  *
1144  * \param[in] file      proc file
1145  * \param[in] buffer    string which represents policy
1146  * \param[in] count     \a buffer length
1147  * \param[in] off       unused for single entry
1148  *
1149  * \retval              \a count on success
1150  * \retval              negative number on error
1151  */
1152 static ssize_t enable_strict_som_store(struct kobject *kobj,
1153                                        struct attribute *attr,
1154                                        const char *buffer, size_t count)
1155 {
1156         struct obd_device *obd = container_of(kobj, struct obd_device,
1157                                               obd_kset.kobj);
1158         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1159         bool val;
1160         int rc;
1161
1162         rc = kstrtobool(buffer, &val);
1163         if (rc)
1164                 return rc;
1165
1166         mdt->mdt_opts.mo_enable_strict_som = !!val;
1167         return count;
1168 }
1169 LUSTRE_RW_ATTR(enable_strict_som);
1170
1171 static ssize_t migrate_hsm_allowed_show(struct kobject *kobj,
1172                                         struct attribute *attr, char *buf)
1173 {
1174         struct obd_device *obd = container_of(kobj, struct obd_device,
1175                                               obd_kset.kobj);
1176         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1177
1178         return scnprintf(buf, PAGE_SIZE, "%u\n",
1179                          mdt->mdt_opts.mo_migrate_hsm_allowed);
1180 }
1181
1182 static ssize_t migrate_hsm_allowed_store(struct kobject *kobj,
1183                                          struct attribute *attr,
1184                                          const char *buffer, size_t count)
1185 {
1186         struct obd_device *obd = container_of(kobj, struct obd_device,
1187                                               obd_kset.kobj);
1188         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1189         bool val;
1190         int rc;
1191
1192         rc = kstrtobool(buffer, &val);
1193         if (rc)
1194                 return rc;
1195
1196         mdt->mdt_opts.mo_migrate_hsm_allowed = val;
1197         return count;
1198 }
1199 LUSTRE_RW_ATTR(migrate_hsm_allowed);
1200
1201 static ssize_t readonly_show(struct kobject *kobj, struct attribute *attr,
1202                              char *buf)
1203 {
1204         struct obd_device *obd = container_of(kobj, struct obd_device,
1205                                               obd_kset.kobj);
1206         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1207
1208         return scnprintf(buf, PAGE_SIZE, "%u\n", mdt->mdt_readonly);
1209 }
1210
1211 static ssize_t readonly_store(struct kobject *kobj, struct attribute *attr,
1212                               const char *buffer, size_t count)
1213 {
1214         struct obd_device *obd = container_of(kobj, struct obd_device,
1215                                               obd_kset.kobj);
1216         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1217         bool val;
1218         int rc;
1219
1220         rc = kstrtobool(buffer, &val);
1221         if (rc)
1222                 return rc;
1223
1224         mdt->mdt_readonly = val;
1225         return count;
1226 }
1227 LUSTRE_RW_ATTR(readonly);
1228
1229 static ssize_t enable_remote_rename_show(struct kobject *kobj,
1230                                          struct attribute *attr,
1231                                          char *buf)
1232 {
1233         struct obd_device *obd = container_of(kobj, struct obd_device,
1234                                               obd_kset.kobj);
1235         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1236
1237         return scnprintf(buf, PAGE_SIZE, "%u\n",
1238                          mdt->mdt_enable_remote_rename);
1239 }
1240
1241 static ssize_t enable_remote_rename_store(struct kobject *kobj,
1242                                           struct attribute *attr,
1243                                           const char *buffer, size_t count)
1244 {
1245         struct obd_device *obd = container_of(kobj, struct obd_device,
1246                                               obd_kset.kobj);
1247         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1248         bool val;
1249         int rc;
1250
1251         rc = kstrtobool(buffer, &val);
1252         if (rc)
1253                 return rc;
1254
1255         mdt->mdt_enable_remote_rename = val;
1256         return count;
1257 }
1258 LUSTRE_RW_ATTR(enable_remote_rename);
1259
1260 static ssize_t dir_split_count_show(struct kobject *kobj,
1261                                      struct attribute *attr,
1262                                      char *buf)
1263 {
1264         struct obd_device *obd = container_of(kobj, struct obd_device,
1265                                               obd_kset.kobj);
1266         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1267
1268         return scnprintf(buf, PAGE_SIZE, "%llu\n",
1269                          mdt->mdt_restriper.mdr_dir_split_count);
1270 }
1271
1272 static ssize_t dir_split_count_store(struct kobject *kobj,
1273                                       struct attribute *attr,
1274                                       const char *buffer, size_t count)
1275 {
1276         struct obd_device *obd = container_of(kobj, struct obd_device,
1277                                               obd_kset.kobj);
1278         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1279         s64 val;
1280         int rc;
1281
1282         rc = sysfs_memparse(buffer, count, &val, "B");
1283         if (rc < 0)
1284                 return rc;
1285
1286         if (val < 0)
1287                 return -ERANGE;
1288
1289         mdt->mdt_restriper.mdr_dir_split_count = val;
1290
1291         return count;
1292 }
1293 LUSTRE_RW_ATTR(dir_split_count);
1294
1295 static ssize_t dir_split_delta_show(struct kobject *kobj,
1296                                     struct attribute *attr,
1297                                     char *buf)
1298 {
1299         struct obd_device *obd = container_of(kobj, struct obd_device,
1300                                               obd_kset.kobj);
1301         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1302
1303         return scnprintf(buf, PAGE_SIZE, "%u\n",
1304                          mdt->mdt_restriper.mdr_dir_split_delta);
1305 }
1306
1307 static ssize_t dir_split_delta_store(struct kobject *kobj,
1308                                      struct attribute *attr,
1309                                      const char *buffer, size_t count)
1310 {
1311         struct obd_device *obd = container_of(kobj, struct obd_device,
1312                                               obd_kset.kobj);
1313         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1314         u32 val;
1315         int rc;
1316
1317         rc = kstrtouint(buffer, 0, &val);
1318         if (rc)
1319                 return rc;
1320
1321         mdt->mdt_restriper.mdr_dir_split_delta = val;
1322
1323         return count;
1324 }
1325 LUSTRE_RW_ATTR(dir_split_delta);
1326
1327 static ssize_t dir_restripe_nsonly_show(struct kobject *kobj,
1328                                         struct attribute *attr, char *buf)
1329 {
1330         struct obd_device *obd = container_of(kobj, struct obd_device,
1331                                               obd_kset.kobj);
1332         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1333
1334         return scnprintf(buf, PAGE_SIZE, "%u\n", mdt->mdt_dir_restripe_nsonly);
1335 }
1336
1337 static ssize_t dir_restripe_nsonly_store(struct kobject *kobj,
1338                                          struct attribute *attr,
1339                                          const char *buffer, size_t count)
1340 {
1341         struct obd_device *obd = container_of(kobj, struct obd_device,
1342                                               obd_kset.kobj);
1343         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1344         bool val;
1345         int rc;
1346
1347         rc = kstrtobool(buffer, &val);
1348         if (rc)
1349                 return rc;
1350
1351         mdt->mdt_dir_restripe_nsonly = val;
1352         return count;
1353 }
1354 LUSTRE_RW_ATTR(dir_restripe_nsonly);
1355
1356 static ssize_t enable_remote_subdir_mount_show(struct kobject *kobj,
1357                                                struct attribute *attr,
1358                                                char *buf)
1359 {
1360         struct obd_device *obd = container_of(kobj, struct obd_device,
1361                                               obd_kset.kobj);
1362         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1363
1364         return scnprintf(buf, PAGE_SIZE, "%u\n",
1365                          mdt->mdt_enable_remote_subdir_mount);
1366 }
1367
1368 static ssize_t enable_remote_subdir_mount_store(struct kobject *kobj,
1369                                                 struct attribute *attr,
1370                                                 const char *buffer,
1371                                                 size_t count)
1372 {
1373         struct obd_device *obd = container_of(kobj, struct obd_device,
1374                                               obd_kset.kobj);
1375         struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
1376         bool val;
1377         int rc;
1378
1379         rc = kstrtobool(buffer, &val);
1380         if (rc)
1381                 return rc;
1382
1383         mdt->mdt_enable_remote_subdir_mount = val;
1384         return count;
1385 }
1386 LUSTRE_RW_ATTR(enable_remote_subdir_mount);
1387
1388 /**
1389  * Show if the OFD enforces T10PI checksum.
1390  *
1391  * \param[in] m         seq_file handle
1392  * \param[in] data      unused for single entry
1393  *
1394  * \retval              0 on success
1395  * \retval              negative value on error
1396  */
1397 static ssize_t checksum_t10pi_enforce_show(struct kobject *kobj,
1398                                            struct attribute *attr,
1399                                            char *buf)
1400 {
1401         struct obd_device *obd = container_of(kobj, struct obd_device,
1402                                               obd_kset.kobj);
1403         struct lu_target *lut = obd->u.obt.obt_lut;
1404
1405         return scnprintf(buf, PAGE_SIZE, "%u\n", lut->lut_cksum_t10pi_enforce);
1406 }
1407
1408 /**
1409  * Force specific T10PI checksum modes to be enabled
1410  *
1411  * If T10PI *is* supported in hardware, allow only the supported T10PI type
1412  * to be used. If T10PI is *not* supported by the OSD, setting the enforce
1413  * parameter forces all T10PI types to be enabled (even if slower) for
1414  * testing.
1415  *
1416  * The final determination of which algorithm to be used depends whether
1417  * the client supports T10PI or not, and is handled at client connect time.
1418  *
1419  * \param[in] file      proc file
1420  * \param[in] buffer    string which represents mode
1421  *                      1: set T10PI checksums enforced
1422  *                      0: unset T10PI checksums enforced
1423  * \param[in] count     \a buffer length
1424  * \param[in] off       unused for single entry
1425  *
1426  * \retval              \a count on success
1427  * \retval              negative number on error
1428  */
1429 static ssize_t checksum_t10pi_enforce_store(struct kobject *kobj,
1430                                             struct attribute *attr,
1431                                             const char *buffer, size_t count)
1432 {
1433         struct obd_device *obd = container_of(kobj, struct obd_device,
1434                                               obd_kset.kobj);
1435         struct lu_target *lut = obd->u.obt.obt_lut;
1436         bool enforce;
1437         int rc;
1438
1439         rc = kstrtobool(buffer, &enforce);
1440         if (rc)
1441                 return rc;
1442
1443         spin_lock(&lut->lut_flags_lock);
1444         lut->lut_cksum_t10pi_enforce = enforce;
1445         spin_unlock(&lut->lut_flags_lock);
1446         return count;
1447 }
1448 LUSTRE_RW_ATTR(checksum_t10pi_enforce);
1449
1450 /*
1451  * mdt_checksum_type(server) proc handling
1452  */
1453 DECLARE_CKSUM_NAME;
1454
1455 static int mdt_checksum_type_seq_show(struct seq_file *m, void *data)
1456 {
1457         struct obd_device *obd = m->private;
1458         struct lu_target *lut;
1459         enum cksum_types pref;
1460         int i;
1461
1462         if (!obd)
1463                 return 0;
1464
1465         lut = obd->u.obt.obt_lut;
1466
1467         /* select fastest checksum type on the server */
1468         pref = obd_cksum_type_select(obd->obd_name,
1469                                      lut->lut_cksum_types_supported, 0);
1470
1471         for (i = 0; i < ARRAY_SIZE(cksum_name); i++) {
1472                 if ((BIT(i) & lut->lut_cksum_types_supported) == 0)
1473                         continue;
1474
1475                 if (pref == BIT(i))
1476                         seq_printf(m, "[%s] ", cksum_name[i]);
1477                 else
1478                         seq_printf(m, "%s ", cksum_name[i]);
1479         }
1480         seq_puts(m, "\n");
1481
1482         return 0;
1483 }
1484
1485 LPROC_SEQ_FOPS_RO(mdt_checksum_type);
1486
1487 LPROC_SEQ_FOPS_RO_TYPE(mdt, hash);
1488 LPROC_SEQ_FOPS_WR_ONLY(mdt, mds_evict_client);
1489 LPROC_SEQ_FOPS_RW_TYPE(mdt, checksum_dump);
1490 LUSTRE_RW_ATTR(job_cleanup_interval);
1491 LPROC_SEQ_FOPS_RW_TYPE(mdt, nid_stats_clear);
1492 LUSTRE_RW_ATTR(hsm_control);
1493
1494 LPROC_SEQ_FOPS_RO_TYPE(mdt, recovery_status);
1495 LUSTRE_RW_ATTR(recovery_time_hard);
1496 LUSTRE_RW_ATTR(recovery_time_soft);
1497 LUSTRE_RW_ATTR(ir_factor);
1498
1499 LUSTRE_RO_ATTR(tot_dirty);
1500 LUSTRE_RO_ATTR(tot_granted);
1501 LUSTRE_RO_ATTR(tot_pending);
1502 LUSTRE_RW_ATTR(grant_compat_disable);
1503 LUSTRE_RO_ATTR(instance);
1504
1505 LUSTRE_RO_ATTR(num_exports);
1506 LUSTRE_RW_ATTR(grant_check_threshold);
1507
1508 static struct attribute *mdt_attrs[] = {
1509         &lustre_attr_tot_dirty.attr,
1510         &lustre_attr_tot_granted.attr,
1511         &lustre_attr_tot_pending.attr,
1512         &lustre_attr_grant_compat_disable.attr,
1513         &lustre_attr_instance.attr,
1514         &lustre_attr_recovery_time_hard.attr,
1515         &lustre_attr_recovery_time_soft.attr,
1516         &lustre_attr_ir_factor.attr,
1517         &lustre_attr_num_exports.attr,
1518         &lustre_attr_grant_check_threshold.attr,
1519         &lustre_attr_identity_expire.attr,
1520         &lustre_attr_identity_acquire_expire.attr,
1521         &lustre_attr_identity_upcall.attr,
1522         &lustre_attr_identity_flush.attr,
1523         &lustre_attr_evict_tgt_nids.attr,
1524         &lustre_attr_enable_chprojid_gid.attr,
1525         &lustre_attr_enable_dir_migration.attr,
1526         &lustre_attr_enable_dir_restripe.attr,
1527         &lustre_attr_enable_dir_auto_split.attr,
1528         &lustre_attr_enable_parallel_rename_dir.attr,
1529         &lustre_attr_enable_parallel_rename_file.attr,
1530         &lustre_attr_enable_remote_dir.attr,
1531         &lustre_attr_enable_remote_dir_gid.attr,
1532         &lustre_attr_enable_remote_rename.attr,
1533         &lustre_attr_enable_striped_dir.attr,
1534         &lustre_attr_commit_on_sharing.attr,
1535         &lustre_attr_local_recovery.attr,
1536         &lustre_attr_async_commit_count.attr,
1537         &lustre_attr_sync_count.attr,
1538         &lustre_attr_dom_lock.attr,
1539         &lustre_attr_dom_read_open.attr,
1540         &lustre_attr_enable_strict_som.attr,
1541         &lustre_attr_migrate_hsm_allowed.attr,
1542         &lustre_attr_hsm_control.attr,
1543         &lustre_attr_job_cleanup_interval.attr,
1544         &lustre_attr_readonly.attr,
1545         &lustre_attr_dir_split_count.attr,
1546         &lustre_attr_dir_split_delta.attr,
1547         &lustre_attr_dir_restripe_nsonly.attr,
1548         &lustre_attr_checksum_t10pi_enforce.attr,
1549         &lustre_attr_enable_remote_subdir_mount.attr,
1550         NULL,
1551 };
1552
1553 static struct lprocfs_vars lprocfs_mdt_obd_vars[] = {
1554         { .name =       "recovery_status",
1555           .fops =       &mdt_recovery_status_fops               },
1556         { .name =       "identity_info",
1557           .fops =       &mdt_identity_info_fops                 },
1558         { .name =       "site_stats",
1559           .fops =       &mdt_site_stats_fops                    },
1560         { .name =       "evict_client",
1561           .fops =       &mdt_mds_evict_client_fops              },
1562         { .name =       "checksum_dump",
1563           .fops =       &mdt_checksum_dump_fops                 },
1564         { .name =       "hash_stats",
1565           .fops =       &mdt_hash_fops                          },
1566         { .name =       "root_squash",
1567           .fops =       &mdt_root_squash_fops                   },
1568         { .name =       "nosquash_nids",
1569           .fops =       &mdt_nosquash_nids_fops                 },
1570         { .name =       "checksum_type",
1571           .fops =       &mdt_checksum_type_fops         },
1572         { NULL }
1573 };
1574
1575 static int
1576 lprocfs_mdt_print_open_files(struct obd_export *exp, void *v)
1577 {
1578         struct seq_file         *seq = v;
1579
1580         if (exp->exp_lock_hash != NULL) {
1581                 struct mdt_export_data  *med = &exp->exp_mdt_data;
1582                 struct mdt_file_data    *mfd;
1583
1584                 spin_lock(&med->med_open_lock);
1585                 list_for_each_entry(mfd, &med->med_open_head, mfd_list) {
1586                         seq_printf(seq, DFID"\n",
1587                                    PFID(mdt_object_fid(mfd->mfd_object)));
1588                 }
1589                 spin_unlock(&med->med_open_lock);
1590         }
1591
1592         return 0;
1593 }
1594
1595 static int lprocfs_mdt_open_files_seq_show(struct seq_file *seq, void *v)
1596 {
1597         struct nid_stat *stats = seq->private;
1598
1599         return obd_nid_export_for_each(stats->nid_obd, &stats->nid,
1600                                        lprocfs_mdt_print_open_files, seq);
1601 }
1602
1603 int lprocfs_mdt_open_files_seq_open(struct inode *inode, struct file *file)
1604 {
1605         struct seq_file         *seq;
1606         int                     rc;
1607
1608         rc = single_open(file, &lprocfs_mdt_open_files_seq_show, NULL);
1609         if (rc != 0)
1610                 return rc;
1611
1612         seq = file->private_data;
1613         seq->private = PDE_DATA(inode);
1614
1615         return 0;
1616 }
1617
1618 void mdt_counter_incr(struct ptlrpc_request *req, int opcode, long amount)
1619 {
1620         struct obd_export *exp = req->rq_export;
1621
1622         if (exp->exp_obd && exp->exp_obd->obd_md_stats)
1623                 lprocfs_counter_add(exp->exp_obd->obd_md_stats,
1624                                     opcode + LPROC_MD_LAST_OPC, amount);
1625         if (exp->exp_nid_stats && exp->exp_nid_stats->nid_stats != NULL)
1626                 lprocfs_counter_add(exp->exp_nid_stats->nid_stats, opcode,
1627                                     amount);
1628         if (exp->exp_obd && exp->exp_obd->u.obt.obt_jobstats.ojs_hash &&
1629             (exp_connect_flags(exp) & OBD_CONNECT_JOBSTATS))
1630                 lprocfs_job_stats_log(exp->exp_obd,
1631                                       lustre_msg_get_jobid(req->rq_reqmsg),
1632                                       opcode, amount);
1633 }
1634
1635 static const char * const mdt_stats[] = {
1636         [LPROC_MDT_OPEN]                = "open",
1637         [LPROC_MDT_CLOSE]               = "close",
1638         [LPROC_MDT_MKNOD]               = "mknod",
1639         [LPROC_MDT_LINK]                = "link",
1640         [LPROC_MDT_UNLINK]              = "unlink",
1641         [LPROC_MDT_MKDIR]               = "mkdir",
1642         [LPROC_MDT_RMDIR]               = "rmdir",
1643         [LPROC_MDT_RENAME]              = "rename",
1644         [LPROC_MDT_GETATTR]             = "getattr",
1645         [LPROC_MDT_SETATTR]             = "setattr",
1646         [LPROC_MDT_GETXATTR]            = "getxattr",
1647         [LPROC_MDT_SETXATTR]            = "setxattr",
1648         [LPROC_MDT_STATFS]              = "statfs",
1649         [LPROC_MDT_SYNC]                = "sync",
1650         [LPROC_MDT_RENAME_SAMEDIR]      = "samedir_rename",
1651         [LPROC_MDT_RENAME_PAR_FILE]     = "parallel_rename_file",
1652         [LPROC_MDT_RENAME_PAR_DIR]      = "parallel_rename_dir",
1653         [LPROC_MDT_RENAME_CROSSDIR]     = "crossdir_rename",
1654         [LPROC_MDT_IO_READ_BYTES]       = "read_bytes",
1655         [LPROC_MDT_IO_WRITE_BYTES]      = "write_bytes",
1656         [LPROC_MDT_IO_READ]             = "read",
1657         [LPROC_MDT_IO_WRITE]            = "write",
1658         [LPROC_MDT_IO_PUNCH]            = "punch",
1659         [LPROC_MDT_MIGRATE]             = "migrate",
1660         [LPROC_MDT_FALLOCATE]           = "fallocate",
1661 };
1662
1663 void mdt_stats_counter_init(struct lprocfs_stats *stats, unsigned int offset)
1664 {
1665         int array_size = ARRAY_SIZE(mdt_stats);
1666         int oidx; /* obd_md_stats index */
1667         int midx; /* mdt_stats index */
1668
1669         LASSERT(stats && stats->ls_num >= offset + array_size);
1670
1671         for (midx = 0; midx < array_size; midx++) {
1672                 oidx = midx + offset;
1673                 if (midx == LPROC_MDT_IO_READ_BYTES ||
1674                     midx == LPROC_MDT_IO_WRITE_BYTES)
1675                         lprocfs_counter_init(stats, oidx,
1676                                              LPROCFS_TYPE_BYTES_FULL,
1677                                              mdt_stats[midx], "bytes");
1678                 else
1679                         lprocfs_counter_init(stats, oidx,
1680                                              LPROCFS_TYPE_LATENCY,
1681                                              mdt_stats[midx], "usecs");
1682         }
1683 }
1684
1685 int mdt_tunables_init(struct mdt_device *mdt, const char *name)
1686 {
1687         struct obd_device *obd = mdt2obd_dev(mdt);
1688         int rc;
1689
1690         ENTRY;
1691         LASSERT(name != NULL);
1692
1693         obd->obd_ktype.default_attrs = mdt_attrs;
1694         obd->obd_vars = lprocfs_mdt_obd_vars;
1695         rc = lprocfs_obd_setup(obd, true);
1696         if (rc) {
1697                 CERROR("%s: cannot create proc entries: rc = %d\n",
1698                        mdt_obd_name(mdt), rc);
1699                 return rc;
1700         }
1701
1702         rc = tgt_tunables_init(&mdt->mdt_lut);
1703         if (rc) {
1704                 CERROR("%s: failed to init target tunables: rc = %d\n",
1705                        mdt_obd_name(mdt), rc);
1706                 return rc;
1707         }
1708
1709         rc = hsm_cdt_tunables_init(mdt);
1710         if (rc) {
1711                 CERROR("%s: cannot create hsm proc entries: rc = %d\n",
1712                        mdt_obd_name(mdt), rc);
1713                 return rc;
1714         }
1715
1716         obd->obd_proc_exports_entry = proc_mkdir("exports",
1717                                                  obd->obd_proc_entry);
1718         if (obd->obd_proc_exports_entry)
1719                 lprocfs_add_simple(obd->obd_proc_exports_entry, "clear",
1720                                    obd, &mdt_nid_stats_clear_fops);
1721
1722         rc = lprocfs_alloc_md_stats(obd, ARRAY_SIZE(mdt_stats));
1723         if (rc)
1724                 return rc;
1725
1726         /* add additional MDT md_stats after the default ones */
1727         mdt_stats_counter_init(obd->obd_md_stats, LPROC_MD_LAST_OPC);
1728         rc = lprocfs_job_stats_init(obd, ARRAY_SIZE(mdt_stats),
1729                                     mdt_stats_counter_init);
1730
1731         rc = lproc_mdt_attach_rename_seqstat(mdt);
1732         if (rc)
1733                 CERROR("%s: MDT can not create rename stats rc = %d\n",
1734                        mdt_obd_name(mdt), rc);
1735
1736         RETURN(rc);
1737 }
1738
1739 void mdt_tunables_fini(struct mdt_device *mdt)
1740 {
1741         struct obd_device *obd = mdt2obd_dev(mdt);
1742
1743         if (obd->obd_proc_exports_entry != NULL) {
1744                 lprocfs_remove_proc_entry("clear", obd->obd_proc_exports_entry);
1745                 obd->obd_proc_exports_entry = NULL;
1746         }
1747
1748         lprocfs_free_per_client_stats(obd);
1749         /* hsm_cdt_tunables is disabled earlier than this to avoid
1750          * coordinator restart.
1751          */
1752         hsm_cdt_tunables_fini(mdt);
1753         tgt_tunables_fini(&mdt->mdt_lut);
1754         lprocfs_obd_cleanup(obd);
1755         lprocfs_free_md_stats(obd);
1756         lprocfs_free_obd_stats(obd);
1757         lprocfs_job_stats_fini(obd);
1758 }