|
@@ -434,6 +434,8 @@ void coroutine_fn v9fs_reclaim_fd(V9fsPDU *pdu)
|
|
|
V9fsFidState *f;
|
|
|
GHashTableIter iter;
|
|
|
gpointer fid;
|
|
|
+ int err;
|
|
|
+ int nclosed = 0;
|
|
|
|
|
|
/* prevent multiple coroutines running this function simultaniously */
|
|
|
if (s->reclaiming) {
|
|
@@ -446,10 +448,10 @@ void coroutine_fn v9fs_reclaim_fd(V9fsPDU *pdu)
|
|
|
QSLIST_HEAD(, V9fsFidState) reclaim_list =
|
|
|
QSLIST_HEAD_INITIALIZER(reclaim_list);
|
|
|
|
|
|
+ /* Pick FIDs to be closed, collect them on reclaim_list. */
|
|
|
while (g_hash_table_iter_next(&iter, &fid, (gpointer *) &f)) {
|
|
|
/*
|
|
|
- * Unlink fids cannot be reclaimed. Check
|
|
|
- * for them and skip them. Also skip fids
|
|
|
+ * Unlinked fids cannot be reclaimed, skip those, and also skip fids
|
|
|
* currently being operated on.
|
|
|
*/
|
|
|
if (f->ref || f->flags & FID_NON_RECLAIMABLE) {
|
|
@@ -499,17 +501,26 @@ void coroutine_fn v9fs_reclaim_fd(V9fsPDU *pdu)
|
|
|
}
|
|
|
}
|
|
|
/*
|
|
|
- * Now close the fid in reclaim list. Free them if they
|
|
|
- * are already clunked.
|
|
|
+ * Close the picked FIDs altogether on a background I/O driver thread. Do
|
|
|
+ * this all at once to keep latency (i.e. amount of thread hops between main
|
|
|
+ * thread <-> fs driver background thread) as low as possible.
|
|
|
*/
|
|
|
+ v9fs_co_run_in_worker({
|
|
|
+ QSLIST_FOREACH(f, &reclaim_list, reclaim_next) {
|
|
|
+ err = (f->fid_type == P9_FID_DIR) ?
|
|
|
+ s->ops->closedir(&s->ctx, &f->fs_reclaim) :
|
|
|
+ s->ops->close(&s->ctx, &f->fs_reclaim);
|
|
|
+ if (!err) {
|
|
|
+ /* total_open_fd must only be mutated on main thread */
|
|
|
+ nclosed++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ total_open_fd -= nclosed;
|
|
|
+ /* Free the closed FIDs. */
|
|
|
while (!QSLIST_EMPTY(&reclaim_list)) {
|
|
|
f = QSLIST_FIRST(&reclaim_list);
|
|
|
QSLIST_REMOVE(&reclaim_list, f, V9fsFidState, reclaim_next);
|
|
|
- if (f->fid_type == P9_FID_FILE) {
|
|
|
- v9fs_co_close(pdu, &f->fs_reclaim);
|
|
|
- } else if (f->fid_type == P9_FID_DIR) {
|
|
|
- v9fs_co_closedir(pdu, &f->fs_reclaim);
|
|
|
- }
|
|
|
/*
|
|
|
* Now drop the fid reference, free it
|
|
|
* if clunked.
|