@@ -1088,12 +1088,7 @@ func (inode *Inode) patchObjectRanges() (initiated bool) {
1088
1088
if inode .flushLimitsExceeded () {
1089
1089
return
1090
1090
}
1091
- var flushBufs []* FileBuffer
1092
- for _ , buf := range inode .buffers {
1093
- if buf .state == BUF_DIRTY {
1094
- flushBufs = append (flushBufs , buf )
1095
- }
1096
- }
1091
+ flushBufs := inode .buffers .Select (0 , inode .Attributes .Size , func (buf * FileBuffer ) bool { return buf .state == BUF_DIRTY ; })
1097
1092
inode .patchSimpleObj (flushBufs )
1098
1093
return true
1099
1094
}
@@ -1133,27 +1128,11 @@ func (inode *Inode) patchObjectRanges() (initiated bool) {
1133
1128
continue
1134
1129
}
1135
1130
1136
- var flushBufs []* FileBuffer
1137
- for pos := locateBuffer (inode .buffers , partStart ); pos < len (inode .buffers ); pos ++ {
1138
- buf := inode .buffers [pos ]
1139
- if buf .offset >= partEnd {
1140
- break
1141
- }
1142
- if buf .state != BUF_DIRTY || buf .zero && ! wantFlush && ! appendPatch {
1143
- continue
1144
- }
1145
-
1146
- if buf .offset < partStart {
1147
- inode .splitBuffer (pos , partStart - buf .offset )
1148
- continue
1149
- }
1150
- if buf .offset + buf .length > partEnd {
1151
- inode .splitBuffer (pos , partEnd - buf .offset )
1152
- }
1153
-
1154
- flushBufs = append (flushBufs , buf )
1155
- }
1156
-
1131
+ inode .buffers .SplitAt (partStart )
1132
+ inode .buffers .SplitAt (partEnd )
1133
+ flushBufs := inode .buffers .Select (partStart , partEnd , func (buf * FileBuffer ) bool {
1134
+ return buf .state == BUF_DIRTY && (! buf .zero || wantFlush || appendPatch )
1135
+ })
1157
1136
if len (flushBufs ) != 0 {
1158
1137
inode .patchPart (partStart , partSize , flushBufs )
1159
1138
initiated = true
@@ -1222,7 +1201,7 @@ func (inode *Inode) patchFromBuffers(bufs []*FileBuffer, partSize uint64) {
1222
1201
// If bufs is a contiguous range of buffers then we can send them as PATCH immediately,
1223
1202
// otherwise we need to read missing ranges first.
1224
1203
var (
1225
- reader io.ReadSeeker
1204
+ reader io.ReadSeeker
1226
1205
dirtyBufs map [uint64 ]bool
1227
1206
)
1228
1207
if contiguous {
@@ -1256,21 +1235,19 @@ func (inode *Inode) patchFromBuffers(bufs []*FileBuffer, partSize uint64) {
1256
1235
log .Warnf ("Local state of file %s (inode %d) changed, aborting patch" , key , inode .Id )
1257
1236
return
1258
1237
}
1259
- reader , dirtyBufs = inode .GetMultiReader (offset , size )
1238
+ reader , dirtyBufs , err = inode .getMultiReader (offset , size )
1239
+ if err != nil {
1240
+ log .Errorf ("File %s data in %v+%v is missing during PATCH attempt: %v" , key , offset , size , err )
1241
+ return
1242
+ }
1260
1243
}
1261
1244
1262
1245
if ok := inode .sendPatch (offset , size , reader , partSize ); ! ok {
1263
1246
return
1264
1247
}
1265
1248
1266
- inodeClean := inode .userMetadataDirty == 0 && inode .oldParent == nil
1267
- for _ , buf := range inode .buffers {
1268
- if dirtyBufs [buf .dirtyID ] {
1269
- buf .dirtyID , buf .state = 0 , BUF_CLEAN
1270
- }
1271
- inodeClean = inodeClean && buf .state == BUF_CLEAN
1272
- }
1273
- if inodeClean {
1249
+ inode .buffers .SetState (offset , size , dirtyBufs , BUF_CLEAN )
1250
+ if ! inode .isStillDirty () {
1274
1251
inode .SetCacheState (ST_CACHED )
1275
1252
}
1276
1253
}
@@ -1323,7 +1300,7 @@ func (inode *Inode) sendPatch(offset, size uint64, r io.ReadSeeker, partSize uin
1323
1300
}
1324
1301
1325
1302
func (inode * Inode ) discardChanges (offset , size uint64 ) {
1326
- allocated := inode .removeRange (offset , size , BUF_DIRTY )
1303
+ allocated := inode .buffers . RemoveRange (offset , size , nil )
1327
1304
inode .fs .bufferPool .Use (allocated , true )
1328
1305
}
1329
1306
0 commit comments