From: Ian Pilcher <arequipeno@gmail.com>
To: linux-bcache@vger.kernel.org
Subject: RFC: Handle "device busy" error when registering
Date: Tue, 22 Jul 2014 00:13:00 -0500 [thread overview]
Message-ID: <lqkrss$h1s$1@ger.gmane.org> (raw)
In-Reply-To: <lqcd46$hvl$1@ger.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1563 bytes --]
On 07/18/2014 07:11 PM, Ian Pilcher wrote:
> Suggested fix:
>
> (1) Change bcache_register to return -EBUSY in the device busy case
> (while still returning -EINVAL in the already registered case).
>
> (2) Change bcache-register to check the exit code of the registration
> attempt and retry in the EBUSY case.
>
> Does this make sense?
I've gone ahead and implemented an initial version of this approach.
See the attached files:
* linux-bcache-register-retval.patch - Makes bcache_register return
-EBUSY when it is unable to get exclusive access to the device, but
the device is not already registered. It still returns -EINVAL in all
other error cases.
This allows userspace to distinguish the "device busy" case from other
errors. I couldn't find an easy way to make this determination from a
shell script, though, so I created ...
* bcreg.c - This does most of the work that was previously done in the
bcache-register script. Specifically, it will wait for the sysfs
register file to be created and then write the name of the device to
that file -- retrying if it encounters an EBUSY.
* bcache-register - bcreg doesn't call modprobe, so this script is still
required. It now calls bcreg to register the device.
Thoughts?
--
========================================================================
Ian Pilcher arequipeno@gmail.com
-------- "I grew up before Mark Zuckerberg invented friendship" --------
========================================================================
[-- Attachment #2: bcache-register --]
[-- Type: text/plain, Size: 65 bytes --]
#!/bin/sh
/sbin/modprobe -qba bcache
exec /usr/lib/udev/bcreg $1
[-- Attachment #3: bcreg.c --]
[-- Type: text/x-csrc, Size: 1674 bytes --]
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
/* How often to wake up and check when waiting for something; 1/10 second */
#define WAKEUP_NSEC 100000000L
/* Timeouts are in multiples of WAKEUP_NSEC */
#define SYSFS_TIMEOUT 50 /* 5 seconds */
#define DEVICE_TIMEOUT 50 /* 5 seconds */
static const char sysfs_reg[] = "/sys/fs/bcache/register";
int main(int argc, char *argv[])
{
struct timespec timeout;
size_t len;
int i, fd;
if (argc != 2) {
fprintf(stderr, "USAGE: %s <BLOCK_DEVICE>\n", argv[0]);
exit(EXIT_FAILURE);
}
i = SYSFS_TIMEOUT;
while (1) {
fd = open(sysfs_reg, O_WRONLY);
if (fd != -1)
break;
if (errno != ENOENT) {
perror(sysfs_reg);
exit(EXIT_FAILURE);
}
if (i-- == 0) {
fprintf(stderr, "Timed out waiting for %s\n", sysfs_reg);
exit(EXIT_FAILURE);
}
timeout.tv_sec = 0;
timeout.tv_nsec = WAKEUP_NSEC;
if (nanosleep(&timeout, NULL) == -1) {
perror("nanosleep");
exit(EXIT_FAILURE);
}
}
len = strlen(argv[1]);
i = DEVICE_TIMEOUT;
while (1) {
if (lseek(fd, 0, SEEK_SET) == -1) {
perror(sysfs_reg);
close(fd);
exit(EXIT_FAILURE);
}
if (write(fd, argv[1], len) == (ssize_t)len)
break;
if (errno != EBUSY) {
perror(argv[1]);
close(fd);
exit(EXIT_FAILURE);
}
if (i-- == 0) {
fprintf(stderr, "Timed out waiting for %s\n", argv[1]);
close(fd);
exit(EXIT_FAILURE);
}
timeout.tv_sec = 0;
timeout.tv_nsec = WAKEUP_NSEC;
if (nanosleep(&timeout, NULL) == -1) {
perror("nanosleep");
close(fd);
exit(EXIT_FAILURE);
}
}
close(fd);
return 0;
}
[-- Attachment #4: linux-bcache-register-retval.patch --]
[-- Type: text/x-patch, Size: 1054 bytes --]
--- ./drivers/md/bcache/super.c.orig 2014-07-21 09:43:03.599875510 -0400
+++ ./drivers/md/bcache/super.c 2014-07-21 11:22:56.774478317 -0400
@@ -1924,7 +1924,7 @@
static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
const char *buffer, size_t size)
{
- ssize_t ret = size;
+ ssize_t ret = -EINVAL;
const char *err = "cannot allocate memory";
char *path = NULL;
struct cache_sb *sb = NULL;
@@ -1945,10 +1945,12 @@
if (IS_ERR(bdev)) {
if (bdev == ERR_PTR(-EBUSY)) {
bdev = lookup_bdev(strim(path));
- if (!IS_ERR(bdev) && bch_is_open(bdev))
+ if (!IS_ERR(bdev) && bch_is_open(bdev)) {
err = "device already registered";
- else
+ } else {
err = "device busy";
+ ret = -EBUSY;
+ }
}
goto err;
}
@@ -1976,6 +1978,9 @@
register_cache(sb, sb_page, bdev, ca);
}
+
+ ret = size;
+
out:
if (sb_page)
put_page(sb_page);
@@ -1989,7 +1994,6 @@
err:
if (attr != &ksysfs_register_quiet)
pr_info("error opening %s: %s", path, err);
- ret = -EINVAL;
goto out;
}
next prev parent reply other threads:[~2014-07-22 5:13 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-19 0:11 "device busy" error when registering device Ian Pilcher
2014-07-19 7:23 ` Josep Lladonosa
2014-07-22 4:46 ` Ian Pilcher
2014-07-22 5:13 ` Ian Pilcher [this message]
2014-07-23 3:43 ` RFC: Handle "device busy" error when registering Ian Pilcher
2014-08-13 20:24 ` "device busy" error when registering device Rolf Fokkens
2014-08-20 1:38 ` Ian Pilcher
2014-09-06 7:34 ` Rolf Fokkens
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='lqkrss$h1s$1@ger.gmane.org' \
--to=arequipeno@gmail.com \
--cc=linux-bcache@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.