Merge branch 'modsplit-Oct31_2011' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / fs / pstore / inode.c
index 893b961..379a02d 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/highmem.h>
 #include <linux/time.h>
 #include <linux/init.h>
+#include <linux/list.h>
 #include <linux/string.h>
 #include <linux/mount.h>
 #include <linux/ramfs.h>
 #include <linux/magic.h>
 #include <linux/pstore.h>
 #include <linux/slab.h>
+#include <linux/spinlock.h>
 #include <linux/uaccess.h>
 
 #include "internal.h"
 
 #define        PSTORE_NAMELEN  64
 
+static DEFINE_SPINLOCK(allpstore_lock);
+static LIST_HEAD(allpstore);
+
 struct pstore_private {
+       struct list_head list;
        struct pstore_info *psi;
        enum pstore_type_id type;
        u64     id;
@@ -81,8 +87,16 @@ static int pstore_unlink(struct inode *dir, struct dentry *dentry)
 
 static void pstore_evict_inode(struct inode *inode)
 {
+       struct pstore_private   *p = inode->i_private;
+       unsigned long           flags;
+
        end_writeback(inode);
-       kfree(inode->i_private);
+       if (p) {
+               spin_lock_irqsave(&allpstore_lock, flags);
+               list_del(&p->list);
+               spin_unlock_irqrestore(&allpstore_lock, flags);
+               kfree(p);
+       }
 }
 
 static const struct inode_operations pstore_dir_inode_operations = {
@@ -182,9 +196,23 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id,
        struct dentry           *root = pstore_sb->s_root;
        struct dentry           *dentry;
        struct inode            *inode;
-       int                     rc;
+       int                     rc = 0;
        char                    name[PSTORE_NAMELEN];
-       struct pstore_private   *private;
+       struct pstore_private   *private, *pos;
+       unsigned long           flags;
+
+       spin_lock_irqsave(&allpstore_lock, flags);
+       list_for_each_entry(pos, &allpstore, list) {
+               if (pos->type == type &&
+                   pos->id == id &&
+                   pos->psi == psi) {
+                       rc = -EEXIST;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&allpstore_lock, flags);
+       if (rc)
+               return rc;
 
        rc = -ENOMEM;
        inode = pstore_get_inode(pstore_sb, root->d_inode, S_IFREG | 0444, 0);
@@ -229,6 +257,10 @@ int pstore_mkfile(enum pstore_type_id type, char *psname, u64 id,
 
        d_add(dentry, inode);
 
+       spin_lock_irqsave(&allpstore_lock, flags);
+       list_add(&private->list, &allpstore);
+       spin_unlock_irqrestore(&allpstore_lock, flags);
+
        mutex_unlock(&root->d_inode->i_mutex);
 
        return 0;
@@ -277,7 +309,7 @@ int pstore_fill_super(struct super_block *sb, void *data, int silent)
                goto fail;
        }
 
-       pstore_get_records();
+       pstore_get_records(0);
 
        return 0;
 fail: