- LASSERT(lli->lli_opendir_pid == current_pid());
-
- if (sai) {
- thread = &sai->sai_thread;
- if (unlikely(thread_is_stopped(thread) &&
- cfs_list_empty(&sai->sai_entries_stated))) {
- /* to release resource */
- ll_stop_statahead(dir, lli->lli_opendir_key);
- RETURN(-EAGAIN);
- }
-
- if ((*dentryp)->d_name.name[0] == '.') {
- if (sai->sai_ls_all ||
- sai->sai_miss_hidden >= sai->sai_skip_hidden) {
- /*
- * Hidden dentry is the first one, or statahead
- * thread does not skip so many hidden dentries
- * before "sai_ls_all" enabled as below.
- */
- } else {
- if (!sai->sai_ls_all)
- /*
- * It maybe because hidden dentry is not
- * the first one, "sai_ls_all" was not
- * set, then "ls -al" missed. Enable
- * "sai_ls_all" for such case.
- */
- sai->sai_ls_all = 1;
-
- /*
- * Such "getattr" has been skipped before
- * "sai_ls_all" enabled as above.
- */
- sai->sai_miss_hidden++;
- RETURN(-EAGAIN);
- }
- }
-
- entry = ll_sa_entry_get_byname(sai, &(*dentryp)->d_name);
- if (entry == NULL || only_unplug) {
- ll_sai_unplug(sai, entry);
- RETURN(entry ? 1 : -EAGAIN);
- }
-
- /* if statahead is busy in readdir, help it do post-work */
- while (!ll_sa_entry_stated(entry) &&
- sai->sai_in_readpage &&
- !sa_received_empty(sai))
- ll_post_statahead(sai);
-
- if (!ll_sa_entry_stated(entry)) {
- sai->sai_index_wait = entry->se_index;
- lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(30), NULL,
- LWI_ON_SIGNAL_NOOP, NULL);
- rc = l_wait_event(sai->sai_waitq,
- ll_sa_entry_stated(entry) ||
- thread_is_stopped(thread),
- &lwi);
- if (rc < 0) {
- ll_sai_unplug(sai, entry);
- RETURN(-EAGAIN);
- }
- }
-
- if (entry->se_stat == SA_ENTRY_SUCC &&
- entry->se_inode != NULL) {
- struct inode *inode = entry->se_inode;
- struct lookup_intent it = { .it_op = IT_GETATTR,
- .d.lustre.it_lock_handle =
- entry->se_handle };
- __u64 bits;
-
- rc = md_revalidate_lock(ll_i2mdexp(dir), &it,
- ll_inode2fid(inode), &bits);
- if (rc == 1) {
- if ((*dentryp)->d_inode == NULL) {
- struct dentry *alias;
-
- alias = ll_splice_alias(inode,
- *dentryp);
- if (IS_ERR(alias)) {
- ll_sai_unplug(sai, entry);
- RETURN(PTR_ERR(alias));
- }
- *dentryp = alias;
- } else if ((*dentryp)->d_inode != inode) {
- /* revalidate, but inode is recreated */
- CDEBUG(D_READA,
- "%s: stale dentry %.*s inode "
- DFID", statahead inode "DFID
- "\n",
- ll_get_fsname((*dentryp)->d_inode->i_sb, NULL, 0),
- (*dentryp)->d_name.len,
- (*dentryp)->d_name.name,
- PFID(ll_inode2fid((*dentryp)->d_inode)),
- PFID(ll_inode2fid(inode)));
- ll_sai_unplug(sai, entry);
- RETURN(-ESTALE);
- } else {
- iput(inode);
- }
- entry->se_inode = NULL;
-
- if ((bits & MDS_INODELOCK_LOOKUP) &&
- d_lustre_invalid(*dentryp))
- d_lustre_revalidate(*dentryp);
- ll_intent_release(&it);
- }
- }