Whamcloud - gitweb
LU-1484 lprocfs: refine LC_PROCFS_USERS check
[fs/lustre-release.git] / lustre / llite / statahead.c
index 2033633..e231cd2 100644 (file)
@@ -1,6 +1,4 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
  * GPL HEADER START
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -39,7 +37,6 @@
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
-#include <linux/smp_lock.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 
@@ -48,7 +45,6 @@
 #include <obd_support.h>
 #include <lustre_lite.h>
 #include <lustre_dlm.h>
-#include <linux/lustre_version.h>
 #include "llite_internal.h"
 
 #define SA_OMITTED_ENTRY_MAX 8ULL
@@ -142,10 +138,10 @@ ll_sa_entry_unhash(struct ll_statahead_info *sai, struct ll_sa_entry *entry)
 static inline int agl_should_run(struct ll_statahead_info *sai,
                                  struct inode *inode)
 {
-        if (inode != NULL && S_ISREG(inode->i_mode) &&
-            ll_i2info(inode)->lli_smd != NULL && sai->sai_agl_valid)
-                return 1;
-        return 0;
+       if (inode != NULL && S_ISREG(inode->i_mode) &&
+           ll_i2info(inode)->lli_has_smd && sai->sai_agl_valid)
+               return 1;
+       return 0;
 }
 
 static inline struct ll_sa_entry *
@@ -1075,6 +1071,7 @@ static void ll_start_agl(struct dentry *parent, struct ll_statahead_info *sai)
         rc = cfs_create_thread(ll_agl_thread, parent, 0);
         if (rc < 0) {
                 CERROR("can't start ll_agl thread, rc: %d\n", rc);
+                thread_set_flags(thread, SVC_STOPPED);
                 RETURN_EXIT;
         }
 
@@ -1093,6 +1090,7 @@ static int ll_statahead_thread(void *arg)
         struct ll_sb_info        *sbi    = ll_i2sbi(dir);
         struct ll_statahead_info *sai    = ll_sai_get(plli->lli_sai);
         struct ptlrpc_thread     *thread = &sai->sai_thread;
+        struct ptlrpc_thread *agl_thread = &sai->sai_agl_thread;
         struct page              *page;
         __u64                     pos    = 0;
         int                       first  = 0;
@@ -1294,8 +1292,6 @@ do_it:
 
 out:
         if (sai->sai_agl_valid) {
-                struct ptlrpc_thread *agl_thread = &sai->sai_agl_thread;
-
                 cfs_spin_lock(&plli->lli_agl_lock);
                 thread_set_flags(agl_thread, SVC_STOPPING);
                 cfs_spin_unlock(&plli->lli_agl_lock);
@@ -1306,8 +1302,10 @@ out:
                 l_wait_event(agl_thread->t_ctl_waitq,
                              thread_is_stopped(agl_thread),
                              &lwi);
+        } else {
+                /* Set agl_thread flags anyway. */
+                thread_set_flags(&sai->sai_agl_thread, SVC_STOPPED);
         }
-
         ll_dir_chain_fini(&chain);
         cfs_spin_lock(&plli->lli_sa_lock);
         if (!sa_received_empty(sai)) {
@@ -1646,27 +1644,35 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentryp,
                         struct lookup_intent it = { .it_op = IT_GETATTR,
                                                     .d.lustre.it_lock_handle =
                                                      entry->se_handle };
-                        struct ll_dentry_data *lld;
-                        __u64 bits;
-
-                        rc = md_revalidate_lock(ll_i2mdexp(dir), &it,
-                                                ll_inode2fid(inode), &bits);
-                        if (rc == 1) {
-                                if ((*dentryp)->d_inode == NULL) {
-                                        *dentryp = ll_find_alias(inode,
-                                                                 *dentryp);
-                                        lld = ll_d2d(*dentryp);
-                                        if (unlikely(lld == NULL))
-                                                ll_dops_init(*dentryp, 1, 1);
+                       __u64 bits;
+
+                       rc = md_revalidate_lock(ll_i2mdexp(dir), &it,
+                                               ll_inode2fid(inode), &bits);
+                       if (rc == 1) {
+                               if ((*dentryp)->d_inode == NULL) {
+                                       *dentryp = ll_splice_alias(inode,
+                                                                  *dentryp);
+                                } else if ((*dentryp)->d_inode != inode) {
+                                        /* revalidate, but inode is recreated */
+                                        CDEBUG(D_READA,
+                                              "stale dentry %.*s inode %lu/%u, "
+                                              "statahead inode %lu/%u\n",
+                                              (*dentryp)->d_name.len,
+                                              (*dentryp)->d_name.name,
+                                              (*dentryp)->d_inode->i_ino,
+                                              (*dentryp)->d_inode->i_generation,
+                                              inode->i_ino,
+                                              inode->i_generation);
+                                        ll_sai_unplug(sai, entry);
+                                        RETURN(-ESTALE);
                                 } else {
-                                        LASSERT((*dentryp)->d_inode == inode);
-
-                                        ll_dentry_rehash(*dentryp, 0);
-                                        iput(inode);
-                                }
-                                entry->se_inode = NULL;
+                                       iput(inode);
+                               }
+                               entry->se_inode = NULL;
 
-                                ll_dentry_reset_flags(*dentryp, bits);
+                               if ((bits & MDS_INODELOCK_LOOKUP) &&
+                                   d_lustre_invalid(*dentryp))
+                                       d_lustre_revalidate(*dentryp);
                                 ll_intent_release(&it);
                         }
                 }
@@ -1718,6 +1724,7 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentryp,
                 dput(parent);
                 lli->lli_opendir_key = NULL;
                 thread_set_flags(thread, SVC_STOPPED);
+                thread_set_flags(&sai->sai_agl_thread, SVC_STOPPED);
                 ll_sai_put(sai);
                 LASSERT(lli->lli_sai == NULL);
                 RETURN(-EAGAIN);
@@ -1729,9 +1736,9 @@ int do_statahead_enter(struct inode *dir, struct dentry **dentryp,
 
         /*
          * We don't stat-ahead for the first dirent since we are already in
-         * lookup, and -EEXIST also indicates that this is the first dirent.
+         * lookup.
          */
-        RETURN(-EEXIST);
+        RETURN(-EAGAIN);
 
 out:
         if (sai != NULL)