From: Yan, Zheng Date: Tue, 1 Apr 2014 03:19:10 +0000 (+0800) Subject: mds: handle freeze authpin race X-Git-Tag: v0.79~27^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=06ecb2c74c113c52d90cb3f2b76f70ed7b6ce774;p=ceph.git 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 --- diff --git a/src/mds/Mutation.cc b/src/mds/Mutation.cc index 3916b2a1a338..0bf5475fae18 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 92750bef2f40..206b71a9158d 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 33870d1bc6ea..984ad2909d8c 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