@@ -72,7 +72,7 @@ func getFreeLoopDev() (uint32, error) {
7272// setupLoopDev attaches the backing file to the loop device and returns
7373// the file handle for the loop device. The caller is responsible for
7474// closing the file handle.
75- func setupLoopDev (backingFile , loopDev string , param LoopParams ) (* os.File , error ) {
75+ func setupLoopDev (backingFile , loopDev string , param LoopParams ) (_ * os.File , retErr error ) {
7676 // 1. Open backing file and loop device
7777 flags := os .O_RDWR
7878 if param .Readonly {
@@ -85,12 +85,15 @@ func setupLoopDev(backingFile, loopDev string, param LoopParams) (*os.File, erro
8585 }
8686 defer back .Close ()
8787
88- // To make Autoclear (LO_FLAGS_AUTOCLEAR) work, this function intentionally
89- // doesn't close this file handle on defer.
9088 loop , err := os .OpenFile (loopDev , flags , 0 )
9189 if err != nil {
9290 return nil , errors .Wrapf (err , "could not open loop device: %s" , loopDev )
9391 }
92+ defer func () {
93+ if retErr != nil {
94+ loop .Close ()
95+ }
96+ }()
9497
9598 // 2. Set FD
9699 if _ , _ , err = ioctl (loop .Fd (), unix .LOOP_SET_FD , back .Fd ()); err != nil {
@@ -127,10 +130,6 @@ func setupLoopDev(backingFile, loopDev string, param LoopParams) (*os.File, erro
127130 }
128131 }
129132
130- // Cleanup loop fd and return error.
131- // If this function doesn't return this file handle, it must close the handle to
132- // prevent file descriptor leaks.
133- loop .Close ()
134133 _ , _ , _ = ioctl (loop .Fd (), unix .LOOP_CLR_FD , 0 )
135134 return nil , errors .Errorf ("failed to set loop device info: %v" , err )
136135}
0 commit comments