*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
*
* GPL HEADER END
*/
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2015, Intel Corporation.
+ * Copyright (c) 2011, 2016, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
/* allocate sa_entry and hash it to allow scanner process to find it */
static struct sa_entry *
-sa_alloc(struct ll_statahead_info *sai, __u64 index, const char *name, int len,
- const struct lu_fid *fid)
+sa_alloc(struct dentry *parent, struct ll_statahead_info *sai, __u64 index,
+ const char *name, int len, const struct lu_fid *fid)
{
struct ll_inode_info *lli;
struct sa_entry *entry;
if (unlikely(entry == NULL))
RETURN(ERR_PTR(-ENOMEM));
- CDEBUG(D_READA, "alloc sa entry %.*s(%p) index "LPU64"\n",
+ CDEBUG(D_READA, "alloc sa entry %.*s(%p) index %llu\n",
len, name, entry, index);
entry->se_index = index;
dname = (char *)entry + sizeof(struct sa_entry);
memcpy(dname, name, len);
dname[len] = 0;
- entry->se_qstr.hash = full_name_hash(name, len);
+ entry->se_qstr.hash = ll_full_name_hash(parent, name, len);
entry->se_qstr.len = len;
entry->se_qstr.name = dname;
entry->se_fid = *fid;
/* free sa_entry, which should have been unhashed and not in any list */
static void sa_free(struct ll_statahead_info *sai, struct sa_entry *entry)
{
- CDEBUG(D_READA, "free sa entry %.*s(%p) index "LPU64"\n",
+ CDEBUG(D_READA, "free sa entry %.*s(%p) index %llu\n",
entry->se_qstr.len, entry->se_qstr.name, entry,
entry->se_index);
RETURN_EXIT;
}
+ /* In case of restore, the MDT has the right size and has already
+ * sent it back without granting the layout lock, inode is up-to-date.
+ * Then AGL (async glimpse lock) is useless.
+ * Also to glimpse we need the layout, in case of a runninh restore
+ * the MDT holds the layout lock so the glimpse will block up to the
+ * end of restore (statahead/agl will block) */
+ if (ll_file_test_flag(lli, LLIF_FILE_RESTORING)) {
+ lli->lli_agl_index = 0;
+ iput(inode);
+ RETURN_EXIT;
+ }
+
/* Someone is in glimpse (sync or async), do nothing. */
rc = down_write_trylock(&lli->lli_glimpse_sem);
if (rc == 0) {
}
CDEBUG(D_READA, "Handling (init) async glimpse: inode = "
- DFID", idx = "LPU64"\n", PFID(&lli->lli_fid), index);
+ DFID", idx = %llu\n", PFID(&lli->lli_fid), index);
cl_agl(inode);
lli->lli_agl_index = 0;
up_write(&lli->lli_glimpse_sem);
CDEBUG(D_READA, "Handled (init) async glimpse: inode= "
- DFID", idx = "LPU64", rc = %d\n",
+ DFID", idx = %llu, rc = %d\n",
PFID(&lli->lli_fid), index, rc);
iput(inode);
}
}
- it->d.lustre.it_lock_handle = entry->se_handle;
+ it->it_lock_handle = entry->se_handle;
rc = md_revalidate_lock(ll_i2mdexp(dir), it, ll_inode2fid(dir), NULL);
if (rc != 1)
GOTO(out, rc = -EAGAIN);
* thread enqueues lock on parent in readdir and another
* process enqueues lock on child with parent lock held, eg.
* unlink. */
- handle = it->d.lustre.it_lock_handle;
+ handle = it->it_lock_handle;
ll_intent_drop_lock(it);
}
list_add_tail(&entry->se_list, &sai->sai_interim_entries);
}
sai->sai_replied++;
+
+ smp_mb();
if (waitq != NULL)
wake_up(waitq);
spin_unlock(&lli->lli_sa_lock);
{
struct inode *inode = dentry->d_inode;
struct lookup_intent it = { .it_op = IT_GETATTR,
- .d.lustre.it_lock_handle = 0 };
+ .it_lock_handle = 0 };
struct md_enqueue_info *minfo;
int rc;
ENTRY;
rc = md_revalidate_lock(ll_i2mdexp(dir), &it, ll_inode2fid(inode),
NULL);
if (rc == 1) {
- entry->se_handle = it.d.lustre.it_lock_handle;
+ entry->se_handle = it.it_lock_handle;
ll_intent_release(&it);
RETURN(1);
}
int rc;
ENTRY;
- entry = sa_alloc(sai, sai->sai_index, name, len, fid);
+ entry = sa_alloc(parent, sai, sai->sai_index, name, len, fid);
if (IS_ERR(entry))
RETURN_EXIT;
if (IS_ERR(op_data))
GOTO(out, rc = PTR_ERR(op_data));
- op_data->op_max_pages = ll_i2sbi(dir)->ll_md_brw_pages;
-
if (sbi->ll_flags & LL_SBI_AGL_ENABLED)
ll_start_agl(parent, sai);
sai->sai_in_readpage = 0;
if (IS_ERR(page)) {
rc = PTR_ERR(page);
- CDEBUG(D_READA, "error reading dir "DFID" at "LPU64
- "/"LPU64" opendir_pid = %u: rc = %d\n",
+ CDEBUG(D_READA, "error reading dir "DFID" at %llu"
+ "/%llu opendir_pid = %u: rc = %d\n",
PFID(ll_inode2fid(dir)), pos, sai->sai_index,
lli->lli_opendir_pid, rc);
break;
rc = -EFAULT;
atomic_inc(&sbi->ll_sa_wrong);
CDEBUG(D_READA, "Statahead for dir "DFID" hit "
- "ratio too low: hit/miss "LPU64"/"LPU64
- ", sent/replied "LPU64"/"LPU64", stopping "
+ "ratio too low: hit/miss %llu/%llu"
+ ", sent/replied %llu/%llu, stopping "
"statahead thread: pid %d\n",
PFID(&lli->lli_fid), sai->sai_hit,
sai->sai_miss, sai->sai_sent,
/*
* statahead thread may not quit yet because it needs to cache
* entries, now it's time to tell it to quit.
+ *
+ * In case sai is released, wake_up() is called inside spinlock,
+ * so we have to call smp_mb() explicitely to serialize ops.
*/
thread_set_flags(&sai->sai_thread, SVC_STOPPING);
+ smp_mb();
wake_up(&sai->sai_thread.t_ctl_waitq);
}
spin_unlock(&lli->lli_sa_lock);
/**
*FIXME choose the start offset of the readdir
*/
- op_data->op_max_pages = ll_i2sbi(dir)->ll_md_brw_pages;
ll_dir_chain_init(&chain);
page = ll_get_dir_page(dir, op_data, 0, &chain);
struct ll_inode_info *lli = ll_i2info(dir);
rc = PTR_ERR(page);
- CERROR("%s: reading dir "DFID" at "LPU64
+ CERROR("%s: reading dir "DFID" at %llu"
"opendir_pid = %u : rc = %d\n",
ll_get_fsname(dir->i_sb, NULL, 0),
PFID(ll_inode2fid(dir)), pos,
if (entry->se_state == 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 =
+ .it_lock_handle =
entry->se_handle };
__u64 bits;