Whamcloud - gitweb
LU-10681: Disable tiny writes for append
[fs/lustre-release.git] / lustre / llite / lproc_llite.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) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2012, 2017, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Sun Microsystems, Inc.
31  */
32 #define DEBUG_SUBSYSTEM S_LLITE
33
34 #include <linux/version.h>
35 #include <linux/user_namespace.h>
36 #ifdef HAVE_UIDGID_HEADER
37 # include <linux/uidgid.h>
38 #endif
39 #include <uapi/linux/lustre/lustre_param.h>
40 #include <lprocfs_status.h>
41 #include <obd_support.h>
42
43 #include "llite_internal.h"
44 #include "vvp_internal.h"
45
46 struct proc_dir_entry *proc_lustre_fs_root;
47
48 #ifdef CONFIG_PROC_FS
49 /* /proc/lustre/llite mount point registration */
50 static const struct file_operations ll_rw_extents_stats_fops;
51 static const struct file_operations ll_rw_extents_stats_pp_fops;
52 static const struct file_operations ll_rw_offset_stats_fops;
53 static __s64 ll_stats_pid_write(const char __user *buf, size_t len);
54
55 static int ll_blksize_seq_show(struct seq_file *m, void *v)
56 {
57         struct super_block *sb = m->private;
58         struct obd_statfs osfs;
59         int rc;
60
61         LASSERT(sb != NULL);
62         rc = ll_statfs_internal(sb, &osfs, OBD_STATFS_NODELAY);
63         if (!rc)
64                 seq_printf(m, "%u\n", osfs.os_bsize);
65         return rc;
66 }
67 LPROC_SEQ_FOPS_RO(ll_blksize);
68
69 static int ll_stat_blksize_seq_show(struct seq_file *m, void *v)
70 {
71         struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)m->private);
72
73         seq_printf(m, "%u\n", sbi->ll_stat_blksize);
74
75         return 0;
76 }
77
78 static ssize_t ll_stat_blksize_seq_write(struct file *file,
79                                          const char __user *buffer,
80                                          size_t count, loff_t *off)
81 {
82         struct seq_file *m = file->private_data;
83         struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)m->private);
84         unsigned int val;
85         int rc;
86
87         rc = kstrtouint_from_user(buffer, count, 0, &val);
88         if (rc)
89                 return rc;
90
91         if (val != 0 && (val < PAGE_SIZE || (val & (val - 1))) != 0)
92                 return -ERANGE;
93
94         sbi->ll_stat_blksize = val;
95
96         return count;
97 }
98 LPROC_SEQ_FOPS(ll_stat_blksize);
99
100 static int ll_kbytestotal_seq_show(struct seq_file *m, void *v)
101 {
102         struct super_block *sb = m->private;
103         struct obd_statfs osfs;
104         int rc;
105
106         LASSERT(sb != NULL);
107         rc = ll_statfs_internal(sb, &osfs, OBD_STATFS_NODELAY);
108         if (!rc) {
109                 __u32 blk_size = osfs.os_bsize >> 10;
110                 __u64 result = osfs.os_blocks;
111
112                 while (blk_size >>= 1)
113                         result <<= 1;
114
115                 seq_printf(m, "%llu\n", result);
116         }
117         return rc;
118 }
119 LPROC_SEQ_FOPS_RO(ll_kbytestotal);
120
121 static int ll_kbytesfree_seq_show(struct seq_file *m, void *v)
122 {
123         struct super_block *sb = m->private;
124         struct obd_statfs osfs;
125         int rc;
126
127         LASSERT(sb != NULL);
128         rc = ll_statfs_internal(sb, &osfs, OBD_STATFS_NODELAY);
129         if (!rc) {
130                 __u32 blk_size = osfs.os_bsize >> 10;
131                 __u64 result = osfs.os_bfree;
132
133                 while (blk_size >>= 1)
134                         result <<= 1;
135
136                 seq_printf(m, "%llu\n", result);
137         }
138         return rc;
139 }
140 LPROC_SEQ_FOPS_RO(ll_kbytesfree);
141
142 static int ll_kbytesavail_seq_show(struct seq_file *m, void *v)
143 {
144         struct super_block *sb = m->private;
145         struct obd_statfs osfs;
146         int rc;
147
148         LASSERT(sb != NULL);
149         rc = ll_statfs_internal(sb, &osfs, OBD_STATFS_NODELAY);
150         if (!rc) {
151                 __u32 blk_size = osfs.os_bsize >> 10;
152                 __u64 result = osfs.os_bavail;
153
154                 while (blk_size >>= 1)
155                         result <<= 1;
156
157                 seq_printf(m, "%llu\n", result);
158         }
159         return rc;
160 }
161 LPROC_SEQ_FOPS_RO(ll_kbytesavail);
162
163 static int ll_filestotal_seq_show(struct seq_file *m, void *v)
164 {
165         struct super_block *sb = m->private;
166         struct obd_statfs osfs;
167         int rc;
168
169         LASSERT(sb != NULL);
170         rc = ll_statfs_internal(sb, &osfs, OBD_STATFS_NODELAY);
171         if (!rc)
172                 seq_printf(m, "%llu\n", osfs.os_files);
173         return rc;
174 }
175 LPROC_SEQ_FOPS_RO(ll_filestotal);
176
177 static int ll_filesfree_seq_show(struct seq_file *m, void *v)
178 {
179         struct super_block *sb = m->private;
180         struct obd_statfs osfs;
181         int rc;
182
183         LASSERT(sb != NULL);
184         rc = ll_statfs_internal(sb, &osfs, OBD_STATFS_NODELAY);
185         if (!rc)
186                 seq_printf(m, "%llu\n", osfs.os_ffree);
187         return rc;
188 }
189 LPROC_SEQ_FOPS_RO(ll_filesfree);
190
191 static int ll_client_type_seq_show(struct seq_file *m, void *v)
192 {
193         struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)m->private);
194
195         LASSERT(sbi != NULL);
196
197         seq_puts(m, "local client\n");
198         return 0;
199 }
200 LPROC_SEQ_FOPS_RO(ll_client_type);
201
202 static int ll_fstype_seq_show(struct seq_file *m, void *v)
203 {
204         struct super_block *sb = m->private;
205
206         LASSERT(sb != NULL);
207         seq_printf(m, "%s\n", sb->s_type->name);
208         return 0;
209 }
210 LPROC_SEQ_FOPS_RO(ll_fstype);
211
212 static int ll_sb_uuid_seq_show(struct seq_file *m, void *v)
213 {
214         struct super_block *sb = m->private;
215
216         LASSERT(sb != NULL);
217         seq_printf(m, "%s\n", ll_s2sbi(sb)->ll_sb_uuid.uuid);
218         return 0;
219 }
220 LPROC_SEQ_FOPS_RO(ll_sb_uuid);
221
222 static int ll_xattr_cache_seq_show(struct seq_file *m, void *v)
223 {
224         struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)m->private);
225
226         seq_printf(m, "%u\n", sbi->ll_xattr_cache_enabled);
227         return 0;
228 }
229
230 static ssize_t ll_xattr_cache_seq_write(struct file *file,
231                                         const char __user *buffer,
232                                         size_t count, loff_t *off)
233 {
234         struct seq_file *m = file->private_data;
235         struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)m->private);
236         bool val;
237         int rc;
238
239         rc = kstrtobool_from_user(buffer, count, &val);
240         if (rc)
241                 return rc;
242
243         if (val && !(sbi->ll_flags & LL_SBI_XATTR_CACHE))
244                 return -ENOTSUPP;
245
246         sbi->ll_xattr_cache_enabled = val;
247         sbi->ll_xattr_cache_set = 1;
248
249         return count;
250 }
251 LPROC_SEQ_FOPS(ll_xattr_cache);
252
253 static int ll_site_stats_seq_show(struct seq_file *m, void *v)
254 {
255         struct super_block *sb = m->private;
256
257         /*
258          * See description of statistical counters in struct cl_site, and
259          * struct lu_site.
260          */
261         return cl_site_stats_print(lu2cl_site(ll_s2sbi(sb)->ll_site), m);
262 }
263 LPROC_SEQ_FOPS_RO(ll_site_stats);
264
265 static int ll_max_readahead_mb_seq_show(struct seq_file *m, void *v)
266 {
267         struct super_block *sb = m->private;
268         struct ll_sb_info *sbi = ll_s2sbi(sb);
269         long pages_number;
270         int mult;
271
272         spin_lock(&sbi->ll_lock);
273         pages_number = sbi->ll_ra_info.ra_max_pages;
274         spin_unlock(&sbi->ll_lock);
275
276         mult = 1 << (20 - PAGE_SHIFT);
277         return lprocfs_seq_read_frac_helper(m, pages_number, mult);
278 }
279
280 static ssize_t
281 ll_max_readahead_mb_seq_write(struct file *file, const char __user *buffer,
282                               size_t count, loff_t *off)
283 {
284         struct seq_file *m = file->private_data;
285         struct super_block *sb = m->private;
286         struct ll_sb_info *sbi = ll_s2sbi(sb);
287         __s64 pages_number;
288         int rc;
289
290         rc = lprocfs_str_with_units_to_s64(buffer, count, &pages_number, 'M');
291         if (rc)
292                 return rc;
293
294         pages_number >>= PAGE_SHIFT;
295
296         if (pages_number < 0 || pages_number > totalram_pages / 2) {
297                 /* 1/2 of RAM */
298                 CERROR("%s: can't set max_readahead_mb=%lu > %luMB\n",
299                        ll_get_fsname(sb, NULL, 0),
300                        (unsigned long)pages_number >> (20 - PAGE_SHIFT),
301                        totalram_pages >> (20 - PAGE_SHIFT + 1));
302                 return -ERANGE;
303         }
304
305         spin_lock(&sbi->ll_lock);
306         sbi->ll_ra_info.ra_max_pages = pages_number;
307         spin_unlock(&sbi->ll_lock);
308         return count;
309 }
310 LPROC_SEQ_FOPS(ll_max_readahead_mb);
311
312 static int ll_max_readahead_per_file_mb_seq_show(struct seq_file *m, void *v)
313 {
314         struct super_block *sb = m->private;
315         struct ll_sb_info *sbi = ll_s2sbi(sb);
316         long pages_number;
317         int mult;
318
319         spin_lock(&sbi->ll_lock);
320         pages_number = sbi->ll_ra_info.ra_max_pages_per_file;
321         spin_unlock(&sbi->ll_lock);
322
323         mult = 1 << (20 - PAGE_SHIFT);
324         return lprocfs_seq_read_frac_helper(m, pages_number, mult);
325 }
326
327 static ssize_t
328 ll_max_readahead_per_file_mb_seq_write(struct file *file,
329                                        const char __user *buffer,
330                                        size_t count, loff_t *off)
331 {
332         struct seq_file *m = file->private_data;
333         struct super_block *sb = m->private;
334         struct ll_sb_info *sbi = ll_s2sbi(sb);
335         int rc;
336         __s64 pages_number;
337
338         rc = lprocfs_str_with_units_to_s64(buffer, count, &pages_number, 'M');
339         if (rc)
340                 return rc;
341
342         pages_number >>= PAGE_SHIFT;
343
344         if (pages_number < 0 || pages_number > sbi->ll_ra_info.ra_max_pages) {
345                 CERROR("%s: can't set max_readahead_per_file_mb=%lu > "
346                        "max_read_ahead_mb=%lu\n", ll_get_fsname(sb, NULL, 0),
347                        (unsigned long)pages_number >> (20 - PAGE_SHIFT),
348                        sbi->ll_ra_info.ra_max_pages >> (20 - PAGE_SHIFT));
349                 return -ERANGE;
350         }
351
352         spin_lock(&sbi->ll_lock);
353         sbi->ll_ra_info.ra_max_pages_per_file = pages_number;
354         spin_unlock(&sbi->ll_lock);
355         return count;
356 }
357 LPROC_SEQ_FOPS(ll_max_readahead_per_file_mb);
358
359 static int ll_max_read_ahead_whole_mb_seq_show(struct seq_file *m, void *v)
360 {
361         struct super_block *sb = m->private;
362         struct ll_sb_info *sbi = ll_s2sbi(sb);
363         long pages_number;
364         int mult;
365
366         spin_lock(&sbi->ll_lock);
367         pages_number = sbi->ll_ra_info.ra_max_read_ahead_whole_pages;
368         spin_unlock(&sbi->ll_lock);
369
370         mult = 1 << (20 - PAGE_SHIFT);
371         return lprocfs_seq_read_frac_helper(m, pages_number, mult);
372 }
373
374 static ssize_t
375 ll_max_read_ahead_whole_mb_seq_write(struct file *file,
376                                      const char __user *buffer,
377                                      size_t count, loff_t *off)
378 {
379         struct seq_file *m = file->private_data;
380         struct super_block *sb = m->private;
381         struct ll_sb_info *sbi = ll_s2sbi(sb);
382         int rc;
383         __s64 pages_number;
384
385         rc = lprocfs_str_with_units_to_s64(buffer, count, &pages_number, 'M');
386         if (rc)
387                 return rc;
388
389         pages_number >>= PAGE_SHIFT;
390
391         /* Cap this at the current max readahead window size, the readahead
392          * algorithm does this anyway so it's pointless to set it larger. */
393         if (pages_number < 0 ||
394             pages_number > sbi->ll_ra_info.ra_max_pages_per_file) {
395                 int pages_shift = 20 - PAGE_SHIFT;
396                 CERROR("%s: can't set max_read_ahead_whole_mb=%lu > "
397                        "max_read_ahead_per_file_mb=%lu\n",
398                        ll_get_fsname(sb, NULL, 0),
399                        (unsigned long)pages_number >> pages_shift,
400                        sbi->ll_ra_info.ra_max_pages_per_file >> pages_shift);
401                 return -ERANGE;
402         }
403
404         spin_lock(&sbi->ll_lock);
405         sbi->ll_ra_info.ra_max_read_ahead_whole_pages = pages_number;
406         spin_unlock(&sbi->ll_lock);
407         return count;
408 }
409 LPROC_SEQ_FOPS(ll_max_read_ahead_whole_mb);
410
411 static int ll_max_cached_mb_seq_show(struct seq_file *m, void *v)
412 {
413         struct super_block     *sb    = m->private;
414         struct ll_sb_info      *sbi   = ll_s2sbi(sb);
415         struct cl_client_cache *cache = sbi->ll_cache;
416         int shift = 20 - PAGE_SHIFT;
417         long max_cached_mb;
418         long unused_mb;
419
420         max_cached_mb = cache->ccc_lru_max >> shift;
421         unused_mb = atomic_long_read(&cache->ccc_lru_left) >> shift;
422         seq_printf(m, "users: %d\n"
423                    "max_cached_mb: %ld\n"
424                    "used_mb: %ld\n"
425                    "unused_mb: %ld\n"
426                    "reclaim_count: %u\n",
427                    atomic_read(&cache->ccc_users),
428                    max_cached_mb,
429                    max_cached_mb - unused_mb,
430                    unused_mb,
431                    cache->ccc_lru_shrinkers);
432         return 0;
433 }
434
435 static ssize_t
436 ll_max_cached_mb_seq_write(struct file *file, const char __user *buffer,
437                            size_t count, loff_t *off)
438 {
439         struct seq_file *m = file->private_data;
440         struct super_block *sb = m->private;
441         struct ll_sb_info *sbi = ll_s2sbi(sb);
442         struct cl_client_cache *cache = sbi->ll_cache;
443         struct lu_env *env;
444         long diff = 0;
445         long nrpages = 0;
446         __u16 refcheck;
447         __s64 pages_number;
448         long rc;
449         char kernbuf[128];
450         ENTRY;
451
452         if (count >= sizeof(kernbuf))
453                 RETURN(-EINVAL);
454
455         if (copy_from_user(kernbuf, buffer, count))
456                 RETURN(-EFAULT);
457         kernbuf[count] = 0;
458
459         buffer += lprocfs_find_named_value(kernbuf, "max_cached_mb:", &count) -
460                   kernbuf;
461         rc = lprocfs_str_with_units_to_s64(buffer, count, &pages_number, 'M');
462         if (rc)
463                 RETURN(rc);
464
465         pages_number >>= PAGE_SHIFT;
466
467         if (pages_number < 0 || pages_number > totalram_pages) {
468                 CERROR("%s: can't set max cache more than %lu MB\n",
469                        ll_get_fsname(sb, NULL, 0),
470                        totalram_pages >> (20 - PAGE_SHIFT));
471                 RETURN(-ERANGE);
472         }
473         /* Allow enough cache so clients can make well-formed RPCs */
474         pages_number = max_t(long, pages_number, PTLRPC_MAX_BRW_PAGES);
475
476         spin_lock(&sbi->ll_lock);
477         diff = pages_number - cache->ccc_lru_max;
478         spin_unlock(&sbi->ll_lock);
479
480         /* easy - add more LRU slots. */
481         if (diff >= 0) {
482                 atomic_long_add(diff, &cache->ccc_lru_left);
483                 GOTO(out, rc = 0);
484         }
485
486         env = cl_env_get(&refcheck);
487         if (IS_ERR(env))
488                 RETURN(rc);
489
490         diff = -diff;
491         while (diff > 0) {
492                 long tmp;
493
494                 /* reduce LRU budget from free slots. */
495                 do {
496                         long ov, nv;
497
498                         ov = atomic_long_read(&cache->ccc_lru_left);
499                         if (ov == 0)
500                                 break;
501
502                         nv = ov > diff ? ov - diff : 0;
503                         rc = atomic_long_cmpxchg(&cache->ccc_lru_left, ov, nv);
504                         if (likely(ov == rc)) {
505                                 diff -= ov - nv;
506                                 nrpages += ov - nv;
507                                 break;
508                         }
509                 } while (1);
510
511                 if (diff <= 0)
512                         break;
513
514                 if (sbi->ll_dt_exp == NULL) { /* being initialized */
515                         rc = -ENODEV;
516                         break;
517                 }
518
519                 /* difficult - have to ask OSCs to drop LRU slots. */
520                 tmp = diff << 1;
521                 rc = obd_set_info_async(env, sbi->ll_dt_exp,
522                                 sizeof(KEY_CACHE_LRU_SHRINK),
523                                 KEY_CACHE_LRU_SHRINK,
524                                 sizeof(tmp), &tmp, NULL);
525                 if (rc < 0)
526                         break;
527         }
528         cl_env_put(env, &refcheck);
529
530 out:
531         if (rc >= 0) {
532                 spin_lock(&sbi->ll_lock);
533                 cache->ccc_lru_max = pages_number;
534                 spin_unlock(&sbi->ll_lock);
535                 rc = count;
536         } else {
537                 atomic_long_add(nrpages, &cache->ccc_lru_left);
538         }
539         return rc;
540 }
541 LPROC_SEQ_FOPS(ll_max_cached_mb);
542
543 static int ll_checksum_seq_show(struct seq_file *m, void *v)
544 {
545         struct super_block *sb = m->private;
546         struct ll_sb_info *sbi = ll_s2sbi(sb);
547
548         seq_printf(m, "%u\n", (sbi->ll_flags & LL_SBI_CHECKSUM) ? 1 : 0);
549         return 0;
550 }
551
552 static ssize_t ll_checksum_seq_write(struct file *file,
553                                      const char __user *buffer,
554                                      size_t count, loff_t *off)
555 {
556         struct seq_file *m = file->private_data;
557         struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)m->private);
558         bool val;
559         int tmp;
560         int rc;
561
562         if (!sbi->ll_dt_exp)
563                 /* Not set up yet */
564                 return -EAGAIN;
565
566         rc = kstrtobool_from_user(buffer, count, &val);
567         if (rc)
568                 return rc;
569         if (val)
570                 sbi->ll_flags |= LL_SBI_CHECKSUM;
571         else
572                 sbi->ll_flags &= ~LL_SBI_CHECKSUM;
573         tmp = val;
574
575         rc = obd_set_info_async(NULL, sbi->ll_dt_exp, sizeof(KEY_CHECKSUM),
576                                 KEY_CHECKSUM, sizeof(tmp), &tmp, NULL);
577         if (rc)
578                 CWARN("Failed to set OSC checksum flags: %d\n", rc);
579
580         return count;
581 }
582 LPROC_SEQ_FOPS(ll_checksum);
583
584 static int ll_rd_track_id(struct seq_file *m, enum stats_track_type type)
585 {
586         struct super_block *sb = m->private;
587
588         if (ll_s2sbi(sb)->ll_stats_track_type == type) {
589                 seq_printf(m, "%d\n",
590                            ll_s2sbi(sb)->ll_stats_track_id);
591         } else if (ll_s2sbi(sb)->ll_stats_track_type == STATS_TRACK_ALL) {
592                 seq_puts(m, "0 (all)\n");
593         } else {
594                 seq_puts(m, "untracked\n");
595         }
596         return 0;
597 }
598
599 static int ll_wr_track_id(const char __user *buffer, unsigned long count,
600                           void *data, enum stats_track_type type)
601 {
602         struct super_block *sb = data;
603         unsigned int pid;
604         int rc;
605
606         rc = kstrtouint_from_user(buffer, count, 0, &pid);
607         if (rc)
608                 return rc;
609
610         ll_s2sbi(sb)->ll_stats_track_id = pid;
611         if (pid == 0)
612                 ll_s2sbi(sb)->ll_stats_track_type = STATS_TRACK_ALL;
613         else
614                 ll_s2sbi(sb)->ll_stats_track_type = type;
615         lprocfs_clear_stats(ll_s2sbi(sb)->ll_stats);
616         return count;
617 }
618
619 static int ll_track_pid_seq_show(struct seq_file *m, void *v)
620 {
621         return ll_rd_track_id(m, STATS_TRACK_PID);
622 }
623
624 static ssize_t ll_track_pid_seq_write(struct file *file,
625                                       const char __user *buffer,
626                                       size_t count, loff_t *off)
627 {
628         struct seq_file *seq = file->private_data;
629         return ll_wr_track_id(buffer, count, seq->private, STATS_TRACK_PID);
630 }
631 LPROC_SEQ_FOPS(ll_track_pid);
632
633 static int ll_track_ppid_seq_show(struct seq_file *m, void *v)
634 {
635         return ll_rd_track_id(m, STATS_TRACK_PPID);
636 }
637
638 static ssize_t ll_track_ppid_seq_write(struct file *file,
639                                        const char __user *buffer,
640                                        size_t count, loff_t *off)
641 {
642         struct seq_file *seq = file->private_data;
643         return ll_wr_track_id(buffer, count, seq->private, STATS_TRACK_PPID);
644 }
645 LPROC_SEQ_FOPS(ll_track_ppid);
646
647 static int ll_track_gid_seq_show(struct seq_file *m, void *v)
648 {
649         return ll_rd_track_id(m, STATS_TRACK_GID);
650 }
651
652 static ssize_t ll_track_gid_seq_write(struct file *file,
653                                       const char __user *buffer,
654                                       size_t count, loff_t *off)
655 {
656         struct seq_file *seq = file->private_data;
657         return ll_wr_track_id(buffer, count, seq->private, STATS_TRACK_GID);
658 }
659 LPROC_SEQ_FOPS(ll_track_gid);
660
661 static int ll_statahead_max_seq_show(struct seq_file *m, void *v)
662 {
663         struct super_block *sb = m->private;
664         struct ll_sb_info *sbi = ll_s2sbi(sb);
665
666         seq_printf(m, "%u\n", sbi->ll_sa_max);
667         return 0;
668 }
669
670 static ssize_t ll_statahead_max_seq_write(struct file *file,
671                                           const char __user *buffer,
672                                           size_t count, loff_t *off)
673 {
674         struct seq_file *m = file->private_data;
675         struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)m->private);
676         unsigned int val;
677         int rc;
678
679         rc = kstrtouint_from_user(buffer, count, 0, &val);
680         if (rc)
681                 return rc;
682
683         if (val <= LL_SA_RPC_MAX)
684                 sbi->ll_sa_max = val;
685         else
686                 CERROR("Bad statahead_max value %u. Valid values are in "
687                        "the range [0, %d]\n", val, LL_SA_RPC_MAX);
688
689         return count;
690 }
691 LPROC_SEQ_FOPS(ll_statahead_max);
692
693 static int ll_statahead_agl_seq_show(struct seq_file *m, void *v)
694 {
695         struct super_block *sb = m->private;
696         struct ll_sb_info *sbi = ll_s2sbi(sb);
697
698         seq_printf(m, "%u\n",
699                    sbi->ll_flags & LL_SBI_AGL_ENABLED ? 1 : 0);
700         return 0;
701 }
702
703 static ssize_t ll_statahead_agl_seq_write(struct file *file,
704                                           const char __user *buffer,
705                                           size_t count, loff_t *off)
706 {
707         struct seq_file *m = file->private_data;
708         struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)m->private);
709         bool val;
710         int rc;
711
712         rc = kstrtobool_from_user(buffer, count, &val);
713         if (rc)
714                 return rc;
715
716         if (val)
717                 sbi->ll_flags |= LL_SBI_AGL_ENABLED;
718         else
719                 sbi->ll_flags &= ~LL_SBI_AGL_ENABLED;
720
721         return count;
722 }
723 LPROC_SEQ_FOPS(ll_statahead_agl);
724
725 static int ll_statahead_stats_seq_show(struct seq_file *m, void *v)
726 {
727         struct super_block *sb = m->private;
728         struct ll_sb_info *sbi = ll_s2sbi(sb);
729
730         seq_printf(m, "statahead total: %u\n"
731                     "statahead wrong: %u\n"
732                     "agl total: %u\n",
733                     atomic_read(&sbi->ll_sa_total),
734                     atomic_read(&sbi->ll_sa_wrong),
735                     atomic_read(&sbi->ll_agl_total));
736         return 0;
737 }
738 LPROC_SEQ_FOPS_RO(ll_statahead_stats);
739
740 static int ll_lazystatfs_seq_show(struct seq_file *m, void *v)
741 {
742         struct super_block *sb = m->private;
743         struct ll_sb_info *sbi = ll_s2sbi(sb);
744
745         seq_printf(m, "%u\n",
746                    (sbi->ll_flags & LL_SBI_LAZYSTATFS) ? 1 : 0);
747         return 0;
748 }
749
750 static ssize_t ll_lazystatfs_seq_write(struct file *file,
751                                        const char __user *buffer,
752                                         size_t count, loff_t *off)
753 {
754         struct seq_file *m = file->private_data;
755         struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)m->private);
756         bool val;
757         int rc;
758
759         rc = kstrtobool_from_user(buffer, count, &val);
760         if (rc)
761                 return rc;
762
763         if (val)
764                 sbi->ll_flags |= LL_SBI_LAZYSTATFS;
765         else
766                 sbi->ll_flags &= ~LL_SBI_LAZYSTATFS;
767
768         return count;
769 }
770 LPROC_SEQ_FOPS(ll_lazystatfs);
771
772 static int ll_max_easize_seq_show(struct seq_file *m, void *v)
773 {
774         struct super_block *sb = m->private;
775         struct ll_sb_info *sbi = ll_s2sbi(sb);
776         unsigned int ealen;
777         int rc;
778
779         rc = ll_get_max_mdsize(sbi, &ealen);
780         if (rc)
781                 return rc;
782
783         seq_printf(m, "%u\n", ealen);
784         return 0;
785 }
786 LPROC_SEQ_FOPS_RO(ll_max_easize);
787
788 /**
789  * Get default_easize.
790  *
791  * \see client_obd::cl_default_mds_easize
792  *
793  * \param[in] m         seq_file handle
794  * \param[in] v         unused for single entry
795  *
796  * \retval 0            on success
797  * \retval negative     negated errno on failure
798  */
799 static int ll_default_easize_seq_show(struct seq_file *m, void *v)
800 {
801         struct super_block *sb = m->private;
802         struct ll_sb_info *sbi = ll_s2sbi(sb);
803         unsigned int ealen;
804         int rc;
805
806         rc = ll_get_default_mdsize(sbi, &ealen);
807         if (rc)
808                 return rc;
809
810         seq_printf(m, "%u\n", ealen);
811         return 0;
812 }
813
814 /**
815  * Set default_easize.
816  *
817  * Range checking on the passed value is handled by
818  * ll_set_default_mdsize().
819  *
820  * \see client_obd::cl_default_mds_easize
821  *
822  * \param[in] file      proc file
823  * \param[in] buffer    string passed from user space
824  * \param[in] count     \a buffer length
825  * \param[in] off       unused for single entry
826  *
827  * \retval positive     \a count on success
828  * \retval negative     negated errno on failure
829  */
830 static ssize_t ll_default_easize_seq_write(struct file *file,
831                                            const char __user *buffer,
832                                            size_t count, loff_t *unused)
833 {
834         struct seq_file *seq = file->private_data;
835         struct super_block *sb = (struct super_block *)seq->private;
836         struct ll_sb_info *sbi = ll_s2sbi(sb);
837         unsigned int val;
838         int rc;
839
840         if (count == 0)
841                 return 0;
842
843         rc = kstrtouint_from_user(buffer, count, 0, &val);
844         if (rc)
845                 return rc;
846
847         rc = ll_set_default_mdsize(sbi, val);
848         if (rc)
849                 return rc;
850
851         return count;
852 }
853 LPROC_SEQ_FOPS(ll_default_easize);
854
855 static int ll_sbi_flags_seq_show(struct seq_file *m, void *v)
856 {
857         const char *str[] = LL_SBI_FLAGS;
858         struct super_block *sb = m->private;
859         int flags = ll_s2sbi(sb)->ll_flags;
860         int i = 0;
861
862         while (flags != 0) {
863                 if (ARRAY_SIZE(str) <= i) {
864                         CERROR("%s: Revise array LL_SBI_FLAGS to match sbi "
865                                 "flags please.\n", ll_get_fsname(sb, NULL, 0));
866                         return -EINVAL;
867                 }
868
869                 if (flags & 0x1)
870                         seq_printf(m, "%s ", str[i]);
871                 flags >>= 1;
872                 ++i;
873         }
874         seq_printf(m, "\b\n");
875         return 0;
876 }
877 LPROC_SEQ_FOPS_RO(ll_sbi_flags);
878
879 static int ll_tiny_write_seq_show(struct seq_file *m, void *v)
880 {
881         struct super_block *sb = m->private;
882         struct ll_sb_info *sbi = ll_s2sbi(sb);
883
884         seq_printf(m, "%u\n", !!(sbi->ll_flags & LL_SBI_TINY_WRITE));
885         return 0;
886 }
887
888 static ssize_t ll_tiny_write_seq_write(
889         struct file *file, const char __user *buffer, size_t count, loff_t *off)
890 {
891         struct seq_file *m = file->private_data;
892         struct super_block *sb = m->private;
893         struct ll_sb_info *sbi = ll_s2sbi(sb);
894         bool val;
895         int rc;
896
897         rc = kstrtobool_from_user(buffer, count, &val);
898         if (rc)
899                 return rc;
900
901         spin_lock(&sbi->ll_lock);
902         if (val)
903                 sbi->ll_flags |= LL_SBI_TINY_WRITE;
904         else
905                 sbi->ll_flags &= ~LL_SBI_TINY_WRITE;
906         spin_unlock(&sbi->ll_lock);
907
908         return count;
909 }
910 LPROC_SEQ_FOPS(ll_tiny_write);
911
912 static int ll_fast_read_seq_show(struct seq_file *m, void *v)
913 {
914         struct super_block *sb = m->private;
915         struct ll_sb_info *sbi = ll_s2sbi(sb);
916
917         seq_printf(m, "%u\n", !!(sbi->ll_flags & LL_SBI_FAST_READ));
918         return 0;
919 }
920
921 static ssize_t
922 ll_fast_read_seq_write(struct file *file, const char __user *buffer,
923                        size_t count, loff_t *off)
924 {
925         struct seq_file *m = file->private_data;
926         struct super_block *sb = m->private;
927         struct ll_sb_info *sbi = ll_s2sbi(sb);
928         bool val;
929         int rc;
930
931         rc = kstrtobool_from_user(buffer, count, &val);
932         if (rc)
933                 return rc;
934
935         spin_lock(&sbi->ll_lock);
936         if (val)
937                 sbi->ll_flags |= LL_SBI_FAST_READ;
938         else
939                 sbi->ll_flags &= ~LL_SBI_FAST_READ;
940         spin_unlock(&sbi->ll_lock);
941
942         return count;
943 }
944 LPROC_SEQ_FOPS(ll_fast_read);
945
946 static int ll_pio_seq_show(struct seq_file *m, void *v)
947 {
948         struct super_block *sb = m->private;
949         struct ll_sb_info *sbi = ll_s2sbi(sb);
950
951         seq_printf(m, "%u\n", !!(sbi->ll_flags & LL_SBI_PIO));
952         return 0;
953 }
954
955 static ssize_t ll_pio_seq_write(struct file *file, const char __user *buffer,
956                                 size_t count, loff_t *off)
957 {
958         struct seq_file *m = file->private_data;
959         struct super_block *sb = m->private;
960         struct ll_sb_info *sbi = ll_s2sbi(sb);
961         bool val;
962         int rc;
963
964         rc = kstrtobool_from_user(buffer, count, &val);
965         if (rc)
966                 return rc;
967
968         spin_lock(&sbi->ll_lock);
969         if (val)
970                 sbi->ll_flags |= LL_SBI_PIO;
971         else
972                 sbi->ll_flags &= ~LL_SBI_PIO;
973         spin_unlock(&sbi->ll_lock);
974
975         return count;
976 }
977 LPROC_SEQ_FOPS(ll_pio);
978
979 static int ll_unstable_stats_seq_show(struct seq_file *m, void *v)
980 {
981         struct super_block      *sb    = m->private;
982         struct ll_sb_info       *sbi   = ll_s2sbi(sb);
983         struct cl_client_cache  *cache = sbi->ll_cache;
984         long pages;
985         int mb;
986
987         pages = atomic_long_read(&cache->ccc_unstable_nr);
988         mb    = (pages * PAGE_SIZE) >> 20;
989
990         seq_printf(m, "unstable_check:     %8d\n"
991                    "unstable_pages: %12ld\n"
992                    "unstable_mb:        %8d\n",
993                    cache->ccc_unstable_check, pages, mb);
994         return 0;
995 }
996
997 static ssize_t ll_unstable_stats_seq_write(struct file *file,
998                                            const char __user *buffer,
999                                            size_t count, loff_t *unused)
1000 {
1001         struct seq_file *seq = file->private_data;
1002         struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)seq->private);
1003         char kernbuf[128];
1004         bool val;
1005         int rc;
1006
1007         if (count == 0)
1008                 return 0;
1009         if (count >= sizeof(kernbuf))
1010                 return -EINVAL;
1011
1012         if (copy_from_user(kernbuf, buffer, count))
1013                 return -EFAULT;
1014         kernbuf[count] = 0;
1015
1016         buffer += lprocfs_find_named_value(kernbuf, "unstable_check:", &count) -
1017                   kernbuf;
1018         rc = kstrtobool_from_user(buffer, count, &val);
1019         if (rc < 0)
1020                 return rc;
1021
1022         /* borrow lru lock to set the value */
1023         spin_lock(&sbi->ll_cache->ccc_lru_lock);
1024         sbi->ll_cache->ccc_unstable_check = val;
1025         spin_unlock(&sbi->ll_cache->ccc_lru_lock);
1026
1027         return count;
1028 }
1029 LPROC_SEQ_FOPS(ll_unstable_stats);
1030
1031 static int ll_root_squash_seq_show(struct seq_file *m, void *v)
1032 {
1033         struct super_block *sb = m->private;
1034         struct ll_sb_info *sbi = ll_s2sbi(sb);
1035         struct root_squash_info *squash = &sbi->ll_squash;
1036
1037         seq_printf(m, "%u:%u\n", squash->rsi_uid, squash->rsi_gid);
1038         return 0;
1039 }
1040
1041 static ssize_t ll_root_squash_seq_write(struct file *file,
1042                                         const char __user *buffer,
1043                                         size_t count, loff_t *off)
1044 {
1045         struct seq_file *m = file->private_data;
1046         struct super_block *sb = m->private;
1047         struct ll_sb_info *sbi = ll_s2sbi(sb);
1048         struct root_squash_info *squash = &sbi->ll_squash;
1049
1050         return lprocfs_wr_root_squash(buffer, count, squash,
1051                                       ll_get_fsname(sb, NULL, 0));
1052 }
1053 LPROC_SEQ_FOPS(ll_root_squash);
1054
1055 static int ll_nosquash_nids_seq_show(struct seq_file *m, void *v)
1056 {
1057         struct super_block *sb = m->private;
1058         struct ll_sb_info *sbi = ll_s2sbi(sb);
1059         struct root_squash_info *squash = &sbi->ll_squash;
1060         int len;
1061
1062         down_read(&squash->rsi_sem);
1063         if (!list_empty(&squash->rsi_nosquash_nids)) {
1064                 len = cfs_print_nidlist(m->buf + m->count, m->size - m->count,
1065                                         &squash->rsi_nosquash_nids);
1066                 m->count += len;
1067                 seq_putc(m, '\n');
1068         } else {
1069                 seq_puts(m, "NONE\n");
1070         }
1071         up_read(&squash->rsi_sem);
1072
1073         return 0;
1074 }
1075
1076 static ssize_t ll_nosquash_nids_seq_write(struct file *file,
1077                                           const char __user *buffer,
1078                                           size_t count, loff_t *off)
1079 {
1080         struct seq_file *m = file->private_data;
1081         struct super_block *sb = m->private;
1082         struct ll_sb_info *sbi = ll_s2sbi(sb);
1083         struct root_squash_info *squash = &sbi->ll_squash;
1084         int rc;
1085
1086         rc = lprocfs_wr_nosquash_nids(buffer, count, squash,
1087                                       ll_get_fsname(sb, NULL, 0));
1088         if (rc < 0)
1089                 return rc;
1090
1091         ll_compute_rootsquash_state(sbi);
1092
1093         return rc;
1094 }
1095 LPROC_SEQ_FOPS(ll_nosquash_nids);
1096
1097 struct lprocfs_vars lprocfs_llite_obd_vars[] = {
1098         { .name =       "uuid",
1099           .fops =       &ll_sb_uuid_fops                        },
1100         { .name =       "fstype",
1101           .fops =       &ll_fstype_fops                         },
1102         { .name =       "site",
1103           .fops =       &ll_site_stats_fops                     },
1104         { .name =       "blocksize",
1105           .fops =       &ll_blksize_fops                        },
1106         { .name =       "stat_blocksize",
1107           .fops =       &ll_stat_blksize_fops                   },
1108         { .name =       "kbytestotal",
1109           .fops =       &ll_kbytestotal_fops                    },
1110         { .name =       "kbytesfree",
1111           .fops =       &ll_kbytesfree_fops                     },
1112         { .name =       "kbytesavail",
1113           .fops =       &ll_kbytesavail_fops                    },
1114         { .name =       "filestotal",
1115           .fops =       &ll_filestotal_fops                     },
1116         { .name =       "filesfree",
1117           .fops =       &ll_filesfree_fops                      },
1118         { .name =       "client_type",
1119           .fops =       &ll_client_type_fops                    },
1120         { .name =       "max_read_ahead_mb",
1121           .fops =       &ll_max_readahead_mb_fops               },
1122         { .name =       "max_read_ahead_per_file_mb",
1123           .fops =       &ll_max_readahead_per_file_mb_fops      },
1124         { .name =       "max_read_ahead_whole_mb",
1125           .fops =       &ll_max_read_ahead_whole_mb_fops        },
1126         { .name =       "max_cached_mb",
1127           .fops =       &ll_max_cached_mb_fops                  },
1128         { .name =       "checksum_pages",
1129           .fops =       &ll_checksum_fops                       },
1130         { .name =       "stats_track_pid",
1131           .fops =       &ll_track_pid_fops                      },
1132         { .name =       "stats_track_ppid",
1133           .fops =       &ll_track_ppid_fops                     },
1134         { .name =       "stats_track_gid",
1135           .fops =       &ll_track_gid_fops                      },
1136         { .name =       "statahead_max",
1137           .fops =       &ll_statahead_max_fops                  },
1138         { .name =       "statahead_agl",
1139           .fops =       &ll_statahead_agl_fops                  },
1140         { .name =       "statahead_stats",
1141           .fops =       &ll_statahead_stats_fops                },
1142         { .name =       "lazystatfs",
1143           .fops =       &ll_lazystatfs_fops                     },
1144         { .name =       "max_easize",
1145           .fops =       &ll_max_easize_fops                     },
1146         { .name =       "default_easize",
1147           .fops =       &ll_default_easize_fops                 },
1148         { .name =       "sbi_flags",
1149           .fops =       &ll_sbi_flags_fops                      },
1150         { .name =       "xattr_cache",
1151           .fops =       &ll_xattr_cache_fops                    },
1152         { .name =       "unstable_stats",
1153           .fops =       &ll_unstable_stats_fops                 },
1154         { .name =       "root_squash",
1155           .fops =       &ll_root_squash_fops                    },
1156         { .name =       "nosquash_nids",
1157           .fops =       &ll_nosquash_nids_fops                  },
1158         { .name =       "fast_read",
1159           .fops =       &ll_fast_read_fops,                     },
1160         { .name =       "pio",
1161           .fops =       &ll_pio_fops,                           },
1162         { .name =       "tiny_write",
1163           .fops =       &ll_tiny_write_fops,                    },
1164         { NULL }
1165 };
1166
1167 #define MAX_STRING_SIZE 128
1168
1169 static const struct llite_file_opcode {
1170         __u32       opcode;
1171         __u32       type;
1172         const char *opname;
1173 } llite_opcode_table[LPROC_LL_FILE_OPCODES] = {
1174         /* file operation */
1175         { LPROC_LL_DIRTY_HITS,     LPROCFS_TYPE_REGS, "dirty_pages_hits" },
1176         { LPROC_LL_DIRTY_MISSES,   LPROCFS_TYPE_REGS, "dirty_pages_misses" },
1177         { LPROC_LL_READ_BYTES,     LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_BYTES,
1178                                    "read_bytes" },
1179         { LPROC_LL_WRITE_BYTES,    LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_BYTES,
1180                                    "write_bytes" },
1181         { LPROC_LL_BRW_READ,       LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_PAGES,
1182                                    "brw_read" },
1183         { LPROC_LL_BRW_WRITE,      LPROCFS_CNTR_AVGMINMAX|LPROCFS_TYPE_PAGES,
1184                                    "brw_write" },
1185         { LPROC_LL_IOCTL,          LPROCFS_TYPE_REGS, "ioctl" },
1186         { LPROC_LL_OPEN,           LPROCFS_TYPE_REGS, "open" },
1187         { LPROC_LL_RELEASE,        LPROCFS_TYPE_REGS, "close" },
1188         { LPROC_LL_MAP,            LPROCFS_TYPE_REGS, "mmap" },
1189         { LPROC_LL_FAULT,          LPROCFS_TYPE_REGS, "page_fault" },
1190         { LPROC_LL_MKWRITE,        LPROCFS_TYPE_REGS, "page_mkwrite" },
1191         { LPROC_LL_LLSEEK,         LPROCFS_TYPE_REGS, "seek" },
1192         { LPROC_LL_FSYNC,          LPROCFS_TYPE_REGS, "fsync" },
1193         { LPROC_LL_READDIR,        LPROCFS_TYPE_REGS, "readdir" },
1194         /* inode operation */
1195         { LPROC_LL_SETATTR,        LPROCFS_TYPE_REGS, "setattr" },
1196         { LPROC_LL_TRUNC,          LPROCFS_TYPE_REGS, "truncate" },
1197         { LPROC_LL_FLOCK,          LPROCFS_TYPE_REGS, "flock" },
1198         { LPROC_LL_GETATTR,        LPROCFS_TYPE_REGS, "getattr" },
1199         /* dir inode operation */
1200         { LPROC_LL_CREATE,         LPROCFS_TYPE_REGS, "create" },
1201         { LPROC_LL_LINK,           LPROCFS_TYPE_REGS, "link" },
1202         { LPROC_LL_UNLINK,         LPROCFS_TYPE_REGS, "unlink" },
1203         { LPROC_LL_SYMLINK,        LPROCFS_TYPE_REGS, "symlink" },
1204         { LPROC_LL_MKDIR,          LPROCFS_TYPE_REGS, "mkdir" },
1205         { LPROC_LL_RMDIR,          LPROCFS_TYPE_REGS, "rmdir" },
1206         { LPROC_LL_MKNOD,          LPROCFS_TYPE_REGS, "mknod" },
1207         { LPROC_LL_RENAME,         LPROCFS_TYPE_REGS, "rename" },
1208         /* special inode operation */
1209         { LPROC_LL_STAFS,          LPROCFS_TYPE_REGS, "statfs" },
1210         { LPROC_LL_ALLOC_INODE,    LPROCFS_TYPE_REGS, "alloc_inode" },
1211         { LPROC_LL_SETXATTR,       LPROCFS_TYPE_REGS, "setxattr" },
1212         { LPROC_LL_GETXATTR,       LPROCFS_TYPE_REGS, "getxattr" },
1213         { LPROC_LL_GETXATTR_HITS,  LPROCFS_TYPE_REGS, "getxattr_hits" },
1214         { LPROC_LL_LISTXATTR,      LPROCFS_TYPE_REGS, "listxattr" },
1215         { LPROC_LL_REMOVEXATTR,    LPROCFS_TYPE_REGS, "removexattr" },
1216         { LPROC_LL_INODE_PERM,     LPROCFS_TYPE_REGS, "inode_permission" },
1217 };
1218
1219 void ll_stats_ops_tally(struct ll_sb_info *sbi, int op, int count)
1220 {
1221         if (!sbi->ll_stats)
1222                 return;
1223         if (sbi->ll_stats_track_type == STATS_TRACK_ALL)
1224                 lprocfs_counter_add(sbi->ll_stats, op, count);
1225         else if (sbi->ll_stats_track_type == STATS_TRACK_PID &&
1226                  sbi->ll_stats_track_id == current->pid)
1227                 lprocfs_counter_add(sbi->ll_stats, op, count);
1228         else if (sbi->ll_stats_track_type == STATS_TRACK_PPID &&
1229                  sbi->ll_stats_track_id == current->parent->pid)
1230                 lprocfs_counter_add(sbi->ll_stats, op, count);
1231         else if (sbi->ll_stats_track_type == STATS_TRACK_GID &&
1232                  sbi->ll_stats_track_id ==
1233                         from_kgid(&init_user_ns, current_gid()))
1234                 lprocfs_counter_add(sbi->ll_stats, op, count);
1235 }
1236 EXPORT_SYMBOL(ll_stats_ops_tally);
1237
1238 static const char *ra_stat_string[] = {
1239         [RA_STAT_HIT] = "hits",
1240         [RA_STAT_MISS] = "misses",
1241         [RA_STAT_DISTANT_READPAGE] = "readpage not consecutive",
1242         [RA_STAT_MISS_IN_WINDOW] = "miss inside window",
1243         [RA_STAT_FAILED_GRAB_PAGE] = "failed grab_cache_page",
1244         [RA_STAT_FAILED_MATCH] = "failed lock match",
1245         [RA_STAT_DISCARDED] = "read but discarded",
1246         [RA_STAT_ZERO_LEN] = "zero length file",
1247         [RA_STAT_ZERO_WINDOW] = "zero size window",
1248         [RA_STAT_EOF] = "read-ahead to EOF",
1249         [RA_STAT_MAX_IN_FLIGHT] = "hit max r-a issue",
1250         [RA_STAT_WRONG_GRAB_PAGE] = "wrong page from grab_cache_page",
1251         [RA_STAT_FAILED_REACH_END] = "failed to reach end"
1252 };
1253
1254 LPROC_SEQ_FOPS_RO_TYPE(llite, name);
1255 LPROC_SEQ_FOPS_RO_TYPE(llite, uuid);
1256
1257 int lprocfs_ll_register_mountpoint(struct proc_dir_entry *parent,
1258                                    struct super_block *sb)
1259 {
1260         struct lprocfs_vars lvars[2];
1261         struct lustre_sb_info *lsi = s2lsi(sb);
1262         struct ll_sb_info *sbi = ll_s2sbi(sb);
1263         char name[MAX_STRING_SIZE + 1], *ptr;
1264         int err, id, len, rc;
1265         ENTRY;
1266
1267         memset(lvars, 0, sizeof(lvars));
1268
1269         name[MAX_STRING_SIZE] = '\0';
1270         lvars[0].name = name;
1271
1272         LASSERT(sbi != NULL);
1273
1274         /* Get fsname */
1275         len = strlen(lsi->lsi_lmd->lmd_profile);
1276         ptr = strrchr(lsi->lsi_lmd->lmd_profile, '-');
1277         if (ptr && (strcmp(ptr, "-client") == 0))
1278                 len -= 7;
1279
1280         /* Mount info */
1281         snprintf(name, MAX_STRING_SIZE, "%.*s-%p", len,
1282                  lsi->lsi_lmd->lmd_profile, sb);
1283
1284         sbi->ll_proc_root = lprocfs_register(name, parent, NULL, NULL);
1285         if (IS_ERR(sbi->ll_proc_root)) {
1286                 err = PTR_ERR(sbi->ll_proc_root);
1287                 sbi->ll_proc_root = NULL;
1288                 RETURN(err);
1289         }
1290
1291         rc = lprocfs_seq_create(sbi->ll_proc_root, "dump_page_cache", 0444,
1292                                 &vvp_dump_pgcache_file_ops, sbi);
1293         if (rc)
1294                 CWARN("Error adding the dump_page_cache file\n");
1295
1296         rc = lprocfs_seq_create(sbi->ll_proc_root, "extents_stats", 0644,
1297                                 &ll_rw_extents_stats_fops, sbi);
1298         if (rc)
1299                 CWARN("Error adding the extent_stats file\n");
1300
1301         rc = lprocfs_seq_create(sbi->ll_proc_root, "extents_stats_per_process",
1302                                 0644, &ll_rw_extents_stats_pp_fops, sbi);
1303         if (rc)
1304                 CWARN("Error adding the extents_stats_per_process file\n");
1305
1306         rc = lprocfs_seq_create(sbi->ll_proc_root, "offset_stats", 0644,
1307                                 &ll_rw_offset_stats_fops, sbi);
1308         if (rc)
1309                 CWARN("Error adding the offset_stats file\n");
1310
1311         /* File operations stats */
1312         sbi->ll_stats = lprocfs_alloc_stats(LPROC_LL_FILE_OPCODES,
1313                                             LPROCFS_STATS_FLAG_NONE);
1314         if (sbi->ll_stats == NULL)
1315                 GOTO(out, err = -ENOMEM);
1316         /* do counter init */
1317         for (id = 0; id < LPROC_LL_FILE_OPCODES; id++) {
1318                 __u32 type = llite_opcode_table[id].type;
1319                 void *ptr = NULL;
1320                 if (type & LPROCFS_TYPE_REGS)
1321                         ptr = "regs";
1322                 else if (type & LPROCFS_TYPE_BYTES)
1323                         ptr = "bytes";
1324                 else if (type & LPROCFS_TYPE_PAGES)
1325                         ptr = "pages";
1326                 lprocfs_counter_init(sbi->ll_stats,
1327                                      llite_opcode_table[id].opcode,
1328                                      (type & LPROCFS_CNTR_AVGMINMAX),
1329                                      llite_opcode_table[id].opname, ptr);
1330         }
1331         err = lprocfs_register_stats(sbi->ll_proc_root, "stats", sbi->ll_stats);
1332         if (err)
1333                 GOTO(out, err);
1334
1335         sbi->ll_ra_stats = lprocfs_alloc_stats(ARRAY_SIZE(ra_stat_string),
1336                                                LPROCFS_STATS_FLAG_NONE);
1337         if (sbi->ll_ra_stats == NULL)
1338                 GOTO(out, err = -ENOMEM);
1339
1340         for (id = 0; id < ARRAY_SIZE(ra_stat_string); id++)
1341                 lprocfs_counter_init(sbi->ll_ra_stats, id, 0,
1342                                      ra_stat_string[id], "pages");
1343         err = lprocfs_register_stats(sbi->ll_proc_root, "read_ahead_stats",
1344                                      sbi->ll_ra_stats);
1345         if (err)
1346                 GOTO(out, err);
1347
1348
1349         err = lprocfs_add_vars(sbi->ll_proc_root, lprocfs_llite_obd_vars, sb);
1350         if (err)
1351                 GOTO(out, err);
1352
1353 out:
1354         if (err) {
1355                 lprocfs_remove(&sbi->ll_proc_root);
1356                 lprocfs_free_stats(&sbi->ll_ra_stats);
1357                 lprocfs_free_stats(&sbi->ll_stats);
1358         }
1359         RETURN(err);
1360 }
1361
1362 int lprocfs_ll_register_obd(struct super_block *sb, const char *obdname)
1363 {
1364         struct lprocfs_vars lvars[2];
1365         struct ll_sb_info *sbi = ll_s2sbi(sb);
1366         struct obd_device *obd;
1367         struct proc_dir_entry *dir;
1368         char name[MAX_STRING_SIZE + 1];
1369         int err;
1370         ENTRY;
1371
1372         memset(lvars, 0, sizeof(lvars));
1373
1374         name[MAX_STRING_SIZE] = '\0';
1375         lvars[0].name = name;
1376
1377         LASSERT(sbi != NULL);
1378         LASSERT(obdname != NULL);
1379
1380         obd = class_name2obd(obdname);
1381
1382         LASSERT(obd != NULL);
1383         LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
1384         LASSERT(obd->obd_type->typ_name != NULL);
1385
1386         dir = proc_mkdir(obd->obd_type->typ_name, sbi->ll_proc_root);
1387         if (dir == NULL)
1388                 GOTO(out, err = -ENOMEM);
1389
1390         snprintf(name, MAX_STRING_SIZE, "common_name");
1391         lvars[0].fops = &llite_name_fops;
1392         err = lprocfs_add_vars(dir, lvars, obd);
1393         if (err)
1394                 GOTO(out, err);
1395
1396         snprintf(name, MAX_STRING_SIZE, "uuid");
1397         lvars[0].fops = &llite_uuid_fops;
1398         err = lprocfs_add_vars(dir, lvars, obd);
1399         if (err)
1400                 GOTO(out, err);
1401
1402 out:
1403         if (err) {
1404                 lprocfs_remove(&sbi->ll_proc_root);
1405                 lprocfs_free_stats(&sbi->ll_ra_stats);
1406                 lprocfs_free_stats(&sbi->ll_stats);
1407         }
1408         RETURN(err);
1409 }
1410
1411 void lprocfs_ll_unregister_mountpoint(struct ll_sb_info *sbi)
1412 {
1413         if (sbi->ll_proc_root) {
1414                 lprocfs_remove(&sbi->ll_proc_root);
1415                 lprocfs_free_stats(&sbi->ll_ra_stats);
1416                 lprocfs_free_stats(&sbi->ll_stats);
1417         }
1418 }
1419 #undef MAX_STRING_SIZE
1420
1421 #define pct(a,b) (b ? a * 100 / b : 0)
1422
1423 static void ll_display_extents_info(struct ll_rw_extents_info *io_extents,
1424                                    struct seq_file *seq, int which)
1425 {
1426         unsigned long read_tot = 0, write_tot = 0, read_cum, write_cum;
1427         unsigned long start, end, r, w;
1428         char *unitp = "KMGTPEZY";
1429         int i, units = 10;
1430         struct per_process_info *pp_info = &io_extents->pp_extents[which];
1431
1432         read_cum = 0;
1433         write_cum = 0;
1434         start = 0;
1435
1436         for(i = 0; i < LL_HIST_MAX; i++) {
1437                 read_tot += pp_info->pp_r_hist.oh_buckets[i];
1438                 write_tot += pp_info->pp_w_hist.oh_buckets[i];
1439         }
1440
1441         for(i = 0; i < LL_HIST_MAX; i++) {
1442                 r = pp_info->pp_r_hist.oh_buckets[i];
1443                 w = pp_info->pp_w_hist.oh_buckets[i];
1444                 read_cum += r;
1445                 write_cum += w;
1446                 end = 1 << (i + LL_HIST_START - units);
1447                 seq_printf(seq, "%4lu%c - %4lu%c%c: %14lu %4lu %4lu  | "
1448                            "%14lu %4lu %4lu\n", start, *unitp, end, *unitp,
1449                            (i == LL_HIST_MAX - 1) ? '+' : ' ',
1450                            r, pct(r, read_tot), pct(read_cum, read_tot),
1451                            w, pct(w, write_tot), pct(write_cum, write_tot));
1452                 start = end;
1453                 if (start == 1<<10) {
1454                         start = 1;
1455                         units += 10;
1456                         unitp++;
1457                 }
1458                 if (read_cum == read_tot && write_cum == write_tot)
1459                         break;
1460         }
1461 }
1462
1463 static int ll_rw_extents_stats_pp_seq_show(struct seq_file *seq, void *v)
1464 {
1465         struct timespec64 now;
1466         struct ll_sb_info *sbi = seq->private;
1467         struct ll_rw_extents_info *io_extents = &sbi->ll_rw_extents_info;
1468         int k;
1469
1470         ktime_get_real_ts64(&now);
1471
1472         if (!sbi->ll_rw_stats_on) {
1473                 seq_puts(seq, "disabled\n write anything to this file to activate, then '0' or 'disable' to deactivate\n");
1474                 return 0;
1475         }
1476         seq_printf(seq, "snapshot_time:         %llu.%09lu (secs.nsecs)\n",
1477                    (s64)now.tv_sec, now.tv_nsec);
1478         seq_printf(seq, "%15s %19s       | %20s\n", " ", "read", "write");
1479         seq_printf(seq, "%13s   %14s %4s %4s  | %14s %4s %4s\n",
1480                    "extents", "calls", "%", "cum%",
1481                    "calls", "%", "cum%");
1482         spin_lock(&sbi->ll_pp_extent_lock);
1483         for (k = 0; k < LL_PROCESS_HIST_MAX; k++) {
1484                 if (io_extents->pp_extents[k].pid != 0) {
1485                         seq_printf(seq, "\nPID: %d\n",
1486                                    io_extents->pp_extents[k].pid);
1487                         ll_display_extents_info(io_extents, seq, k);
1488                 }
1489         }
1490         spin_unlock(&sbi->ll_pp_extent_lock);
1491         return 0;
1492 }
1493
1494 static ssize_t ll_rw_extents_stats_pp_seq_write(struct file *file,
1495                                                 const char __user *buf,
1496                                                 size_t len,
1497                                                 loff_t *off)
1498 {
1499         struct seq_file *seq = file->private_data;
1500         struct ll_sb_info *sbi = seq->private;
1501         struct ll_rw_extents_info *io_extents = &sbi->ll_rw_extents_info;
1502         int i;
1503         __s64 value;
1504
1505         if (len == 0)
1506                 return -EINVAL;
1507
1508         value = ll_stats_pid_write(buf, len);
1509
1510         if (value == 0)
1511                 sbi->ll_rw_stats_on = 0;
1512         else
1513                 sbi->ll_rw_stats_on = 1;
1514
1515         spin_lock(&sbi->ll_pp_extent_lock);
1516         for (i = 0; i < LL_PROCESS_HIST_MAX; i++) {
1517                 io_extents->pp_extents[i].pid = 0;
1518                 lprocfs_oh_clear(&io_extents->pp_extents[i].pp_r_hist);
1519                 lprocfs_oh_clear(&io_extents->pp_extents[i].pp_w_hist);
1520         }
1521         spin_unlock(&sbi->ll_pp_extent_lock);
1522         return len;
1523 }
1524
1525 LPROC_SEQ_FOPS(ll_rw_extents_stats_pp);
1526
1527 static int ll_rw_extents_stats_seq_show(struct seq_file *seq, void *v)
1528 {
1529         struct timespec64 now;
1530         struct ll_sb_info *sbi = seq->private;
1531         struct ll_rw_extents_info *io_extents = &sbi->ll_rw_extents_info;
1532
1533         ktime_get_real_ts64(&now);
1534
1535         if (!sbi->ll_rw_stats_on) {
1536                 seq_puts(seq, "disabled\n write anything to this file to activate, then '0' or 'disable' to deactivate\n");
1537                 return 0;
1538         }
1539         seq_printf(seq, "snapshot_time:         %llu.%09lu (secs.nsecs)\n",
1540                    (s64)now.tv_sec, now.tv_nsec);
1541
1542         seq_printf(seq, "%15s %19s       | %20s\n", " ", "read", "write");
1543         seq_printf(seq, "%13s   %14s %4s %4s  | %14s %4s %4s\n",
1544                    "extents", "calls", "%", "cum%",
1545                    "calls", "%", "cum%");
1546         spin_lock(&sbi->ll_lock);
1547         ll_display_extents_info(io_extents, seq, LL_PROCESS_HIST_MAX);
1548         spin_unlock(&sbi->ll_lock);
1549
1550         return 0;
1551 }
1552
1553 static ssize_t ll_rw_extents_stats_seq_write(struct file *file,
1554                                              const char __user *buf,
1555                                              size_t len, loff_t *off)
1556 {
1557         struct seq_file *seq = file->private_data;
1558         struct ll_sb_info *sbi = seq->private;
1559         struct ll_rw_extents_info *io_extents = &sbi->ll_rw_extents_info;
1560         int i;
1561         __s64 value;
1562
1563         if (len == 0)
1564                 return -EINVAL;
1565
1566         value = ll_stats_pid_write(buf, len);
1567
1568         if (value == 0)
1569                 sbi->ll_rw_stats_on = 0;
1570         else
1571                 sbi->ll_rw_stats_on = 1;
1572
1573         spin_lock(&sbi->ll_pp_extent_lock);
1574         for (i = 0; i <= LL_PROCESS_HIST_MAX; i++) {
1575                 io_extents->pp_extents[i].pid = 0;
1576                 lprocfs_oh_clear(&io_extents->pp_extents[i].pp_r_hist);
1577                 lprocfs_oh_clear(&io_extents->pp_extents[i].pp_w_hist);
1578         }
1579         spin_unlock(&sbi->ll_pp_extent_lock);
1580
1581         return len;
1582 }
1583 LPROC_SEQ_FOPS(ll_rw_extents_stats);
1584
1585 void ll_rw_stats_tally(struct ll_sb_info *sbi, pid_t pid,
1586                        struct ll_file_data *file, loff_t pos,
1587                        size_t count, int rw)
1588 {
1589         int i, cur = -1;
1590         struct ll_rw_process_info *process;
1591         struct ll_rw_process_info *offset;
1592         int *off_count = &sbi->ll_rw_offset_entry_count;
1593         int *process_count = &sbi->ll_offset_process_count;
1594         struct ll_rw_extents_info *io_extents = &sbi->ll_rw_extents_info;
1595
1596         if(!sbi->ll_rw_stats_on)
1597                 return;
1598         process = sbi->ll_rw_process_info;
1599         offset = sbi->ll_rw_offset_info;
1600
1601         spin_lock(&sbi->ll_pp_extent_lock);
1602         /* Extent statistics */
1603         for(i = 0; i < LL_PROCESS_HIST_MAX; i++) {
1604                 if(io_extents->pp_extents[i].pid == pid) {
1605                         cur = i;
1606                         break;
1607                 }
1608         }
1609
1610         if (cur == -1) {
1611                 /* new process */
1612                 sbi->ll_extent_process_count =
1613                         (sbi->ll_extent_process_count + 1) % LL_PROCESS_HIST_MAX;
1614                 cur = sbi->ll_extent_process_count;
1615                 io_extents->pp_extents[cur].pid = pid;
1616                 lprocfs_oh_clear(&io_extents->pp_extents[cur].pp_r_hist);
1617                 lprocfs_oh_clear(&io_extents->pp_extents[cur].pp_w_hist);
1618         }
1619
1620         for(i = 0; (count >= (1 << LL_HIST_START << i)) &&
1621              (i < (LL_HIST_MAX - 1)); i++);
1622         if (rw == 0) {
1623                 io_extents->pp_extents[cur].pp_r_hist.oh_buckets[i]++;
1624                 io_extents->pp_extents[LL_PROCESS_HIST_MAX].pp_r_hist.oh_buckets[i]++;
1625         } else {
1626                 io_extents->pp_extents[cur].pp_w_hist.oh_buckets[i]++;
1627                 io_extents->pp_extents[LL_PROCESS_HIST_MAX].pp_w_hist.oh_buckets[i]++;
1628         }
1629         spin_unlock(&sbi->ll_pp_extent_lock);
1630
1631         spin_lock(&sbi->ll_process_lock);
1632         /* Offset statistics */
1633         for (i = 0; i < LL_PROCESS_HIST_MAX; i++) {
1634                 if (process[i].rw_pid == pid) {
1635                         if (process[i].rw_last_file != file) {
1636                                 process[i].rw_range_start = pos;
1637                                 process[i].rw_last_file_pos = pos + count;
1638                                 process[i].rw_smallest_extent = count;
1639                                 process[i].rw_largest_extent = count;
1640                                 process[i].rw_offset = 0;
1641                                 process[i].rw_last_file = file;
1642                                 spin_unlock(&sbi->ll_process_lock);
1643                                 return;
1644                         }
1645                         if (process[i].rw_last_file_pos != pos) {
1646                                 *off_count =
1647                                     (*off_count + 1) % LL_OFFSET_HIST_MAX;
1648                                 offset[*off_count].rw_op = process[i].rw_op;
1649                                 offset[*off_count].rw_pid = pid;
1650                                 offset[*off_count].rw_range_start =
1651                                         process[i].rw_range_start;
1652                                 offset[*off_count].rw_range_end =
1653                                         process[i].rw_last_file_pos;
1654                                 offset[*off_count].rw_smallest_extent =
1655                                         process[i].rw_smallest_extent;
1656                                 offset[*off_count].rw_largest_extent =
1657                                         process[i].rw_largest_extent;
1658                                 offset[*off_count].rw_offset =
1659                                         process[i].rw_offset;
1660                                 process[i].rw_op = rw;
1661                                 process[i].rw_range_start = pos;
1662                                 process[i].rw_smallest_extent = count;
1663                                 process[i].rw_largest_extent = count;
1664                                 process[i].rw_offset = pos -
1665                                         process[i].rw_last_file_pos;
1666                         }
1667                         if(process[i].rw_smallest_extent > count)
1668                                 process[i].rw_smallest_extent = count;
1669                         if(process[i].rw_largest_extent < count)
1670                                 process[i].rw_largest_extent = count;
1671                         process[i].rw_last_file_pos = pos + count;
1672                         spin_unlock(&sbi->ll_process_lock);
1673                         return;
1674                 }
1675         }
1676         *process_count = (*process_count + 1) % LL_PROCESS_HIST_MAX;
1677         process[*process_count].rw_pid = pid;
1678         process[*process_count].rw_op = rw;
1679         process[*process_count].rw_range_start = pos;
1680         process[*process_count].rw_last_file_pos = pos + count;
1681         process[*process_count].rw_smallest_extent = count;
1682         process[*process_count].rw_largest_extent = count;
1683         process[*process_count].rw_offset = 0;
1684         process[*process_count].rw_last_file = file;
1685         spin_unlock(&sbi->ll_process_lock);
1686 }
1687
1688 static int ll_rw_offset_stats_seq_show(struct seq_file *seq, void *v)
1689 {
1690         struct timespec64 now;
1691         struct ll_sb_info *sbi = seq->private;
1692         struct ll_rw_process_info *offset = sbi->ll_rw_offset_info;
1693         struct ll_rw_process_info *process = sbi->ll_rw_process_info;
1694         int i;
1695
1696         ktime_get_real_ts64(&now);
1697
1698         if (!sbi->ll_rw_stats_on) {
1699                 seq_puts(seq, "disabled\n write anything to this file to activate, then '0' or 'disable' to deactivate\n");
1700                 return 0;
1701         }
1702         spin_lock(&sbi->ll_process_lock);
1703
1704         seq_printf(seq, "snapshot_time:         %llu.%09lu (secs.nsecs)\n",
1705                    (s64)now.tv_sec, now.tv_nsec);
1706         seq_printf(seq, "%3s %10s %14s %14s %17s %17s %14s\n",
1707                    "R/W", "PID", "RANGE START", "RANGE END",
1708                    "SMALLEST EXTENT", "LARGEST EXTENT", "OFFSET");
1709
1710         /* We stored the discontiguous offsets here; print them first */
1711         for (i = 0; i < LL_OFFSET_HIST_MAX; i++) {
1712                 if (offset[i].rw_pid != 0)
1713                         seq_printf(seq,
1714                                    "%3c %10d %14Lu %14Lu %17lu %17lu %14Lu",
1715                                    offset[i].rw_op == READ ? 'R' : 'W',
1716                                    offset[i].rw_pid,
1717                                    offset[i].rw_range_start,
1718                                    offset[i].rw_range_end,
1719                                    (unsigned long)offset[i].rw_smallest_extent,
1720                                    (unsigned long)offset[i].rw_largest_extent,
1721                                    offset[i].rw_offset);
1722         }
1723
1724         /* Then print the current offsets for each process */
1725         for (i = 0; i < LL_PROCESS_HIST_MAX; i++) {
1726                 if (process[i].rw_pid != 0)
1727                         seq_printf(seq,
1728                                    "%3c %10d %14Lu %14Lu %17lu %17lu %14Lu",
1729                                    process[i].rw_op == READ ? 'R' : 'W',
1730                                    process[i].rw_pid,
1731                                    process[i].rw_range_start,
1732                                    process[i].rw_last_file_pos,
1733                                    (unsigned long)process[i].rw_smallest_extent,
1734                                    (unsigned long)process[i].rw_largest_extent,
1735                                    process[i].rw_offset);
1736         }
1737         spin_unlock(&sbi->ll_process_lock);
1738
1739         return 0;
1740 }
1741
1742 static ssize_t ll_rw_offset_stats_seq_write(struct file *file,
1743                                             const char __user *buf,
1744                                             size_t len, loff_t *off)
1745 {
1746         struct seq_file *seq = file->private_data;
1747         struct ll_sb_info *sbi = seq->private;
1748         struct ll_rw_process_info *process_info = sbi->ll_rw_process_info;
1749         struct ll_rw_process_info *offset_info = sbi->ll_rw_offset_info;
1750         __s64 value;
1751
1752         if (len == 0)
1753                 return -EINVAL;
1754
1755         value = ll_stats_pid_write(buf, len);
1756
1757         if (value == 0)
1758                 sbi->ll_rw_stats_on = 0;
1759         else
1760                 sbi->ll_rw_stats_on = 1;
1761
1762         spin_lock(&sbi->ll_process_lock);
1763         sbi->ll_offset_process_count = 0;
1764         sbi->ll_rw_offset_entry_count = 0;
1765         memset(process_info, 0, sizeof(struct ll_rw_process_info) *
1766                LL_PROCESS_HIST_MAX);
1767         memset(offset_info, 0, sizeof(struct ll_rw_process_info) *
1768                LL_OFFSET_HIST_MAX);
1769         spin_unlock(&sbi->ll_process_lock);
1770
1771         return len;
1772 }
1773
1774 /**
1775  * ll_stats_pid_write() - Determine if stats collection should be enabled
1776  * @buf: Buffer containing the data written
1777  * @len: Number of bytes in the buffer
1778  *
1779  * Several proc files begin collecting stats when a value is written, and stop
1780  * collecting when either '0' or 'disable' is written. This function checks the
1781  * written value to see if collection should be enabled or disabled.
1782  *
1783  * Return: If '0' or 'disable' is provided, 0 is returned. If the text
1784  * equivalent of a number is written, that number is returned. Otherwise,
1785  * 1 is returned. Non-zero return values indicate collection should be enabled.
1786  */
1787 static __s64 ll_stats_pid_write(const char __user *buf, size_t len)
1788 {
1789         unsigned long long value = 1;
1790         int rc;
1791         char kernbuf[16];
1792
1793         rc = kstrtoull_from_user(buf, len, 0, &value);
1794         if (rc < 0 && len < sizeof(kernbuf)) {
1795
1796                 if (copy_from_user(kernbuf, buf, len))
1797                         return -EFAULT;
1798                 kernbuf[len] = 0;
1799
1800                 if (kernbuf[len - 1] == '\n')
1801                         kernbuf[len - 1] = 0;
1802
1803                 if (strncasecmp(kernbuf, "disable", 7) == 0)
1804                         value = 0;
1805         }
1806
1807         return value;
1808 }
1809
1810 LPROC_SEQ_FOPS(ll_rw_offset_stats);
1811 #endif /* CONFIG_PROC_FS */