Cephfs kernel client書き込みプロセス


kernel  ceph        fs/ceph  ,     ceph      。
 fs/ceph/file.c   ceph_file_fops          ceph_write_iter
const struct file_operations ceph_file_fops = {
	.open = ceph_open,
	.release = ceph_release,
	.llseek = ceph_llseek,
	.read_iter = ceph_read_iter,
	.write_iter = ceph_write_iter,
	}

static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
	if ((got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO)) == 0 ||
	    (iocb->ki_flags & IOCB_DIRECT) || (fi->flags & CEPH_F_SYNC) ||
	    (ci->i_ceph_flags & CEPH_I_ERROR_WRITE)) {
		struct ceph_snap_context *snapc;
		struct iov_iter data;
		inode_unlock(inode);


		#       client      direct io  bufffer io    
		/* we might need to revert back to that point */
		data = *from;
		if (iocb->ki_flags & IOCB_DIRECT)
			written = ceph_direct_read_write(iocb, &data, snapc,
							 &prealloc_cf);
		else
			written = ceph_sync_write(iocb, &data, pos, snapc);
		if (written > 0)
			iov_iter_advance(from, written);
		ceph_put_snap_context(snapc);
	}
}
   direct io   
               request ,   ceph_osdc_new_request->ceph_osdc_start_request->ceph_osdc_wait_request
static ssize_t
ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
		       struct ceph_snap_context *snapc,
		       struct ceph_cap_flush **pcf)
{
	
	while (iov_iter_count(iter) > 0) {
		u64 size = dio_get_pagev_size(iter);
		size_t start = 0;
		ssize_t len;

		vino = ceph_vino(inode);
		#new request          req,         ,       req
		req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout,
					    vino, pos, &size, 0,
					    1,
					    write ? CEPH_OSD_OP_WRITE :
						    CEPH_OSD_OP_READ,
					    flags, snapc,
					    ci->i_truncate_seq,
					    ci->i_truncate_size,
					    false);
		#start request        submiet_quest        
		ret = ceph_osdc_start_request(req->r_osdc, req, false);
		if (!ret)
		#       req       
			ret = ceph_osdc_wait_request(&fsc->client->osdc, req);

		
}
         :
int ceph_osdc_wait_request(struct ceph_osd_client *osdc,
			   struct ceph_osd_request *req)
{
	return wait_request_timeout(req, 0);
}
      wait_for_completion_killable_timeout        ,        wait_for_completion_killable_timeout     
          cpu。         
static int wait_request_timeout(struct ceph_osd_request *req,
				unsigned long timeout)
{
	long left;

	dout("%s req %p tid %llu
", __func__, req, req->r_tid); left = wait_for_completion_killable_timeout(&req->r_completion, ceph_timeout_jiffies(timeout)); if (left <= 0) { left = left ?: -ETIMEDOUT; ceph_osdc_cancel_request(req); } else { left = req->r_result; /* completed */ } return left; } client ,direct io , kernel cache , , 。 client , client