| 905 | } |
| 906 | |
| 907 | int |
| 908 | CacheVC::scanOpenWrite(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */) |
| 909 | { |
| 910 | Dbg(dbg_ctl_cache_scan_truss, "inside %p:scanOpenWrite", this); |
| 911 | cancel_trigger(); |
| 912 | // get volume lock |
| 913 | if (writer_lock_retry > SCAN_WRITER_LOCK_MAX_RETRY) { |
| 914 | int r = _action.continuation->handleEvent(CACHE_EVENT_SCAN_OPERATION_BLOCKED, nullptr); |
| 915 | Dbg(dbg_ctl_cache_scan, "still haven't got the writer lock, asking user.."); |
| 916 | switch (r) { |
| 917 | case CACHE_SCAN_RESULT_RETRY: |
| 918 | writer_lock_retry = 0; |
| 919 | break; |
| 920 | case CACHE_SCAN_RESULT_CONTINUE: |
| 921 | SET_HANDLER(&CacheVC::scanObject); |
| 922 | return scanObject(EVENT_IMMEDIATE, nullptr); |
| 923 | } |
| 924 | } |
| 925 | int ret = 0; |
| 926 | { |
| 927 | CACHE_TRY_LOCK(lock, stripe->mutex, mutex->thread_holding); |
| 928 | if (!lock.is_locked()) { |
| 929 | Dbg(dbg_ctl_cache_scan, "stripe->mutex %p:scanOpenWrite", this); |
| 930 | VC_SCHED_LOCK_RETRY(); |
| 931 | } |
| 932 | |
| 933 | Dbg(dbg_ctl_cache_scan, "trying for writer lock"); |
| 934 | if (stripe->open_write(this, false, 1)) { |
| 935 | writer_lock_retry++; |
| 936 | SET_HANDLER(&CacheVC::scanOpenWrite); |
| 937 | mutex->thread_holding->schedule_in_local(this, scan_msec_delay); |
| 938 | return EVENT_CONT; |
| 939 | } |
| 940 | |
| 941 | ink_assert(this->od); |
| 942 | // put all the alternates in the open directory vector |
| 943 | int alt_count = vector.count(); |
| 944 | for (int i = 0; i < alt_count; i++) { |
| 945 | write_vector->insert(vector.get(i)); |
| 946 | } |
| 947 | od->writing_vec = true; |
| 948 | vector.clear(false); |
| 949 | // check that the directory entry was not overwritten |
| 950 | // if so return failure |
| 951 | Dbg(dbg_ctl_cache_scan, "got writer lock"); |
| 952 | Dir *l = nullptr; |
| 953 | Dir d; |
| 954 | Doc *doc = reinterpret_cast<Doc *>(buf->data() + offset); |
| 955 | offset = reinterpret_cast<char *>(doc) - buf->data() + stripe->round_to_approx_size(doc->len); |
| 956 | // if the doc contains some data, then we need to create |
| 957 | // a new directory entry for this fragment. Remember the |
| 958 | // offset and the key in earliest_key |
| 959 | dir_assign(&od->first_dir, &dir); |
| 960 | if (doc->total_len) { |
| 961 | dir_assign(&od->single_doc_dir, &dir); |
| 962 | dir_set_tag(&od->single_doc_dir, doc->key.slice32(2)); |
| 963 | od->single_doc_key = doc->key; |
| 964 | od->move_resident_alt = true; |
nothing calls this directly
no test coverage detected