]>
Commit | Line | Data |
---|---|---|
ca6c34d8 | 1 | --- cluster-2.03.10.a/gfs-kernel/src/gfs/ops_address.c 2009-07-15 12:29:31.003964220 +0200 |
2 | +++ cluster-2.03.10.b/gfs-kernel/src/gfs/ops_address.c 2009-07-15 12:32:52.853942346 +0200 | |
3 | @@ -7,6 +7,7 @@ | |
4 | #include <linux/completion.h> | |
5 | #include <linux/buffer_head.h> | |
6 | #include <linux/pagemap.h> | |
7 | +#include <linux/version.h> | |
8 | ||
9 | #include "gfs.h" | |
10 | #include "bmap.h" | |
11 | @@ -19,8 +20,16 @@ | |
12 | #include "quota.h" | |
13 | #include "trans.h" | |
14 | ||
15 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) | |
16 | static int gfs_commit_write(struct file *file, struct page *page, | |
17 | unsigned from, unsigned to); | |
18 | +#else | |
19 | +static int | |
20 | +gfs_write_end(struct file *file, struct address_space *mapping, | |
21 | + loff_t pos, unsigned len, unsigned copied, | |
22 | + struct page *page, void *fsdata); | |
23 | +#endif | |
24 | + | |
25 | /** | |
26 | * get_block - Fills in a buffer head with details about a block | |
27 | * @inode: The inode | |
28 | @@ -283,6 +292,7 @@ | |
29 | return error; | |
30 | } | |
31 | ||
32 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) | |
33 | /** | |
34 | * gfs_prepare_write - Prepare to write a page to a file | |
35 | * @file: The file to write to | |
36 | @@ -333,7 +343,75 @@ | |
37 | ||
38 | return error; | |
39 | } | |
40 | +#else | |
41 | +/** | |
42 | + * gfs_write_begin - Begin to write to a file | |
43 | + * @file: The file to write to | |
44 | + * @mapping: The mapping in which to write | |
45 | + * @pos: The file offset at which to start writing | |
46 | + * @len: Length of the write | |
47 | + * @flags: Various flags | |
48 | + * @pagep: Pointer to return the page | |
49 | + * @fsdata: Pointer to return fs data (unused by GFS) | |
50 | + * | |
51 | + * Returns: errno | |
52 | + * | |
53 | + * Make sure file's inode is glocked; we shouldn't write without that! | |
54 | + * If GFS dinode is currently stuffed (small enough that all data fits within | |
55 | + * the dinode block), and new file size is too large, unstuff it. | |
56 | + * Use Linux VFS block_prepare_write() to write blocks, using GFS' get_block() | |
57 | + * to find which blocks to write. | |
58 | + */ | |
59 | + | |
60 | +static int | |
61 | +gfs_write_begin(struct file *file, struct address_space *mapping, | |
62 | + loff_t pos, unsigned len, unsigned flags, | |
63 | + struct page **pagep, void **fsdata) | |
64 | +{ | |
65 | + struct gfs_inode *ip = get_v2ip(mapping->host); | |
66 | + struct gfs_sbd *sdp = ip->i_sbd; | |
67 | + int error = 0; | |
68 | + pgoff_t index = pos >> PAGE_CACHE_SHIFT; | |
69 | + unsigned from = pos & (PAGE_CACHE_SIZE - 1); | |
70 | + unsigned to = from + len; | |
71 | + struct page *page; | |
72 | + | |
73 | + atomic_inc(&sdp->sd_ops_address); | |
74 | + /* We can't set write_end in the structure in the declare */ | |
75 | + /* because if we do, loopback (loop.c) will interpret that to mean */ | |
76 | + /* it's okay to do buffered writes without locking through sendfile. */ | |
77 | + /* This is a kludge to get around the problem with loop.c because */ | |
78 | + /* the upstream community rejected my changes to loop.c. */ | |
79 | + ip->gfs_file_aops.write_end = gfs_write_end; | |
80 | + | |
81 | + if (gfs_assert_warn(sdp, gfs_glock_is_locked_by_me(ip->i_gl))) | |
82 | + return -ENOSYS; | |
83 | + | |
84 | + error = -ENOMEM; | |
85 | + page = grab_cache_page_write_begin(mapping, index, flags); | |
86 | + *pagep = page; | |
87 | + if (!page) | |
88 | + goto out; | |
89 | + | |
90 | + if (gfs_is_stuffed(ip)) { | |
91 | + if (pos + len > sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)) { | |
92 | + error = gfs_unstuff_dinode(ip, gfs_unstuffer_page, page); | |
93 | + if (!error) | |
94 | + error = block_prepare_write(page, from, to, get_block); | |
95 | + } else if (!PageUptodate(page)) | |
96 | + error = stuffed_readpage(ip, page); | |
97 | + } else | |
98 | + error = block_prepare_write(page, from, to, get_block); | |
99 | + | |
100 | + if (error) | |
101 | + page_cache_release(page); | |
102 | + | |
103 | +out: | |
104 | + return error; | |
105 | +} | |
106 | +#endif | |
107 | ||
108 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) | |
109 | /** | |
110 | * gfs_commit_write - Commit write to a file | |
111 | * @file: The file to write to | |
112 | @@ -397,6 +475,77 @@ | |
113 | ||
114 | return error; | |
115 | } | |
116 | +#else | |
117 | +/** | |
118 | + * gfs_write_end | |
119 | + * @file: The file to write to | |
120 | + * @mapping: The address space to write to | |
121 | + * @pos: The file position | |
122 | + * @len: The length of the data | |
123 | + * @copied: | |
124 | + * @page: The page that has been written | |
125 | + * @fsdata: The fsdata (unused in GFS) | |
126 | + * | |
127 | + * The main write_end function for GFS. We have a separate one for | |
128 | + * stuffed files as they are slightly different, otherwise we just | |
129 | + * put our locking around the VFS provided functions | |
130 | + * | |
131 | + * Returns: errno | |
132 | + */ | |
133 | + | |
134 | +static int | |
135 | +gfs_write_end(struct file *file, struct address_space *mapping, | |
136 | + loff_t pos, unsigned len, unsigned copied, | |
137 | + struct page *page, void *fsdata) | |
138 | +{ | |
139 | + struct inode *inode = page->mapping->host; | |
140 | + struct gfs_inode *ip = get_v2ip(inode); | |
141 | + struct gfs_sbd *sdp = ip->i_sbd; | |
142 | + int ret; | |
143 | + | |
144 | + atomic_inc(&sdp->sd_ops_address); | |
145 | + BUG_ON(gfs_glock_is_locked_by_me(ip->i_gl) == 0); | |
146 | + | |
147 | + if (gfs_is_stuffed(ip)) { | |
148 | + struct buffer_head *dibh; | |
149 | + u64 to = pos + copied; | |
150 | + void *kaddr; | |
151 | + unsigned char *buf; | |
152 | + | |
153 | + ret = gfs_get_inode_buffer(ip, &dibh); | |
154 | + if (ret) | |
155 | + goto fail; | |
156 | + buf = dibh->b_data + sizeof(struct gfs_dinode); | |
157 | + BUG_ON((pos + len) > (dibh->b_size - sizeof(struct gfs_dinode))); | |
158 | + | |
159 | + kaddr = kmap(page); | |
160 | + memcpy(buf + pos, kaddr + pos, copied); | |
161 | + memset(kaddr + pos + copied, 0, len - copied); | |
162 | + flush_dcache_page(page); | |
163 | + kunmap(page); | |
164 | + | |
165 | + brelse(dibh); | |
166 | + if (!PageUptodate(page)) | |
167 | + SetPageUptodate(page); | |
168 | + unlock_page(page); | |
169 | + page_cache_release(page); | |
170 | + | |
171 | + if (inode->i_size < to) | |
172 | + i_size_write(inode, to); | |
173 | + } else { | |
174 | + ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata); | |
175 | + } | |
176 | + | |
177 | + ip->gfs_file_aops.write_end = NULL; | |
178 | + return ret; | |
179 | + | |
180 | +fail: | |
181 | + ClearPageUptodate(page); | |
182 | + unlock_page(page); | |
183 | + page_cache_release(page); | |
184 | + return ret; | |
185 | +} | |
186 | +#endif | |
187 | ||
188 | /** | |
189 | * gfs_bmap - Block map function | |
190 | @@ -473,7 +622,11 @@ | |
191 | .writepage = gfs_writepage, | |
192 | .readpage = gfs_readpage, | |
193 | .sync_page = block_sync_page, | |
194 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) | |
195 | .prepare_write = gfs_prepare_write, | |
196 | +#else | |
197 | + .write_begin = gfs_write_begin, | |
198 | +#endif | |
199 | .bmap = gfs_bmap, | |
200 | .direct_IO = gfs_direct_IO, | |
201 | }; | |
202 | --- cluster-2.03.10.a/gfs-kernel/src/gfs/ops_export.c 2008-12-09 09:36:04.000000000 +0100 | |
203 | +++ cluster-2.03.10.b/gfs-kernel/src/gfs/ops_export.c 2009-07-15 12:57:19.207191847 +0200 | |
204 | @@ -6,6 +6,7 @@ | |
205 | #include <linux/completion.h> | |
206 | #include <linux/buffer_head.h> | |
207 | #include <linux/exportfs.h> | |
208 | +#include <linux/version.h> | |
209 | ||
210 | #include "gfs.h" | |
211 | #include "dio.h" | |
212 | @@ -208,6 +209,7 @@ | |
213 | if (!inode) | |
214 | return ERR_PTR(-ENOMEM); | |
215 | ||
216 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) | |
217 | dentry = d_alloc_anon(inode); | |
218 | if (!dentry) { | |
219 | iput(inode); | |
220 | @@ -215,6 +217,11 @@ | |
221 | } | |
222 | ||
223 | dentry->d_op = &gfs_dops; | |
224 | +#else | |
225 | + dentry = d_obtain_alias(inode); | |
226 | + if (!IS_ERR(dentry)) | |
227 | + dentry->d_op = &gfs_dops; | |
228 | +#endif | |
229 | return dentry; | |
230 | ||
231 | fail: | |
232 | @@ -326,6 +333,7 @@ | |
233 | return ERR_PTR(-ESTALE); | |
234 | } | |
235 | ||
236 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) | |
237 | dentry = d_alloc_anon(inode); | |
238 | if (!dentry) { | |
239 | iput(inode); | |
240 | @@ -333,6 +341,11 @@ | |
241 | } | |
242 | ||
243 | dentry->d_op = &gfs_dops; | |
244 | +#else | |
245 | + dentry = d_obtain_alias(inode); | |
246 | + if (!IS_ERR(dentry)) | |
247 | + dentry->d_op = &gfs_dops; | |
248 | +#endif | |
249 | return dentry; | |
250 | ||
251 | fail_relse: |