| 1215 | } |
| 1216 | |
| 1217 | int packed_refs_lock(struct ref_store *ref_store, int flags, struct strbuf *err) |
| 1218 | { |
| 1219 | struct packed_ref_store *refs = |
| 1220 | packed_downcast(ref_store, REF_STORE_WRITE | REF_STORE_MAIN, |
| 1221 | "packed_refs_lock"); |
| 1222 | static int timeout_configured = 0; |
| 1223 | static int timeout_value = 1000; |
| 1224 | |
| 1225 | if (!timeout_configured) { |
| 1226 | repo_config_get_int(the_repository, "core.packedrefstimeout", &timeout_value); |
| 1227 | timeout_configured = 1; |
| 1228 | } |
| 1229 | |
| 1230 | /* |
| 1231 | * Note that we close the lockfile immediately because we |
| 1232 | * don't write new content to it, but rather to a separate |
| 1233 | * tempfile. |
| 1234 | */ |
| 1235 | if (hold_lock_file_for_update_timeout( |
| 1236 | &refs->lock, |
| 1237 | refs->path, |
| 1238 | flags, timeout_value) < 0) { |
| 1239 | unable_to_lock_message(refs->path, errno, err); |
| 1240 | return -1; |
| 1241 | } |
| 1242 | |
| 1243 | if (close_lock_file_gently(&refs->lock)) { |
| 1244 | strbuf_addf(err, "unable to close %s: %s", refs->path, strerror(errno)); |
| 1245 | rollback_lock_file(&refs->lock); |
| 1246 | return -1; |
| 1247 | } |
| 1248 | |
| 1249 | /* |
| 1250 | * There is a stat-validity problem might cause `update-ref -d` |
| 1251 | * lost the newly commit of a ref, because a new `packed-refs` |
| 1252 | * file might has the same on-disk file attributes such as |
| 1253 | * timestamp, file size and inode value, but has a changed |
| 1254 | * ref value. |
| 1255 | * |
| 1256 | * This could happen with a very small chance when |
| 1257 | * `update-ref -d` is called and at the same time another |
| 1258 | * `pack-refs --all` process is running. |
| 1259 | * |
| 1260 | * Now that we hold the `packed-refs` lock, it is important |
| 1261 | * to make sure we could read the latest version of |
| 1262 | * `packed-refs` file no matter we have just mmap it or not. |
| 1263 | * So what need to do is clear the snapshot if we hold it |
| 1264 | * already. |
| 1265 | */ |
| 1266 | clear_snapshot(refs); |
| 1267 | |
| 1268 | /* |
| 1269 | * Now make sure that the packed-refs file as it exists in the |
| 1270 | * locked state is loaded into the snapshot: |
| 1271 | */ |
| 1272 | get_snapshot(refs); |
| 1273 | return 0; |
| 1274 | } |
no test coverage detected