📄 file.c
字号:
lock_page(page); /* Already truncated by somebody */ if (!page->mapping) GOTO(out, rc = 0); mapping = page->mapping; ll_teardown_mmaps(mapping, (__u64)page->index << PAGE_CACHE_SHIFT, ((__u64)page->index<<PAGE_CACHE_SHIFT)| ~PAGE_CACHE_MASK); LL_CDEBUG_PAGE(D_PAGE, page, "removing page\n"); if (!discard && clear_page_dirty_for_io(page)) { LASSERT(page->mapping); rc = ll_call_writepage(page->mapping->host, page); /* either waiting for io to complete or reacquiring * the lock that the failed writepage released */ lock_page(page); wait_on_page_writeback(page); if (rc != 0) { CERROR("writepage inode %lu(%p) of page %p " "failed: %d\n", mapping->host->i_ino, mapping->host, page, rc);#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) if (rc == -ENOSPC) set_bit(AS_ENOSPC, &mapping->flags); else set_bit(AS_EIO, &mapping->flags);#else mapping->gfp_mask |= AS_EIO_MASK;#endif } } if (page->mapping != NULL) { struct ll_async_page *llap = llap_cast_private(page); // checking again to account for writeback's lock_page() LL_CDEBUG_PAGE(D_PAGE, page, "truncating\n"); if (llap) ll_ra_accounting(llap, page->mapping); ll_truncate_complete_page(page); } EXIT;out: LASSERT(!PageWriteback(page)); unlock_page(page); page_cache_release(page); return 0;}int ll_extent_lock_cancel_cb(struct ldlm_lock *lock, struct ldlm_lock_desc *new, void *data, int flag){ struct inode *inode; struct ll_inode_info *lli; struct lov_stripe_md *lsm; int stripe; __u64 kms; ENTRY; if ((unsigned long)data > 0 && (unsigned long)data < 0x1000) { LDLM_ERROR(lock, "cancelling lock with bad data %p", data); LBUG(); } inode = ll_inode_from_lock(lock); if (inode == NULL) RETURN(0); lli = ll_i2info(inode); if (lli == NULL) GOTO(iput, 0); if (lli->lli_smd == NULL) GOTO(iput, 0); lsm = lli->lli_smd; stripe = ll_lock_to_stripe_offset(inode, lock); if (stripe < 0) GOTO(iput, 0); lov_stripe_lock(lsm); lock_res_and_lock(lock); kms = ldlm_extent_shift_kms(lock, lsm->lsm_oinfo[stripe]->loi_kms); if (lsm->lsm_oinfo[stripe]->loi_kms != kms) LDLM_DEBUG(lock, "updating kms from "LPU64" to "LPU64, lsm->lsm_oinfo[stripe]->loi_kms, kms); lsm->lsm_oinfo[stripe]->loi_kms = kms; unlock_res_and_lock(lock); lov_stripe_unlock(lsm); ll_try_done_writing(inode); EXIT;iput: iput(inode); return 0;}#if 0int ll_async_completion_ast(struct ldlm_lock *lock, int flags, void *data){ /* XXX ALLOCATE - 160 bytes */ struct inode *inode = ll_inode_from_lock(lock); struct ll_inode_info *lli = ll_i2info(inode); struct lustre_handle lockh = { 0 }; struct ost_lvb *lvb; int stripe; ENTRY; if (flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED | LDLM_FL_BLOCK_CONV)) { LBUG(); /* not expecting any blocked async locks yet */ LDLM_DEBUG(lock, "client-side async enqueue returned a blocked " "lock, returning"); ldlm_lock_dump(D_OTHER, lock, 0); ldlm_reprocess_all(lock->l_resource); RETURN(0); } LDLM_DEBUG(lock, "client-side async enqueue: granted/glimpsed"); stripe = ll_lock_to_stripe_offset(inode, lock); if (stripe < 0) goto iput; if (lock->l_lvb_len) { struct lov_stripe_md *lsm = lli->lli_smd; __u64 kms; lvb = lock->l_lvb_data; lsm->lsm_oinfo[stripe].loi_rss = lvb->lvb_size; lock_res_and_lock(lock); ll_inode_size_lock(inode, 1); kms = MAX(lsm->lsm_oinfo[stripe].loi_kms, lvb->lvb_size); kms = ldlm_extent_shift_kms(NULL, kms); if (lsm->lsm_oinfo[stripe].loi_kms != kms) LDLM_DEBUG(lock, "updating kms from "LPU64" to "LPU64, lsm->lsm_oinfo[stripe].loi_kms, kms); lsm->lsm_oinfo[stripe].loi_kms = kms; ll_inode_size_unlock(inode, 1); unlock_res_and_lock(lock); }iput: iput(inode); wake_up(&lock->l_waitq); ldlm_lock2handle(lock, &lockh); ldlm_lock_decref(&lockh, LCK_PR); RETURN(0);}#endifstatic int ll_glimpse_callback(struct ldlm_lock *lock, void *reqp){ struct ptlrpc_request *req = reqp; struct inode *inode = ll_inode_from_lock(lock); struct ll_inode_info *lli; struct lov_stripe_md *lsm; struct ost_lvb *lvb; int rc, stripe; int size[2] = { sizeof(struct ptlrpc_body), sizeof(*lvb) }; ENTRY; if (inode == NULL) GOTO(out, rc = -ELDLM_NO_LOCK_DATA); lli = ll_i2info(inode); if (lli == NULL) GOTO(iput, rc = -ELDLM_NO_LOCK_DATA); lsm = lli->lli_smd; if (lsm == NULL) GOTO(iput, rc = -ELDLM_NO_LOCK_DATA); /* First, find out which stripe index this lock corresponds to. */ stripe = ll_lock_to_stripe_offset(inode, lock); if (stripe < 0) GOTO(iput, rc = -ELDLM_NO_LOCK_DATA); rc = lustre_pack_reply(req, 2, size, NULL); if (rc) GOTO(iput, rc); lvb = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*lvb)); lvb->lvb_size = lli->lli_smd->lsm_oinfo[stripe]->loi_kms; lvb->lvb_mtime = LTIME_S(inode->i_mtime); lvb->lvb_atime = LTIME_S(inode->i_atime); lvb->lvb_ctime = LTIME_S(inode->i_ctime); LDLM_DEBUG(lock, "i_size: %llu -> stripe number %u -> kms "LPU64 " atime "LPU64", mtime "LPU64", ctime "LPU64, i_size_read(inode), stripe, lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_atime, lvb->lvb_ctime); iput: iput(inode); out: /* These errors are normal races, so we don't want to fill the console * with messages by calling ptlrpc_error() */ if (rc == -ELDLM_NO_LOCK_DATA) lustre_pack_reply(req, 1, NULL, NULL); req->rq_status = rc; return rc;}int ll_glimpse_ioctl(struct ll_sb_info *sbi, struct lov_stripe_md *lsm, lstat_t *st){ struct lustre_handle lockh = { 0 }; struct ldlm_enqueue_info einfo = { 0 }; struct obd_info oinfo = { { { 0 } } }; struct ost_lvb lvb; int rc; ENTRY; einfo.ei_type = LDLM_EXTENT; einfo.ei_mode = LCK_PR; einfo.ei_cb_bl = osc_extent_blocking_cb; einfo.ei_cb_cp = ldlm_completion_ast; einfo.ei_cb_gl = ll_glimpse_callback; einfo.ei_cbdata = NULL; oinfo.oi_policy.l_extent.end = OBD_OBJECT_EOF; oinfo.oi_lockh = &lockh; oinfo.oi_md = lsm; oinfo.oi_flags = LDLM_FL_HAS_INTENT; rc = obd_enqueue_rqset(sbi->ll_osc_exp, &oinfo, &einfo); if (rc == -ENOENT) RETURN(rc); if (rc != 0) { CERROR("obd_enqueue returned rc %d, " "returning -EIO\n", rc); RETURN(rc > 0 ? -EIO : rc); } lov_stripe_lock(lsm); memset(&lvb, 0, sizeof(lvb)); obd_merge_lvb(sbi->ll_osc_exp, lsm, &lvb, 0); st->st_size = lvb.lvb_size; st->st_blocks = lvb.lvb_blocks; st->st_mtime = lvb.lvb_mtime; st->st_atime = lvb.lvb_atime; st->st_ctime = lvb.lvb_ctime; lov_stripe_unlock(lsm); RETURN(rc);}/* NB: obd_merge_lvb will prefer locally cached writes if they extend the * file (because it prefers KMS over RSS when larger) */int ll_glimpse_size(struct inode *inode, int ast_flags){ struct ll_inode_info *lli = ll_i2info(inode); struct ll_sb_info *sbi = ll_i2sbi(inode); struct lustre_handle lockh = { 0 }; struct ldlm_enqueue_info einfo = { 0 }; struct obd_info oinfo = { { { 0 } } }; struct ost_lvb lvb; int rc; ENTRY; CDEBUG(D_DLMTRACE, "Glimpsing inode %lu\n", inode->i_ino); if (!lli->lli_smd) { CDEBUG(D_DLMTRACE, "No objects for inode %lu\n", inode->i_ino); RETURN(0); } /* NOTE: this looks like DLM lock request, but it may not be one. Due * to LDLM_FL_HAS_INTENT flag, this is glimpse request, that * won't revoke any conflicting DLM locks held. Instead, * ll_glimpse_callback() will be called on each client * holding a DLM lock against this file, and resulting size * will be returned for each stripe. DLM lock on [0, EOF] is * acquired only if there were no conflicting locks. */ einfo.ei_type = LDLM_EXTENT; einfo.ei_mode = LCK_PR; einfo.ei_cb_bl = osc_extent_blocking_cb; einfo.ei_cb_cp = ldlm_completion_ast; einfo.ei_cb_gl = ll_glimpse_callback; einfo.ei_cbdata = inode; oinfo.oi_policy.l_extent.end = OBD_OBJECT_EOF; oinfo.oi_lockh = &lockh; oinfo.oi_md = lli->lli_smd; oinfo.oi_flags = ast_flags | LDLM_FL_HAS_INTENT; rc = obd_enqueue_rqset(sbi->ll_osc_exp, &oinfo, &einfo); if (rc == -ENOENT) RETURN(rc); if (rc != 0) { CERROR("obd_enqueue returned rc %d, returning -EIO\n", rc); RETURN(rc > 0 ? -EIO : rc); } ll_inode_size_lock(inode, 1); inode_init_lvb(inode, &lvb); rc = obd_merge_lvb(sbi->ll_osc_exp, lli->lli_smd, &lvb, 0); i_size_write(inode, lvb.lvb_size); inode->i_blocks = lvb.lvb_blocks; LTIME_S(inode->i_mtime) = lvb.lvb_mtime; LTIME_S(inode->i_atime) = lvb.lvb_atime; LTIME_S(inode->i_ctime) = lvb.lvb_ctime; ll_inode_size_unlock(inode, 1); CDEBUG(D_DLMTRACE, "glimpse: size: %llu, blocks: %llu\n", i_size_read(inode), (long long)inode->i_blocks); RETURN(rc);}int ll_extent_lock(struct ll_file_data *fd, struct inode *inode, struct lov_stripe_md *lsm, int mode, ldlm_policy_data_t *policy, struct lustre_handle *lockh, int ast_flags){ struct ll_sb_info *sbi = ll_i2sbi(inode); struct ost_lvb lvb; struct ldlm_enqueue_info einfo = { 0 }; struct obd_info oinfo = { { { 0 } } }; int rc; ENTRY; LASSERT(!lustre_handle_is_used(lockh)); LASSERT(lsm != NULL); /* don't drop the mmapped file to LRU */ if (mapping_mapped(inode->i_mapping)) ast_flags |= LDLM_FL_NO_LRU; /* XXX phil: can we do this? won't it screw the file size up? */ if ((fd && (fd->fd_flags & LL_FILE_IGNORE_LOCK)) || (sbi->ll_flags & LL_SBI_NOLCK)) RETURN(0); CDEBUG(D_DLMTRACE, "Locking inode %lu, start "LPU64" end "LPU64"\n", inode->i_ino, policy->l_extent.start, policy->l_extent.end); einfo.ei_type = LDLM_EXTENT; einfo.ei_mode = mode; einfo.ei_cb_bl = osc_extent_blocking_cb; einfo.ei_cb_cp = ldlm_completion_ast; einfo.ei_cb_gl = ll_glimpse_callback; einfo.ei_cbdata = inode; oinfo.oi_policy = *policy; oinfo.oi_lockh = lockh;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -