From: Linus Torvalds <torvalds@linux-foundation.org>
To: Al Viro <viro@zeniv.linux.org.uk>
Cc: Mauro Carvalho Chehab <mchehab@redhat.com>,
Ming Lei <ming.lei@canonical.com>,
Greg KH <gregkh@linuxfoundation.org>, Kay Sievers <kay@vrfy.org>,
Lennart Poettering <lennart@poettering.net>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Kay Sievers <kay@redhat.com>,
Linux Media Mailing List <linux-media@vger.kernel.org>,
Michael Krufky <mkrufky@linuxtv.org>,
Ivan Kalvachev <ikalvachev@gmail.com>
Subject: Re: udev breakages - was: Re: Need of an ".async_probe()" type of callback at driver's core - Was: Re: [PATCH] [media] drxk: change it to use request_firmware_nowait()
Date: Wed, 3 Oct 2012 10:32:08 -0700 [thread overview]
Message-ID: <CA+55aFw0pB99ztq5YUS56db-ijdxzevA=mvY3ce5O_yujVFOcA@mail.gmail.com> (raw)
In-Reply-To: <20121003170907.GA23473@ZenIV.linux.org.uk>
[-- Attachment #1: Type: text/plain, Size: 714 bytes --]
On Wed, Oct 3, 2012 at 10:09 AM, Al Viro <viro@zeniv.linux.org.uk> wrote:
>
> + if (!S_ISREG(inode->i_mode))
> + return false;
> + size = i_size_read(inode);
>
> Probably better to do vfs_getattr() and check mode and size in kstat; if
> it's sufficiently hot for that to hurt, we are fucked anyway.
>
> + file = filp_open(path, O_RDONLY, 0);
> + if (IS_ERR(file))
> + continue;
> +printk("from file '%s' ", path);
> + success = fw_read_file_contents(file, fw);
> + filp_close(file, NULL);
>
> fput(file), please. We have enough misuses of filp_close() as it is...
Ok, like this?
Linus
[-- Attachment #2: patch.diff --]
[-- Type: application/octet-stream, Size: 2814 bytes --]
drivers/base/firmware_class.c | 73 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 72 insertions(+), 1 deletion(-)
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 6e210802c37b..38feac4af991 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -21,6 +21,7 @@
#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/sched.h>
+#include <linux/file.h>
#include <linux/list.h>
#include <linux/async.h>
#include <linux/pm.h>
@@ -33,6 +34,67 @@ MODULE_AUTHOR("Manuel Estrada Sainz");
MODULE_DESCRIPTION("Multi purpose firmware loading support");
MODULE_LICENSE("GPL");
+/* Don't inline this: 'struct kstat' is biggish */
+static noinline long fw_file_size(struct file *file)
+{
+ struct kstat st;
+ if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st))
+ return -1;
+ if (!S_ISREG(st.mode))
+ return -1;
+ if (st.size != (long)st.size)
+ return -1;
+ return st.size;
+}
+
+static bool fw_read_file_contents(struct file *file, struct firmware *fw)
+{
+ loff_t pos;
+ long size;
+ char *buf;
+
+ size = fw_file_size(file);
+ if (size < 0)
+ return false;
+ buf = vmalloc(size);
+ if (!buf)
+ return false;
+ pos = 0;
+ if (vfs_read(file, buf, size, &pos) != size) {
+ vfree(buf);
+ return false;
+ }
+ fw->data = buf;
+ fw->size = size;
+ return true;
+}
+
+static bool fw_get_filesystem_firmware(struct firmware *fw, const char *name)
+{
+ int i;
+ bool success = false;
+ const char *fw_path[] = { "/lib/firmware/update", "/firmware", "/lib/firmware" };
+ char *path = __getname();
+
+printk("Trying to load fw '%s' ", name);
+ for (i = 0; i < ARRAY_SIZE(fw_path); i++) {
+ struct file *file;
+ snprintf(path, PATH_MAX, "%s/%s", fw_path[i], name);
+
+ file = filp_open(path, O_RDONLY, 0);
+ if (IS_ERR(file))
+ continue;
+printk("from file '%s' ", path);
+ success = fw_read_file_contents(file, fw);
+ fput(file);
+ if (success)
+ break;
+ }
+printk(" %s.\n", success ? "Ok" : "failed");
+ __putname(path);
+ return success;
+}
+
/* Builtin firmware support */
#ifdef CONFIG_FW_LOADER
@@ -346,7 +408,11 @@ static ssize_t firmware_loading_show(struct device *dev,
/* firmware holds the ownership of pages */
static void firmware_free_data(const struct firmware *fw)
{
- WARN_ON(!fw->priv);
+ /* Loaded directly? */
+ if (!fw->priv) {
+ vfree(fw->data);
+ return;
+ }
fw_free_buf(fw->priv);
}
@@ -709,6 +775,11 @@ _request_firmware_prepare(const struct firmware **firmware_p, const char *name,
return NULL;
}
+ if (fw_get_filesystem_firmware(firmware, name)) {
+ dev_dbg(device, "firmware: direct-loading firmware %s\n", name);
+ return NULL;
+ }
+
ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf);
if (!ret)
fw_priv = fw_create_instance(firmware, name, device,
next prev parent reply other threads:[~2012-10-03 17:32 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1340285798-8322-1-git-send-email-mchehab@redhat.com>
[not found] ` <4FE37194.30407@redhat.com>
[not found] ` <4FE8B8BC.3020702@iki.fi>
[not found] ` <4FE8C4C4.1050901@redhat.com>
[not found] ` <4FE8CED5.104@redhat.com>
[not found] ` <20120625223306.GA2764@kroah.com>
[not found] ` <4FE9169D.5020300@redhat.com>
2012-10-02 13:03 ` udev breakages - was: Re: Need of an ".async_probe()" type of callback at driver's core - Was: Re: [PATCH] [media] drxk: change it to use request_firmware_nowait() Mauro Carvalho Chehab
2012-10-02 16:33 ` Linus Torvalds
2012-10-02 21:03 ` Ivan Kalvachev
2012-10-02 22:37 ` Linus Torvalds
2012-10-03 22:15 ` Lucas De Marchi
2012-10-11 18:33 ` Shea Levy
2012-10-12 1:55 ` Ming Lei
2012-10-02 22:12 ` Greg KH
2012-10-02 22:23 ` Greg KH
2012-10-02 22:47 ` Linus Torvalds
2012-10-03 0:01 ` Jiri Kosina
2012-10-03 0:12 ` Linus Torvalds
2012-10-04 14:36 ` Jiri Kosina
2012-10-03 15:13 ` Mauro Carvalho Chehab
2012-10-03 16:38 ` Linus Torvalds
2012-10-03 17:00 ` Linus Torvalds
2012-10-03 17:09 ` Al Viro
2012-10-03 17:32 ` Linus Torvalds [this message]
2012-10-03 19:26 ` Al Viro
2012-10-04 0:57 ` udev breakages - Nix
2012-10-04 10:35 ` Nix
2012-10-03 19:50 ` udev breakages - was: Re: Need of an ".async_probe()" type of callback at driver's core - Was: Re: [PATCH] [media] drxk: change it to use request_firmware_nowait() Greg KH
2012-10-03 20:39 ` Linus Torvalds
2012-10-03 21:04 ` Kay Sievers
2012-10-03 21:05 ` Greg KH
2012-10-03 21:18 ` Kay Sievers
2012-10-03 21:45 ` Alan Cox
2012-10-03 21:58 ` Lucas De Marchi
2012-10-03 22:17 ` Linus Torvalds
2012-10-03 22:48 ` Andy Walls
2012-10-03 22:58 ` Linus Torvalds
2012-10-04 2:39 ` Kay Sievers
2012-10-04 17:29 ` udev breakages - Eric W. Biederman
2012-10-04 17:42 ` Greg KH
2012-10-04 19:17 ` Alan Cox
2012-10-10 3:19 ` Felipe Contreras
2012-10-10 16:08 ` Geert Uytterhoeven
2012-10-11 3:32 ` Eric W. Biederman
2012-10-04 13:39 ` udev breakages - was: Re: Need of an ".async_probe()" type of callback at driver's core - Was: Re: [PATCH] [media] drxk: change it to use request_firmware_nowait() Josh Boyer
2012-10-04 13:58 ` Greg KH
2012-10-03 22:53 ` Stephen Rothwell
2012-10-03 21:10 ` Andy Walls
2012-10-03 19:48 ` Access files from kernel Kirill A. Shutemov
2012-10-03 20:32 ` Linus Torvalds
[not found] ` <CACVXFVNTZmG+zTQNi9mCn9ynsCjkM084TmHKDcYYggtqLfhqNQ@mail.gmail.com>
2012-10-04 1:42 ` udev breakages - was: Re: Need of an ".async_probe()" type of callback at driver's core - Was: Re: [PATCH] [media] drxk: change it to use request_firmware_nowait() Linus Torvalds
2012-10-03 14:12 ` Mauro Carvalho Chehab
2012-10-03 14:36 ` Kay Sievers
2012-10-03 14:44 ` Linus Torvalds
2012-10-03 16:57 ` Greg KH
2012-10-03 17:24 ` Kay Sievers
2012-10-03 18:07 ` Linus Torvalds
2012-10-03 19:46 ` Mauro Carvalho Chehab
[not found] <fa.90I1W/wmSTgRFXVG67o7Pp3+rKA@ifi.uio.no>
[not found] ` <fa.Oszo+r/ZqdTxC2FHqqg+CRVMJ5Y@ifi.uio.no>
[not found] ` <fa.CoxzZZId9dJONv353c+pFG/HO8E@ifi.uio.no>
[not found] ` <fa.ixJ/7D7BnMK8xp7CwikX7jbmnKU@ifi.uio.no>
[not found] ` <fa./ubRQE7P/T+ateohnOKdDxOFhL4@ifi.uio.no>
[not found] ` <fa.lpiFTa5CtuIkUf2Z5eJ0YlsNwYI@ifi.uio.no>
2012-10-04 14:50 ` Kurt H Maier
2012-10-05 8:03 ` Emmanuel Benisty
2012-10-05 20:17 ` david
2012-10-05 21:43 ` Henrique de Moraes Holschuh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CA+55aFw0pB99ztq5YUS56db-ijdxzevA=mvY3ce5O_yujVFOcA@mail.gmail.com' \
--to=torvalds@linux-foundation.org \
--cc=gregkh@linuxfoundation.org \
--cc=ikalvachev@gmail.com \
--cc=kay@redhat.com \
--cc=kay@vrfy.org \
--cc=lennart@poettering.net \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@redhat.com \
--cc=ming.lei@canonical.com \
--cc=mkrufky@linuxtv.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).