* [PATCH v4] file-posix: detect the lock using the real file
@ 2020-12-15 7:09 Li Feng
2020-12-15 10:08 ` Daniel P. Berrangé
0 siblings, 1 reply; 3+ messages in thread
From: Li Feng @ 2020-12-15 7:09 UTC (permalink / raw)
To: berrange, Kevin Wolf, Max Reitz, open list:raw,
open list:All patches CC here
Cc: lifeng1519, Li Feng, kyle
This patch addresses this issue:
When accessing a volume on an NFS filesystem without supporting the file lock,
tools, like qemu-img, will complain "Failed to lock byte 100".
In the original code, the qemu_has_ofd_lock will test the lock on the
"/dev/null" pseudo-file. Actually, the file.locking is per-drive property,
which depends on the underlay filesystem.
In this patch, add a new 'qemu_has_file_lock' to detect whether the
file supports the file lock. And disable the lock when the underlay file
system doesn't support locks.
Signed-off-by: Li Feng <fengli@smartx.com>
---
v4: use the fd as the qemu_has_file_lock argument.
v3: don't call the qemu_has_ofd_lock, use a new function instead.
v2: remove the refactoring.
---
block/file-posix.c | 66 +++++++++++++++++++++++++-------------------
include/qemu/osdep.h | 1 +
util/osdep.c | 19 +++++++++++++
3 files changed, 58 insertions(+), 28 deletions(-)
diff --git a/block/file-posix.c b/block/file-posix.c
index 806764f7e3..9708212f01 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -584,6 +584,21 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
s->use_linux_io_uring = (aio == BLOCKDEV_AIO_OPTIONS_IO_URING);
#endif
+ s->open_flags = open_flags;
+ raw_parse_flags(bdrv_flags, &s->open_flags, false);
+
+ s->fd = -1;
+ fd = qemu_open(filename, s->open_flags, errp);
+ ret = fd < 0 ? -errno : 0;
+
+ if (ret < 0) {
+ if (ret == -EROFS) {
+ ret = -EACCES;
+ }
+ goto fail;
+ }
+ s->fd = fd;
+
locking = qapi_enum_parse(&OnOffAuto_lookup,
qemu_opt_get(opts, "locking"),
ON_OFF_AUTO_AUTO, &local_err);
@@ -607,6 +622,13 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
break;
case ON_OFF_AUTO_AUTO:
s->use_lock = qemu_has_ofd_lock();
+ if (s->use_lock && !qemu_has_file_lock(s->fd)) {
+ /*
+ * When the os supports the OFD lock, but the filesystem doesn't
+ * support, just disable the file lock.
+ */
+ s->use_lock = false;
+ }
break;
default:
abort();
@@ -625,22 +647,6 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
s->drop_cache = qemu_opt_get_bool(opts, "drop-cache", true);
s->check_cache_dropped = qemu_opt_get_bool(opts, "x-check-cache-dropped",
false);
-
- s->open_flags = open_flags;
- raw_parse_flags(bdrv_flags, &s->open_flags, false);
-
- s->fd = -1;
- fd = qemu_open(filename, s->open_flags, errp);
- ret = fd < 0 ? -errno : 0;
-
- if (ret < 0) {
- if (ret == -EROFS) {
- ret = -EACCES;
- }
- goto fail;
- }
- s->fd = fd;
-
/* Check s->open_flags rather than bdrv_flags due to auto-read-only */
if (s->open_flags & O_RDWR) {
ret = check_hdev_writable(s->fd);
@@ -2388,6 +2394,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
int fd;
uint64_t perm, shared;
int result = 0;
+ bool use_lock;
/* Validate options and set default values */
assert(options->driver == BLOCKDEV_DRIVER_FILE);
@@ -2428,19 +2435,22 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
perm = BLK_PERM_WRITE | BLK_PERM_RESIZE;
shared = BLK_PERM_ALL & ~BLK_PERM_RESIZE;
- /* Step one: Take locks */
- result = raw_apply_lock_bytes(NULL, fd, perm, ~shared, false, errp);
- if (result < 0) {
- goto out_close;
- }
+ use_lock = qemu_has_file_lock(fd);
+ if (use_lock) {
+ /* Step one: Take locks */
+ result = raw_apply_lock_bytes(NULL, fd, perm, ~shared, false, errp);
+ if (result < 0) {
+ goto out_close;
+ }
- /* Step two: Check that nobody else has taken conflicting locks */
- result = raw_check_lock_bytes(fd, perm, shared, errp);
- if (result < 0) {
- error_append_hint(errp,
- "Is another process using the image [%s]?\n",
- file_opts->filename);
- goto out_unlock;
+ /* Step two: Check that nobody else has taken conflicting locks */
+ result = raw_check_lock_bytes(fd, perm, shared, errp);
+ if (result < 0) {
+ error_append_hint(errp,
+ "Is another process using the image [%s]?\n",
+ file_opts->filename);
+ goto out_unlock;
+ }
}
/* Clear the file by truncating it to 0 */
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index f9ec8c84e9..c7587be99d 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -513,6 +513,7 @@ int qemu_lock_fd(int fd, int64_t start, int64_t len, bool exclusive);
int qemu_unlock_fd(int fd, int64_t start, int64_t len);
int qemu_lock_fd_test(int fd, int64_t start, int64_t len, bool exclusive);
bool qemu_has_ofd_lock(void);
+bool qemu_has_file_lock(int fd);
#endif
#if defined(__HAIKU__) && defined(__i386__)
diff --git a/util/osdep.c b/util/osdep.c
index 66d01b9160..07de97e2c5 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -225,6 +225,25 @@ static void qemu_probe_lock_ops(void)
}
}
+bool qemu_has_file_lock(int fd)
+{
+#ifdef F_OFD_SETLK
+ int cmd = F_OFD_GETLK;
+#else
+ int cmd = F_GETLK;
+#endif
+ int ret;
+ struct flock fl = {
+ .l_whence = SEEK_SET,
+ .l_start = 0,
+ .l_len = 0,
+ .l_type = F_WRLCK,
+ };
+
+ ret = fcntl(fd, cmd, &fl);
+ return ret == 0;
+}
+
bool qemu_has_ofd_lock(void)
{
qemu_probe_lock_ops();
--
2.24.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v4] file-posix: detect the lock using the real file
2020-12-15 7:09 [PATCH v4] file-posix: detect the lock using the real file Li Feng
@ 2020-12-15 10:08 ` Daniel P. Berrangé
2020-12-15 10:51 ` Li Feng
0 siblings, 1 reply; 3+ messages in thread
From: Daniel P. Berrangé @ 2020-12-15 10:08 UTC (permalink / raw)
To: Li Feng
Cc: Kevin Wolf, lifeng1519, open list:raw,
open list:All patches CC here, Max Reitz, kyle
On Tue, Dec 15, 2020 at 03:09:28PM +0800, Li Feng wrote:
> This patch addresses this issue:
> When accessing a volume on an NFS filesystem without supporting the file lock,
> tools, like qemu-img, will complain "Failed to lock byte 100".
>
> In the original code, the qemu_has_ofd_lock will test the lock on the
> "/dev/null" pseudo-file. Actually, the file.locking is per-drive property,
> which depends on the underlay filesystem.
>
> In this patch, add a new 'qemu_has_file_lock' to detect whether the
> file supports the file lock. And disable the lock when the underlay file
> system doesn't support locks.
>
> Signed-off-by: Li Feng <fengli@smartx.com>
> ---
> v4: use the fd as the qemu_has_file_lock argument.
> v3: don't call the qemu_has_ofd_lock, use a new function instead.
> v2: remove the refactoring.
> ---
> block/file-posix.c | 66 +++++++++++++++++++++++++-------------------
> include/qemu/osdep.h | 1 +
> util/osdep.c | 19 +++++++++++++
> 3 files changed, 58 insertions(+), 28 deletions(-)
>
> diff --git a/block/file-posix.c b/block/file-posix.c
> index 806764f7e3..9708212f01 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -584,6 +584,21 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
> s->use_linux_io_uring = (aio == BLOCKDEV_AIO_OPTIONS_IO_URING);
> #endif
>
> + s->open_flags = open_flags;
> + raw_parse_flags(bdrv_flags, &s->open_flags, false);
> +
> + s->fd = -1;
> + fd = qemu_open(filename, s->open_flags, errp);
> + ret = fd < 0 ? -errno : 0;
> +
> + if (ret < 0) {
> + if (ret == -EROFS) {
> + ret = -EACCES;
> + }
> + goto fail;
> + }
> + s->fd = fd;
> +
> locking = qapi_enum_parse(&OnOffAuto_lookup,
> qemu_opt_get(opts, "locking"),
> ON_OFF_AUTO_AUTO, &local_err);
> @@ -607,6 +622,13 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
> break;
> case ON_OFF_AUTO_AUTO:
> s->use_lock = qemu_has_ofd_lock();
> + if (s->use_lock && !qemu_has_file_lock(s->fd)) {
> + /*
> + * When the os supports the OFD lock, but the filesystem doesn't
> + * support, just disable the file lock.
> + */
> + s->use_lock = false;
> + }
This should just be
s->use_lock = qemu_has_file_lock(s->fd) && qemu_has_ofd_lock();
> diff --git a/util/osdep.c b/util/osdep.c
> index 66d01b9160..07de97e2c5 100644
> --- a/util/osdep.c
> +++ b/util/osdep.c
> @@ -225,6 +225,25 @@ static void qemu_probe_lock_ops(void)
> }
> }
>
> +bool qemu_has_file_lock(int fd)
> +{
> +#ifdef F_OFD_SETLK
> + int cmd = F_OFD_GETLK;
> +#else
> + int cmd = F_GETLK;
> +#endif
This should unconditionally use F_GETLK.
> + int ret;
> + struct flock fl = {
> + .l_whence = SEEK_SET,
> + .l_start = 0,
> + .l_len = 0,
> + .l_type = F_WRLCK,
> + };
> +
> + ret = fcntl(fd, cmd, &fl);
> + return ret == 0;
> +}
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v4] file-posix: detect the lock using the real file
2020-12-15 10:08 ` Daniel P. Berrangé
@ 2020-12-15 10:51 ` Li Feng
0 siblings, 0 replies; 3+ messages in thread
From: Li Feng @ 2020-12-15 10:51 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: Kevin Wolf, Feng Li, open list:raw, open list:All patches CC here,
Max Reitz, Kyle Zhang
Daniel P. Berrangé <berrange@redhat.com> 于2020年12月15日周二 下午6:08写道:
>
> On Tue, Dec 15, 2020 at 03:09:28PM +0800, Li Feng wrote:
> > This patch addresses this issue:
> > When accessing a volume on an NFS filesystem without supporting the file lock,
> > tools, like qemu-img, will complain "Failed to lock byte 100".
> >
> > In the original code, the qemu_has_ofd_lock will test the lock on the
> > "/dev/null" pseudo-file. Actually, the file.locking is per-drive property,
> > which depends on the underlay filesystem.
> >
> > In this patch, add a new 'qemu_has_file_lock' to detect whether the
> > file supports the file lock. And disable the lock when the underlay file
> > system doesn't support locks.
> >
> > Signed-off-by: Li Feng <fengli@smartx.com>
> > ---
> > v4: use the fd as the qemu_has_file_lock argument.
> > v3: don't call the qemu_has_ofd_lock, use a new function instead.
> > v2: remove the refactoring.
> > ---
> > block/file-posix.c | 66 +++++++++++++++++++++++++-------------------
> > include/qemu/osdep.h | 1 +
> > util/osdep.c | 19 +++++++++++++
> > 3 files changed, 58 insertions(+), 28 deletions(-)
> >
> > diff --git a/block/file-posix.c b/block/file-posix.c
> > index 806764f7e3..9708212f01 100644
> > --- a/block/file-posix.c
> > +++ b/block/file-posix.c
> > @@ -584,6 +584,21 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
> > s->use_linux_io_uring = (aio == BLOCKDEV_AIO_OPTIONS_IO_URING);
> > #endif
> >
> > + s->open_flags = open_flags;
> > + raw_parse_flags(bdrv_flags, &s->open_flags, false);
> > +
> > + s->fd = -1;
> > + fd = qemu_open(filename, s->open_flags, errp);
> > + ret = fd < 0 ? -errno : 0;
> > +
> > + if (ret < 0) {
> > + if (ret == -EROFS) {
> > + ret = -EACCES;
> > + }
> > + goto fail;
> > + }
> > + s->fd = fd;
> > +
> > locking = qapi_enum_parse(&OnOffAuto_lookup,
> > qemu_opt_get(opts, "locking"),
> > ON_OFF_AUTO_AUTO, &local_err);
> > @@ -607,6 +622,13 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
> > break;
> > case ON_OFF_AUTO_AUTO:
> > s->use_lock = qemu_has_ofd_lock();
> > + if (s->use_lock && !qemu_has_file_lock(s->fd)) {
> > + /*
> > + * When the os supports the OFD lock, but the filesystem doesn't
> > + * support, just disable the file lock.
> > + */
> > + s->use_lock = false;
> > + }
>
> This should just be
>
> s->use_lock = qemu_has_file_lock(s->fd) && qemu_has_ofd_lock();
>
Acked.
>
>
> > diff --git a/util/osdep.c b/util/osdep.c
> > index 66d01b9160..07de97e2c5 100644
> > --- a/util/osdep.c
> > +++ b/util/osdep.c
> > @@ -225,6 +225,25 @@ static void qemu_probe_lock_ops(void)
> > }
> > }
> >
> > +bool qemu_has_file_lock(int fd)
> > +{
> > +#ifdef F_OFD_SETLK
> > + int cmd = F_OFD_GETLK;
> > +#else
> > + int cmd = F_GETLK;
> > +#endif
>
> This should unconditionally use F_GETLK.
Acked.
>
> > + int ret;
> > + struct flock fl = {
> > + .l_whence = SEEK_SET,
> > + .l_start = 0,
> > + .l_len = 0,
> > + .l_type = F_WRLCK,
> > + };
> > +
> > + ret = fcntl(fd, cmd, &fl);
> > + return ret == 0;
> > +}
>
> Regards,
> Daniel
> --
> |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org -o- https://fstop138.berrange.com :|
> |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2020-12-15 10:53 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-12-15 7:09 [PATCH v4] file-posix: detect the lock using the real file Li Feng
2020-12-15 10:08 ` Daniel P. Berrangé
2020-12-15 10:51 ` Li Feng
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).