Whamcloud - gitweb
LU-2139 osc: Track and limit "unstable" pages
[fs/lustre-release.git] / lustre / llite / lproc_llite.c
index dc4fe5d..5f995af 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2012, 2013, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -218,6 +218,40 @@ static int ll_rd_sb_uuid(char *page, char **start, off_t off, int count,
         return snprintf(page, count, "%s\n", ll_s2sbi(sb)->ll_sb_uuid.uuid);
 }
 
+static int ll_rd_xattr_cache(char *page, char **start, off_t off,
+                               int count, int *eof, void *data)
+{
+       struct super_block *sb = (struct super_block *)data;
+       struct ll_sb_info *sbi = ll_s2sbi(sb);
+       int rc;
+
+       rc = snprintf(page, count, "%u\n", sbi->ll_xattr_cache_enabled);
+
+       return rc;
+}
+
+static int ll_wr_xattr_cache(struct file *file, const char *buffer,
+                               unsigned long count, void *data)
+{
+       struct super_block *sb = (struct super_block *)data;
+       struct ll_sb_info *sbi = ll_s2sbi(sb);
+       int val, rc;
+
+       rc = lprocfs_write_helper(buffer, count, &val);
+       if (rc)
+               return rc;
+
+       if (val != 0 && val != 1)
+               return -ERANGE;
+
+       if (val == 1 && !(sbi->ll_flags & LL_SBI_XATTR_CACHE))
+               return -ENOTSUPP;
+
+       sbi->ll_xattr_cache_enabled = val;
+
+       return count;
+}
+
 static int ll_rd_site_stats(char *page, char **start, off_t off,
                             int count, int *eof, void *data)
 {
@@ -248,22 +282,23 @@ static int ll_rd_max_readahead_mb(char *page, char **start, off_t off,
 }
 
 static int ll_wr_max_readahead_mb(struct file *file, const char *buffer,
-                                  unsigned long count, void *data)
+                                 unsigned long count, void *data)
 {
-        struct super_block *sb = data;
-        struct ll_sb_info *sbi = ll_s2sbi(sb);
-        int mult, rc, pages_number;
+       struct super_block *sb = data;
+       struct ll_sb_info *sbi = ll_s2sbi(sb);
+       int mult, rc, pages_number;
 
-        mult = 1 << (20 - CFS_PAGE_SHIFT);
-        rc = lprocfs_write_frac_helper(buffer, count, &pages_number, mult);
-        if (rc)
-                return rc;
+       mult = 1 << (20 - PAGE_CACHE_SHIFT);
+       rc = lprocfs_write_frac_helper(buffer, count, &pages_number, mult);
+       if (rc)
+               return rc;
 
-        if (pages_number < 0 || pages_number > cfs_num_physpages / 2) {
-                CERROR("can't set file readahead more than %lu MB\n",
-                       cfs_num_physpages >> (20 - CFS_PAGE_SHIFT + 1)); /*1/2 of RAM*/
-                return -ERANGE;
-        }
+       if (pages_number < 0 || pages_number > totalram_pages / 2) {
+               /* 1/2 of RAM */
+               CERROR("can't set file readahead more than %lu MB\n",
+                      totalram_pages >> (20 - PAGE_CACHE_SHIFT + 1));
+               return -ERANGE;
+       }
 
        spin_lock(&sbi->ll_lock);
        sbi->ll_ra_info.ra_max_pages = pages_number;
@@ -284,7 +319,7 @@ static int ll_rd_max_readahead_per_file_mb(char *page, char **start, off_t off,
        pages_number = sbi->ll_ra_info.ra_max_pages_per_file;
        spin_unlock(&sbi->ll_lock);
 
-       mult = 1 << (20 - CFS_PAGE_SHIFT);
+       mult = 1 << (20 - PAGE_CACHE_SHIFT);
        return lprocfs_read_frac_helper(page, count, pages_number, mult);
 }
 
@@ -295,7 +330,7 @@ static int ll_wr_max_readahead_per_file_mb(struct file *file, const char *buffer
         struct ll_sb_info *sbi = ll_s2sbi(sb);
         int mult, rc, pages_number;
 
-        mult = 1 << (20 - CFS_PAGE_SHIFT);
+       mult = 1 << (20 - PAGE_CACHE_SHIFT);
         rc = lprocfs_write_frac_helper(buffer, count, &pages_number, mult);
         if (rc)
                 return rc;
@@ -327,31 +362,32 @@ static int ll_rd_max_read_ahead_whole_mb(char *page, char **start, off_t off,
        pages_number = sbi->ll_ra_info.ra_max_read_ahead_whole_pages;
        spin_unlock(&sbi->ll_lock);
 
-       mult = 1 << (20 - CFS_PAGE_SHIFT);
+       mult = 1 << (20 - PAGE_CACHE_SHIFT);
        return lprocfs_read_frac_helper(page, count, pages_number, mult);
 }
 
 static int ll_wr_max_read_ahead_whole_mb(struct file *file, const char *buffer,
-                                         unsigned long count, void *data)
+                                        unsigned long count, void *data)
 {
-        struct super_block *sb = data;
-        struct ll_sb_info *sbi = ll_s2sbi(sb);
-        int mult, rc, pages_number;
-
-        mult = 1 << (20 - CFS_PAGE_SHIFT);
-        rc = lprocfs_write_frac_helper(buffer, count, &pages_number, mult);
-        if (rc)
-                return rc;
+       struct super_block *sb = data;
+       struct ll_sb_info *sbi = ll_s2sbi(sb);
+       int mult, rc, pages_number;
 
-        /* Cap this at the current max readahead window size, the readahead
-         * algorithm does this anyway so it's pointless to set it larger. */
-        if (pages_number < 0 ||
-            pages_number > sbi->ll_ra_info.ra_max_pages_per_file) {
-                CERROR("can't set max_read_ahead_whole_mb more than "
-                       "max_read_ahead_per_file_mb: %lu\n",
-                        sbi->ll_ra_info.ra_max_pages_per_file >> (20 - CFS_PAGE_SHIFT));
-                return -ERANGE;
-        }
+       mult = 1 << (20 - PAGE_CACHE_SHIFT);
+       rc = lprocfs_write_frac_helper(buffer, count, &pages_number, mult);
+       if (rc)
+               return rc;
+
+       /* Cap this at the current max readahead window size, the readahead
+        * algorithm does this anyway so it's pointless to set it larger. */
+       if (pages_number < 0 ||
+           pages_number > sbi->ll_ra_info.ra_max_pages_per_file) {
+               CERROR("can't set max_read_ahead_whole_mb more than "
+                      "max_read_ahead_per_file_mb: %lu\n",
+                       sbi->ll_ra_info.ra_max_pages_per_file >>
+                       (20 - PAGE_CACHE_SHIFT));
+               return -ERANGE;
+       }
 
        spin_lock(&sbi->ll_lock);
        sbi->ll_ra_info.ra_max_read_ahead_whole_pages = pages_number;
@@ -366,7 +402,7 @@ static int ll_rd_max_cached_mb(char *page, char **start, off_t off,
        struct super_block     *sb    = data;
        struct ll_sb_info      *sbi   = ll_s2sbi(sb);
        struct cl_client_cache *cache = &sbi->ll_cache;
-       int shift = 20 - CFS_PAGE_SHIFT;
+       int shift = 20 - PAGE_CACHE_SHIFT;
        int max_cached_mb;
        int unused_mb;
 
@@ -397,21 +433,21 @@ static int ll_wr_max_cached_mb(struct file *file, const char *buffer,
        int nrpages = 0;
        ENTRY;
 
-       mult = 1 << (20 - CFS_PAGE_SHIFT);
+       mult = 1 << (20 - PAGE_CACHE_SHIFT);
        buffer = lprocfs_find_named_value(buffer, "max_cached_mb:", &count);
        rc = lprocfs_write_frac_helper(buffer, count, &pages_number, mult);
        if (rc)
                RETURN(rc);
 
-       if (pages_number < 0 || pages_number > cfs_num_physpages) {
+       if (pages_number < 0 || pages_number > totalram_pages) {
                CERROR("%s: can't set max cache more than %lu MB\n",
                       ll_get_fsname(sb, NULL, 0),
-                      cfs_num_physpages >> (20 - CFS_PAGE_SHIFT));
+                      totalram_pages >> (20 - PAGE_CACHE_SHIFT));
                RETURN(-ERANGE);
        }
 
-       if (sbi->ll_dt_exp == NULL)
-               RETURN(-ENODEV);
+       if (sbi->ll_dt_exp == NULL) /* being initialized */
+               GOTO(out, rc = 0);
 
        spin_lock(&sbi->ll_lock);
        diff = pages_number - cache->ccc_lru_max;
@@ -749,7 +785,7 @@ static int ll_rd_unstable_stats(char *page, char **start, off_t off,
        int pages, mb, rc;
 
        pages = cfs_atomic_read(&cache->ccc_unstable_nr);
-       mb    = (pages * CFS_PAGE_SIZE) >> 20;
+       mb    = (pages * PAGE_CACHE_SIZE) >> 20;
 
        rc = snprintf(page, count, "unstable_pages: %8d\n"
                                   "unstable_mb:    %8d\n", pages, mb);
@@ -788,6 +824,7 @@ static struct lprocfs_vars lprocfs_llite_obd_vars[] = {
         { "lazystatfs",       ll_rd_lazystatfs, ll_wr_lazystatfs, 0 },
         { "max_easize",       ll_rd_maxea_size, 0, 0 },
        { "sbi_flags",        ll_rd_sbi_flags, 0, 0 },
+       { "xattr_cache",      ll_rd_xattr_cache, ll_wr_xattr_cache, 0 },
        { "unstable_stats",   ll_rd_unstable_stats, 0, 0},
         { 0 }
 };
@@ -840,6 +877,7 @@ struct llite_file_opcode {
         { LPROC_LL_ALLOC_INODE,    LPROCFS_TYPE_REGS, "alloc_inode" },
         { LPROC_LL_SETXATTR,       LPROCFS_TYPE_REGS, "setxattr" },
         { LPROC_LL_GETXATTR,       LPROCFS_TYPE_REGS, "getxattr" },
+       { LPROC_LL_GETXATTR_HITS,  LPROCFS_TYPE_REGS, "getxattr_hits" },
         { LPROC_LL_LISTXATTR,      LPROCFS_TYPE_REGS, "listxattr" },
         { LPROC_LL_REMOVEXATTR,    LPROCFS_TYPE_REGS, "removexattr" },
         { LPROC_LL_INODE_PERM,     LPROCFS_TYPE_REGS, "inode_permission" },
@@ -857,9 +895,9 @@ void ll_stats_ops_tally(struct ll_sb_info *sbi, int op, int count)
         else if (sbi->ll_stats_track_type == STATS_TRACK_PPID &&
                  sbi->ll_stats_track_id == current->parent->pid)
                 lprocfs_counter_add(sbi->ll_stats, op, count);
-        else if (sbi->ll_stats_track_type == STATS_TRACK_GID &&
-                 sbi->ll_stats_track_id == cfs_curproc_gid())
-                lprocfs_counter_add(sbi->ll_stats, op, count);
+       else if (sbi->ll_stats_track_type == STATS_TRACK_GID &&
+                sbi->ll_stats_track_id == current_gid())
+               lprocfs_counter_add(sbi->ll_stats, op, count);
 }
 EXPORT_SYMBOL(ll_stats_ops_tally);
 
@@ -1081,12 +1119,12 @@ static int ll_rw_extents_stats_pp_seq_show(struct seq_file *seq, void *v)
         struct timeval now;
         struct ll_sb_info *sbi = seq->private;
         struct ll_rw_extents_info *io_extents = &sbi->ll_rw_extents_info;
-        int k;
+       int k;
 
-        cfs_gettimeofday(&now);
+       do_gettimeofday(&now);
 
-        if (!sbi->ll_rw_stats_on) {
-                seq_printf(seq, "disabled\n"
+       if (!sbi->ll_rw_stats_on) {
+               seq_printf(seq, "disabled\n"
                                 "write anything in this file to activate, "
                                 "then 0 or \"[D/d]isabled\" to deactivate\n");
                 return 0;
@@ -1143,13 +1181,13 @@ LPROC_SEQ_FOPS(ll_rw_extents_stats_pp);
 
 static int ll_rw_extents_stats_seq_show(struct seq_file *seq, void *v)
 {
-        struct timeval now;
-        struct ll_sb_info *sbi = seq->private;
-        struct ll_rw_extents_info *io_extents = &sbi->ll_rw_extents_info;
+       struct timeval now;
+       struct ll_sb_info *sbi = seq->private;
+       struct ll_rw_extents_info *io_extents = &sbi->ll_rw_extents_info;
 
-        cfs_gettimeofday(&now);
+       do_gettimeofday(&now);
 
-        if (!sbi->ll_rw_stats_on) {
+       if (!sbi->ll_rw_stats_on) {
                 seq_printf(seq, "disabled\n"
                                 "write anything in this file to activate, "
                                 "then 0 or \"[D/d]isabled\" to deactivate\n");
@@ -1309,11 +1347,11 @@ static int ll_rw_offset_stats_seq_show(struct seq_file *seq, void *v)
         struct ll_sb_info *sbi = seq->private;
         struct ll_rw_process_info *offset = sbi->ll_rw_offset_info;
         struct ll_rw_process_info *process = sbi->ll_rw_process_info;
-        int i;
+       int i;
 
-        cfs_gettimeofday(&now);
+       do_gettimeofday(&now);
 
-        if (!sbi->ll_rw_stats_on) {
+       if (!sbi->ll_rw_stats_on) {
                 seq_printf(seq, "disabled\n"
                                 "write anything in this file to activate, "
                                 "then 0 or \"[D/d]isabled\" to deactivate\n");
@@ -1326,30 +1364,34 @@ static int ll_rw_offset_stats_seq_show(struct seq_file *seq, void *v)
         seq_printf(seq, "%3s %10s %14s %14s %17s %17s %14s\n",
                    "R/W", "PID", "RANGE START", "RANGE END",
                    "SMALLEST EXTENT", "LARGEST EXTENT", "OFFSET");
-        /* We stored the discontiguous offsets here; print them first */
-        for(i = 0; i < LL_OFFSET_HIST_MAX; i++) {
-                if (offset[i].rw_pid != 0)
-                        seq_printf(seq,"%3c %10d %14Lu %14Lu %17lu %17lu %14Lu",
-                                   offset[i].rw_op ? 'W' : 'R',
-                                   offset[i].rw_pid,
-                                   offset[i].rw_range_start,
-                                   offset[i].rw_range_end,
-                                   (unsigned long)offset[i].rw_smallest_extent,
-                                   (unsigned long)offset[i].rw_largest_extent,
-                                   offset[i].rw_offset);
-        }
-        /* Then print the current offsets for each process */
-        for(i = 0; i < LL_PROCESS_HIST_MAX; i++) {
-                if (process[i].rw_pid != 0)
-                        seq_printf(seq,"%3c %10d %14Lu %14Lu %17lu %17lu %14Lu",
-                                   process[i].rw_op ? 'W' : 'R',
-                                   process[i].rw_pid,
-                                   process[i].rw_range_start,
-                                   process[i].rw_last_file_pos,
-                                   (unsigned long)process[i].rw_smallest_extent,
-                                   (unsigned long)process[i].rw_largest_extent,
-                                   process[i].rw_offset);
-        }
+
+       /* We stored the discontiguous offsets here; print them first */
+       for (i = 0; i < LL_OFFSET_HIST_MAX; i++) {
+               if (offset[i].rw_pid != 0)
+                       seq_printf(seq,
+                                  "%3c %10d %14Lu %14Lu %17lu %17lu %14Lu",
+                                  offset[i].rw_op == READ ? 'R' : 'W',
+                                  offset[i].rw_pid,
+                                  offset[i].rw_range_start,
+                                  offset[i].rw_range_end,
+                                  (unsigned long)offset[i].rw_smallest_extent,
+                                  (unsigned long)offset[i].rw_largest_extent,
+                                  offset[i].rw_offset);
+       }
+
+       /* Then print the current offsets for each process */
+       for (i = 0; i < LL_PROCESS_HIST_MAX; i++) {
+               if (process[i].rw_pid != 0)
+                       seq_printf(seq,
+                                  "%3c %10d %14Lu %14Lu %17lu %17lu %14Lu",
+                                  process[i].rw_op == READ ? 'R' : 'W',
+                                  process[i].rw_pid,
+                                  process[i].rw_range_start,
+                                  process[i].rw_last_file_pos,
+                                  (unsigned long)process[i].rw_smallest_extent,
+                                  (unsigned long)process[i].rw_largest_extent,
+                                  process[i].rw_offset);
+       }
        spin_unlock(&sbi->ll_process_lock);
 
        return 0;