From 06ecb2c74c113c52d90cb3f2b76f70ed7b6ce774 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Tue, 1 Apr 2014 11:19:10 +0800 Subject: [PATCH] mds: handle freeze authpin race For across authority rename, the MDS first freezes the source inode's authpin. It happens while the source dentry isn't locked. So when the inode's authpin become frozen, the source dentry may have changed and be linked to a different inode. Signed-off-by: Yan, Zheng --- src/mds/Mutation.cc | 6 ++++-- src/mds/Mutation.h | 2 +- src/mds/Server.cc | 5 +++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/mds/Mutation.cc b/src/mds/Mutation.cc index 3916b2a1a3384..0bf5475fae18b 100644 --- a/src/mds/Mutation.cc +++ b/src/mds/Mutation.cc @@ -226,7 +226,7 @@ bool MDRequest::freeze_auth_pin(CInode *inode) return true; } -void MDRequest::unfreeze_auth_pin() +void MDRequest::unfreeze_auth_pin(bool clear_inode) { assert(more()->is_freeze_authpin); CInode *inode = more()->rename_inode; @@ -235,6 +235,8 @@ void MDRequest::unfreeze_auth_pin() else inode->unfreeze_inode(); more()->is_freeze_authpin = false; + if (clear_inode) + more()->rename_inode = NULL; } void MDRequest::set_remote_frozen_auth_pin(CInode *inode) @@ -273,7 +275,7 @@ bool MDRequest::can_auth_pin(MDSCacheObject *object) void MDRequest::drop_local_auth_pins() { if (has_more() && more()->is_freeze_authpin) - unfreeze_auth_pin(); + unfreeze_auth_pin(true); Mutation::drop_local_auth_pins(); } diff --git a/src/mds/Mutation.h b/src/mds/Mutation.h index 92750bef2f40e..206b71a9158dd 100644 --- a/src/mds/Mutation.h +++ b/src/mds/Mutation.h @@ -312,7 +312,7 @@ struct MDRequest : public Mutation { bool slave_did_prepare(); bool did_ino_allocation(); bool freeze_auth_pin(CInode *inode); - void unfreeze_auth_pin(); + void unfreeze_auth_pin(bool clear_inode=false); void set_remote_frozen_auth_pin(CInode *inode); bool can_auth_pin(MDSCacheObject *object); void drop_local_auth_pins(); diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 33870d1bc6eaf..984ad2909d8c2 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -1679,6 +1679,11 @@ void Server::handle_slave_auth_pin(MDRequest *mdr) if (fail) { mdr->drop_local_auth_pins(); // just in case } else { + /* freeze authpin wrong inode */ + if (mdr->has_more() && mdr->more()->is_freeze_authpin && + mdr->more()->rename_inode != auth_pin_freeze) + mdr->unfreeze_auth_pin(true); + /* handle_slave_rename_prep() call freeze_inode() to wait for all other operations * on the source inode to complete. This happens after all locks for the rename * operation are acquired. But to acquire locks, we need auth pin locks' parent -- 2.39.5