- struct lu_env *env;
- struct cl_env_nest nest;
- struct cl_io *io;
- struct page *page = NOPAGE_SIGBUS;
- struct vvp_io *vio = NULL;
- unsigned long ra_flags;
- pgoff_t pg_offset;
- int result;
- const unsigned long writable = VM_SHARED|VM_WRITE;
- ENTRY;
-
- pg_offset = ((address - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
- io = ll_fault_io_init(vma, &env, &nest, pg_offset, &ra_flags);
- if (IS_ERR(io))
- return NOPAGE_SIGBUS;
-
- result = io->ci_result;
- if (result < 0)
- goto out_err;
-
- io->u.ci_fault.ft_writable = (vma->vm_flags&writable) == writable;
-
- vio = vvp_env_io(env);
- vio->u.fault.ft_vma = vma;
- vio->u.fault.nopage.ft_address = address;
- vio->u.fault.nopage.ft_type = type;
- vio->u.fault.ft_vmpage = NULL;
-
- result = cl_io_loop(env, io);
- page = vio->u.fault.ft_vmpage;
- if (result != 0 && page != NULL)
- page_cache_release(page);
-
-out_err:
- if (result == -ENOMEM)
- page = NOPAGE_OOM;
-
- vma->vm_flags &= ~VM_RAND_READ;
- vma->vm_flags |= ra_flags;
-
- cl_io_fini(env, io);
- cl_env_nested_put(&nest, env);
-
- RETURN(page);
-}
-
-static int ll_page_mkwrite(struct vm_area_struct *vma, struct page *vmpage)
-{
- int count = 0;
- bool printed = false;
- bool retry;
- int result;
-
- do {
- retry = false;
- result = ll_page_mkwrite0(vma, vmpage, &retry);
-
- if (!printed && ++count > 16) {
- CWARN("app(%s): the page %lu of file %lu is under heavy"
- " contention.\n",
- current->comm, page_index(vmpage),
- vma->vm_file->f_dentry->d_inode->i_ino);
- printed = true;
- }
- } while (retry);
-
- if (result == 0)
- unlock_page(vmpage);
- else if (result == -ENODATA)
- result = 0; /* kernel will know truncate has happened and
- * retry */
-
- return result;