summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/pstore/inode.c37
-rw-r--r--fs/pstore/internal.h5
-rw-r--r--fs/pstore/platform.c10
3 files changed, 36 insertions, 16 deletions
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index 06504b69575b..792a4e5f9226 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -311,9 +311,8 @@ bool pstore_is_mounted(void)
* Load it up with "size" bytes of data from "buf".
* Set the mtime & ctime to the date that this record was originally stored.
*/
-int pstore_mkfile(struct pstore_record *record)
+int pstore_mkfile(struct dentry *root, struct pstore_record *record)
{
- struct dentry *root = pstore_sb->s_root;
struct dentry *dentry;
struct inode *inode;
int rc = 0;
@@ -322,6 +321,8 @@ int pstore_mkfile(struct pstore_record *record)
unsigned long flags;
size_t size = record->size + record->ecc_notice_size;
+ WARN_ON(!inode_is_locked(d_inode(root)));
+
spin_lock_irqsave(&allpstore_lock, flags);
list_for_each_entry(pos, &allpstore, list) {
if (pos->record->type == record->type &&
@@ -336,7 +337,7 @@ int pstore_mkfile(struct pstore_record *record)
return rc;
rc = -ENOMEM;
- inode = pstore_get_inode(pstore_sb);
+ inode = pstore_get_inode(root->d_sb);
if (!inode)
goto fail;
inode->i_mode = S_IFREG | 0444;
@@ -394,11 +395,9 @@ int pstore_mkfile(struct pstore_record *record)
break;
}
- inode_lock(d_inode(root));
-
dentry = d_alloc_name(root, name);
if (!dentry)
- goto fail_lockedalloc;
+ goto fail_private;
inode->i_size = private->total_size = size;
@@ -413,12 +412,9 @@ int pstore_mkfile(struct pstore_record *record)
list_add(&private->list, &allpstore);
spin_unlock_irqrestore(&allpstore_lock, flags);
- inode_unlock(d_inode(root));
-
return 0;
-fail_lockedalloc:
- inode_unlock(d_inode(root));
+fail_private:
free_pstore_private(private);
fail_alloc:
iput(inode);
@@ -427,6 +423,27 @@ fail:
return rc;
}
+/*
+ * Read all the records from the persistent store. Create
+ * files in our filesystem. Don't warn about -EEXIST errors
+ * when we are re-scanning the backing store looking to add new
+ * error records.
+ */
+void pstore_get_records(int quiet)
+{
+ struct pstore_info *psi = psinfo;
+ struct dentry *root;
+
+ if (!psi || !pstore_sb)
+ return;
+
+ root = pstore_sb->s_root;
+
+ inode_lock(d_inode(root));
+ pstore_get_backend_records(psi, root, quiet);
+ inode_unlock(d_inode(root));
+}
+
static int pstore_fill_super(struct super_block *sb, void *data, int silent)
{
struct inode *inode;
diff --git a/fs/pstore/internal.h b/fs/pstore/internal.h
index af1df5a36d86..c416e653dc4f 100644
--- a/fs/pstore/internal.h
+++ b/fs/pstore/internal.h
@@ -25,7 +25,10 @@ extern struct pstore_info *psinfo;
extern void pstore_set_kmsg_bytes(int);
extern void pstore_get_records(int);
-extern int pstore_mkfile(struct pstore_record *record);
+extern void pstore_get_backend_records(struct pstore_info *psi,
+ struct dentry *root, int quiet);
+extern int pstore_mkfile(struct dentry *root,
+ struct pstore_record *record);
extern bool pstore_is_mounted(void);
#endif
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 43b3ca5e045f..d468eec9b8a6 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -810,17 +810,17 @@ static void decompress_record(struct pstore_record *record)
}
/*
- * Read all the records from the persistent store. Create
+ * Read all the records from one persistent store backend. Create
* files in our filesystem. Don't warn about -EEXIST errors
* when we are re-scanning the backing store looking to add new
* error records.
*/
-void pstore_get_records(int quiet)
+void pstore_get_backend_records(struct pstore_info *psi,
+ struct dentry *root, int quiet)
{
- struct pstore_info *psi = psinfo;
int failed = 0;
- if (!psi)
+ if (!psi || !root)
return;
mutex_lock(&psi->read_mutex);
@@ -850,7 +850,7 @@ void pstore_get_records(int quiet)
break;
decompress_record(record);
- rc = pstore_mkfile(record);
+ rc = pstore_mkfile(root, record);
if (rc) {
/* pstore_mkfile() did not take record, so free it. */
kfree(record->buf);