On Thu, Aug 7, 2008 at 1:26 PM, Archie Cobbs <archie@xxxxxxxxxxxx> wrote: > I have an application involving the loopback device where it would be > valuable for the underlying file to be opened with the O_DIRECT flag. > > Any thoughts one way or the other about adding support to losetup(8) > and mount(8) for a 'direct' option that would enable this? > > I will propose a patch if people think this would be a reasonable thing to do. Add support for opening loopback files with O_DIRECT. Signed-off-by: Archie L. Cobbs <archie@xxxxxxxxxxxx> --- mount/lomount.c | 18 ++++++++++++------ mount/lomount.h | 1 + mount/losetup.8 | 10 +++++++++- mount/mount.8 | 4 ++-- mount/mount.c | 6 +++++- 5 files changed, 29 insertions(+), 10 deletions(-) --- --- a/mount/lomount.c +++ b/mount/lomount.c @@ -660,6 +660,8 @@ set_loop(const char *device, const char *file, unsigned long long offset, } mode = (*options & SETLOOP_RDONLY) ? O_RDONLY : O_RDWR; + if (*options & SETLOOP_DIRECT) + mode |= O_DIRECT; if ((ffd = open(file, mode)) < 0) { if (!(*options & SETLOOP_RDONLY) && errno == EROFS) ffd = open(file, mode = O_RDONLY); @@ -879,12 +881,13 @@ main(int argc, char **argv) { int delete, find, c, all; int res = 0; int showdev = 0; - int ro = 0; + int setoptions = 0; int pfd = -1; unsigned long long off, slimit; struct option longopts[] = { { "all", 0, 0, 'a' }, { "detach", 0, 0, 'd' }, + { "direct", 0, 0, 'n' }, { "encryption", 1, 0, 'e' }, { "find", 0, 0, 'f' }, { "help", 0, 0, 'h' }, @@ -911,14 +914,14 @@ main(int argc, char **argv) { if ((p = strrchr(progname, '/')) != NULL) progname = p+1; - while ((c = getopt_long(argc, argv, "ade:E:fhj:o:p:rsv", + while ((c = getopt_long(argc, argv, "ade:E:fhj:no:p:rsv", longopts, NULL)) != -1) { switch (c) { case 'a': all = 1; break; case 'r': - ro = 1; + setoptions |= SETLOOP_RDONLY; break; case 'd': delete = 1; @@ -933,6 +936,9 @@ main(int argc, char **argv) { case 'j': assoc = optarg; break; + case 'n': + setoptions |= SETLOOP_DIRECT; + break; case 'o': offset = optarg; break; @@ -959,7 +965,7 @@ main(int argc, char **argv) { usage(); } else if (delete) { if (argc != optind+1 || encryption || offset || sizelimit || - find || all || showdev || assoc || ro) + find || all || showdev || assoc || setoptions) usage(); } else if (find) { if (all || assoc || argc < optind || argc > optind+1) @@ -968,7 +974,7 @@ main(int argc, char **argv) { if (argc > 2) usage(); } else if (assoc) { - if (encryption || showdev || passfd || ro) + if (encryption || showdev || passfd || setoptions) usage(); } else { if (argc < optind+1 || argc > optind+2) @@ -1012,7 +1018,7 @@ main(int argc, char **argv) { if (passfd && sscanf(passfd, "%d", &pfd) != 1) usage(); do { - res = set_loop(device, file, off, slimit, encryption, pfd, &ro); + res = set_loop(device, file, off, slimit, encryption, pfd, &setoptions); if (res == 2 && find) { if (verbose) printf("stolen loop=%s...trying again\n", diff --git a/mount/lomount.h b/mount/lomount.h index 59108d4..5fae55a 100644 --- a/mount/lomount.h +++ b/mount/lomount.h @@ -10,3 +10,4 @@ extern char *loopfile_used (const char *filename, unsigned long long offset); #define SETLOOP_RDONLY (1<<0) /* Open loop read-only */ #define SETLOOP_AUTOCLEAR (1<<1) /* Automatically detach loop on close (2.6.25?) */ +#define SETLOOP_DIRECT (1<<2) /* Open underlying file with O_DIRECT */ diff --git a/mount/losetup.8 b/mount/losetup.8 index 84f82e7..8aa7955 100644 --- a/mount/losetup.8 +++ b/mount/losetup.8 @@ -37,10 +37,11 @@ Setup loop device: .IR offset ] .RB [ \-\-sizelimit .IR limit ] +.in +8 .RB [ \-p .IR pfd ] .RB [ \-r ] -.in +8 +.RB [ \-n ] .RB { \-f [ \-\-show ] | \fIloop_device\fP } .I file .in -13 @@ -83,6 +84,13 @@ print help .IP "\fB\-j, \-\-associated \fIfile\fP" show status of all loop devices associated with given .I file +.IP "\fB\-n, \-\-direct\fP" +Pass the +.BR O_DIRECT +flag to +.BR open (2) +when opening +.I file .IP "\fB\-o, \-\-offset \fIoffset\fP" the data start is moved \fIoffset\fP bytes into the specified file or device diff --git a/mount/mount.8 b/mount/mount.8 index 7487923..dd6d75a 100644 --- a/mount/mount.8 +++ b/mount/mount.8 @@ -2061,8 +2061,8 @@ to correspond to the file and then mount this device on .IR /mnt . -This type of mount knows about four options, namely -.BR loop ", " offset ", " sizelimit " and " encryption , +This type of mount knows about five options, namely +.BR loop ", " offset ", " sizelimit ", " encryption " and " direct that are really options to .BR \%losetup (8). (These options can be used in addition to those specific diff --git a/mount/mount.c b/mount/mount.c index be05135..58866e6 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -102,10 +102,11 @@ struct opt_map { #define MS_OWNER 0x10000000 #define MS_GROUP 0x08000000 #define MS_COMMENT 0x02000000 +#define MS_DIRECT 0x00020000 #define MS_LOOP 0x00010000 /* Options that we keep the mount system call from seeing. */ -#define MS_NOSYS (MS_NOAUTO|MS_USERS|MS_USER|MS_COMMENT|MS_LOOP) +#define MS_NOSYS (MS_NOAUTO|MS_USERS|MS_USER|MS_COMMENT|MS_LOOP|MS_DIRECT) /* Options that we keep from appearing in the options field in the mtab. */ #define MS_NOMTAB (MS_REMOUNT|MS_NOAUTO|MS_USERS|MS_USER) @@ -161,6 +162,7 @@ static const struct opt_map opt_map[] = { { "nomand", 0, 1, MS_MANDLOCK }, /* Forbid mandatory locks on this FS */ #endif { "loop", 1, 0, MS_LOOP }, /* use a loop device */ + { "direct", 0, 0, MS_DIRECT }, /* open loopback file with O_DIRECT */ #ifdef MS_NOATIME { "atime", 0, 1, MS_NOATIME }, /* Update access time */ { "noatime", 0, 0, MS_NOATIME }, /* Do not update access time */ @@ -911,6 +913,8 @@ loop_check(const char **spec, const char **type, int *flags, if (*flags & MS_RDONLY) loop_opts |= SETLOOP_RDONLY; + if (*flags & MS_DIRECT) + loop_opts |= SETLOOP_DIRECT; offset = opt_offset ? strtoull(opt_offset, NULL, 0) : 0; sizelimit = opt_sizelimit ? strtoull(opt_sizelimit, NULL, 0) : 0; Thanks, -Archie -- Archie L. Cobbs -- To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html