mm,fs: split dump_mapping() out from dump_page()
[sfrench/cifs-2.6.git] / fs / inode.c
index 6b80a51129d56f4175326e1faf1429e4f730f8b9..980e7b7a546077af6a79639889d85b0bcf95fc27 100644 (file)
@@ -526,6 +526,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)
 {
        /*