2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2005 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 v.2.
10 #include <linux/sched.h>
11 #include <linux/slab.h>
12 #include <linux/spinlock.h>
13 #include <linux/completion.h>
14 #include <linux/buffer_head.h>
16 #include <linux/pagemap.h>
17 #include <linux/gfs2_ondisk.h>
18 #include <asm/semaphore.h>
21 #include "lm_interface.h"
33 static void pfault_be_greedy(struct gfs2_inode
*ip
)
37 spin_lock(&ip
->i_spin
);
39 ip
->i_last_pfault
= jiffies
;
40 spin_unlock(&ip
->i_spin
);
43 if (gfs2_glock_be_greedy(ip
->i_gl
, time
))
47 static struct page
*gfs2_private_nopage(struct vm_area_struct
*area
,
48 unsigned long address
, int *type
)
50 struct gfs2_inode
*ip
= area
->vm_file
->f_mapping
->host
->u
.generic_ip
;
51 struct gfs2_holder i_gh
;
55 error
= gfs2_glock_nq_init(ip
->i_gl
, LM_ST_SHARED
, 0, &i_gh
);
59 set_bit(GIF_PAGED
, &ip
->i_flags
);
61 result
= filemap_nopage(area
, address
, type
);
63 if (result
&& result
!= NOPAGE_OOM
)
66 gfs2_glock_dq_uninit(&i_gh
);
71 static int alloc_page_backing(struct gfs2_inode
*ip
, struct page
*page
)
73 struct gfs2_sbd
*sdp
= ip
->i_sbd
;
74 unsigned long index
= page
->index
;
75 uint64_t lblock
= index
<< (PAGE_CACHE_SHIFT
-
76 sdp
->sd_sb
.sb_bsize_shift
);
77 unsigned int blocks
= PAGE_CACHE_SIZE
>> sdp
->sd_sb
.sb_bsize_shift
;
78 struct gfs2_alloc
*al
;
79 unsigned int data_blocks
, ind_blocks
;
83 al
= gfs2_alloc_get(ip
);
85 error
= gfs2_quota_lock(ip
, NO_QUOTA_CHANGE
, NO_QUOTA_CHANGE
);
89 error
= gfs2_quota_check(ip
, ip
->i_di
.di_uid
, ip
->i_di
.di_gid
);
93 gfs2_write_calc_reserv(ip
, PAGE_CACHE_SIZE
,
94 &data_blocks
, &ind_blocks
);
96 al
->al_requested
= data_blocks
+ ind_blocks
;
98 error
= gfs2_inplace_reserve(ip
);
102 error
= gfs2_trans_begin(sdp
,
103 al
->al_rgd
->rd_ri
.ri_length
+
104 ind_blocks
+ RES_DINODE
+
105 RES_STATFS
+ RES_QUOTA
, 0);
109 if (gfs2_is_stuffed(ip
)) {
110 error
= gfs2_unstuff_dinode(ip
, gfs2_unstuffer_page
, NULL
);
115 for (x
= 0; x
< blocks
; ) {
120 error
= gfs2_block_map(ip
, lblock
, &new, &dblock
, &extlen
);
128 gfs2_assert_warn(sdp
, al
->al_alloced
);
134 gfs2_inplace_release(ip
);
137 gfs2_quota_unlock(ip
);
145 static struct page
*gfs2_sharewrite_nopage(struct vm_area_struct
*area
,
146 unsigned long address
, int *type
)
148 struct gfs2_inode
*ip
= area
->vm_file
->f_mapping
->host
->u
.generic_ip
;
149 struct gfs2_holder i_gh
;
150 struct page
*result
= NULL
;
151 unsigned long index
= ((address
- area
->vm_start
) >> PAGE_CACHE_SHIFT
) +
156 error
= gfs2_glock_nq_init(ip
->i_gl
, LM_ST_EXCLUSIVE
, 0, &i_gh
);
160 set_bit(GIF_PAGED
, &ip
->i_flags
);
161 set_bit(GIF_SW_PAGED
, &ip
->i_flags
);
163 error
= gfs2_write_alloc_required(ip
,
164 (uint64_t)index
<< PAGE_CACHE_SHIFT
,
165 PAGE_CACHE_SIZE
, &alloc_required
);
169 result
= filemap_nopage(area
, address
, type
);
170 if (!result
|| result
== NOPAGE_OOM
)
173 if (alloc_required
) {
174 error
= alloc_page_backing(ip
, result
);
176 page_cache_release(result
);
180 set_page_dirty(result
);
183 pfault_be_greedy(ip
);
186 gfs2_glock_dq_uninit(&i_gh
);
191 struct vm_operations_struct gfs2_vm_ops_private
= {
192 .nopage
= gfs2_private_nopage
,
195 struct vm_operations_struct gfs2_vm_ops_sharewrite
= {
196 .nopage
= gfs2_sharewrite_nopage
,