From 8d4cc064b3cb48948dc37e0c057d04b77c1ec27d Mon Sep 17 00:00:00 2001 From: Shuo Wu <shuo.wu@suse.com> Date: Thu, 6 Mar 2025 19:04:33 -0800 Subject: [PATCH] fix: engine unmap uses write lock Otherwise, there will be a race between unmap and write operations. Longhorn 6406 Signed-off-by: Shuo Wu <shuo.wu@suse.com> --- pkg/controller/control.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/controller/control.go b/pkg/controller/control.go index 9ef88ab86..0810145f2 100644 --- a/pkg/controller/control.go +++ b/pkg/controller/control.go @@ -1118,14 +1118,14 @@ func (c *Controller) ReadAt(b []byte, off int64) (int, error) { func (c *Controller) UnmapAt(length uint32, off int64) (int, error) { // TODO: Need to fail unmap requests // if the volume is purging snapshots or creating backups. - c.RLock() + c.Lock() if off < 0 || off+int64(length) > c.size { // This is a legitimate error (which is handled by tgt/liblonghorn at a higher level). Since tgt/liblonghorn // does not actually print the error, print it here. err := fmt.Errorf("EOF: unmap of %v bytes at offset %v is beyond volume size %v", length, off, c.size) logrus.WithError(err).Error("Failed to unmap") - c.RUnlock() + c.Unlock() return 0, err } if c.hasWOReplica() { @@ -1134,7 +1134,7 @@ func (c *Controller) UnmapAt(length uint32, off int64) (int, error) { // will remain paused for the entire duration of the rebuild. err := fmt.Errorf("cannot unmap %v bytes at offset %v while rebuilding is in progress", length, off) logrus.WithError(err).Warn("Failed to unmap") - c.RUnlock() + c.Unlock() return 0, nil } if c.isExpanding { @@ -1143,13 +1143,13 @@ func (c *Controller) UnmapAt(length uint32, off int64) (int, error) { // trimmed, so it can try again. err := fmt.Errorf("cannot unmap %v bytes at offset %v while expansion in is progress", length, off) logrus.WithError(err).Error("Failed to unmap") - c.RUnlock() + c.Unlock() return 0, err } // startTime := time.Now() n, err := c.backend.UnmapAt(length, off) - c.RUnlock() + c.Unlock() if err != nil { return n, c.handleError(err) }