- if (lli->lli_opendir_pid != cfs_curproc_pid())
- RETURN(-EBADFD);
-
- if (lli->lli_sai) {
- struct ll_statahead_info *sai = lli->lli_sai;
-
- if (result >= 1) {
- sbi->ll_sa_hit++;
- sai->sai_hit++;
- sai->sai_consecutive_miss = 0;
- sai->sai_max = min(2 * sai->sai_max, sbi->ll_sa_max);
- } else {
- sbi->ll_sa_miss++;
- sai->sai_miss++;
- sai->sai_consecutive_miss++;
- if (sa_low_hit(sai) && sa_is_running(sai)) {
- sbi->ll_sa_wrong++;
- CDEBUG(D_READA, "statahead for dir %.*s hit "
- "ratio too low: hit/miss %u/%u, "
- "sent/replied %u/%u. stopping statahead "
- "thread: pid %d\n",
- parent->d_name.len, parent->d_name.name,
- sai->sai_hit, sai->sai_miss,
- sai->sai_sent, sai->sai_replied,
- cfs_curproc_pid());
- spin_lock(&lli->lli_lock);
- if (!sa_is_stopped(sai))
- sai->sai_thread.t_flags = SVC_STOPPING;
- spin_unlock(&lli->lli_lock);
- }
+ LASSERT(dir != NULL);
+ lli = ll_i2info(dir);
+ LASSERT(lli->lli_opendir_pid == cfs_curproc_pid());
+ sai = lli->lli_sai;
+ LASSERT(sai != NULL);
+ sbi = ll_i2sbi(dir);
+
+ rc = ll_sai_entry_fini(sai);
+ /* rc == -ENOENT means such dentry was removed just between statahead
+ * readdir and pre-fetched, count it as hit.
+ *
+ * result == -ENOENT has two meanings:
+ * 1. such dentry was removed just between statahead pre-fetched and
+ * main process stat such dentry.
+ * 2. main process stat non-exist dentry.
+ * We can not distinguish such two cases, just count them as miss. */
+ if (result >= 1 || unlikely(rc == -ENOENT)) {
+ sai->sai_hit++;
+ sai->sai_consecutive_miss = 0;
+ sai->sai_max = min(2 * sai->sai_max, sbi->ll_sa_max);
+ } else {
+ sai->sai_miss++;
+ sai->sai_consecutive_miss++;
+ if (sa_low_hit(sai) && sa_is_running(sai)) {
+ atomic_inc(&sbi->ll_sa_wrong);
+ CDEBUG(D_READA, "Statahead for dir "DFID" hit ratio "
+ "too low: hit/miss %u/%u, sent/replied %u/%u, "
+ "stopping statahead thread: pid %d\n",
+ PFID(&lli->lli_fid), sai->sai_hit,
+ sai->sai_miss, sai->sai_sent,
+ sai->sai_replied, cfs_curproc_pid());
+ cfs_spin_lock(&lli->lli_sa_lock);
+ if (!sa_is_stopped(sai))
+ sai->sai_thread.t_flags = SVC_STOPPING;
+ cfs_spin_unlock(&lli->lli_sa_lock);