Support all seek options in gofer specialFileFD.Seek.
Updates #2923. PiperOrigin-RevId: 317298186
This commit is contained in:
parent
46957ed24f
commit
6b69b955d7
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue