/* if object is dying, pack the lov/llog data, * parameter info->mti_attr should be valid at this point! */ int mdt_handle_last_unlink(struct mdt_thread_info *info, struct mdt_object *mo, const struct md_attr *ma) { struct mdt_body *repbody; const struct lu_attr *la = &ma->ma_attr; int rc; ENTRY; repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY); LASSERT(repbody != NULL); if (ma->ma_valid & MA_INODE) mdt_pack_attr2body(info, repbody, la, mdt_object_fid(mo)); if (ma->ma_valid & MA_LOV) { CERROR("No need in LOV EA upon unlink\n"); dump_stack(); } repbody->eadatasize = 0; if (ma->ma_cookie_size && (ma->ma_valid & MA_COOKIE)) { repbody->aclsize = ma->ma_cookie_size; repbody->valid |= OBD_MD_FLCOOKIE; } if (info->mti_mdt->mdt_opts.mo_oss_capa && exp_connect_flags(info->mti_exp) & OBD_CONNECT_OSS_CAPA && repbody->valid & OBD_MD_FLEASIZE) { struct lustre_capa *capa; capa = req_capsule_server_get(info->mti_pill, &RMF_CAPA2); LASSERT(capa); capa->lc_opc = CAPA_OPC_OSS_DESTROY; rc = mo_capa_get(info->mti_env, mdt_object_child(mo), capa, 0); if (rc) RETURN(rc); repbody->valid |= OBD_MD_FLOSSCAPA; } RETURN(0); }
static int mdt_reint_setattr(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) { struct md_attr *ma = &info->mti_attr; struct mdt_reint_record *rr = &info->mti_rr; struct ptlrpc_request *req = mdt_info_req(info); struct mdt_export_data *med = &req->rq_export->exp_mdt_data; struct mdt_file_data *mfd; struct mdt_object *mo; struct mdt_body *repbody; int som_au, rc, rc2; ENTRY; DEBUG_REQ(D_INODE, req, "setattr "DFID" %x", PFID(rr->rr_fid1), (unsigned int)ma->ma_attr.la_valid); if (info->mti_dlm_req) ldlm_request_cancel(req, info->mti_dlm_req, 0); repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY); mo = mdt_object_find(info->mti_env, info->mti_mdt, rr->rr_fid1); if (IS_ERR(mo)) GOTO(out, rc = PTR_ERR(mo)); if (mdt_object_obf(mo)) GOTO(out_put, rc = -EPERM); /* start a log jounal handle if needed */ if (!(mdt_conn_flags(info) & OBD_CONNECT_SOM)) { if ((ma->ma_attr.la_valid & LA_SIZE) || (rr->rr_flags & MRF_OPEN_TRUNC)) { /* Check write access for the O_TRUNC case */ if (mdt_write_read(mo) < 0) GOTO(out_put, rc = -ETXTBSY); } } else if (info->mti_ioepoch && (info->mti_ioepoch->flags & MF_EPOCH_OPEN)) { /* Truncate case. IOEpoch is opened. */ rc = mdt_write_get(mo); if (rc) GOTO(out_put, rc); mfd = mdt_mfd_new(); if (mfd == NULL) { mdt_write_put(mo); GOTO(out_put, rc = -ENOMEM); } mdt_ioepoch_open(info, mo, 0); repbody->ioepoch = mo->mot_ioepoch; mdt_object_get(info->mti_env, mo); mdt_mfd_set_mode(mfd, MDS_FMODE_TRUNC); mfd->mfd_object = mo; mfd->mfd_xid = req->rq_xid; spin_lock(&med->med_open_lock); cfs_list_add(&mfd->mfd_list, &med->med_open_head); spin_unlock(&med->med_open_lock); repbody->handle.cookie = mfd->mfd_handle.h_cookie; } som_au = info->mti_ioepoch && info->mti_ioepoch->flags & MF_SOM_CHANGE; if (som_au) { /* SOM Attribute update case. Find the proper mfd and update * SOM attributes on the proper object. */ LASSERT(mdt_conn_flags(info) & OBD_CONNECT_SOM); LASSERT(info->mti_ioepoch); spin_lock(&med->med_open_lock); mfd = mdt_handle2mfd(info, &info->mti_ioepoch->handle); if (mfd == NULL) { spin_unlock(&med->med_open_lock); CDEBUG(D_INODE, "no handle for file close: " "fid = "DFID": cookie = "LPX64"\n", PFID(info->mti_rr.rr_fid1), info->mti_ioepoch->handle.cookie); GOTO(out_put, rc = -ESTALE); } LASSERT(mfd->mfd_mode == MDS_FMODE_SOM); LASSERT(!(info->mti_ioepoch->flags & MF_EPOCH_CLOSE)); class_handle_unhash(&mfd->mfd_handle); cfs_list_del_init(&mfd->mfd_list); spin_unlock(&med->med_open_lock); mdt_mfd_close(info, mfd); } else if ((ma->ma_valid & MA_INODE) && ma->ma_attr.la_valid) { LASSERT((ma->ma_valid & MA_LOV) == 0); rc = mdt_attr_set(info, mo, ma, rr->rr_flags); if (rc) GOTO(out_put, rc); } else if ((ma->ma_valid & MA_LOV) && (ma->ma_valid & MA_INODE)) { struct lu_buf *buf = &info->mti_buf; LASSERT(ma->ma_attr.la_valid == 0); buf->lb_buf = ma->ma_lmm; buf->lb_len = ma->ma_lmm_size; rc = mo_xattr_set(info->mti_env, mdt_object_child(mo), buf, XATTR_NAME_LOV, 0); if (rc) GOTO(out_put, rc); } else LBUG(); /* If file data is modified, add the dirty flag */ if (ma->ma_attr_flags & MDS_DATA_MODIFIED) rc = mdt_add_dirty_flag(info, mo, ma); ma->ma_need = MA_INODE; ma->ma_valid = 0; rc = mdt_attr_get_complex(info, mo, ma); if (rc != 0) GOTO(out_put, rc); mdt_pack_attr2body(info, repbody, &ma->ma_attr, mdt_object_fid(mo)); if (info->mti_mdt->mdt_opts.mo_oss_capa && exp_connect_flags(info->mti_exp) & OBD_CONNECT_OSS_CAPA && S_ISREG(lu_object_attr(&mo->mot_obj.mo_lu)) && (ma->ma_attr.la_valid & LA_SIZE) && !som_au) { struct lustre_capa *capa; capa = req_capsule_server_get(info->mti_pill, &RMF_CAPA2); LASSERT(capa); capa->lc_opc = CAPA_OPC_OSS_DEFAULT | CAPA_OPC_OSS_TRUNC; rc = mo_capa_get(info->mti_env, mdt_object_child(mo), capa, 0); if (rc) GOTO(out_put, rc); repbody->valid |= OBD_MD_FLOSSCAPA; } EXIT; out_put: mdt_object_put(info->mti_env, mo); out: if (rc == 0) mdt_counter_incr(req, LPROC_MDT_SETATTR); mdt_client_compatibility(info); rc2 = mdt_fix_reply(info); if (rc == 0) rc = rc2; return rc; }