#include <linux/obd_support.h>
#include <linux/lustre_lite.h>
+#include <linux/lustre_idl.h>
#include <linux/lustre_dlm.h>
extern struct address_space_operations ll_aops;
struct lustre_handle *handle;
ENTRY;
+ /* XXX the check for RENAME2 is a workaround for old kernels
+ which call intent_release twice in rename
+ */
if (it == NULL || it->it_op == IT_RENAME2) {
EXIT;
return;
handle = (struct lustre_handle *)it->it_lock_handle;
if (it->it_op == IT_SETATTR) {
int rc;
- struct inode *inode = de->d_inode;
ldlm_lock_decref(handle, it->it_lock_mode);
rc = ldlm_cli_cancel(handle);
if (rc < 0)
CERROR("ldlm_cli_cancel: %d\n", rc);
- /* XXX should we only do this when the last lock goes? */
- LASSERT(igrab(inode) == inode);
- d_delete_aliases(inode);
- iput(inode);
} else
ldlm_lock_decref(handle, it->it_lock_mode);
}
- if (it->it_op != IT_RELEASED_MAGIC) {
+ if (it->it_op == IT_RELEASED_MAGIC) {
+ EXIT;
+ return;
+ }
+
+ if (de->d_it && de->d_it == it) {
+ de->d_it = NULL;
up(&ll_d2d(de)->lld_it_sem);
it->it_op = IT_RELEASED_MAGIC;
}
+
EXIT;
}
return 0;
}
+static int ll_have_lock(struct dentry *de)
+{
+ struct ll_sb_info *sbi = ll_s2sbi(de->d_sb);
+ struct lustre_handle lockh;
+ __u64 res_id[RES_NAME_SIZE] = {0};
+ struct obd_device *obddev;
+ ENTRY;
+
+ if (!de->d_inode)
+ RETURN(0);
+
+ obddev = class_conn2obd(&sbi->ll_mdc_conn);
+ res_id[0] = de->d_inode->i_ino;
+
+ CDEBUG(D_INFO, "trying to match res "LPU64"\n", res_id[0]);
+
+ if (ldlm_lock_match(obddev->obd_namespace, res_id, LDLM_PLAIN,
+ NULL, 0, LCK_PR, &lockh)) {
+ ldlm_lock_decref(&lockh, LCK_PR);
+ RETURN(1);
+ }
+
+ if (ldlm_lock_match(obddev->obd_namespace, res_id, LDLM_PLAIN,
+ NULL, 0, LCK_PW, &lockh)) {
+ ldlm_lock_decref(&lockh, LCK_PW);
+ RETURN(1);
+ }
+ RETURN(0);
+}
+
int ll_revalidate2(struct dentry *de, int flags, struct lookup_intent *it)
{
int rc;
RETURN(0);
}
+ if (ll_have_lock(de))
+ GOTO(out, rc = 0);
+
rc = ll_intent_lock(de->d_parent->d_inode, &de, it, revalidate2_finish);
if (rc < 0) {
/* Something bad happened; overwrite it_status? */
spin_unlock(&dcache_lock);
d_rehash(de);
- if (it != NULL) {
- LL_SAVE_INTENT(de, it);
- } else {
+ out:
+ if (!it)
de->d_it = NULL;
- }
RETURN(1);
}