|
@@ -1160,23 +1160,22 @@ sg_fasync(int fd, struct file *filp, int mode)
|
|
|
return (retval < 0) ? retval : 0;
|
|
|
}
|
|
|
|
|
|
-static struct page *
|
|
|
-sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
|
|
|
+static int
|
|
|
+sg_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|
|
{
|
|
|
Sg_fd *sfp;
|
|
|
- struct page *page = NOPAGE_SIGBUS;
|
|
|
unsigned long offset, len, sa;
|
|
|
Sg_scatter_hold *rsv_schp;
|
|
|
struct scatterlist *sg;
|
|
|
int k;
|
|
|
|
|
|
if ((NULL == vma) || (!(sfp = (Sg_fd *) vma->vm_private_data)))
|
|
|
- return page;
|
|
|
+ return VM_FAULT_SIGBUS;
|
|
|
rsv_schp = &sfp->reserve;
|
|
|
- offset = addr - vma->vm_start;
|
|
|
+ offset = vmf->pgoff << PAGE_SHIFT;
|
|
|
if (offset >= rsv_schp->bufflen)
|
|
|
- return page;
|
|
|
- SCSI_LOG_TIMEOUT(3, printk("sg_vma_nopage: offset=%lu, scatg=%d\n",
|
|
|
+ return VM_FAULT_SIGBUS;
|
|
|
+ SCSI_LOG_TIMEOUT(3, printk("sg_vma_fault: offset=%lu, scatg=%d\n",
|
|
|
offset, rsv_schp->k_use_sg));
|
|
|
sg = rsv_schp->buffer;
|
|
|
sa = vma->vm_start;
|
|
@@ -1185,21 +1184,21 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
|
|
|
len = vma->vm_end - sa;
|
|
|
len = (len < sg->length) ? len : sg->length;
|
|
|
if (offset < len) {
|
|
|
+ struct page *page;
|
|
|
page = virt_to_page(page_address(sg_page(sg)) + offset);
|
|
|
get_page(page); /* increment page count */
|
|
|
- break;
|
|
|
+ vmf->page = page;
|
|
|
+ return 0; /* success */
|
|
|
}
|
|
|
sa += len;
|
|
|
offset -= len;
|
|
|
}
|
|
|
|
|
|
- if (type)
|
|
|
- *type = VM_FAULT_MINOR;
|
|
|
- return page;
|
|
|
+ return VM_FAULT_SIGBUS;
|
|
|
}
|
|
|
|
|
|
static struct vm_operations_struct sg_mmap_vm_ops = {
|
|
|
- .nopage = sg_vma_nopage,
|
|
|
+ .fault = sg_vma_fault,
|
|
|
};
|
|
|
|
|
|
static int
|