| 1145 | } |
| 1146 | |
| 1147 | int bcache_write_partial(struct filemgr *file, |
| 1148 | bid_t bid, |
| 1149 | void *buf, |
| 1150 | size_t offset, |
| 1151 | size_t len, |
| 1152 | bool final_write) |
| 1153 | { |
| 1154 | struct hash_elem *h; |
| 1155 | struct bcache_item *item; |
| 1156 | struct bcache_item query; |
| 1157 | struct fnamedic_item *fname_new; |
| 1158 | |
| 1159 | fname_new = file->bcache; |
| 1160 | if (fname_new == NULL) { |
| 1161 | spin_lock(&bcache_lock); |
| 1162 | fname_new = file->bcache; |
| 1163 | if (fname_new == NULL) { |
| 1164 | // filename doesn't exist in filename dictionary .. create |
| 1165 | fname_new = _fname_create(file); |
| 1166 | } |
| 1167 | spin_unlock(&bcache_lock); |
| 1168 | } |
| 1169 | |
| 1170 | // Update the access timestamp. |
| 1171 | struct timeval tp; |
| 1172 | gettimeofday(&tp, NULL); |
| 1173 | atomic_store_uint64_t(&fname_new->access_timestamp, |
| 1174 | (uint64_t) (tp.tv_sec * 1000000 + tp.tv_usec)); |
| 1175 | |
| 1176 | size_t shard_num = bid % fname_new->num_shards; |
| 1177 | // set query |
| 1178 | query.bid = bid; |
| 1179 | |
| 1180 | spin_lock(&fname_new->shards[shard_num].lock); |
| 1181 | |
| 1182 | // search hash table |
| 1183 | h = hash_find(&fname_new->shards[shard_num].hashtable, &query.hash_elem); |
| 1184 | if (h == NULL) { |
| 1185 | // cache miss .. partial write fail .. return 0 |
| 1186 | spin_unlock(&fname_new->shards[shard_num].lock); |
| 1187 | return 0; |
| 1188 | |
| 1189 | } else { |
| 1190 | // cache hit .. get the block |
| 1191 | item = _get_entry(h, struct bcache_item, hash_elem); |
| 1192 | } |
| 1193 | |
| 1194 | if (item->flag & BCACHE_FREE) { |
| 1195 | DBG("Warning: failed to write on the buffer cache entry for a file '%s' " |
| 1196 | "because the entry belongs to the free list!\n", |
| 1197 | file->filename); |
| 1198 | return 0; |
| 1199 | } |
| 1200 | |
| 1201 | // check whether this is dirty block |
| 1202 | // to avoid re-insert already existing item into tree |
| 1203 | if (!(item->flag & BCACHE_DIRTY)) { |
| 1204 | // this block was clean block |
no test coverage detected