X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fmdt%2Fmdt_recovery.c;h=f5a49da9949d74efa2ab63ef226b20f69272868b;hp=f3e6884d68f8bfca4cf8c61b7f0516cf78558b6e;hb=13352ee70c2f1b3c382fa1bae1885967fb2cf69b;hpb=a1ef13bca025e09e10ce2d6e007013d0e187e6eb diff --git a/lustre/mdt/mdt_recovery.c b/lustre/mdt/mdt_recovery.c index f3e6884..f5a49da 100644 --- a/lustre/mdt/mdt_recovery.c +++ b/lustre/mdt/mdt_recovery.c @@ -234,6 +234,26 @@ void mdt_reconstruct_generic(struct mdt_thread_info *mti, return mdt_req_from_lcd(req, ted->ted_lcd); } +/** + * Generate fake attributes for a non-existing object + * + * While the client was waiting for the reply, the original transaction + * got committed and corresponding rep-ack lock got released, then another + * client was able to destroy the object. But we still need to send some + * attributes back. So we fake them and set nlink=0, so the client will + * be able to detect a non-existing object and drop it from the cache + * immediately. + * + * \param[out] ma attributes to fill + */ +static void mdt_fake_ma(struct md_attr *ma) +{ + ma->ma_valid = MA_INODE; + memset(&ma->ma_attr, 0, sizeof(ma->ma_attr)); + ma->ma_attr.la_valid = LA_NLINK; + ma->ma_attr.la_mode = S_IFREG; +} + static void mdt_reconstruct_create(struct mdt_thread_info *mti, struct mdt_lock_handle *lhc) { @@ -266,7 +286,9 @@ static void mdt_reconstruct_create(struct mdt_thread_info *mti, mti->mti_attr.ma_need = MA_INODE; mti->mti_attr.ma_valid = 0; rc = mdt_attr_get_complex(mti, child, &mti->mti_attr); - if (rc == -EREMOTE) { + if (rc == -ENOENT) { + mdt_fake_ma(&mti->mti_attr); + } else if (rc == -EREMOTE) { /* object was created on remote server */ if (!mdt_is_dne_client(exp)) /* Return -EIO for old client */ @@ -310,7 +332,10 @@ static void mdt_reconstruct_setattr(struct mdt_thread_info *mti, mti->mti_attr.ma_need = MA_INODE; mti->mti_attr.ma_valid = 0; - mdt_attr_get_complex(mti, obj, &mti->mti_attr); + + rc = mdt_attr_get_complex(mti, obj, &mti->mti_attr); + if (rc == -ENOENT) + mdt_fake_ma(&mti->mti_attr); mdt_pack_attr2body(mti, body, &mti->mti_attr.ma_attr, mdt_object_fid(obj)); if (mti->mti_ioepoch && (mti->mti_ioepoch->flags & MF_EPOCH_OPEN)) {