[PATCH] losetup: add option for O_DIRECT

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux