2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions
7 * of the GNU General Public License version 2.
10 #include <linux/slab.h>
11 #include <linux/spinlock.h>
12 #include <linux/completion.h>
13 #include <linux/buffer_head.h>
15 #include <linux/pagemap.h>
16 #include <linux/gfs2_ondisk.h>
17 #include <linux/lm_interface.h>
30 static int gfs2_private_fault(struct vm_area_struct
*vma
, struct vm_fault
*vmf
)
32 struct gfs2_inode
*ip
= GFS2_I(vma
->vm_file
->f_mapping
->host
);
34 set_bit(GIF_PAGED
, &ip
->i_flags
);
35 return filemap_fault(vma
, vmf
);
38 static int alloc_page_backing(struct gfs2_inode
*ip
, struct page
*page
)
40 struct gfs2_sbd
*sdp
= GFS2_SB(&ip
->i_inode
);
41 unsigned long index
= page
->index
;
42 u64 lblock
= index
<< (PAGE_CACHE_SHIFT
-
43 sdp
->sd_sb
.sb_bsize_shift
);
44 unsigned int blocks
= PAGE_CACHE_SIZE
>> sdp
->sd_sb
.sb_bsize_shift
;
45 struct gfs2_alloc
*al
;
46 unsigned int data_blocks
, ind_blocks
;
50 al
= gfs2_alloc_get(ip
);
52 error
= gfs2_quota_lock(ip
, NO_QUOTA_CHANGE
, NO_QUOTA_CHANGE
);
56 error
= gfs2_quota_check(ip
, ip
->i_inode
.i_uid
, ip
->i_inode
.i_gid
);
60 gfs2_write_calc_reserv(ip
, PAGE_CACHE_SIZE
, &data_blocks
, &ind_blocks
);
62 al
->al_requested
= data_blocks
+ ind_blocks
;
64 error
= gfs2_inplace_reserve(ip
);
68 error
= gfs2_trans_begin(sdp
, al
->al_rgd
->rd_length
+
69 ind_blocks
+ RES_DINODE
+
70 RES_STATFS
+ RES_QUOTA
, 0);
74 if (gfs2_is_stuffed(ip
)) {
75 error
= gfs2_unstuff_dinode(ip
, NULL
);
80 for (x
= 0; x
< blocks
; ) {
85 error
= gfs2_extent_map(&ip
->i_inode
, lblock
, &new, &dblock
, &extlen
);
93 gfs2_assert_warn(sdp
, al
->al_alloced
);
98 gfs2_inplace_release(ip
);
100 gfs2_quota_unlock(ip
);
106 static int gfs2_sharewrite_fault(struct vm_area_struct
*vma
,
107 struct vm_fault
*vmf
)
109 struct file
*file
= vma
->vm_file
;
110 struct gfs2_file
*gf
= file
->private_data
;
111 struct gfs2_inode
*ip
= GFS2_I(file
->f_mapping
->host
);
112 struct gfs2_holder i_gh
;
117 error
= gfs2_glock_nq_init(ip
->i_gl
, LM_ST_EXCLUSIVE
, 0, &i_gh
);
121 set_bit(GIF_PAGED
, &ip
->i_flags
);
122 set_bit(GIF_SW_PAGED
, &ip
->i_flags
);
124 error
= gfs2_write_alloc_required(ip
,
125 (u64
)vmf
->pgoff
<< PAGE_CACHE_SHIFT
,
126 PAGE_CACHE_SIZE
, &alloc_required
);
128 ret
= VM_FAULT_OOM
; /* XXX: are these right? */
132 set_bit(GFF_EXLOCK
, &gf
->f_flags
);
133 ret
= filemap_fault(vma
, vmf
);
134 clear_bit(GFF_EXLOCK
, &gf
->f_flags
);
135 if (ret
& VM_FAULT_ERROR
)
138 if (alloc_required
) {
139 /* XXX: do we need to drop page lock around alloc_page_backing?*/
140 error
= alloc_page_backing(ip
, vmf
->page
);
143 * VM_FAULT_LOCKED should always be the case for
144 * filemap_fault, but it may not be in a future
147 if (ret
& VM_FAULT_LOCKED
)
148 unlock_page(vmf
->page
);
149 page_cache_release(vmf
->page
);
153 set_page_dirty(vmf
->page
);
157 gfs2_glock_dq_uninit(&i_gh
);
162 struct vm_operations_struct gfs2_vm_ops_private
= {
163 .fault
= gfs2_private_fault
,
166 struct vm_operations_struct gfs2_vm_ops_sharewrite
= {
167 .fault
= gfs2_sharewrite_fault
,