}
/*
- * XXX We could choose not to check DLM lock. Leave the decision
- * to remote acl handling.
+ * Here we hold DLM lock across permission check, to get better
+ * conformance especially for remote acl. will introduce certain
+ * overhead, maybe need a profile.
*/
static int
lustre_check_acl(struct inode *inode, int mask)
int ll_inode_permission(struct inode *inode, int mask, struct nameidata *nd)
{
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+
+ /* for remote client, permission bits in inode doesn't
+ * play a role anymore.
+ */
+ if (sbi->ll_remote)
+ return lustre_check_acl(inode, mask);
+
return generic_permission(inode, mask, lustre_check_acl);
}
up(&racl->ra_update_sem);
}
} else {
+ /* we can't invalide acl here: suppose we touch a new file
+ * under a dir, blocking ast on dir will lead to open failure
+ * on client, although succeed on mds. it's kind of weird,
+ * the real fix i think is improve client-vfs interaction.
+ *
+ * currently we just do nothing here.
+ */
+ return;
+
LASSERT(!lli->lli_remote_acl);
spin_lock(&lli->lli_lock);
posix_acl_release(lli->lli_posix_acl);
truncate_inode_pages(inode->i_mapping, 0);
}
- /* we can't invalide acl here: suppose we touch a new file
- * under a dir, blocking ast on dir will lead to open failure
- * on client, although succeed on mds. it's kind of weird,
- * the real fix i think is improve client-vfs interaction.
- */
-#if 0
ll_inode_invalidate_acl(inode);
-#endif
if (inode->i_sb->s_root &&
inode != inode->i_sb->s_root->d_inode &&
static void mds_revoke_export_locks(struct obd_export *exp)
{
struct list_head *locklist = &exp->exp_ldlm_data.led_held_locks;
- struct list_head work;
+ struct list_head rpc_list;
struct ldlm_lock *lock, *next;
struct ldlm_lock_desc desc;
+ /* don't do this for local client */
if (!exp->u.eu_mds_data.med_remote)
return;
+ /* don't revoke locks during recovery */
+ if (exp->exp_obd->obd_recovering)
+ return;
+
ENTRY;
- CERROR("implement right locking here! -bzzz\n");
- INIT_LIST_HEAD(&work);
+ INIT_LIST_HEAD(&rpc_list);
+
spin_lock(&exp->exp_ldlm_data.led_lock);
list_for_each_entry_safe(lock, next, locklist, l_export_chain) {
continue;
}
+ LASSERT(lock->l_blocking_ast);
+ LASSERT(!lock->l_blocking_lock);
+
lock->l_flags |= LDLM_FL_AST_SENT;
unlock_res_and_lock(lock);
+ list_move(&lock->l_export_chain, &rpc_list);
+ }
+ spin_unlock(&exp->exp_ldlm_data.led_lock);
+
+ while (!list_empty(&rpc_list)) {
+ lock = list_entry(rpc_list.next, struct ldlm_lock,
+ l_export_chain);
+ list_del_init(&lock->l_export_chain);
+
/* the desc just pretend to exclusive */
ldlm_lock2desc(lock, &desc);
desc.l_req_mode = LCK_EX;
lock->l_blocking_ast(lock, &desc, NULL, LDLM_CB_BLOCKING);
}
- spin_unlock(&exp->exp_ldlm_data.led_lock);
-
EXIT;
}
static void
gss_unhash_msg_nolock(struct gss_upcall_msg *gmsg)
{
-#if defined(CONFIG_SMP)
- LASSERT(spin_is_locked(&gmsg->gum_gsec->gs_lock));
-#endif
+ LASSERT_SPIN_LOCKED(&gmsg->gum_gsec->gs_lock);
if (list_empty(&gmsg->gum_list))
return;
struct gss_upcall_msg *gmsg;
ENTRY;
-#if defined(CONFIG_SMP)
- LASSERT(spin_is_locked(&gsec->gs_lock));
-#endif
+ LASSERT_SPIN_LOCKED(&gsec->gs_lock);
list_for_each_entry(gmsg, &gsec->gs_upcalls, gum_list) {
if (memcmp(&gmsg->gum_data, gmd, sizeof(*gmd)))