Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: deflake the blockfile testsuite #8696

Merged
merged 5 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
mount: support direct-io for loopback device
Signed-off-by: Wei Fu <fuweid89@gmail.com>
  • Loading branch information
fuweid committed Jun 15, 2023
commit 72b7d16505ae499b554b1f6969f58edb6ce8f170
27 changes: 13 additions & 14 deletions mount/losetup_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ func setupLoopDev(backingFile, loopDev string, param LoopParams) (_ *os.File, re
return nil, fmt.Errorf("could not set loop fd for device: %s: %w", loopDev, err)
}

defer func() {
if retErr != nil {
_ = unix.IoctlSetInt(int(loop.Fd()), unix.LOOP_CLR_FD, 0)
}
}()

// 3. Set Info
info := unix.LoopInfo64{}
copy(info.File_name[:], backingFile)
Expand All @@ -100,27 +106,20 @@ func setupLoopDev(backingFile, loopDev string, param LoopParams) (_ *os.File, re
info.Flags |= unix.LO_FLAGS_AUTOCLEAR
}

if param.Direct {
info.Flags |= unix.LO_FLAGS_DIRECT_IO
}

err = unix.IoctlLoopSetStatus64(int(loop.Fd()), &info)
if err == nil {
return loop, nil
if err != nil {
return nil, fmt.Errorf("failed to set loop device info: %w", err)
}

// 4. Set Direct IO
if param.Direct {
// Retry w/o direct IO flag in case kernel does not support it. The downside is that
// it will suffer from double cache problem.
info.Flags &= ^(uint32(unix.LO_FLAGS_DIRECT_IO))
err = unix.IoctlLoopSetStatus64(int(loop.Fd()), &info)
if err == nil {
return loop, nil
err = unix.IoctlSetInt(int(loop.Fd()), unix.LOOP_SET_DIRECT_IO, 1)
if err != nil {
return nil, fmt.Errorf("failed to setup loop with direct: %w", err)
}
}

_ = unix.IoctlSetInt(int(loop.Fd()), unix.LOOP_CLR_FD, 0)
return nil, fmt.Errorf("failed to set loop device info: %v", err)
return loop, nil
}

// setupLoop looks for (and possibly creates) a free loop device, and
Expand Down
38 changes: 28 additions & 10 deletions mount/mount_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,25 +63,34 @@ func (m *Mount) mount(target string) (err error) {
}

flags, data, losetup := parseMountOptions(options)
if len(data) > pagesize {
return errors.New("mount options is too long")
}

// propagation types.
const ptypes = unix.MS_SHARED | unix.MS_PRIVATE | unix.MS_SLAVE | unix.MS_UNBINDABLE

// Ensure propagation type change flags aren't included in other calls.
oflags := flags &^ ptypes

var loopParams LoopParams
if losetup {
loopParams = LoopParams{
Readonly: oflags&unix.MS_RDONLY == unix.MS_RDONLY,
Autoclear: true,
}
loopParams.Direct, data = hasDirectIO(data)
}

dataInStr := strings.Join(data, ",")
if len(dataInStr) > pagesize {
return errors.New("mount options is too long")
}

// In the case of remounting with changed data (data != ""), need to call mount (moby/moby#34077).
if flags&unix.MS_REMOUNT == 0 || data != "" {
if flags&unix.MS_REMOUNT == 0 || dataInStr != "" {
// Initial call applying all non-propagation flags for mount
// or remount with changed data
source := m.Source
if losetup {
loFile, err := setupLoop(m.Source, LoopParams{
Readonly: oflags&unix.MS_RDONLY == unix.MS_RDONLY,
Autoclear: true})
loFile, err := setupLoop(m.Source, loopParams)
if err != nil {
return err
}
Expand All @@ -90,7 +99,7 @@ func (m *Mount) mount(target string) (err error) {
// Mount the loop device instead
source = loFile.Name()
}
if err := mountAt(chdir, source, target, m.Type, uintptr(oflags), data); err != nil {
if err := mountAt(chdir, source, target, m.Type, uintptr(oflags), dataInStr); err != nil {
return err
}
}
Expand Down Expand Up @@ -199,7 +208,7 @@ func UnmountAll(mount string, flags int) error {

// parseMountOptions takes fstab style mount options and parses them for
// use with a standard mount() syscall
func parseMountOptions(options []string) (int, string, bool) {
func parseMountOptions(options []string) (int, []string, bool) {
var (
flag int
losetup bool
Expand Down Expand Up @@ -252,7 +261,16 @@ func parseMountOptions(options []string) (int, string, bool) {
data = append(data, o)
}
}
return flag, strings.Join(data, ","), losetup
return flag, data, losetup
}

func hasDirectIO(opts []string) (bool, []string) {
for idx, opt := range opts {
if opt == "direct-io" {
return true, append(opts[:idx], opts[idx+1:]...)
}
}
return false, opts
}

// compactLowerdirOption updates overlay lowdir option and returns the common
Expand Down