make DCACHE_LUSTRE_INVALID always defined.
Branch HEAD
b=16417
i=green
i=johann
struct ptlrpc_request *);
int (*m_clear_open_replay_data)(struct obd_export *,
struct obd_client_handle *);
- int (*m_set_lock_data)(struct obd_export *, __u64 *, void *);
+ int (*m_set_lock_data)(struct obd_export *, __u64 *, void *, __u32 *);
ldlm_mode_t (*m_lock_match)(struct obd_export *, int,
const struct lu_fid *, ldlm_type_t,
}
static inline int md_set_lock_data(struct obd_export *exp,
- __u64 *lockh, void *data)
+ __u64 *lockh, void *data, __u32 *bits)
{
ENTRY;
EXP_CHECK_MD_OP(exp, set_lock_data);
EXP_MD_COUNTER_INCREMENT(exp, set_lock_data);
- RETURN(MDP(exp->exp_obd, set_lock_data)(exp, lockh, data));
+ RETURN(MDP(exp->exp_obd, set_lock_data)(exp, lockh, data, bits));
}
static inline int md_cancel_unused(struct obd_export *exp,
sbi = llu_i2sbi(inode);
md_set_lock_data(sbi->ll_md_exp,
- &it->d.lustre.it_lock_handle, inode);
+ &it->d.lustre.it_lock_handle, inode, NULL);
}
/* drop lookup/getattr locks */
EXIT;
}
-#ifdef DCACHE_LUSTRE_INVALID
/* Compare if two dentries are the same. Don't match if the existing dentry
* is marked DCACHE_LUSTRE_INVALID. Returns 1 if different, 0 if the same.
*
/* XXX: d_name must be in-dentry structure */
dchild = container_of(d_name, struct dentry, d_name); /* ugh */
- if (dchild->d_flags & DCACHE_LUSTRE_INVALID) {
- CDEBUG(D_DENTRY,"INVALID dentry %p not matched, was bug 3784\n",
- dchild);
+
+ CDEBUG(D_DENTRY,"found name %.*s(%p) - flags %d/%x - refc %d\n",
+ name->len, name->name, dchild,
+ d_mountpoint(dchild), dchild->d_flags & DCACHE_LUSTRE_INVALID,
+ atomic_read(&dchild->d_count));
+
+ /* mountpoint is always valid */
+ if (d_mountpoint(dchild))
+ RETURN(0);
+
+ if (dchild->d_flags & DCACHE_LUSTRE_INVALID)
RETURN(1);
- }
+
RETURN(0);
}
-#endif
/* should NOT be called with the dcache lock, see fs/dcache.c */
static int ll_ddelete(struct dentry *de)
"ino=%lu\n", dentry, inode, inode->i_ino);
lustre_dump_dentry(dentry, 1);
libcfs_debug_dumpstack(NULL);
- } else if (d_mountpoint(dentry)) {
- /* For mountpoints we skip removal of the dentry
- which happens solely because we have a lock on it
- obtained when this dentry was not a mountpoint yet */
- CDEBUG(D_DENTRY, "Skippind mountpoint dentry removal "
- "%.*s (%p) parent %p\n",
- dentry->d_name.len,
- dentry->d_name.name,
- dentry, dentry->d_parent);
-
- continue;
}
if (ll_drop_dentry(dentry))
CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)\n",
inode, inode->i_ino, inode->i_generation);
md_set_lock_data(sbi->ll_md_exp, &it->d.lustre.it_lock_handle,
- inode);
+ inode, NULL);
}
/* drop lookup or getattr locks immediately */
if (rc != -ESTALE) {
CDEBUG(D_INFO, "ll_intent_lock: rc %d : it->it_status "
"%d\n", rc, it->d.lustre.it_status);
- } else {
-#ifndef HAVE_VFS_INTENT_PATCHES
- if (it_disposition(it, DISP_OPEN_OPEN) &&
- !it_open_error(DISP_OPEN_OPEN, it))
- /* server have valid open - close file first*/
- ll_release_openhandle(de, it);
-#endif
}
GOTO(out, rc = 0);
}
.d_revalidate = ll_revalidate_nd,
.d_release = ll_release,
.d_delete = ll_ddelete,
-#ifdef DCACHE_LUSTRE_INVALID
.d_compare = ll_dcompare,
-#endif
#if 0
.d_pin = ll_pin,
.d_unpin = ll_unpin,
} else {
/* for cross-ref object, l_ast_data of the lock may not be set,
* we reset it here */
- md_set_lock_data(ll_i2sbi(dir)->ll_md_exp, &lockh.cookie, dir);
+ md_set_lock_data(ll_i2sbi(dir)->ll_md_exp, &lockh.cookie,
+ dir, NULL);
}
ldlm_lock_dump_handle(D_OTHER, &lockh);
if (itp->d.lustre.it_lock_mode)
md_set_lock_data(sbi->ll_md_exp,
&itp->d.lustre.it_lock_handle,
- file->f_dentry->d_inode);
+ file->f_dentry->d_inode, NULL);
rc = ll_prep_inode(&file->f_dentry->d_inode, req, NULL);
out:
}
md_set_lock_data(ll_i2sbi(inode)->ll_md_exp,
&it->d.lustre.it_lock_handle,
- file->f_dentry->d_inode);
+ file->f_dentry->d_inode, NULL);
goto restart;
}
OBD_ALLOC(*och_p, sizeof (struct obd_client_handle));
#define FMODE_EXEC 0
#endif
+#ifndef DCACHE_LUSTRE_INVALID
+#define DCACHE_LUSTRE_INVALID 0x100
+#endif
+
#define LL_IT2STR(it) ((it) ? ldlm_it2str((it)->it_op) : "0")
#define LUSTRE_FPRIVATE(file) ((file)->private_data)
}
static struct dentry_operations ll_d_root_ops = {
-#ifdef DCACHE_LUSTRE_INVALID
.d_compare = ll_dcompare,
-#endif
.d_revalidate = ll_revalidate_nd,
};
dget_locked(dentry);
lock_dentry(dentry);
__d_drop(dentry);
-#ifdef DCACHE_LUSTRE_INVALID
- dentry->d_flags &= ~DCACHE_LUSTRE_INVALID;
-#endif
unlock_dentry(dentry);
ll_dops_init(dentry, 0);
d_rehash_cond(dentry, 0); /* avoid taking dcache_lock inside */
"refc %d\n", last_discon, last_discon->d_inode,
atomic_read(&last_discon->d_count));
dget_locked(last_discon);
+ lock_dentry(last_discon);
+ last_discon->d_flags |= DCACHE_LUSTRE_INVALID;
+ unlock_dentry(last_discon);
spin_unlock(&dcache_lock);
spin_unlock(&ll_lookup_lock);
ll_dops_init(last_discon, 1);
iput(inode);
return last_discon;
}
-
+ de->d_flags |= DCACHE_LUSTRE_INVALID;
ll_d_add(de, inode);
spin_unlock(&dcache_lock);
* when I return */
if (!it_disposition(it, DISP_LOOKUP_NEG)) {
struct dentry *save = *de;
+ __u32 bits;
rc = ll_prep_inode(&inode, request, (*de)->d_sb);
if (rc)
CDEBUG(D_DLMTRACE, "setting l_data to inode %p (%lu/%u)\n",
inode, inode->i_ino, inode->i_generation);
md_set_lock_data(sbi->ll_md_exp,
- &it->d.lustre.it_lock_handle, inode);
+ &it->d.lustre.it_lock_handle, inode, &bits);
/* We used to query real size from OSTs here, but actually
this is not needed. For stat() calls size would be updated
lld->lld_sa_generation = 0;
}
}
+ /* we have lookup look - unhide dentry */
+ if (bits & MDS_INODELOCK_LOOKUP) {
+ lock_dentry(*de);
+ (*de)->d_flags &= ~(DCACHE_LUSTRE_INVALID);
+ unlock_dentry(*de);
+ }
} else {
ll_dops_init(*de, 1);
/* Check that parent has UPDATE lock. If there is none, we
ll_d_add(*de, NULL);
spin_unlock(&dcache_lock);
} else {
+ /* negative lookup - and don't have update lock to
+ * parent */
+ lock_dentry(*de);
+ (*de)->d_flags |= DCACHE_LUSTRE_INVALID;
+ unlock_dentry(*de);
+
(*de)->d_inode = NULL;
/* We do not want to hash the dentry if don`t have a
* lock, but if this dentry is later used in d_move,
CDEBUG(D_DLMTRACE, "setting l_ast_data to inode %p (%lu/%u)\n",
inode, inode->i_ino, inode->i_generation);
md_set_lock_data(sbi->ll_md_exp,
- &it->d.lustre.it_lock_handle, inode);
+ &it->d.lustre.it_lock_handle, inode, NULL);
EXIT;
out:
ptlrpc_req_finished(request);
RETURN(rc);
}
-int lmv_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data)
+int lmv_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data,
+ __u32 *bits)
{
struct obd_device *obd = exp->exp_obd;
struct lmv_obd *lmv = &obd->u.lmv;
int rc;
ENTRY;
- rc = md_set_lock_data(lmv->tgts[0].ltd_exp, lockh, data);
+
+ rc = md_set_lock_data(lmv->tgts[0].ltd_exp, lockh, data, bits);
RETURN(rc);
}
/* mdc/mdc_locks.c */
int mdc_set_lock_data(struct obd_export *exp,
- __u64 *lockh, void *data);
+ __u64 *lockh, void *data, __u32 *bits);
int mdc_change_cbdata(struct obd_export *exp, const struct lu_fid *fid,
ldlm_iterator_t it, void *data);
EXPORT_SYMBOL(it_open_error);
/* this must be called on a lockh that is known to have a referenced lock */
-int mdc_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data)
+int mdc_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data,
+ __u32 *bits)
{
struct ldlm_lock *lock;
ENTRY;
+ if(bits)
+ *bits = 0;
+
if (!*lockh) {
EXIT;
RETURN(0);
}
#endif
lock->l_ast_data = data;
+ if (bits)
+ *bits = lock->l_policy_data.l_inodebits.bits;
+
unlock_res_and_lock(lock);
LDLM_LOCK_PUT(lock);