Support all seek options in gofer specialFileFD.Seek.

Updates #2923.

PiperOrigin-RevId: 317298186
This commit is contained in:
Dean Deng 2020-06-19 06:37:40 -07:00 committed by gVisor bot
parent 46957ed24f
commit 6b69b955d7
2 changed files with 17 additions and 18 deletions

View File

@ -489,15 +489,24 @@ func (d *dentry) writeback(ctx context.Context, offset, size int64) error {
func (fd *regularFileFD) Seek(ctx context.Context, offset int64, whence int32) (int64, error) {
fd.mu.Lock()
defer fd.mu.Unlock()
newOffset, err := regularFileSeekLocked(ctx, fd.dentry(), fd.off, offset, whence)
if err != nil {
return 0, err
}
fd.off = newOffset
return newOffset, nil
}
// Calculate the new offset for a seek operation on a regular file.
func regularFileSeekLocked(ctx context.Context, d *dentry, fdOffset, offset int64, whence int32) (int64, error) {
switch whence {
case linux.SEEK_SET:
// Use offset as specified.
case linux.SEEK_CUR:
offset += fd.off
offset += fdOffset
case linux.SEEK_END, linux.SEEK_DATA, linux.SEEK_HOLE:
// Ensure file size is up to date.
d := fd.dentry()
if fd.filesystem().opts.interop == InteropModeShared {
if !d.cachedMetadataAuthoritative() {
if err := d.updateFromGetattr(ctx); err != nil {
return 0, err
}
@ -525,7 +534,6 @@ func (fd *regularFileFD) Seek(ctx context.Context, offset int64, whence int32) (
if offset < 0 {
return 0, syserror.EINVAL
}
fd.off = offset
return offset, nil
}

View File

@ -221,21 +221,12 @@ func (fd *specialFileFD) Seek(ctx context.Context, offset int64, whence int32) (
}
fd.mu.Lock()
defer fd.mu.Unlock()
switch whence {
case linux.SEEK_SET:
// Use offset as given.
case linux.SEEK_CUR:
offset += fd.off
default:
// SEEK_END, SEEK_DATA, and SEEK_HOLE aren't supported since it's not
// clear that file size is even meaningful for these files.
return 0, syserror.EINVAL
newOffset, err := regularFileSeekLocked(ctx, fd.dentry(), fd.off, offset, whence)
if err != nil {
return 0, err
}
if offset < 0 {
return 0, syserror.EINVAL
}
fd.off = offset
return offset, nil
fd.off = newOffset
return newOffset, nil
}
// Sync implements vfs.FileDescriptionImpl.Sync.