@@ -63,25 +63,34 @@ func (m *Mount) mount(target string) (err error) {
6363 }
6464
6565 flags , data , losetup := parseMountOptions (options )
66- if len (data ) > pagesize {
67- return errors .New ("mount options is too long" )
68- }
6966
7067 // propagation types.
7168 const ptypes = unix .MS_SHARED | unix .MS_PRIVATE | unix .MS_SLAVE | unix .MS_UNBINDABLE
7269
7370 // Ensure propagation type change flags aren't included in other calls.
7471 oflags := flags &^ ptypes
7572
73+ var loopParams LoopParams
74+ if losetup {
75+ loopParams = LoopParams {
76+ Readonly : oflags & unix .MS_RDONLY == unix .MS_RDONLY ,
77+ Autoclear : true ,
78+ }
79+ loopParams .Direct , data = hasDirectIO (data )
80+ }
81+
82+ dataInStr := strings .Join (data , "," )
83+ if len (dataInStr ) > pagesize {
84+ return errors .New ("mount options is too long" )
85+ }
86+
7687 // In the case of remounting with changed data (data != ""), need to call mount (moby/moby#34077).
77- if flags & unix .MS_REMOUNT == 0 || data != "" {
88+ if flags & unix .MS_REMOUNT == 0 || dataInStr != "" {
7889 // Initial call applying all non-propagation flags for mount
7990 // or remount with changed data
8091 source := m .Source
8192 if losetup {
82- loFile , err := setupLoop (m .Source , LoopParams {
83- Readonly : oflags & unix .MS_RDONLY == unix .MS_RDONLY ,
84- Autoclear : true })
93+ loFile , err := setupLoop (m .Source , loopParams )
8594 if err != nil {
8695 return err
8796 }
@@ -90,7 +99,7 @@ func (m *Mount) mount(target string) (err error) {
9099 // Mount the loop device instead
91100 source = loFile .Name ()
92101 }
93- if err := mountAt (chdir , source , target , m .Type , uintptr (oflags ), data ); err != nil {
102+ if err := mountAt (chdir , source , target , m .Type , uintptr (oflags ), dataInStr ); err != nil {
94103 return err
95104 }
96105 }
@@ -199,7 +208,7 @@ func UnmountAll(mount string, flags int) error {
199208
200209// parseMountOptions takes fstab style mount options and parses them for
201210// use with a standard mount() syscall
202- func parseMountOptions (options []string ) (int , string , bool ) {
211+ func parseMountOptions (options []string ) (int , [] string , bool ) {
203212 var (
204213 flag int
205214 losetup bool
@@ -252,7 +261,16 @@ func parseMountOptions(options []string) (int, string, bool) {
252261 data = append (data , o )
253262 }
254263 }
255- return flag , strings .Join (data , "," ), losetup
264+ return flag , data , losetup
265+ }
266+
267+ func hasDirectIO (opts []string ) (bool , []string ) {
268+ for idx , opt := range opts {
269+ if opt == "direct-io" {
270+ return true , append (opts [:idx ], opts [idx + 1 :]... )
271+ }
272+ }
273+ return false , opts
256274}
257275
258276// compactLowerdirOption updates overlay lowdir option and returns the common
0 commit comments