Merge remote-tracking branch 'block/for-next'
[deliverable/linux.git] / fs / pstore / platform.c
index 16ecca5b72d815d92163def3f03bd9f26c4cc8b1..14984d902a99286ad19a27a906fa0ac2a7255613 100644 (file)
@@ -623,6 +623,40 @@ static int pstore_write_compat(enum pstore_type_id type,
                             size, psi);
 }
 
+static int pstore_write_buf_user_compat(enum pstore_type_id type,
+                              enum kmsg_dump_reason reason,
+                              u64 *id, unsigned int part,
+                              const char __user *buf,
+                              bool compressed, size_t size,
+                              struct pstore_info *psi)
+{
+       unsigned long flags = 0;
+       size_t i, bufsize = size;
+       long ret = 0;
+
+       if (unlikely(!access_ok(VERIFY_READ, buf, size)))
+               return -EFAULT;
+       if (bufsize > psinfo->bufsize)
+               bufsize = psinfo->bufsize;
+       spin_lock_irqsave(&psinfo->buf_lock, flags);
+       for (i = 0; i < size; ) {
+               size_t c = min(size - i, bufsize);
+
+               ret = __copy_from_user(psinfo->buf, buf + i, c);
+               if (unlikely(ret != 0)) {
+                       ret = -EFAULT;
+                       break;
+               }
+               ret = psi->write_buf(type, reason, id, part, psinfo->buf,
+                                    compressed, c, psi);
+               if (unlikely(ret < 0))
+                       break;
+               i += c;
+       }
+       spin_unlock_irqrestore(&psinfo->buf_lock, flags);
+       return unlikely(ret < 0) ? ret : size;
+}
+
 /*
  * platform specific persistent storage driver registers with
  * us here. If pstore is already mounted, call the platform
@@ -645,6 +679,8 @@ int pstore_register(struct pstore_info *psi)
 
        if (!psi->write)
                psi->write = pstore_write_compat;
+       if (!psi->write_buf_user)
+               psi->write_buf_user = pstore_write_buf_user_compat;
        psinfo = psi;
        mutex_init(&psinfo->read_mutex);
        spin_unlock(&pstore_lock);
@@ -659,13 +695,14 @@ int pstore_register(struct pstore_info *psi)
        if (pstore_is_mounted())
                pstore_get_records(0);
 
-       pstore_register_kmsg();
-
-       if ((psi->flags & PSTORE_FLAGS_FRAGILE) == 0) {
+       if (psi->flags & PSTORE_FLAGS_DMESG)
+               pstore_register_kmsg();
+       if (psi->flags & PSTORE_FLAGS_CONSOLE)
                pstore_register_console();
+       if (psi->flags & PSTORE_FLAGS_FTRACE)
                pstore_register_ftrace();
+       if (psi->flags & PSTORE_FLAGS_PMSG)
                pstore_register_pmsg();
-       }
 
        if (pstore_update_ms >= 0) {
                pstore_timer.expires = jiffies +
@@ -689,12 +726,14 @@ EXPORT_SYMBOL_GPL(pstore_register);
 
 void pstore_unregister(struct pstore_info *psi)
 {
-       if ((psi->flags & PSTORE_FLAGS_FRAGILE) == 0) {
+       if (psi->flags & PSTORE_FLAGS_PMSG)
                pstore_unregister_pmsg();
+       if (psi->flags & PSTORE_FLAGS_FTRACE)
                pstore_unregister_ftrace();
+       if (psi->flags & PSTORE_FLAGS_CONSOLE)
                pstore_unregister_console();
-       }
-       pstore_unregister_kmsg();
+       if (psi->flags & PSTORE_FLAGS_DMESG)
+               pstore_unregister_kmsg();
 
        free_buf_for_compression();
 
This page took 0.025039 seconds and 5 git commands to generate.