@@ -2604,17 +2604,19 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session,
{
int client = session->inst.name.num();
assert(snapid);
-
assert(session->connection);
bool valid = true;
// do not issue caps if inode differs from readdir snaprealm
SnapRealm *realm = find_snaprealm();
- bool no_caps = (realm && dir_realm && realm != dir_realm);
+ bool no_caps = (realm && dir_realm && realm != dir_realm) ||
+ is_frozen() || state_test(CInode::STATE_EXPORTINGCAPS);
if (no_caps)
- dout(20) << "encode_inodestat realm=" << realm << " snaprealm " << snaprealm
- << " no_caps=" << no_caps << dendl;
+ dout(20) << "encode_inodestat no caps"
+ << ((realm && dir_realm && realm != dir_realm)?", snaprealm differs ":"")
+ << (state_test(CInode::STATE_EXPORTINGCAPS)?", exporting caps":"")
+ << (is_frozen()?", frozen inode":"") << dendl;
// pick a version!
inode_t *oi = &inode;
@@ -1936,14 +1936,14 @@ CInode* Server::rdlock_path_pin_ref(MDRequest *mdr, int n,
want_auth = true;
if (want_auth) {
+ if (ref->is_ambiguous_auth()) {
+ dout(10) << "waiting for single auth on " << *ref << dendl;
+ ref->add_waiter(CInode::WAIT_SINGLEAUTH, new C_MDS_RetryRequest(mdcache, mdr));
+ return 0;
+ }
if (!ref->is_auth()) {
- if (ref->is_ambiguous_auth()) {
- dout(10) << "waiting for single auth on " << *ref << dendl;
- ref->add_waiter(CInode::WAIT_SINGLEAUTH, new C_MDS_RetryRequest(mdcache, mdr));
- } else {
- dout(10) << "fw to auth for " << *ref << dendl;
- mdcache->request_forward(mdr, ref->authority().first);
- }
+ dout(10) << "fw to auth for " << *ref << dendl;
+ mdcache->request_forward(mdr, ref->authority().first);
return 0;
}
@@ -2435,6 +2435,14 @@ void Server::handle_client_open(MDRequest *mdr)
if (!cur)
return;
+ if (cur->is_frozen() || cur->state_test(CInode::STATE_EXPORTINGCAPS)) {
+ assert(!need_auth);
+ mdr->done_locking = false;
+ CInode *cur = rdlock_path_pin_ref(mdr, 0, rdlocks, true);
+ if (!cur)
+ return;
+ }
+
if (mdr->snapid != CEPH_NOSNAP && mdr->client_request->may_write()) {
reply_request(mdr, -EROFS);
return;