]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Reorder exclusive rename operations in file storage
authorMatt Joiner <anacrolix@gmail.com>
Wed, 28 May 2025 05:26:18 +0000 (15:26 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Wed, 28 May 2025 05:26:18 +0000 (15:26 +1000)
storage/file-piece.go

index f4ab77a15b011291f1acd3413644e8b01834acc6..2dc17233853d3cf0c7e8c6de5ca91049053f0fad 100644 (file)
@@ -199,20 +199,28 @@ func (me *filePieceImpl) promotePartFile(f file) (err error) {
 
 // Rename from if exists, and if so, to must not exist.
 func (me *filePieceImpl) exclRenameIfExists(from, to string) (err error) {
-       _, err = os.Stat(from)
-       if errors.Is(err, fs.ErrNotExist) {
-               return nil
-       }
        // We don't want anyone reading or writing to this until the rename completes.
        f, err := os.OpenFile(to, os.O_CREATE|os.O_EXCL, 0)
+       if errors.Is(err, fs.ErrExist) {
+               _, err = os.Stat(from)
+               if errors.Is(err, fs.ErrNotExist) {
+                       return nil
+               }
+               if err != nil {
+                       return
+               }
+               return errors.New("source and destination files both exist")
+       }
        if err != nil {
-               return fmt.Errorf("error creating destination file: %w", err)
+               return
        }
        f.Close()
        err = os.Rename(from, to)
-       if err == nil {
-               me.logger().Debug("renamed file", "from", from, "to", to)
+       if err != nil {
+               os.Remove(to)
+               return
        }
+       me.logger().Debug("renamed file", "from", from, "to", to)
        return
 }