Skip to content

Commit

Permalink
linux: use O_EXCL when opening a file for write
Browse files Browse the repository at this point in the history
On linux systems, opening a device with O_EXCL will fail with
EBUSY if the drive is in use.  For example, if a partition is
mounted on /dev/nvme1n1p1, the current mounted filesystem check
will allow running write workloads on /dev/nvme1n1 even if
allow_mounted_write is zero.  Opening /dev/nvme1n1 with O_EXCL
will fail with EBUSY in that case.  Add O_EXCL when opening a
file with O_WRONLY or O_RDWR on linux systems.

Fixes: #1820
Signed-of-by: Keith Reynolds <[email protected]>
  • Loading branch information
keithr-mext committed Sep 28, 2024
1 parent fef1936 commit 505e8b5
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 5 deletions.
9 changes: 8 additions & 1 deletion engines/nvme.c
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,14 @@ int fio_nvme_reset_wp(struct thread_data *td, struct fio_file *f,
/* If the file is not yet opened, open it for this function. */
fd = f->fd;
if (fd < 0) {
fd = open(f->file_name, O_RDWR | O_LARGEFILE);
int flags = O_RDWR | O_LARGEFILE;

#ifdef FIO_USE_O_EXCL
if (!td->o.allow_mounted_write)
flags |= O_EXCL;
#endif

fd = open(f->file_name, flags);
if (fd < 0)
return -errno;
}
Expand Down
8 changes: 8 additions & 0 deletions engines/xnvme.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,14 @@ static struct xnvme_opts xnvme_opts_from_fioe(struct thread_data *td)

opts.direct = td->o.odirect;

opts.rdonly = opts.wronly = opts.rdwr = 0;
if (td_rw(td))
opts.rdwr = 1;
else if (td_write(td))
opts.wronly = 1;
else
opts.rdonly = 1;

return opts;
}

Expand Down
12 changes: 9 additions & 3 deletions filesetup.c
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,7 @@ int generic_open_file(struct thread_data *td, struct fio_file *f)
int is_std = 0;
int flags = 0;
int from_hash = 0;
int write_flags = O_RDWR;

dprint(FD_FILE, "fd open %s\n", f->file_name);

Expand All @@ -744,10 +745,15 @@ int generic_open_file(struct thread_data *td, struct fio_file *f)
if (f->filetype != FIO_TYPE_FILE)
flags |= FIO_O_NOATIME;

#ifdef FIO_USE_O_EXCL
if (!td->o.allow_mounted_write && (flags & O_CREAT) == 0)
write_flags |= O_EXCL;
#endif

open_again:
if (td_write(td)) {
if (!read_only)
flags |= O_RDWR;
flags |= write_flags;

if (td->o.verify_only) {
flags &= ~O_RDWR;
Expand All @@ -763,7 +769,7 @@ int generic_open_file(struct thread_data *td, struct fio_file *f)
from_hash = file_lookup_open(f, flags);
} else if (td_read(td)) {
if (td_ioengine_flagged(td, FIO_RO_NEEDS_RW_OPEN) && !read_only)
flags |= O_RDWR;
flags |= write_flags;
else
flags |= O_RDONLY;

Expand All @@ -774,7 +780,7 @@ int generic_open_file(struct thread_data *td, struct fio_file *f)
} else if (td_trim(td)) {
assert(!td_rw(td)); /* should have matched above */
if (!read_only)
flags |= O_RDWR;
flags |= write_flags;
from_hash = file_lookup_open(f, flags);
}

Expand Down
2 changes: 2 additions & 0 deletions os/os-linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,4 +430,6 @@ static inline bool os_cpu_has(cpu_features feature)
return have_feature;
}

#define FIO_USE_O_EXCL

#endif
9 changes: 8 additions & 1 deletion oslib/linux-blkzoned.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,14 @@ int blkzoned_reset_wp(struct thread_data *td, struct fio_file *f,
/* If the file is not yet opened, open it for this function. */
fd = f->fd;
if (fd < 0) {
fd = open(f->file_name, O_RDWR | O_LARGEFILE);
int flags = O_RDWR | O_LARGEFILE;

#ifdef FIO_USE_O_EXCL
if (!td->o.allow_mounted_write)
flags |= O_EXCL;
#endif

fd = open(f->file_name, flags);
if (fd < 0)
return -errno;
}
Expand Down

0 comments on commit 505e8b5

Please sign in to comment.