diff options
-rw-r--r-- | fs/pstore/inode.c | 32 | ||||
-rw-r--r-- | fs/pstore/internal.h | 1 | ||||
-rw-r--r-- | fs/pstore/platform.c | 3 |
3 files changed, 36 insertions, 0 deletions
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index 0e76e12fa6d1..c331efe8de95 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c @@ -36,6 +36,7 @@ static struct super_block *pstore_sb; struct pstore_private { struct list_head list; + struct dentry *dentry; struct pstore_record *record; size_t total_size; }; @@ -191,6 +192,7 @@ static int pstore_unlink(struct inode *dir, struct dentry *dentry) list_del_init(&p->list); else rc = -ENOENT; + p->dentry = NULL; mutex_unlock(&records_list_lock); if (rc) return rc; @@ -306,6 +308,35 @@ static struct dentry *psinfo_lock_root(void) return root; } +int pstore_put_backend_records(struct pstore_info *psi) +{ + struct pstore_private *pos, *tmp; + struct dentry *root; + int rc = 0; + + root = psinfo_lock_root(); + if (!root) + return 0; + + mutex_lock(&records_list_lock); + list_for_each_entry_safe(pos, tmp, &records_list, list) { + if (pos->record->psi == psi) { + list_del_init(&pos->list); + rc = simple_unlink(d_inode(root), pos->dentry); + if (WARN_ON(rc)) + break; + d_drop(pos->dentry); + dput(pos->dentry); + pos->dentry = NULL; + } + } + mutex_unlock(&records_list_lock); + + inode_unlock(d_inode(root)); + + return rc; +} + /* * Make a regular file in the root directory of our file system. * Load it up with "size" bytes of data from "buf". @@ -352,6 +383,7 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record) if (!dentry) goto fail_private; + private->dentry = dentry; private->record = record; inode->i_size = private->total_size = size; inode->i_private = private; diff --git a/fs/pstore/internal.h b/fs/pstore/internal.h index fe5f7ef7323f..8efd72d93b10 100644 --- a/fs/pstore/internal.h +++ b/fs/pstore/internal.h @@ -31,6 +31,7 @@ extern void pstore_set_kmsg_bytes(int); extern void pstore_get_records(int); extern void pstore_get_backend_records(struct pstore_info *psi, struct dentry *root, int quiet); +extern int pstore_put_backend_records(struct pstore_info *psi); extern int pstore_mkfile(struct dentry *root, struct pstore_record *record); extern void pstore_record_init(struct pstore_record *record, diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 327ee70e881d..398785ab059f 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -657,6 +657,9 @@ void pstore_unregister(struct pstore_info *psi) del_timer_sync(&pstore_timer); flush_work(&pstore_work); + /* Remove all backend records from filesystem tree. */ + pstore_put_backend_records(psi); + free_buf_for_compression(); psinfo = NULL; |