sysctl: move maxolduid as a sysctl specific const
[linux-2.6-microblaze.git] / fs / inode.c
index 6b80a51..63324df 100644 (file)
@@ -67,11 +67,6 @@ const struct address_space_operations empty_aops = {
 };
 EXPORT_SYMBOL(empty_aops);
 
-/*
- * Statistics gathering..
- */
-struct inodes_stat_t inodes_stat;
-
 static DEFINE_PER_CPU(unsigned long, nr_inodes);
 static DEFINE_PER_CPU(unsigned long, nr_unused);
 
@@ -106,13 +101,43 @@ long get_nr_dirty_inodes(void)
  * Handle nr_inode sysctl
  */
 #ifdef CONFIG_SYSCTL
-int proc_nr_inodes(struct ctl_table *table, int write,
-                  void *buffer, size_t *lenp, loff_t *ppos)
+/*
+ * Statistics gathering..
+ */
+static struct inodes_stat_t inodes_stat;
+
+static int proc_nr_inodes(struct ctl_table *table, int write, void *buffer,
+                         size_t *lenp, loff_t *ppos)
 {
        inodes_stat.nr_inodes = get_nr_inodes();
        inodes_stat.nr_unused = get_nr_inodes_unused();
        return proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
 }
+
+static struct ctl_table inodes_sysctls[] = {
+       {
+               .procname       = "inode-nr",
+               .data           = &inodes_stat,
+               .maxlen         = 2*sizeof(long),
+               .mode           = 0444,
+               .proc_handler   = proc_nr_inodes,
+       },
+       {
+               .procname       = "inode-state",
+               .data           = &inodes_stat,
+               .maxlen         = 7*sizeof(long),
+               .mode           = 0444,
+               .proc_handler   = proc_nr_inodes,
+       },
+       { }
+};
+
+static int __init init_fs_inode_sysctls(void)
+{
+       register_sysctl_init("fs", inodes_sysctls);
+       return 0;
+}
+early_initcall(init_fs_inode_sysctls);
 #endif
 
 static int no_open(struct inode *inode, struct file *file)
@@ -526,6 +551,55 @@ void __remove_inode_hash(struct inode *inode)
 }
 EXPORT_SYMBOL(__remove_inode_hash);
 
+void dump_mapping(const struct address_space *mapping)
+{
+       struct inode *host;
+       const struct address_space_operations *a_ops;
+       struct hlist_node *dentry_first;
+       struct dentry *dentry_ptr;
+       struct dentry dentry;
+       unsigned long ino;
+
+       /*
+        * If mapping is an invalid pointer, we don't want to crash
+        * accessing it, so probe everything depending on it carefully.
+        */
+       if (get_kernel_nofault(host, &mapping->host) ||
+           get_kernel_nofault(a_ops, &mapping->a_ops)) {
+               pr_warn("invalid mapping:%px\n", mapping);
+               return;
+       }
+
+       if (!host) {
+               pr_warn("aops:%ps\n", a_ops);
+               return;
+       }
+
+       if (get_kernel_nofault(dentry_first, &host->i_dentry.first) ||
+           get_kernel_nofault(ino, &host->i_ino)) {
+               pr_warn("aops:%ps invalid inode:%px\n", a_ops, host);
+               return;
+       }
+
+       if (!dentry_first) {
+               pr_warn("aops:%ps ino:%lx\n", a_ops, ino);
+               return;
+       }
+
+       dentry_ptr = container_of(dentry_first, struct dentry, d_u.d_alias);
+       if (get_kernel_nofault(dentry, dentry_ptr)) {
+               pr_warn("aops:%ps ino:%lx invalid dentry:%px\n",
+                               a_ops, ino, dentry_ptr);
+               return;
+       }
+
+       /*
+        * if dentry is corrupted, the %pd handler may still crash,
+        * but it's unlikely that we reach here with a corrupt mapping
+        */
+       pr_warn("aops:%ps ino:%lx dentry name:\"%pd\"\n", a_ops, ino, &dentry);
+}
+
 void clear_inode(struct inode *inode)
 {
        /*