1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
4*4882a593Smuzhiyun * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include <linux/spinlock.h>
8*4882a593Smuzhiyun #include <linux/completion.h>
9*4882a593Smuzhiyun #include <linux/buffer_head.h>
10*4882a593Smuzhiyun #include <linux/blkdev.h>
11*4882a593Smuzhiyun #include <linux/gfs2_ondisk.h>
12*4882a593Smuzhiyun #include <linux/crc32.h>
13*4882a593Smuzhiyun #include <linux/iomap.h>
14*4882a593Smuzhiyun #include <linux/ktime.h>
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #include "gfs2.h"
17*4882a593Smuzhiyun #include "incore.h"
18*4882a593Smuzhiyun #include "bmap.h"
19*4882a593Smuzhiyun #include "glock.h"
20*4882a593Smuzhiyun #include "inode.h"
21*4882a593Smuzhiyun #include "meta_io.h"
22*4882a593Smuzhiyun #include "quota.h"
23*4882a593Smuzhiyun #include "rgrp.h"
24*4882a593Smuzhiyun #include "log.h"
25*4882a593Smuzhiyun #include "super.h"
26*4882a593Smuzhiyun #include "trans.h"
27*4882a593Smuzhiyun #include "dir.h"
28*4882a593Smuzhiyun #include "util.h"
29*4882a593Smuzhiyun #include "aops.h"
30*4882a593Smuzhiyun #include "trace_gfs2.h"
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun /* This doesn't need to be that large as max 64 bit pointers in a 4k
33*4882a593Smuzhiyun * block is 512, so __u16 is fine for that. It saves stack space to
34*4882a593Smuzhiyun * keep it small.
35*4882a593Smuzhiyun */
36*4882a593Smuzhiyun struct metapath {
37*4882a593Smuzhiyun struct buffer_head *mp_bh[GFS2_MAX_META_HEIGHT];
38*4882a593Smuzhiyun __u16 mp_list[GFS2_MAX_META_HEIGHT];
39*4882a593Smuzhiyun int mp_fheight; /* find_metapath height */
40*4882a593Smuzhiyun int mp_aheight; /* actual height (lookup height) */
41*4882a593Smuzhiyun };
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length);
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun /**
46*4882a593Smuzhiyun * gfs2_unstuffer_page - unstuff a stuffed inode into a block cached by a page
47*4882a593Smuzhiyun * @ip: the inode
48*4882a593Smuzhiyun * @dibh: the dinode buffer
49*4882a593Smuzhiyun * @block: the block number that was allocated
50*4882a593Smuzhiyun * @page: The (optional) page. This is looked up if @page is NULL
51*4882a593Smuzhiyun *
52*4882a593Smuzhiyun * Returns: errno
53*4882a593Smuzhiyun */
54*4882a593Smuzhiyun
gfs2_unstuffer_page(struct gfs2_inode * ip,struct buffer_head * dibh,u64 block,struct page * page)55*4882a593Smuzhiyun static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
56*4882a593Smuzhiyun u64 block, struct page *page)
57*4882a593Smuzhiyun {
58*4882a593Smuzhiyun struct inode *inode = &ip->i_inode;
59*4882a593Smuzhiyun int release = 0;
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun if (!page || page->index) {
62*4882a593Smuzhiyun page = find_or_create_page(inode->i_mapping, 0, GFP_NOFS);
63*4882a593Smuzhiyun if (!page)
64*4882a593Smuzhiyun return -ENOMEM;
65*4882a593Smuzhiyun release = 1;
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun if (!PageUptodate(page)) {
69*4882a593Smuzhiyun void *kaddr = kmap(page);
70*4882a593Smuzhiyun u64 dsize = i_size_read(inode);
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun if (dsize > gfs2_max_stuffed_size(ip))
73*4882a593Smuzhiyun dsize = gfs2_max_stuffed_size(ip);
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
76*4882a593Smuzhiyun memset(kaddr + dsize, 0, PAGE_SIZE - dsize);
77*4882a593Smuzhiyun kunmap(page);
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun SetPageUptodate(page);
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun if (gfs2_is_jdata(ip)) {
83*4882a593Smuzhiyun struct buffer_head *bh;
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun if (!page_has_buffers(page))
86*4882a593Smuzhiyun create_empty_buffers(page, BIT(inode->i_blkbits),
87*4882a593Smuzhiyun BIT(BH_Uptodate));
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun bh = page_buffers(page);
90*4882a593Smuzhiyun if (!buffer_mapped(bh))
91*4882a593Smuzhiyun map_bh(bh, inode->i_sb, block);
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun set_buffer_uptodate(bh);
94*4882a593Smuzhiyun gfs2_trans_add_data(ip->i_gl, bh);
95*4882a593Smuzhiyun } else {
96*4882a593Smuzhiyun set_page_dirty(page);
97*4882a593Smuzhiyun gfs2_ordered_add_inode(ip);
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun if (release) {
101*4882a593Smuzhiyun unlock_page(page);
102*4882a593Smuzhiyun put_page(page);
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun return 0;
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun /**
109*4882a593Smuzhiyun * gfs2_unstuff_dinode - Unstuff a dinode when the data has grown too big
110*4882a593Smuzhiyun * @ip: The GFS2 inode to unstuff
111*4882a593Smuzhiyun * @page: The (optional) page. This is looked up if the @page is NULL
112*4882a593Smuzhiyun *
113*4882a593Smuzhiyun * This routine unstuffs a dinode and returns it to a "normal" state such
114*4882a593Smuzhiyun * that the height can be grown in the traditional way.
115*4882a593Smuzhiyun *
116*4882a593Smuzhiyun * Returns: errno
117*4882a593Smuzhiyun */
118*4882a593Smuzhiyun
gfs2_unstuff_dinode(struct gfs2_inode * ip,struct page * page)119*4882a593Smuzhiyun int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun struct buffer_head *bh, *dibh;
122*4882a593Smuzhiyun struct gfs2_dinode *di;
123*4882a593Smuzhiyun u64 block = 0;
124*4882a593Smuzhiyun int isdir = gfs2_is_dir(ip);
125*4882a593Smuzhiyun int error;
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun down_write(&ip->i_rw_mutex);
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun error = gfs2_meta_inode_buffer(ip, &dibh);
130*4882a593Smuzhiyun if (error)
131*4882a593Smuzhiyun goto out;
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun if (i_size_read(&ip->i_inode)) {
134*4882a593Smuzhiyun /* Get a free block, fill it with the stuffed data,
135*4882a593Smuzhiyun and write it out to disk */
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun unsigned int n = 1;
138*4882a593Smuzhiyun error = gfs2_alloc_blocks(ip, &block, &n, 0, NULL);
139*4882a593Smuzhiyun if (error)
140*4882a593Smuzhiyun goto out_brelse;
141*4882a593Smuzhiyun if (isdir) {
142*4882a593Smuzhiyun gfs2_trans_remove_revoke(GFS2_SB(&ip->i_inode), block, 1);
143*4882a593Smuzhiyun error = gfs2_dir_get_new_buffer(ip, block, &bh);
144*4882a593Smuzhiyun if (error)
145*4882a593Smuzhiyun goto out_brelse;
146*4882a593Smuzhiyun gfs2_buffer_copy_tail(bh, sizeof(struct gfs2_meta_header),
147*4882a593Smuzhiyun dibh, sizeof(struct gfs2_dinode));
148*4882a593Smuzhiyun brelse(bh);
149*4882a593Smuzhiyun } else {
150*4882a593Smuzhiyun error = gfs2_unstuffer_page(ip, dibh, block, page);
151*4882a593Smuzhiyun if (error)
152*4882a593Smuzhiyun goto out_brelse;
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun /* Set up the pointer to the new block */
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun gfs2_trans_add_meta(ip->i_gl, dibh);
159*4882a593Smuzhiyun di = (struct gfs2_dinode *)dibh->b_data;
160*4882a593Smuzhiyun gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun if (i_size_read(&ip->i_inode)) {
163*4882a593Smuzhiyun *(__be64 *)(di + 1) = cpu_to_be64(block);
164*4882a593Smuzhiyun gfs2_add_inode_blocks(&ip->i_inode, 1);
165*4882a593Smuzhiyun di->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode));
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun ip->i_height = 1;
169*4882a593Smuzhiyun di->di_height = cpu_to_be16(1);
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun out_brelse:
172*4882a593Smuzhiyun brelse(dibh);
173*4882a593Smuzhiyun out:
174*4882a593Smuzhiyun up_write(&ip->i_rw_mutex);
175*4882a593Smuzhiyun return error;
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun /**
180*4882a593Smuzhiyun * find_metapath - Find path through the metadata tree
181*4882a593Smuzhiyun * @sdp: The superblock
182*4882a593Smuzhiyun * @block: The disk block to look up
183*4882a593Smuzhiyun * @mp: The metapath to return the result in
184*4882a593Smuzhiyun * @height: The pre-calculated height of the metadata tree
185*4882a593Smuzhiyun *
186*4882a593Smuzhiyun * This routine returns a struct metapath structure that defines a path
187*4882a593Smuzhiyun * through the metadata of inode "ip" to get to block "block".
188*4882a593Smuzhiyun *
189*4882a593Smuzhiyun * Example:
190*4882a593Smuzhiyun * Given: "ip" is a height 3 file, "offset" is 101342453, and this is a
191*4882a593Smuzhiyun * filesystem with a blocksize of 4096.
192*4882a593Smuzhiyun *
193*4882a593Smuzhiyun * find_metapath() would return a struct metapath structure set to:
194*4882a593Smuzhiyun * mp_fheight = 3, mp_list[0] = 0, mp_list[1] = 48, and mp_list[2] = 165.
195*4882a593Smuzhiyun *
196*4882a593Smuzhiyun * That means that in order to get to the block containing the byte at
197*4882a593Smuzhiyun * offset 101342453, we would load the indirect block pointed to by pointer
198*4882a593Smuzhiyun * 0 in the dinode. We would then load the indirect block pointed to by
199*4882a593Smuzhiyun * pointer 48 in that indirect block. We would then load the data block
200*4882a593Smuzhiyun * pointed to by pointer 165 in that indirect block.
201*4882a593Smuzhiyun *
202*4882a593Smuzhiyun * ----------------------------------------
203*4882a593Smuzhiyun * | Dinode | |
204*4882a593Smuzhiyun * | | 4|
205*4882a593Smuzhiyun * | |0 1 2 3 4 5 9|
206*4882a593Smuzhiyun * | | 6|
207*4882a593Smuzhiyun * ----------------------------------------
208*4882a593Smuzhiyun * |
209*4882a593Smuzhiyun * |
210*4882a593Smuzhiyun * V
211*4882a593Smuzhiyun * ----------------------------------------
212*4882a593Smuzhiyun * | Indirect Block |
213*4882a593Smuzhiyun * | 5|
214*4882a593Smuzhiyun * | 4 4 4 4 4 5 5 1|
215*4882a593Smuzhiyun * |0 5 6 7 8 9 0 1 2|
216*4882a593Smuzhiyun * ----------------------------------------
217*4882a593Smuzhiyun * |
218*4882a593Smuzhiyun * |
219*4882a593Smuzhiyun * V
220*4882a593Smuzhiyun * ----------------------------------------
221*4882a593Smuzhiyun * | Indirect Block |
222*4882a593Smuzhiyun * | 1 1 1 1 1 5|
223*4882a593Smuzhiyun * | 6 6 6 6 6 1|
224*4882a593Smuzhiyun * |0 3 4 5 6 7 2|
225*4882a593Smuzhiyun * ----------------------------------------
226*4882a593Smuzhiyun * |
227*4882a593Smuzhiyun * |
228*4882a593Smuzhiyun * V
229*4882a593Smuzhiyun * ----------------------------------------
230*4882a593Smuzhiyun * | Data block containing offset |
231*4882a593Smuzhiyun * | 101342453 |
232*4882a593Smuzhiyun * | |
233*4882a593Smuzhiyun * | |
234*4882a593Smuzhiyun * ----------------------------------------
235*4882a593Smuzhiyun *
236*4882a593Smuzhiyun */
237*4882a593Smuzhiyun
find_metapath(const struct gfs2_sbd * sdp,u64 block,struct metapath * mp,unsigned int height)238*4882a593Smuzhiyun static void find_metapath(const struct gfs2_sbd *sdp, u64 block,
239*4882a593Smuzhiyun struct metapath *mp, unsigned int height)
240*4882a593Smuzhiyun {
241*4882a593Smuzhiyun unsigned int i;
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun mp->mp_fheight = height;
244*4882a593Smuzhiyun for (i = height; i--;)
245*4882a593Smuzhiyun mp->mp_list[i] = do_div(block, sdp->sd_inptrs);
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun
metapath_branch_start(const struct metapath * mp)248*4882a593Smuzhiyun static inline unsigned int metapath_branch_start(const struct metapath *mp)
249*4882a593Smuzhiyun {
250*4882a593Smuzhiyun if (mp->mp_list[0] == 0)
251*4882a593Smuzhiyun return 2;
252*4882a593Smuzhiyun return 1;
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun /**
256*4882a593Smuzhiyun * metaptr1 - Return the first possible metadata pointer in a metapath buffer
257*4882a593Smuzhiyun * @height: The metadata height (0 = dinode)
258*4882a593Smuzhiyun * @mp: The metapath
259*4882a593Smuzhiyun */
metaptr1(unsigned int height,const struct metapath * mp)260*4882a593Smuzhiyun static inline __be64 *metaptr1(unsigned int height, const struct metapath *mp)
261*4882a593Smuzhiyun {
262*4882a593Smuzhiyun struct buffer_head *bh = mp->mp_bh[height];
263*4882a593Smuzhiyun if (height == 0)
264*4882a593Smuzhiyun return ((__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)));
265*4882a593Smuzhiyun return ((__be64 *)(bh->b_data + sizeof(struct gfs2_meta_header)));
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun /**
269*4882a593Smuzhiyun * metapointer - Return pointer to start of metadata in a buffer
270*4882a593Smuzhiyun * @height: The metadata height (0 = dinode)
271*4882a593Smuzhiyun * @mp: The metapath
272*4882a593Smuzhiyun *
273*4882a593Smuzhiyun * Return a pointer to the block number of the next height of the metadata
274*4882a593Smuzhiyun * tree given a buffer containing the pointer to the current height of the
275*4882a593Smuzhiyun * metadata tree.
276*4882a593Smuzhiyun */
277*4882a593Smuzhiyun
metapointer(unsigned int height,const struct metapath * mp)278*4882a593Smuzhiyun static inline __be64 *metapointer(unsigned int height, const struct metapath *mp)
279*4882a593Smuzhiyun {
280*4882a593Smuzhiyun __be64 *p = metaptr1(height, mp);
281*4882a593Smuzhiyun return p + mp->mp_list[height];
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun
metaend(unsigned int height,const struct metapath * mp)284*4882a593Smuzhiyun static inline const __be64 *metaend(unsigned int height, const struct metapath *mp)
285*4882a593Smuzhiyun {
286*4882a593Smuzhiyun const struct buffer_head *bh = mp->mp_bh[height];
287*4882a593Smuzhiyun return (const __be64 *)(bh->b_data + bh->b_size);
288*4882a593Smuzhiyun }
289*4882a593Smuzhiyun
clone_metapath(struct metapath * clone,struct metapath * mp)290*4882a593Smuzhiyun static void clone_metapath(struct metapath *clone, struct metapath *mp)
291*4882a593Smuzhiyun {
292*4882a593Smuzhiyun unsigned int hgt;
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun *clone = *mp;
295*4882a593Smuzhiyun for (hgt = 0; hgt < mp->mp_aheight; hgt++)
296*4882a593Smuzhiyun get_bh(clone->mp_bh[hgt]);
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun
gfs2_metapath_ra(struct gfs2_glock * gl,__be64 * start,__be64 * end)299*4882a593Smuzhiyun static void gfs2_metapath_ra(struct gfs2_glock *gl, __be64 *start, __be64 *end)
300*4882a593Smuzhiyun {
301*4882a593Smuzhiyun const __be64 *t;
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun for (t = start; t < end; t++) {
304*4882a593Smuzhiyun struct buffer_head *rabh;
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun if (!*t)
307*4882a593Smuzhiyun continue;
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun rabh = gfs2_getbuf(gl, be64_to_cpu(*t), CREATE);
310*4882a593Smuzhiyun if (trylock_buffer(rabh)) {
311*4882a593Smuzhiyun if (!buffer_uptodate(rabh)) {
312*4882a593Smuzhiyun rabh->b_end_io = end_buffer_read_sync;
313*4882a593Smuzhiyun submit_bh(REQ_OP_READ,
314*4882a593Smuzhiyun REQ_RAHEAD | REQ_META | REQ_PRIO,
315*4882a593Smuzhiyun rabh);
316*4882a593Smuzhiyun continue;
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun unlock_buffer(rabh);
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun brelse(rabh);
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun
__fillup_metapath(struct gfs2_inode * ip,struct metapath * mp,unsigned int x,unsigned int h)324*4882a593Smuzhiyun static int __fillup_metapath(struct gfs2_inode *ip, struct metapath *mp,
325*4882a593Smuzhiyun unsigned int x, unsigned int h)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun for (; x < h; x++) {
328*4882a593Smuzhiyun __be64 *ptr = metapointer(x, mp);
329*4882a593Smuzhiyun u64 dblock = be64_to_cpu(*ptr);
330*4882a593Smuzhiyun int ret;
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun if (!dblock)
333*4882a593Smuzhiyun break;
334*4882a593Smuzhiyun ret = gfs2_meta_indirect_buffer(ip, x + 1, dblock, &mp->mp_bh[x + 1]);
335*4882a593Smuzhiyun if (ret)
336*4882a593Smuzhiyun return ret;
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun mp->mp_aheight = x + 1;
339*4882a593Smuzhiyun return 0;
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun /**
343*4882a593Smuzhiyun * lookup_metapath - Walk the metadata tree to a specific point
344*4882a593Smuzhiyun * @ip: The inode
345*4882a593Smuzhiyun * @mp: The metapath
346*4882a593Smuzhiyun *
347*4882a593Smuzhiyun * Assumes that the inode's buffer has already been looked up and
348*4882a593Smuzhiyun * hooked onto mp->mp_bh[0] and that the metapath has been initialised
349*4882a593Smuzhiyun * by find_metapath().
350*4882a593Smuzhiyun *
351*4882a593Smuzhiyun * If this function encounters part of the tree which has not been
352*4882a593Smuzhiyun * allocated, it returns the current height of the tree at the point
353*4882a593Smuzhiyun * at which it found the unallocated block. Blocks which are found are
354*4882a593Smuzhiyun * added to the mp->mp_bh[] list.
355*4882a593Smuzhiyun *
356*4882a593Smuzhiyun * Returns: error
357*4882a593Smuzhiyun */
358*4882a593Smuzhiyun
lookup_metapath(struct gfs2_inode * ip,struct metapath * mp)359*4882a593Smuzhiyun static int lookup_metapath(struct gfs2_inode *ip, struct metapath *mp)
360*4882a593Smuzhiyun {
361*4882a593Smuzhiyun return __fillup_metapath(ip, mp, 0, ip->i_height - 1);
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun /**
365*4882a593Smuzhiyun * fillup_metapath - fill up buffers for the metadata path to a specific height
366*4882a593Smuzhiyun * @ip: The inode
367*4882a593Smuzhiyun * @mp: The metapath
368*4882a593Smuzhiyun * @h: The height to which it should be mapped
369*4882a593Smuzhiyun *
370*4882a593Smuzhiyun * Similar to lookup_metapath, but does lookups for a range of heights
371*4882a593Smuzhiyun *
372*4882a593Smuzhiyun * Returns: error or the number of buffers filled
373*4882a593Smuzhiyun */
374*4882a593Smuzhiyun
fillup_metapath(struct gfs2_inode * ip,struct metapath * mp,int h)375*4882a593Smuzhiyun static int fillup_metapath(struct gfs2_inode *ip, struct metapath *mp, int h)
376*4882a593Smuzhiyun {
377*4882a593Smuzhiyun unsigned int x = 0;
378*4882a593Smuzhiyun int ret;
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun if (h) {
381*4882a593Smuzhiyun /* find the first buffer we need to look up. */
382*4882a593Smuzhiyun for (x = h - 1; x > 0; x--) {
383*4882a593Smuzhiyun if (mp->mp_bh[x])
384*4882a593Smuzhiyun break;
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun ret = __fillup_metapath(ip, mp, x, h);
388*4882a593Smuzhiyun if (ret)
389*4882a593Smuzhiyun return ret;
390*4882a593Smuzhiyun return mp->mp_aheight - x - 1;
391*4882a593Smuzhiyun }
392*4882a593Smuzhiyun
metapath_to_block(struct gfs2_sbd * sdp,struct metapath * mp)393*4882a593Smuzhiyun static sector_t metapath_to_block(struct gfs2_sbd *sdp, struct metapath *mp)
394*4882a593Smuzhiyun {
395*4882a593Smuzhiyun sector_t factor = 1, block = 0;
396*4882a593Smuzhiyun int hgt;
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun for (hgt = mp->mp_fheight - 1; hgt >= 0; hgt--) {
399*4882a593Smuzhiyun if (hgt < mp->mp_aheight)
400*4882a593Smuzhiyun block += mp->mp_list[hgt] * factor;
401*4882a593Smuzhiyun factor *= sdp->sd_inptrs;
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun return block;
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun
release_metapath(struct metapath * mp)406*4882a593Smuzhiyun static void release_metapath(struct metapath *mp)
407*4882a593Smuzhiyun {
408*4882a593Smuzhiyun int i;
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun for (i = 0; i < GFS2_MAX_META_HEIGHT; i++) {
411*4882a593Smuzhiyun if (mp->mp_bh[i] == NULL)
412*4882a593Smuzhiyun break;
413*4882a593Smuzhiyun brelse(mp->mp_bh[i]);
414*4882a593Smuzhiyun mp->mp_bh[i] = NULL;
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun }
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun /**
419*4882a593Smuzhiyun * gfs2_extent_length - Returns length of an extent of blocks
420*4882a593Smuzhiyun * @bh: The metadata block
421*4882a593Smuzhiyun * @ptr: Current position in @bh
422*4882a593Smuzhiyun * @limit: Max extent length to return
423*4882a593Smuzhiyun * @eob: Set to 1 if we hit "end of block"
424*4882a593Smuzhiyun *
425*4882a593Smuzhiyun * Returns: The length of the extent (minimum of one block)
426*4882a593Smuzhiyun */
427*4882a593Smuzhiyun
gfs2_extent_length(struct buffer_head * bh,__be64 * ptr,size_t limit,int * eob)428*4882a593Smuzhiyun static inline unsigned int gfs2_extent_length(struct buffer_head *bh, __be64 *ptr, size_t limit, int *eob)
429*4882a593Smuzhiyun {
430*4882a593Smuzhiyun const __be64 *end = (__be64 *)(bh->b_data + bh->b_size);
431*4882a593Smuzhiyun const __be64 *first = ptr;
432*4882a593Smuzhiyun u64 d = be64_to_cpu(*ptr);
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun *eob = 0;
435*4882a593Smuzhiyun do {
436*4882a593Smuzhiyun ptr++;
437*4882a593Smuzhiyun if (ptr >= end)
438*4882a593Smuzhiyun break;
439*4882a593Smuzhiyun d++;
440*4882a593Smuzhiyun } while(be64_to_cpu(*ptr) == d);
441*4882a593Smuzhiyun if (ptr >= end)
442*4882a593Smuzhiyun *eob = 1;
443*4882a593Smuzhiyun return ptr - first;
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun enum walker_status { WALK_STOP, WALK_FOLLOW, WALK_CONTINUE };
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun /*
449*4882a593Smuzhiyun * gfs2_metadata_walker - walk an indirect block
450*4882a593Smuzhiyun * @mp: Metapath to indirect block
451*4882a593Smuzhiyun * @ptrs: Number of pointers to look at
452*4882a593Smuzhiyun *
453*4882a593Smuzhiyun * When returning WALK_FOLLOW, the walker must update @mp to point at the right
454*4882a593Smuzhiyun * indirect block to follow.
455*4882a593Smuzhiyun */
456*4882a593Smuzhiyun typedef enum walker_status (*gfs2_metadata_walker)(struct metapath *mp,
457*4882a593Smuzhiyun unsigned int ptrs);
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun /*
460*4882a593Smuzhiyun * gfs2_walk_metadata - walk a tree of indirect blocks
461*4882a593Smuzhiyun * @inode: The inode
462*4882a593Smuzhiyun * @mp: Starting point of walk
463*4882a593Smuzhiyun * @max_len: Maximum number of blocks to walk
464*4882a593Smuzhiyun * @walker: Called during the walk
465*4882a593Smuzhiyun *
466*4882a593Smuzhiyun * Returns 1 if the walk was stopped by @walker, 0 if we went past @max_len or
467*4882a593Smuzhiyun * past the end of metadata, and a negative error code otherwise.
468*4882a593Smuzhiyun */
469*4882a593Smuzhiyun
gfs2_walk_metadata(struct inode * inode,struct metapath * mp,u64 max_len,gfs2_metadata_walker walker)470*4882a593Smuzhiyun static int gfs2_walk_metadata(struct inode *inode, struct metapath *mp,
471*4882a593Smuzhiyun u64 max_len, gfs2_metadata_walker walker)
472*4882a593Smuzhiyun {
473*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
474*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(inode);
475*4882a593Smuzhiyun u64 factor = 1;
476*4882a593Smuzhiyun unsigned int hgt;
477*4882a593Smuzhiyun int ret;
478*4882a593Smuzhiyun
479*4882a593Smuzhiyun /*
480*4882a593Smuzhiyun * The walk starts in the lowest allocated indirect block, which may be
481*4882a593Smuzhiyun * before the position indicated by @mp. Adjust @max_len accordingly
482*4882a593Smuzhiyun * to avoid a short walk.
483*4882a593Smuzhiyun */
484*4882a593Smuzhiyun for (hgt = mp->mp_fheight - 1; hgt >= mp->mp_aheight; hgt--) {
485*4882a593Smuzhiyun max_len += mp->mp_list[hgt] * factor;
486*4882a593Smuzhiyun mp->mp_list[hgt] = 0;
487*4882a593Smuzhiyun factor *= sdp->sd_inptrs;
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun for (;;) {
491*4882a593Smuzhiyun u16 start = mp->mp_list[hgt];
492*4882a593Smuzhiyun enum walker_status status;
493*4882a593Smuzhiyun unsigned int ptrs;
494*4882a593Smuzhiyun u64 len;
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun /* Walk indirect block. */
497*4882a593Smuzhiyun ptrs = (hgt >= 1 ? sdp->sd_inptrs : sdp->sd_diptrs) - start;
498*4882a593Smuzhiyun len = ptrs * factor;
499*4882a593Smuzhiyun if (len > max_len)
500*4882a593Smuzhiyun ptrs = DIV_ROUND_UP_ULL(max_len, factor);
501*4882a593Smuzhiyun status = walker(mp, ptrs);
502*4882a593Smuzhiyun switch (status) {
503*4882a593Smuzhiyun case WALK_STOP:
504*4882a593Smuzhiyun return 1;
505*4882a593Smuzhiyun case WALK_FOLLOW:
506*4882a593Smuzhiyun BUG_ON(mp->mp_aheight == mp->mp_fheight);
507*4882a593Smuzhiyun ptrs = mp->mp_list[hgt] - start;
508*4882a593Smuzhiyun len = ptrs * factor;
509*4882a593Smuzhiyun break;
510*4882a593Smuzhiyun case WALK_CONTINUE:
511*4882a593Smuzhiyun break;
512*4882a593Smuzhiyun }
513*4882a593Smuzhiyun if (len >= max_len)
514*4882a593Smuzhiyun break;
515*4882a593Smuzhiyun max_len -= len;
516*4882a593Smuzhiyun if (status == WALK_FOLLOW)
517*4882a593Smuzhiyun goto fill_up_metapath;
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun lower_metapath:
520*4882a593Smuzhiyun /* Decrease height of metapath. */
521*4882a593Smuzhiyun brelse(mp->mp_bh[hgt]);
522*4882a593Smuzhiyun mp->mp_bh[hgt] = NULL;
523*4882a593Smuzhiyun mp->mp_list[hgt] = 0;
524*4882a593Smuzhiyun if (!hgt)
525*4882a593Smuzhiyun break;
526*4882a593Smuzhiyun hgt--;
527*4882a593Smuzhiyun factor *= sdp->sd_inptrs;
528*4882a593Smuzhiyun
529*4882a593Smuzhiyun /* Advance in metadata tree. */
530*4882a593Smuzhiyun (mp->mp_list[hgt])++;
531*4882a593Smuzhiyun if (hgt) {
532*4882a593Smuzhiyun if (mp->mp_list[hgt] >= sdp->sd_inptrs)
533*4882a593Smuzhiyun goto lower_metapath;
534*4882a593Smuzhiyun } else {
535*4882a593Smuzhiyun if (mp->mp_list[hgt] >= sdp->sd_diptrs)
536*4882a593Smuzhiyun break;
537*4882a593Smuzhiyun }
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun fill_up_metapath:
540*4882a593Smuzhiyun /* Increase height of metapath. */
541*4882a593Smuzhiyun ret = fillup_metapath(ip, mp, ip->i_height - 1);
542*4882a593Smuzhiyun if (ret < 0)
543*4882a593Smuzhiyun return ret;
544*4882a593Smuzhiyun hgt += ret;
545*4882a593Smuzhiyun for (; ret; ret--)
546*4882a593Smuzhiyun do_div(factor, sdp->sd_inptrs);
547*4882a593Smuzhiyun mp->mp_aheight = hgt + 1;
548*4882a593Smuzhiyun }
549*4882a593Smuzhiyun return 0;
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun
gfs2_hole_walker(struct metapath * mp,unsigned int ptrs)552*4882a593Smuzhiyun static enum walker_status gfs2_hole_walker(struct metapath *mp,
553*4882a593Smuzhiyun unsigned int ptrs)
554*4882a593Smuzhiyun {
555*4882a593Smuzhiyun const __be64 *start, *ptr, *end;
556*4882a593Smuzhiyun unsigned int hgt;
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun hgt = mp->mp_aheight - 1;
559*4882a593Smuzhiyun start = metapointer(hgt, mp);
560*4882a593Smuzhiyun end = start + ptrs;
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun for (ptr = start; ptr < end; ptr++) {
563*4882a593Smuzhiyun if (*ptr) {
564*4882a593Smuzhiyun mp->mp_list[hgt] += ptr - start;
565*4882a593Smuzhiyun if (mp->mp_aheight == mp->mp_fheight)
566*4882a593Smuzhiyun return WALK_STOP;
567*4882a593Smuzhiyun return WALK_FOLLOW;
568*4882a593Smuzhiyun }
569*4882a593Smuzhiyun }
570*4882a593Smuzhiyun return WALK_CONTINUE;
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun /**
574*4882a593Smuzhiyun * gfs2_hole_size - figure out the size of a hole
575*4882a593Smuzhiyun * @inode: The inode
576*4882a593Smuzhiyun * @lblock: The logical starting block number
577*4882a593Smuzhiyun * @len: How far to look (in blocks)
578*4882a593Smuzhiyun * @mp: The metapath at lblock
579*4882a593Smuzhiyun * @iomap: The iomap to store the hole size in
580*4882a593Smuzhiyun *
581*4882a593Smuzhiyun * This function modifies @mp.
582*4882a593Smuzhiyun *
583*4882a593Smuzhiyun * Returns: errno on error
584*4882a593Smuzhiyun */
gfs2_hole_size(struct inode * inode,sector_t lblock,u64 len,struct metapath * mp,struct iomap * iomap)585*4882a593Smuzhiyun static int gfs2_hole_size(struct inode *inode, sector_t lblock, u64 len,
586*4882a593Smuzhiyun struct metapath *mp, struct iomap *iomap)
587*4882a593Smuzhiyun {
588*4882a593Smuzhiyun struct metapath clone;
589*4882a593Smuzhiyun u64 hole_size;
590*4882a593Smuzhiyun int ret;
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun clone_metapath(&clone, mp);
593*4882a593Smuzhiyun ret = gfs2_walk_metadata(inode, &clone, len, gfs2_hole_walker);
594*4882a593Smuzhiyun if (ret < 0)
595*4882a593Smuzhiyun goto out;
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun if (ret == 1)
598*4882a593Smuzhiyun hole_size = metapath_to_block(GFS2_SB(inode), &clone) - lblock;
599*4882a593Smuzhiyun else
600*4882a593Smuzhiyun hole_size = len;
601*4882a593Smuzhiyun iomap->length = hole_size << inode->i_blkbits;
602*4882a593Smuzhiyun ret = 0;
603*4882a593Smuzhiyun
604*4882a593Smuzhiyun out:
605*4882a593Smuzhiyun release_metapath(&clone);
606*4882a593Smuzhiyun return ret;
607*4882a593Smuzhiyun }
608*4882a593Smuzhiyun
gfs2_indirect_init(struct metapath * mp,struct gfs2_glock * gl,unsigned int i,unsigned offset,u64 bn)609*4882a593Smuzhiyun static inline __be64 *gfs2_indirect_init(struct metapath *mp,
610*4882a593Smuzhiyun struct gfs2_glock *gl, unsigned int i,
611*4882a593Smuzhiyun unsigned offset, u64 bn)
612*4882a593Smuzhiyun {
613*4882a593Smuzhiyun __be64 *ptr = (__be64 *)(mp->mp_bh[i - 1]->b_data +
614*4882a593Smuzhiyun ((i > 1) ? sizeof(struct gfs2_meta_header) :
615*4882a593Smuzhiyun sizeof(struct gfs2_dinode)));
616*4882a593Smuzhiyun BUG_ON(i < 1);
617*4882a593Smuzhiyun BUG_ON(mp->mp_bh[i] != NULL);
618*4882a593Smuzhiyun mp->mp_bh[i] = gfs2_meta_new(gl, bn);
619*4882a593Smuzhiyun gfs2_trans_add_meta(gl, mp->mp_bh[i]);
620*4882a593Smuzhiyun gfs2_metatype_set(mp->mp_bh[i], GFS2_METATYPE_IN, GFS2_FORMAT_IN);
621*4882a593Smuzhiyun gfs2_buffer_clear_tail(mp->mp_bh[i], sizeof(struct gfs2_meta_header));
622*4882a593Smuzhiyun ptr += offset;
623*4882a593Smuzhiyun *ptr = cpu_to_be64(bn);
624*4882a593Smuzhiyun return ptr;
625*4882a593Smuzhiyun }
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun enum alloc_state {
628*4882a593Smuzhiyun ALLOC_DATA = 0,
629*4882a593Smuzhiyun ALLOC_GROW_DEPTH = 1,
630*4882a593Smuzhiyun ALLOC_GROW_HEIGHT = 2,
631*4882a593Smuzhiyun /* ALLOC_UNSTUFF = 3, TBD and rather complicated */
632*4882a593Smuzhiyun };
633*4882a593Smuzhiyun
634*4882a593Smuzhiyun /**
635*4882a593Smuzhiyun * gfs2_iomap_alloc - Build a metadata tree of the requested height
636*4882a593Smuzhiyun * @inode: The GFS2 inode
637*4882a593Smuzhiyun * @iomap: The iomap structure
638*4882a593Smuzhiyun * @mp: The metapath, with proper height information calculated
639*4882a593Smuzhiyun *
640*4882a593Smuzhiyun * In this routine we may have to alloc:
641*4882a593Smuzhiyun * i) Indirect blocks to grow the metadata tree height
642*4882a593Smuzhiyun * ii) Indirect blocks to fill in lower part of the metadata tree
643*4882a593Smuzhiyun * iii) Data blocks
644*4882a593Smuzhiyun *
645*4882a593Smuzhiyun * This function is called after gfs2_iomap_get, which works out the
646*4882a593Smuzhiyun * total number of blocks which we need via gfs2_alloc_size.
647*4882a593Smuzhiyun *
648*4882a593Smuzhiyun * We then do the actual allocation asking for an extent at a time (if
649*4882a593Smuzhiyun * enough contiguous free blocks are available, there will only be one
650*4882a593Smuzhiyun * allocation request per call) and uses the state machine to initialise
651*4882a593Smuzhiyun * the blocks in order.
652*4882a593Smuzhiyun *
653*4882a593Smuzhiyun * Right now, this function will allocate at most one indirect block
654*4882a593Smuzhiyun * worth of data -- with a default block size of 4K, that's slightly
655*4882a593Smuzhiyun * less than 2M. If this limitation is ever removed to allow huge
656*4882a593Smuzhiyun * allocations, we would probably still want to limit the iomap size we
657*4882a593Smuzhiyun * return to avoid stalling other tasks during huge writes; the next
658*4882a593Smuzhiyun * iomap iteration would then find the blocks already allocated.
659*4882a593Smuzhiyun *
660*4882a593Smuzhiyun * Returns: errno on error
661*4882a593Smuzhiyun */
662*4882a593Smuzhiyun
gfs2_iomap_alloc(struct inode * inode,struct iomap * iomap,struct metapath * mp)663*4882a593Smuzhiyun static int gfs2_iomap_alloc(struct inode *inode, struct iomap *iomap,
664*4882a593Smuzhiyun struct metapath *mp)
665*4882a593Smuzhiyun {
666*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
667*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(inode);
668*4882a593Smuzhiyun struct buffer_head *dibh = mp->mp_bh[0];
669*4882a593Smuzhiyun u64 bn;
670*4882a593Smuzhiyun unsigned n, i, blks, alloced = 0, iblks = 0, branch_start = 0;
671*4882a593Smuzhiyun size_t dblks = iomap->length >> inode->i_blkbits;
672*4882a593Smuzhiyun const unsigned end_of_metadata = mp->mp_fheight - 1;
673*4882a593Smuzhiyun int ret;
674*4882a593Smuzhiyun enum alloc_state state;
675*4882a593Smuzhiyun __be64 *ptr;
676*4882a593Smuzhiyun __be64 zero_bn = 0;
677*4882a593Smuzhiyun
678*4882a593Smuzhiyun BUG_ON(mp->mp_aheight < 1);
679*4882a593Smuzhiyun BUG_ON(dibh == NULL);
680*4882a593Smuzhiyun BUG_ON(dblks < 1);
681*4882a593Smuzhiyun
682*4882a593Smuzhiyun gfs2_trans_add_meta(ip->i_gl, dibh);
683*4882a593Smuzhiyun
684*4882a593Smuzhiyun down_write(&ip->i_rw_mutex);
685*4882a593Smuzhiyun
686*4882a593Smuzhiyun if (mp->mp_fheight == mp->mp_aheight) {
687*4882a593Smuzhiyun /* Bottom indirect block exists */
688*4882a593Smuzhiyun state = ALLOC_DATA;
689*4882a593Smuzhiyun } else {
690*4882a593Smuzhiyun /* Need to allocate indirect blocks */
691*4882a593Smuzhiyun if (mp->mp_fheight == ip->i_height) {
692*4882a593Smuzhiyun /* Writing into existing tree, extend tree down */
693*4882a593Smuzhiyun iblks = mp->mp_fheight - mp->mp_aheight;
694*4882a593Smuzhiyun state = ALLOC_GROW_DEPTH;
695*4882a593Smuzhiyun } else {
696*4882a593Smuzhiyun /* Building up tree height */
697*4882a593Smuzhiyun state = ALLOC_GROW_HEIGHT;
698*4882a593Smuzhiyun iblks = mp->mp_fheight - ip->i_height;
699*4882a593Smuzhiyun branch_start = metapath_branch_start(mp);
700*4882a593Smuzhiyun iblks += (mp->mp_fheight - branch_start);
701*4882a593Smuzhiyun }
702*4882a593Smuzhiyun }
703*4882a593Smuzhiyun
704*4882a593Smuzhiyun /* start of the second part of the function (state machine) */
705*4882a593Smuzhiyun
706*4882a593Smuzhiyun blks = dblks + iblks;
707*4882a593Smuzhiyun i = mp->mp_aheight;
708*4882a593Smuzhiyun do {
709*4882a593Smuzhiyun n = blks - alloced;
710*4882a593Smuzhiyun ret = gfs2_alloc_blocks(ip, &bn, &n, 0, NULL);
711*4882a593Smuzhiyun if (ret)
712*4882a593Smuzhiyun goto out;
713*4882a593Smuzhiyun alloced += n;
714*4882a593Smuzhiyun if (state != ALLOC_DATA || gfs2_is_jdata(ip))
715*4882a593Smuzhiyun gfs2_trans_remove_revoke(sdp, bn, n);
716*4882a593Smuzhiyun switch (state) {
717*4882a593Smuzhiyun /* Growing height of tree */
718*4882a593Smuzhiyun case ALLOC_GROW_HEIGHT:
719*4882a593Smuzhiyun if (i == 1) {
720*4882a593Smuzhiyun ptr = (__be64 *)(dibh->b_data +
721*4882a593Smuzhiyun sizeof(struct gfs2_dinode));
722*4882a593Smuzhiyun zero_bn = *ptr;
723*4882a593Smuzhiyun }
724*4882a593Smuzhiyun for (; i - 1 < mp->mp_fheight - ip->i_height && n > 0;
725*4882a593Smuzhiyun i++, n--)
726*4882a593Smuzhiyun gfs2_indirect_init(mp, ip->i_gl, i, 0, bn++);
727*4882a593Smuzhiyun if (i - 1 == mp->mp_fheight - ip->i_height) {
728*4882a593Smuzhiyun i--;
729*4882a593Smuzhiyun gfs2_buffer_copy_tail(mp->mp_bh[i],
730*4882a593Smuzhiyun sizeof(struct gfs2_meta_header),
731*4882a593Smuzhiyun dibh, sizeof(struct gfs2_dinode));
732*4882a593Smuzhiyun gfs2_buffer_clear_tail(dibh,
733*4882a593Smuzhiyun sizeof(struct gfs2_dinode) +
734*4882a593Smuzhiyun sizeof(__be64));
735*4882a593Smuzhiyun ptr = (__be64 *)(mp->mp_bh[i]->b_data +
736*4882a593Smuzhiyun sizeof(struct gfs2_meta_header));
737*4882a593Smuzhiyun *ptr = zero_bn;
738*4882a593Smuzhiyun state = ALLOC_GROW_DEPTH;
739*4882a593Smuzhiyun for(i = branch_start; i < mp->mp_fheight; i++) {
740*4882a593Smuzhiyun if (mp->mp_bh[i] == NULL)
741*4882a593Smuzhiyun break;
742*4882a593Smuzhiyun brelse(mp->mp_bh[i]);
743*4882a593Smuzhiyun mp->mp_bh[i] = NULL;
744*4882a593Smuzhiyun }
745*4882a593Smuzhiyun i = branch_start;
746*4882a593Smuzhiyun }
747*4882a593Smuzhiyun if (n == 0)
748*4882a593Smuzhiyun break;
749*4882a593Smuzhiyun fallthrough; /* To branching from existing tree */
750*4882a593Smuzhiyun case ALLOC_GROW_DEPTH:
751*4882a593Smuzhiyun if (i > 1 && i < mp->mp_fheight)
752*4882a593Smuzhiyun gfs2_trans_add_meta(ip->i_gl, mp->mp_bh[i-1]);
753*4882a593Smuzhiyun for (; i < mp->mp_fheight && n > 0; i++, n--)
754*4882a593Smuzhiyun gfs2_indirect_init(mp, ip->i_gl, i,
755*4882a593Smuzhiyun mp->mp_list[i-1], bn++);
756*4882a593Smuzhiyun if (i == mp->mp_fheight)
757*4882a593Smuzhiyun state = ALLOC_DATA;
758*4882a593Smuzhiyun if (n == 0)
759*4882a593Smuzhiyun break;
760*4882a593Smuzhiyun fallthrough; /* To tree complete, adding data blocks */
761*4882a593Smuzhiyun case ALLOC_DATA:
762*4882a593Smuzhiyun BUG_ON(n > dblks);
763*4882a593Smuzhiyun BUG_ON(mp->mp_bh[end_of_metadata] == NULL);
764*4882a593Smuzhiyun gfs2_trans_add_meta(ip->i_gl, mp->mp_bh[end_of_metadata]);
765*4882a593Smuzhiyun dblks = n;
766*4882a593Smuzhiyun ptr = metapointer(end_of_metadata, mp);
767*4882a593Smuzhiyun iomap->addr = bn << inode->i_blkbits;
768*4882a593Smuzhiyun iomap->flags |= IOMAP_F_MERGED | IOMAP_F_NEW;
769*4882a593Smuzhiyun while (n-- > 0)
770*4882a593Smuzhiyun *ptr++ = cpu_to_be64(bn++);
771*4882a593Smuzhiyun break;
772*4882a593Smuzhiyun }
773*4882a593Smuzhiyun } while (iomap->addr == IOMAP_NULL_ADDR);
774*4882a593Smuzhiyun
775*4882a593Smuzhiyun iomap->type = IOMAP_MAPPED;
776*4882a593Smuzhiyun iomap->length = (u64)dblks << inode->i_blkbits;
777*4882a593Smuzhiyun ip->i_height = mp->mp_fheight;
778*4882a593Smuzhiyun gfs2_add_inode_blocks(&ip->i_inode, alloced);
779*4882a593Smuzhiyun gfs2_dinode_out(ip, dibh->b_data);
780*4882a593Smuzhiyun out:
781*4882a593Smuzhiyun up_write(&ip->i_rw_mutex);
782*4882a593Smuzhiyun return ret;
783*4882a593Smuzhiyun }
784*4882a593Smuzhiyun
785*4882a593Smuzhiyun #define IOMAP_F_GFS2_BOUNDARY IOMAP_F_PRIVATE
786*4882a593Smuzhiyun
787*4882a593Smuzhiyun /**
788*4882a593Smuzhiyun * gfs2_alloc_size - Compute the maximum allocation size
789*4882a593Smuzhiyun * @inode: The inode
790*4882a593Smuzhiyun * @mp: The metapath
791*4882a593Smuzhiyun * @size: Requested size in blocks
792*4882a593Smuzhiyun *
793*4882a593Smuzhiyun * Compute the maximum size of the next allocation at @mp.
794*4882a593Smuzhiyun *
795*4882a593Smuzhiyun * Returns: size in blocks
796*4882a593Smuzhiyun */
gfs2_alloc_size(struct inode * inode,struct metapath * mp,u64 size)797*4882a593Smuzhiyun static u64 gfs2_alloc_size(struct inode *inode, struct metapath *mp, u64 size)
798*4882a593Smuzhiyun {
799*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
800*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(inode);
801*4882a593Smuzhiyun const __be64 *first, *ptr, *end;
802*4882a593Smuzhiyun
803*4882a593Smuzhiyun /*
804*4882a593Smuzhiyun * For writes to stuffed files, this function is called twice via
805*4882a593Smuzhiyun * gfs2_iomap_get, before and after unstuffing. The size we return the
806*4882a593Smuzhiyun * first time needs to be large enough to get the reservation and
807*4882a593Smuzhiyun * allocation sizes right. The size we return the second time must
808*4882a593Smuzhiyun * be exact or else gfs2_iomap_alloc won't do the right thing.
809*4882a593Smuzhiyun */
810*4882a593Smuzhiyun
811*4882a593Smuzhiyun if (gfs2_is_stuffed(ip) || mp->mp_fheight != mp->mp_aheight) {
812*4882a593Smuzhiyun unsigned int maxsize = mp->mp_fheight > 1 ?
813*4882a593Smuzhiyun sdp->sd_inptrs : sdp->sd_diptrs;
814*4882a593Smuzhiyun maxsize -= mp->mp_list[mp->mp_fheight - 1];
815*4882a593Smuzhiyun if (size > maxsize)
816*4882a593Smuzhiyun size = maxsize;
817*4882a593Smuzhiyun return size;
818*4882a593Smuzhiyun }
819*4882a593Smuzhiyun
820*4882a593Smuzhiyun first = metapointer(ip->i_height - 1, mp);
821*4882a593Smuzhiyun end = metaend(ip->i_height - 1, mp);
822*4882a593Smuzhiyun if (end - first > size)
823*4882a593Smuzhiyun end = first + size;
824*4882a593Smuzhiyun for (ptr = first; ptr < end; ptr++) {
825*4882a593Smuzhiyun if (*ptr)
826*4882a593Smuzhiyun break;
827*4882a593Smuzhiyun }
828*4882a593Smuzhiyun return ptr - first;
829*4882a593Smuzhiyun }
830*4882a593Smuzhiyun
831*4882a593Smuzhiyun /**
832*4882a593Smuzhiyun * gfs2_iomap_get - Map blocks from an inode to disk blocks
833*4882a593Smuzhiyun * @inode: The inode
834*4882a593Smuzhiyun * @pos: Starting position in bytes
835*4882a593Smuzhiyun * @length: Length to map, in bytes
836*4882a593Smuzhiyun * @flags: iomap flags
837*4882a593Smuzhiyun * @iomap: The iomap structure
838*4882a593Smuzhiyun * @mp: The metapath
839*4882a593Smuzhiyun *
840*4882a593Smuzhiyun * Returns: errno
841*4882a593Smuzhiyun */
gfs2_iomap_get(struct inode * inode,loff_t pos,loff_t length,unsigned flags,struct iomap * iomap,struct metapath * mp)842*4882a593Smuzhiyun static int gfs2_iomap_get(struct inode *inode, loff_t pos, loff_t length,
843*4882a593Smuzhiyun unsigned flags, struct iomap *iomap,
844*4882a593Smuzhiyun struct metapath *mp)
845*4882a593Smuzhiyun {
846*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
847*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(inode);
848*4882a593Smuzhiyun loff_t size = i_size_read(inode);
849*4882a593Smuzhiyun __be64 *ptr;
850*4882a593Smuzhiyun sector_t lblock;
851*4882a593Smuzhiyun sector_t lblock_stop;
852*4882a593Smuzhiyun int ret;
853*4882a593Smuzhiyun int eob;
854*4882a593Smuzhiyun u64 len;
855*4882a593Smuzhiyun struct buffer_head *dibh = NULL, *bh;
856*4882a593Smuzhiyun u8 height;
857*4882a593Smuzhiyun
858*4882a593Smuzhiyun if (!length)
859*4882a593Smuzhiyun return -EINVAL;
860*4882a593Smuzhiyun
861*4882a593Smuzhiyun down_read(&ip->i_rw_mutex);
862*4882a593Smuzhiyun
863*4882a593Smuzhiyun ret = gfs2_meta_inode_buffer(ip, &dibh);
864*4882a593Smuzhiyun if (ret)
865*4882a593Smuzhiyun goto unlock;
866*4882a593Smuzhiyun mp->mp_bh[0] = dibh;
867*4882a593Smuzhiyun
868*4882a593Smuzhiyun if (gfs2_is_stuffed(ip)) {
869*4882a593Smuzhiyun if (flags & IOMAP_WRITE) {
870*4882a593Smuzhiyun loff_t max_size = gfs2_max_stuffed_size(ip);
871*4882a593Smuzhiyun
872*4882a593Smuzhiyun if (pos + length > max_size)
873*4882a593Smuzhiyun goto unstuff;
874*4882a593Smuzhiyun iomap->length = max_size;
875*4882a593Smuzhiyun } else {
876*4882a593Smuzhiyun if (pos >= size) {
877*4882a593Smuzhiyun if (flags & IOMAP_REPORT) {
878*4882a593Smuzhiyun ret = -ENOENT;
879*4882a593Smuzhiyun goto unlock;
880*4882a593Smuzhiyun } else {
881*4882a593Smuzhiyun iomap->offset = pos;
882*4882a593Smuzhiyun iomap->length = length;
883*4882a593Smuzhiyun goto hole_found;
884*4882a593Smuzhiyun }
885*4882a593Smuzhiyun }
886*4882a593Smuzhiyun iomap->length = size;
887*4882a593Smuzhiyun }
888*4882a593Smuzhiyun iomap->addr = (ip->i_no_addr << inode->i_blkbits) +
889*4882a593Smuzhiyun sizeof(struct gfs2_dinode);
890*4882a593Smuzhiyun iomap->type = IOMAP_INLINE;
891*4882a593Smuzhiyun iomap->inline_data = dibh->b_data + sizeof(struct gfs2_dinode);
892*4882a593Smuzhiyun goto out;
893*4882a593Smuzhiyun }
894*4882a593Smuzhiyun
895*4882a593Smuzhiyun unstuff:
896*4882a593Smuzhiyun lblock = pos >> inode->i_blkbits;
897*4882a593Smuzhiyun iomap->offset = lblock << inode->i_blkbits;
898*4882a593Smuzhiyun lblock_stop = (pos + length - 1) >> inode->i_blkbits;
899*4882a593Smuzhiyun len = lblock_stop - lblock + 1;
900*4882a593Smuzhiyun iomap->length = len << inode->i_blkbits;
901*4882a593Smuzhiyun
902*4882a593Smuzhiyun height = ip->i_height;
903*4882a593Smuzhiyun while ((lblock + 1) * sdp->sd_sb.sb_bsize > sdp->sd_heightsize[height])
904*4882a593Smuzhiyun height++;
905*4882a593Smuzhiyun find_metapath(sdp, lblock, mp, height);
906*4882a593Smuzhiyun if (height > ip->i_height || gfs2_is_stuffed(ip))
907*4882a593Smuzhiyun goto do_alloc;
908*4882a593Smuzhiyun
909*4882a593Smuzhiyun ret = lookup_metapath(ip, mp);
910*4882a593Smuzhiyun if (ret)
911*4882a593Smuzhiyun goto unlock;
912*4882a593Smuzhiyun
913*4882a593Smuzhiyun if (mp->mp_aheight != ip->i_height)
914*4882a593Smuzhiyun goto do_alloc;
915*4882a593Smuzhiyun
916*4882a593Smuzhiyun ptr = metapointer(ip->i_height - 1, mp);
917*4882a593Smuzhiyun if (*ptr == 0)
918*4882a593Smuzhiyun goto do_alloc;
919*4882a593Smuzhiyun
920*4882a593Smuzhiyun bh = mp->mp_bh[ip->i_height - 1];
921*4882a593Smuzhiyun len = gfs2_extent_length(bh, ptr, len, &eob);
922*4882a593Smuzhiyun
923*4882a593Smuzhiyun iomap->addr = be64_to_cpu(*ptr) << inode->i_blkbits;
924*4882a593Smuzhiyun iomap->length = len << inode->i_blkbits;
925*4882a593Smuzhiyun iomap->type = IOMAP_MAPPED;
926*4882a593Smuzhiyun iomap->flags |= IOMAP_F_MERGED;
927*4882a593Smuzhiyun if (eob)
928*4882a593Smuzhiyun iomap->flags |= IOMAP_F_GFS2_BOUNDARY;
929*4882a593Smuzhiyun
930*4882a593Smuzhiyun out:
931*4882a593Smuzhiyun iomap->bdev = inode->i_sb->s_bdev;
932*4882a593Smuzhiyun unlock:
933*4882a593Smuzhiyun up_read(&ip->i_rw_mutex);
934*4882a593Smuzhiyun return ret;
935*4882a593Smuzhiyun
936*4882a593Smuzhiyun do_alloc:
937*4882a593Smuzhiyun if (flags & IOMAP_REPORT) {
938*4882a593Smuzhiyun if (pos >= size)
939*4882a593Smuzhiyun ret = -ENOENT;
940*4882a593Smuzhiyun else if (height == ip->i_height)
941*4882a593Smuzhiyun ret = gfs2_hole_size(inode, lblock, len, mp, iomap);
942*4882a593Smuzhiyun else
943*4882a593Smuzhiyun iomap->length = size - iomap->offset;
944*4882a593Smuzhiyun } else if (flags & IOMAP_WRITE) {
945*4882a593Smuzhiyun u64 alloc_size;
946*4882a593Smuzhiyun
947*4882a593Smuzhiyun if (flags & IOMAP_DIRECT)
948*4882a593Smuzhiyun goto out; /* (see gfs2_file_direct_write) */
949*4882a593Smuzhiyun
950*4882a593Smuzhiyun len = gfs2_alloc_size(inode, mp, len);
951*4882a593Smuzhiyun alloc_size = len << inode->i_blkbits;
952*4882a593Smuzhiyun if (alloc_size < iomap->length)
953*4882a593Smuzhiyun iomap->length = alloc_size;
954*4882a593Smuzhiyun } else {
955*4882a593Smuzhiyun if (pos < size && height == ip->i_height)
956*4882a593Smuzhiyun ret = gfs2_hole_size(inode, lblock, len, mp, iomap);
957*4882a593Smuzhiyun }
958*4882a593Smuzhiyun hole_found:
959*4882a593Smuzhiyun iomap->addr = IOMAP_NULL_ADDR;
960*4882a593Smuzhiyun iomap->type = IOMAP_HOLE;
961*4882a593Smuzhiyun goto out;
962*4882a593Smuzhiyun }
963*4882a593Smuzhiyun
964*4882a593Smuzhiyun /**
965*4882a593Smuzhiyun * gfs2_lblk_to_dblk - convert logical block to disk block
966*4882a593Smuzhiyun * @inode: the inode of the file we're mapping
967*4882a593Smuzhiyun * @lblock: the block relative to the start of the file
968*4882a593Smuzhiyun * @dblock: the returned dblock, if no error
969*4882a593Smuzhiyun *
970*4882a593Smuzhiyun * This function maps a single block from a file logical block (relative to
971*4882a593Smuzhiyun * the start of the file) to a file system absolute block using iomap.
972*4882a593Smuzhiyun *
973*4882a593Smuzhiyun * Returns: the absolute file system block, or an error
974*4882a593Smuzhiyun */
gfs2_lblk_to_dblk(struct inode * inode,u32 lblock,u64 * dblock)975*4882a593Smuzhiyun int gfs2_lblk_to_dblk(struct inode *inode, u32 lblock, u64 *dblock)
976*4882a593Smuzhiyun {
977*4882a593Smuzhiyun struct iomap iomap = { };
978*4882a593Smuzhiyun struct metapath mp = { .mp_aheight = 1, };
979*4882a593Smuzhiyun loff_t pos = (loff_t)lblock << inode->i_blkbits;
980*4882a593Smuzhiyun int ret;
981*4882a593Smuzhiyun
982*4882a593Smuzhiyun ret = gfs2_iomap_get(inode, pos, i_blocksize(inode), 0, &iomap, &mp);
983*4882a593Smuzhiyun release_metapath(&mp);
984*4882a593Smuzhiyun if (ret == 0)
985*4882a593Smuzhiyun *dblock = iomap.addr >> inode->i_blkbits;
986*4882a593Smuzhiyun
987*4882a593Smuzhiyun return ret;
988*4882a593Smuzhiyun }
989*4882a593Smuzhiyun
gfs2_write_lock(struct inode * inode)990*4882a593Smuzhiyun static int gfs2_write_lock(struct inode *inode)
991*4882a593Smuzhiyun {
992*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
993*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(inode);
994*4882a593Smuzhiyun int error;
995*4882a593Smuzhiyun
996*4882a593Smuzhiyun gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh);
997*4882a593Smuzhiyun error = gfs2_glock_nq(&ip->i_gh);
998*4882a593Smuzhiyun if (error)
999*4882a593Smuzhiyun goto out_uninit;
1000*4882a593Smuzhiyun if (&ip->i_inode == sdp->sd_rindex) {
1001*4882a593Smuzhiyun struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
1002*4882a593Smuzhiyun
1003*4882a593Smuzhiyun error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE,
1004*4882a593Smuzhiyun GL_NOCACHE, &m_ip->i_gh);
1005*4882a593Smuzhiyun if (error)
1006*4882a593Smuzhiyun goto out_unlock;
1007*4882a593Smuzhiyun }
1008*4882a593Smuzhiyun return 0;
1009*4882a593Smuzhiyun
1010*4882a593Smuzhiyun out_unlock:
1011*4882a593Smuzhiyun gfs2_glock_dq(&ip->i_gh);
1012*4882a593Smuzhiyun out_uninit:
1013*4882a593Smuzhiyun gfs2_holder_uninit(&ip->i_gh);
1014*4882a593Smuzhiyun return error;
1015*4882a593Smuzhiyun }
1016*4882a593Smuzhiyun
gfs2_write_unlock(struct inode * inode)1017*4882a593Smuzhiyun static void gfs2_write_unlock(struct inode *inode)
1018*4882a593Smuzhiyun {
1019*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
1020*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(inode);
1021*4882a593Smuzhiyun
1022*4882a593Smuzhiyun if (&ip->i_inode == sdp->sd_rindex) {
1023*4882a593Smuzhiyun struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
1024*4882a593Smuzhiyun
1025*4882a593Smuzhiyun gfs2_glock_dq_uninit(&m_ip->i_gh);
1026*4882a593Smuzhiyun }
1027*4882a593Smuzhiyun gfs2_glock_dq_uninit(&ip->i_gh);
1028*4882a593Smuzhiyun }
1029*4882a593Smuzhiyun
gfs2_iomap_page_prepare(struct inode * inode,loff_t pos,unsigned len,struct iomap * iomap)1030*4882a593Smuzhiyun static int gfs2_iomap_page_prepare(struct inode *inode, loff_t pos,
1031*4882a593Smuzhiyun unsigned len, struct iomap *iomap)
1032*4882a593Smuzhiyun {
1033*4882a593Smuzhiyun unsigned int blockmask = i_blocksize(inode) - 1;
1034*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(inode);
1035*4882a593Smuzhiyun unsigned int blocks;
1036*4882a593Smuzhiyun
1037*4882a593Smuzhiyun blocks = ((pos & blockmask) + len + blockmask) >> inode->i_blkbits;
1038*4882a593Smuzhiyun return gfs2_trans_begin(sdp, RES_DINODE + blocks, 0);
1039*4882a593Smuzhiyun }
1040*4882a593Smuzhiyun
gfs2_iomap_page_done(struct inode * inode,loff_t pos,unsigned copied,struct page * page,struct iomap * iomap)1041*4882a593Smuzhiyun static void gfs2_iomap_page_done(struct inode *inode, loff_t pos,
1042*4882a593Smuzhiyun unsigned copied, struct page *page,
1043*4882a593Smuzhiyun struct iomap *iomap)
1044*4882a593Smuzhiyun {
1045*4882a593Smuzhiyun struct gfs2_trans *tr = current->journal_info;
1046*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
1047*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(inode);
1048*4882a593Smuzhiyun
1049*4882a593Smuzhiyun if (page && !gfs2_is_stuffed(ip))
1050*4882a593Smuzhiyun gfs2_page_add_databufs(ip, page, offset_in_page(pos), copied);
1051*4882a593Smuzhiyun
1052*4882a593Smuzhiyun if (tr->tr_num_buf_new)
1053*4882a593Smuzhiyun __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
1054*4882a593Smuzhiyun
1055*4882a593Smuzhiyun gfs2_trans_end(sdp);
1056*4882a593Smuzhiyun }
1057*4882a593Smuzhiyun
1058*4882a593Smuzhiyun static const struct iomap_page_ops gfs2_iomap_page_ops = {
1059*4882a593Smuzhiyun .page_prepare = gfs2_iomap_page_prepare,
1060*4882a593Smuzhiyun .page_done = gfs2_iomap_page_done,
1061*4882a593Smuzhiyun };
1062*4882a593Smuzhiyun
gfs2_iomap_begin_write(struct inode * inode,loff_t pos,loff_t length,unsigned flags,struct iomap * iomap,struct metapath * mp)1063*4882a593Smuzhiyun static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos,
1064*4882a593Smuzhiyun loff_t length, unsigned flags,
1065*4882a593Smuzhiyun struct iomap *iomap,
1066*4882a593Smuzhiyun struct metapath *mp)
1067*4882a593Smuzhiyun {
1068*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
1069*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(inode);
1070*4882a593Smuzhiyun bool unstuff;
1071*4882a593Smuzhiyun int ret;
1072*4882a593Smuzhiyun
1073*4882a593Smuzhiyun unstuff = gfs2_is_stuffed(ip) &&
1074*4882a593Smuzhiyun pos + length > gfs2_max_stuffed_size(ip);
1075*4882a593Smuzhiyun
1076*4882a593Smuzhiyun if (unstuff || iomap->type == IOMAP_HOLE) {
1077*4882a593Smuzhiyun unsigned int data_blocks, ind_blocks;
1078*4882a593Smuzhiyun struct gfs2_alloc_parms ap = {};
1079*4882a593Smuzhiyun unsigned int rblocks;
1080*4882a593Smuzhiyun struct gfs2_trans *tr;
1081*4882a593Smuzhiyun
1082*4882a593Smuzhiyun gfs2_write_calc_reserv(ip, iomap->length, &data_blocks,
1083*4882a593Smuzhiyun &ind_blocks);
1084*4882a593Smuzhiyun ap.target = data_blocks + ind_blocks;
1085*4882a593Smuzhiyun ret = gfs2_quota_lock_check(ip, &ap);
1086*4882a593Smuzhiyun if (ret)
1087*4882a593Smuzhiyun return ret;
1088*4882a593Smuzhiyun
1089*4882a593Smuzhiyun ret = gfs2_inplace_reserve(ip, &ap);
1090*4882a593Smuzhiyun if (ret)
1091*4882a593Smuzhiyun goto out_qunlock;
1092*4882a593Smuzhiyun
1093*4882a593Smuzhiyun rblocks = RES_DINODE + ind_blocks;
1094*4882a593Smuzhiyun if (gfs2_is_jdata(ip))
1095*4882a593Smuzhiyun rblocks += data_blocks;
1096*4882a593Smuzhiyun if (ind_blocks || data_blocks)
1097*4882a593Smuzhiyun rblocks += RES_STATFS + RES_QUOTA;
1098*4882a593Smuzhiyun if (inode == sdp->sd_rindex)
1099*4882a593Smuzhiyun rblocks += 2 * RES_STATFS;
1100*4882a593Smuzhiyun rblocks += gfs2_rg_blocks(ip, data_blocks + ind_blocks);
1101*4882a593Smuzhiyun
1102*4882a593Smuzhiyun ret = gfs2_trans_begin(sdp, rblocks,
1103*4882a593Smuzhiyun iomap->length >> inode->i_blkbits);
1104*4882a593Smuzhiyun if (ret)
1105*4882a593Smuzhiyun goto out_trans_fail;
1106*4882a593Smuzhiyun
1107*4882a593Smuzhiyun if (unstuff) {
1108*4882a593Smuzhiyun ret = gfs2_unstuff_dinode(ip, NULL);
1109*4882a593Smuzhiyun if (ret)
1110*4882a593Smuzhiyun goto out_trans_end;
1111*4882a593Smuzhiyun release_metapath(mp);
1112*4882a593Smuzhiyun ret = gfs2_iomap_get(inode, iomap->offset,
1113*4882a593Smuzhiyun iomap->length, flags, iomap, mp);
1114*4882a593Smuzhiyun if (ret)
1115*4882a593Smuzhiyun goto out_trans_end;
1116*4882a593Smuzhiyun }
1117*4882a593Smuzhiyun
1118*4882a593Smuzhiyun if (iomap->type == IOMAP_HOLE) {
1119*4882a593Smuzhiyun ret = gfs2_iomap_alloc(inode, iomap, mp);
1120*4882a593Smuzhiyun if (ret) {
1121*4882a593Smuzhiyun gfs2_trans_end(sdp);
1122*4882a593Smuzhiyun gfs2_inplace_release(ip);
1123*4882a593Smuzhiyun punch_hole(ip, iomap->offset, iomap->length);
1124*4882a593Smuzhiyun goto out_qunlock;
1125*4882a593Smuzhiyun }
1126*4882a593Smuzhiyun }
1127*4882a593Smuzhiyun
1128*4882a593Smuzhiyun tr = current->journal_info;
1129*4882a593Smuzhiyun if (tr->tr_num_buf_new)
1130*4882a593Smuzhiyun __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
1131*4882a593Smuzhiyun
1132*4882a593Smuzhiyun gfs2_trans_end(sdp);
1133*4882a593Smuzhiyun }
1134*4882a593Smuzhiyun
1135*4882a593Smuzhiyun if (gfs2_is_stuffed(ip) || gfs2_is_jdata(ip))
1136*4882a593Smuzhiyun iomap->page_ops = &gfs2_iomap_page_ops;
1137*4882a593Smuzhiyun return 0;
1138*4882a593Smuzhiyun
1139*4882a593Smuzhiyun out_trans_end:
1140*4882a593Smuzhiyun gfs2_trans_end(sdp);
1141*4882a593Smuzhiyun out_trans_fail:
1142*4882a593Smuzhiyun gfs2_inplace_release(ip);
1143*4882a593Smuzhiyun out_qunlock:
1144*4882a593Smuzhiyun gfs2_quota_unlock(ip);
1145*4882a593Smuzhiyun return ret;
1146*4882a593Smuzhiyun }
1147*4882a593Smuzhiyun
gfs2_iomap_need_write_lock(unsigned flags)1148*4882a593Smuzhiyun static inline bool gfs2_iomap_need_write_lock(unsigned flags)
1149*4882a593Smuzhiyun {
1150*4882a593Smuzhiyun return (flags & IOMAP_WRITE) && !(flags & IOMAP_DIRECT);
1151*4882a593Smuzhiyun }
1152*4882a593Smuzhiyun
gfs2_iomap_begin(struct inode * inode,loff_t pos,loff_t length,unsigned flags,struct iomap * iomap,struct iomap * srcmap)1153*4882a593Smuzhiyun static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
1154*4882a593Smuzhiyun unsigned flags, struct iomap *iomap,
1155*4882a593Smuzhiyun struct iomap *srcmap)
1156*4882a593Smuzhiyun {
1157*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
1158*4882a593Smuzhiyun struct metapath mp = { .mp_aheight = 1, };
1159*4882a593Smuzhiyun int ret;
1160*4882a593Smuzhiyun
1161*4882a593Smuzhiyun if (gfs2_is_jdata(ip))
1162*4882a593Smuzhiyun iomap->flags |= IOMAP_F_BUFFER_HEAD;
1163*4882a593Smuzhiyun
1164*4882a593Smuzhiyun trace_gfs2_iomap_start(ip, pos, length, flags);
1165*4882a593Smuzhiyun if (gfs2_iomap_need_write_lock(flags)) {
1166*4882a593Smuzhiyun ret = gfs2_write_lock(inode);
1167*4882a593Smuzhiyun if (ret)
1168*4882a593Smuzhiyun goto out;
1169*4882a593Smuzhiyun }
1170*4882a593Smuzhiyun
1171*4882a593Smuzhiyun ret = gfs2_iomap_get(inode, pos, length, flags, iomap, &mp);
1172*4882a593Smuzhiyun if (ret)
1173*4882a593Smuzhiyun goto out_unlock;
1174*4882a593Smuzhiyun
1175*4882a593Smuzhiyun switch(flags & (IOMAP_WRITE | IOMAP_ZERO)) {
1176*4882a593Smuzhiyun case IOMAP_WRITE:
1177*4882a593Smuzhiyun if (flags & IOMAP_DIRECT) {
1178*4882a593Smuzhiyun /*
1179*4882a593Smuzhiyun * Silently fall back to buffered I/O for stuffed files
1180*4882a593Smuzhiyun * or if we've got a hole (see gfs2_file_direct_write).
1181*4882a593Smuzhiyun */
1182*4882a593Smuzhiyun if (iomap->type != IOMAP_MAPPED)
1183*4882a593Smuzhiyun ret = -ENOTBLK;
1184*4882a593Smuzhiyun goto out_unlock;
1185*4882a593Smuzhiyun }
1186*4882a593Smuzhiyun break;
1187*4882a593Smuzhiyun case IOMAP_ZERO:
1188*4882a593Smuzhiyun if (iomap->type == IOMAP_HOLE)
1189*4882a593Smuzhiyun goto out_unlock;
1190*4882a593Smuzhiyun break;
1191*4882a593Smuzhiyun default:
1192*4882a593Smuzhiyun goto out_unlock;
1193*4882a593Smuzhiyun }
1194*4882a593Smuzhiyun
1195*4882a593Smuzhiyun ret = gfs2_iomap_begin_write(inode, pos, length, flags, iomap, &mp);
1196*4882a593Smuzhiyun
1197*4882a593Smuzhiyun out_unlock:
1198*4882a593Smuzhiyun if (ret && gfs2_iomap_need_write_lock(flags))
1199*4882a593Smuzhiyun gfs2_write_unlock(inode);
1200*4882a593Smuzhiyun release_metapath(&mp);
1201*4882a593Smuzhiyun out:
1202*4882a593Smuzhiyun trace_gfs2_iomap_end(ip, iomap, ret);
1203*4882a593Smuzhiyun return ret;
1204*4882a593Smuzhiyun }
1205*4882a593Smuzhiyun
gfs2_iomap_end(struct inode * inode,loff_t pos,loff_t length,ssize_t written,unsigned flags,struct iomap * iomap)1206*4882a593Smuzhiyun static int gfs2_iomap_end(struct inode *inode, loff_t pos, loff_t length,
1207*4882a593Smuzhiyun ssize_t written, unsigned flags, struct iomap *iomap)
1208*4882a593Smuzhiyun {
1209*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
1210*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(inode);
1211*4882a593Smuzhiyun
1212*4882a593Smuzhiyun switch (flags & (IOMAP_WRITE | IOMAP_ZERO)) {
1213*4882a593Smuzhiyun case IOMAP_WRITE:
1214*4882a593Smuzhiyun if (flags & IOMAP_DIRECT)
1215*4882a593Smuzhiyun return 0;
1216*4882a593Smuzhiyun break;
1217*4882a593Smuzhiyun case IOMAP_ZERO:
1218*4882a593Smuzhiyun if (iomap->type == IOMAP_HOLE)
1219*4882a593Smuzhiyun return 0;
1220*4882a593Smuzhiyun break;
1221*4882a593Smuzhiyun default:
1222*4882a593Smuzhiyun return 0;
1223*4882a593Smuzhiyun }
1224*4882a593Smuzhiyun
1225*4882a593Smuzhiyun if (!gfs2_is_stuffed(ip))
1226*4882a593Smuzhiyun gfs2_ordered_add_inode(ip);
1227*4882a593Smuzhiyun
1228*4882a593Smuzhiyun if (inode == sdp->sd_rindex)
1229*4882a593Smuzhiyun adjust_fs_space(inode);
1230*4882a593Smuzhiyun
1231*4882a593Smuzhiyun gfs2_inplace_release(ip);
1232*4882a593Smuzhiyun
1233*4882a593Smuzhiyun if (ip->i_qadata && ip->i_qadata->qa_qd_num)
1234*4882a593Smuzhiyun gfs2_quota_unlock(ip);
1235*4882a593Smuzhiyun
1236*4882a593Smuzhiyun if (length != written && (iomap->flags & IOMAP_F_NEW)) {
1237*4882a593Smuzhiyun /* Deallocate blocks that were just allocated. */
1238*4882a593Smuzhiyun loff_t hstart = round_up(pos + written, i_blocksize(inode));
1239*4882a593Smuzhiyun loff_t hend = iomap->offset + iomap->length;
1240*4882a593Smuzhiyun
1241*4882a593Smuzhiyun if (hstart < hend) {
1242*4882a593Smuzhiyun truncate_pagecache_range(inode, hstart, hend - 1);
1243*4882a593Smuzhiyun punch_hole(ip, hstart, hend - hstart);
1244*4882a593Smuzhiyun }
1245*4882a593Smuzhiyun }
1246*4882a593Smuzhiyun
1247*4882a593Smuzhiyun if (unlikely(!written))
1248*4882a593Smuzhiyun goto out_unlock;
1249*4882a593Smuzhiyun
1250*4882a593Smuzhiyun if (iomap->flags & IOMAP_F_SIZE_CHANGED)
1251*4882a593Smuzhiyun mark_inode_dirty(inode);
1252*4882a593Smuzhiyun set_bit(GLF_DIRTY, &ip->i_gl->gl_flags);
1253*4882a593Smuzhiyun
1254*4882a593Smuzhiyun out_unlock:
1255*4882a593Smuzhiyun if (gfs2_iomap_need_write_lock(flags))
1256*4882a593Smuzhiyun gfs2_write_unlock(inode);
1257*4882a593Smuzhiyun return 0;
1258*4882a593Smuzhiyun }
1259*4882a593Smuzhiyun
1260*4882a593Smuzhiyun const struct iomap_ops gfs2_iomap_ops = {
1261*4882a593Smuzhiyun .iomap_begin = gfs2_iomap_begin,
1262*4882a593Smuzhiyun .iomap_end = gfs2_iomap_end,
1263*4882a593Smuzhiyun };
1264*4882a593Smuzhiyun
1265*4882a593Smuzhiyun /**
1266*4882a593Smuzhiyun * gfs2_block_map - Map one or more blocks of an inode to a disk block
1267*4882a593Smuzhiyun * @inode: The inode
1268*4882a593Smuzhiyun * @lblock: The logical block number
1269*4882a593Smuzhiyun * @bh_map: The bh to be mapped
1270*4882a593Smuzhiyun * @create: True if its ok to alloc blocks to satify the request
1271*4882a593Smuzhiyun *
1272*4882a593Smuzhiyun * The size of the requested mapping is defined in bh_map->b_size.
1273*4882a593Smuzhiyun *
1274*4882a593Smuzhiyun * Clears buffer_mapped(bh_map) and leaves bh_map->b_size unchanged
1275*4882a593Smuzhiyun * when @lblock is not mapped. Sets buffer_mapped(bh_map) and
1276*4882a593Smuzhiyun * bh_map->b_size to indicate the size of the mapping when @lblock and
1277*4882a593Smuzhiyun * successive blocks are mapped, up to the requested size.
1278*4882a593Smuzhiyun *
1279*4882a593Smuzhiyun * Sets buffer_boundary() if a read of metadata will be required
1280*4882a593Smuzhiyun * before the next block can be mapped. Sets buffer_new() if new
1281*4882a593Smuzhiyun * blocks were allocated.
1282*4882a593Smuzhiyun *
1283*4882a593Smuzhiyun * Returns: errno
1284*4882a593Smuzhiyun */
1285*4882a593Smuzhiyun
gfs2_block_map(struct inode * inode,sector_t lblock,struct buffer_head * bh_map,int create)1286*4882a593Smuzhiyun int gfs2_block_map(struct inode *inode, sector_t lblock,
1287*4882a593Smuzhiyun struct buffer_head *bh_map, int create)
1288*4882a593Smuzhiyun {
1289*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
1290*4882a593Smuzhiyun loff_t pos = (loff_t)lblock << inode->i_blkbits;
1291*4882a593Smuzhiyun loff_t length = bh_map->b_size;
1292*4882a593Smuzhiyun struct metapath mp = { .mp_aheight = 1, };
1293*4882a593Smuzhiyun struct iomap iomap = { };
1294*4882a593Smuzhiyun int flags = create ? IOMAP_WRITE : 0;
1295*4882a593Smuzhiyun int ret;
1296*4882a593Smuzhiyun
1297*4882a593Smuzhiyun clear_buffer_mapped(bh_map);
1298*4882a593Smuzhiyun clear_buffer_new(bh_map);
1299*4882a593Smuzhiyun clear_buffer_boundary(bh_map);
1300*4882a593Smuzhiyun trace_gfs2_bmap(ip, bh_map, lblock, create, 1);
1301*4882a593Smuzhiyun
1302*4882a593Smuzhiyun ret = gfs2_iomap_get(inode, pos, length, flags, &iomap, &mp);
1303*4882a593Smuzhiyun if (create && !ret && iomap.type == IOMAP_HOLE)
1304*4882a593Smuzhiyun ret = gfs2_iomap_alloc(inode, &iomap, &mp);
1305*4882a593Smuzhiyun release_metapath(&mp);
1306*4882a593Smuzhiyun if (ret)
1307*4882a593Smuzhiyun goto out;
1308*4882a593Smuzhiyun
1309*4882a593Smuzhiyun if (iomap.length > bh_map->b_size) {
1310*4882a593Smuzhiyun iomap.length = bh_map->b_size;
1311*4882a593Smuzhiyun iomap.flags &= ~IOMAP_F_GFS2_BOUNDARY;
1312*4882a593Smuzhiyun }
1313*4882a593Smuzhiyun if (iomap.addr != IOMAP_NULL_ADDR)
1314*4882a593Smuzhiyun map_bh(bh_map, inode->i_sb, iomap.addr >> inode->i_blkbits);
1315*4882a593Smuzhiyun bh_map->b_size = iomap.length;
1316*4882a593Smuzhiyun if (iomap.flags & IOMAP_F_GFS2_BOUNDARY)
1317*4882a593Smuzhiyun set_buffer_boundary(bh_map);
1318*4882a593Smuzhiyun if (iomap.flags & IOMAP_F_NEW)
1319*4882a593Smuzhiyun set_buffer_new(bh_map);
1320*4882a593Smuzhiyun
1321*4882a593Smuzhiyun out:
1322*4882a593Smuzhiyun trace_gfs2_bmap(ip, bh_map, lblock, create, ret);
1323*4882a593Smuzhiyun return ret;
1324*4882a593Smuzhiyun }
1325*4882a593Smuzhiyun
1326*4882a593Smuzhiyun /*
1327*4882a593Smuzhiyun * Deprecated: do not use in new code
1328*4882a593Smuzhiyun */
gfs2_extent_map(struct inode * inode,u64 lblock,int * new,u64 * dblock,unsigned * extlen)1329*4882a593Smuzhiyun int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen)
1330*4882a593Smuzhiyun {
1331*4882a593Smuzhiyun struct buffer_head bh = { .b_state = 0, .b_blocknr = 0 };
1332*4882a593Smuzhiyun int ret;
1333*4882a593Smuzhiyun int create = *new;
1334*4882a593Smuzhiyun
1335*4882a593Smuzhiyun BUG_ON(!extlen);
1336*4882a593Smuzhiyun BUG_ON(!dblock);
1337*4882a593Smuzhiyun BUG_ON(!new);
1338*4882a593Smuzhiyun
1339*4882a593Smuzhiyun bh.b_size = BIT(inode->i_blkbits + (create ? 0 : 5));
1340*4882a593Smuzhiyun ret = gfs2_block_map(inode, lblock, &bh, create);
1341*4882a593Smuzhiyun *extlen = bh.b_size >> inode->i_blkbits;
1342*4882a593Smuzhiyun *dblock = bh.b_blocknr;
1343*4882a593Smuzhiyun if (buffer_new(&bh))
1344*4882a593Smuzhiyun *new = 1;
1345*4882a593Smuzhiyun else
1346*4882a593Smuzhiyun *new = 0;
1347*4882a593Smuzhiyun return ret;
1348*4882a593Smuzhiyun }
1349*4882a593Smuzhiyun
1350*4882a593Smuzhiyun /*
1351*4882a593Smuzhiyun * NOTE: Never call gfs2_block_zero_range with an open transaction because it
1352*4882a593Smuzhiyun * uses iomap write to perform its actions, which begin their own transactions
1353*4882a593Smuzhiyun * (iomap_begin, page_prepare, etc.)
1354*4882a593Smuzhiyun */
gfs2_block_zero_range(struct inode * inode,loff_t from,unsigned int length)1355*4882a593Smuzhiyun static int gfs2_block_zero_range(struct inode *inode, loff_t from,
1356*4882a593Smuzhiyun unsigned int length)
1357*4882a593Smuzhiyun {
1358*4882a593Smuzhiyun BUG_ON(current->journal_info);
1359*4882a593Smuzhiyun return iomap_zero_range(inode, from, length, NULL, &gfs2_iomap_ops);
1360*4882a593Smuzhiyun }
1361*4882a593Smuzhiyun
1362*4882a593Smuzhiyun #define GFS2_JTRUNC_REVOKES 8192
1363*4882a593Smuzhiyun
1364*4882a593Smuzhiyun /**
1365*4882a593Smuzhiyun * gfs2_journaled_truncate - Wrapper for truncate_pagecache for jdata files
1366*4882a593Smuzhiyun * @inode: The inode being truncated
1367*4882a593Smuzhiyun * @oldsize: The original (larger) size
1368*4882a593Smuzhiyun * @newsize: The new smaller size
1369*4882a593Smuzhiyun *
1370*4882a593Smuzhiyun * With jdata files, we have to journal a revoke for each block which is
1371*4882a593Smuzhiyun * truncated. As a result, we need to split this into separate transactions
1372*4882a593Smuzhiyun * if the number of pages being truncated gets too large.
1373*4882a593Smuzhiyun */
1374*4882a593Smuzhiyun
gfs2_journaled_truncate(struct inode * inode,u64 oldsize,u64 newsize)1375*4882a593Smuzhiyun static int gfs2_journaled_truncate(struct inode *inode, u64 oldsize, u64 newsize)
1376*4882a593Smuzhiyun {
1377*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(inode);
1378*4882a593Smuzhiyun u64 max_chunk = GFS2_JTRUNC_REVOKES * sdp->sd_vfs->s_blocksize;
1379*4882a593Smuzhiyun u64 chunk;
1380*4882a593Smuzhiyun int error;
1381*4882a593Smuzhiyun
1382*4882a593Smuzhiyun while (oldsize != newsize) {
1383*4882a593Smuzhiyun struct gfs2_trans *tr;
1384*4882a593Smuzhiyun unsigned int offs;
1385*4882a593Smuzhiyun
1386*4882a593Smuzhiyun chunk = oldsize - newsize;
1387*4882a593Smuzhiyun if (chunk > max_chunk)
1388*4882a593Smuzhiyun chunk = max_chunk;
1389*4882a593Smuzhiyun
1390*4882a593Smuzhiyun offs = oldsize & ~PAGE_MASK;
1391*4882a593Smuzhiyun if (offs && chunk > PAGE_SIZE)
1392*4882a593Smuzhiyun chunk = offs + ((chunk - offs) & PAGE_MASK);
1393*4882a593Smuzhiyun
1394*4882a593Smuzhiyun truncate_pagecache(inode, oldsize - chunk);
1395*4882a593Smuzhiyun oldsize -= chunk;
1396*4882a593Smuzhiyun
1397*4882a593Smuzhiyun tr = current->journal_info;
1398*4882a593Smuzhiyun if (!test_bit(TR_TOUCHED, &tr->tr_flags))
1399*4882a593Smuzhiyun continue;
1400*4882a593Smuzhiyun
1401*4882a593Smuzhiyun gfs2_trans_end(sdp);
1402*4882a593Smuzhiyun error = gfs2_trans_begin(sdp, RES_DINODE, GFS2_JTRUNC_REVOKES);
1403*4882a593Smuzhiyun if (error)
1404*4882a593Smuzhiyun return error;
1405*4882a593Smuzhiyun }
1406*4882a593Smuzhiyun
1407*4882a593Smuzhiyun return 0;
1408*4882a593Smuzhiyun }
1409*4882a593Smuzhiyun
trunc_start(struct inode * inode,u64 newsize)1410*4882a593Smuzhiyun static int trunc_start(struct inode *inode, u64 newsize)
1411*4882a593Smuzhiyun {
1412*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
1413*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(inode);
1414*4882a593Smuzhiyun struct buffer_head *dibh = NULL;
1415*4882a593Smuzhiyun int journaled = gfs2_is_jdata(ip);
1416*4882a593Smuzhiyun u64 oldsize = inode->i_size;
1417*4882a593Smuzhiyun int error;
1418*4882a593Smuzhiyun
1419*4882a593Smuzhiyun if (!gfs2_is_stuffed(ip)) {
1420*4882a593Smuzhiyun unsigned int blocksize = i_blocksize(inode);
1421*4882a593Smuzhiyun unsigned int offs = newsize & (blocksize - 1);
1422*4882a593Smuzhiyun if (offs) {
1423*4882a593Smuzhiyun error = gfs2_block_zero_range(inode, newsize,
1424*4882a593Smuzhiyun blocksize - offs);
1425*4882a593Smuzhiyun if (error)
1426*4882a593Smuzhiyun return error;
1427*4882a593Smuzhiyun }
1428*4882a593Smuzhiyun }
1429*4882a593Smuzhiyun if (journaled)
1430*4882a593Smuzhiyun error = gfs2_trans_begin(sdp, RES_DINODE + RES_JDATA, GFS2_JTRUNC_REVOKES);
1431*4882a593Smuzhiyun else
1432*4882a593Smuzhiyun error = gfs2_trans_begin(sdp, RES_DINODE, 0);
1433*4882a593Smuzhiyun if (error)
1434*4882a593Smuzhiyun return error;
1435*4882a593Smuzhiyun
1436*4882a593Smuzhiyun error = gfs2_meta_inode_buffer(ip, &dibh);
1437*4882a593Smuzhiyun if (error)
1438*4882a593Smuzhiyun goto out;
1439*4882a593Smuzhiyun
1440*4882a593Smuzhiyun gfs2_trans_add_meta(ip->i_gl, dibh);
1441*4882a593Smuzhiyun
1442*4882a593Smuzhiyun if (gfs2_is_stuffed(ip))
1443*4882a593Smuzhiyun gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + newsize);
1444*4882a593Smuzhiyun else
1445*4882a593Smuzhiyun ip->i_diskflags |= GFS2_DIF_TRUNC_IN_PROG;
1446*4882a593Smuzhiyun
1447*4882a593Smuzhiyun i_size_write(inode, newsize);
1448*4882a593Smuzhiyun ip->i_inode.i_mtime = ip->i_inode.i_ctime = current_time(&ip->i_inode);
1449*4882a593Smuzhiyun gfs2_dinode_out(ip, dibh->b_data);
1450*4882a593Smuzhiyun
1451*4882a593Smuzhiyun if (journaled)
1452*4882a593Smuzhiyun error = gfs2_journaled_truncate(inode, oldsize, newsize);
1453*4882a593Smuzhiyun else
1454*4882a593Smuzhiyun truncate_pagecache(inode, newsize);
1455*4882a593Smuzhiyun
1456*4882a593Smuzhiyun out:
1457*4882a593Smuzhiyun brelse(dibh);
1458*4882a593Smuzhiyun if (current->journal_info)
1459*4882a593Smuzhiyun gfs2_trans_end(sdp);
1460*4882a593Smuzhiyun return error;
1461*4882a593Smuzhiyun }
1462*4882a593Smuzhiyun
gfs2_iomap_get_alloc(struct inode * inode,loff_t pos,loff_t length,struct iomap * iomap)1463*4882a593Smuzhiyun int gfs2_iomap_get_alloc(struct inode *inode, loff_t pos, loff_t length,
1464*4882a593Smuzhiyun struct iomap *iomap)
1465*4882a593Smuzhiyun {
1466*4882a593Smuzhiyun struct metapath mp = { .mp_aheight = 1, };
1467*4882a593Smuzhiyun int ret;
1468*4882a593Smuzhiyun
1469*4882a593Smuzhiyun ret = gfs2_iomap_get(inode, pos, length, IOMAP_WRITE, iomap, &mp);
1470*4882a593Smuzhiyun if (!ret && iomap->type == IOMAP_HOLE)
1471*4882a593Smuzhiyun ret = gfs2_iomap_alloc(inode, iomap, &mp);
1472*4882a593Smuzhiyun release_metapath(&mp);
1473*4882a593Smuzhiyun return ret;
1474*4882a593Smuzhiyun }
1475*4882a593Smuzhiyun
1476*4882a593Smuzhiyun /**
1477*4882a593Smuzhiyun * sweep_bh_for_rgrps - find an rgrp in a meta buffer and free blocks therein
1478*4882a593Smuzhiyun * @ip: inode
1479*4882a593Smuzhiyun * @rg_gh: holder of resource group glock
1480*4882a593Smuzhiyun * @bh: buffer head to sweep
1481*4882a593Smuzhiyun * @start: starting point in bh
1482*4882a593Smuzhiyun * @end: end point in bh
1483*4882a593Smuzhiyun * @meta: true if bh points to metadata (rather than data)
1484*4882a593Smuzhiyun * @btotal: place to keep count of total blocks freed
1485*4882a593Smuzhiyun *
1486*4882a593Smuzhiyun * We sweep a metadata buffer (provided by the metapath) for blocks we need to
1487*4882a593Smuzhiyun * free, and free them all. However, we do it one rgrp at a time. If this
1488*4882a593Smuzhiyun * block has references to multiple rgrps, we break it into individual
1489*4882a593Smuzhiyun * transactions. This allows other processes to use the rgrps while we're
1490*4882a593Smuzhiyun * focused on a single one, for better concurrency / performance.
1491*4882a593Smuzhiyun * At every transaction boundary, we rewrite the inode into the journal.
1492*4882a593Smuzhiyun * That way the bitmaps are kept consistent with the inode and we can recover
1493*4882a593Smuzhiyun * if we're interrupted by power-outages.
1494*4882a593Smuzhiyun *
1495*4882a593Smuzhiyun * Returns: 0, or return code if an error occurred.
1496*4882a593Smuzhiyun * *btotal has the total number of blocks freed
1497*4882a593Smuzhiyun */
sweep_bh_for_rgrps(struct gfs2_inode * ip,struct gfs2_holder * rd_gh,struct buffer_head * bh,__be64 * start,__be64 * end,bool meta,u32 * btotal)1498*4882a593Smuzhiyun static int sweep_bh_for_rgrps(struct gfs2_inode *ip, struct gfs2_holder *rd_gh,
1499*4882a593Smuzhiyun struct buffer_head *bh, __be64 *start, __be64 *end,
1500*4882a593Smuzhiyun bool meta, u32 *btotal)
1501*4882a593Smuzhiyun {
1502*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1503*4882a593Smuzhiyun struct gfs2_rgrpd *rgd;
1504*4882a593Smuzhiyun struct gfs2_trans *tr;
1505*4882a593Smuzhiyun __be64 *p;
1506*4882a593Smuzhiyun int blks_outside_rgrp;
1507*4882a593Smuzhiyun u64 bn, bstart, isize_blks;
1508*4882a593Smuzhiyun s64 blen; /* needs to be s64 or gfs2_add_inode_blocks breaks */
1509*4882a593Smuzhiyun int ret = 0;
1510*4882a593Smuzhiyun bool buf_in_tr = false; /* buffer was added to transaction */
1511*4882a593Smuzhiyun
1512*4882a593Smuzhiyun more_rgrps:
1513*4882a593Smuzhiyun rgd = NULL;
1514*4882a593Smuzhiyun if (gfs2_holder_initialized(rd_gh)) {
1515*4882a593Smuzhiyun rgd = gfs2_glock2rgrp(rd_gh->gh_gl);
1516*4882a593Smuzhiyun gfs2_assert_withdraw(sdp,
1517*4882a593Smuzhiyun gfs2_glock_is_locked_by_me(rd_gh->gh_gl));
1518*4882a593Smuzhiyun }
1519*4882a593Smuzhiyun blks_outside_rgrp = 0;
1520*4882a593Smuzhiyun bstart = 0;
1521*4882a593Smuzhiyun blen = 0;
1522*4882a593Smuzhiyun
1523*4882a593Smuzhiyun for (p = start; p < end; p++) {
1524*4882a593Smuzhiyun if (!*p)
1525*4882a593Smuzhiyun continue;
1526*4882a593Smuzhiyun bn = be64_to_cpu(*p);
1527*4882a593Smuzhiyun
1528*4882a593Smuzhiyun if (rgd) {
1529*4882a593Smuzhiyun if (!rgrp_contains_block(rgd, bn)) {
1530*4882a593Smuzhiyun blks_outside_rgrp++;
1531*4882a593Smuzhiyun continue;
1532*4882a593Smuzhiyun }
1533*4882a593Smuzhiyun } else {
1534*4882a593Smuzhiyun rgd = gfs2_blk2rgrpd(sdp, bn, true);
1535*4882a593Smuzhiyun if (unlikely(!rgd)) {
1536*4882a593Smuzhiyun ret = -EIO;
1537*4882a593Smuzhiyun goto out;
1538*4882a593Smuzhiyun }
1539*4882a593Smuzhiyun ret = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE,
1540*4882a593Smuzhiyun 0, rd_gh);
1541*4882a593Smuzhiyun if (ret)
1542*4882a593Smuzhiyun goto out;
1543*4882a593Smuzhiyun
1544*4882a593Smuzhiyun /* Must be done with the rgrp glock held: */
1545*4882a593Smuzhiyun if (gfs2_rs_active(&ip->i_res) &&
1546*4882a593Smuzhiyun rgd == ip->i_res.rs_rbm.rgd)
1547*4882a593Smuzhiyun gfs2_rs_deltree(&ip->i_res);
1548*4882a593Smuzhiyun }
1549*4882a593Smuzhiyun
1550*4882a593Smuzhiyun /* The size of our transactions will be unknown until we
1551*4882a593Smuzhiyun actually process all the metadata blocks that relate to
1552*4882a593Smuzhiyun the rgrp. So we estimate. We know it can't be more than
1553*4882a593Smuzhiyun the dinode's i_blocks and we don't want to exceed the
1554*4882a593Smuzhiyun journal flush threshold, sd_log_thresh2. */
1555*4882a593Smuzhiyun if (current->journal_info == NULL) {
1556*4882a593Smuzhiyun unsigned int jblocks_rqsted, revokes;
1557*4882a593Smuzhiyun
1558*4882a593Smuzhiyun jblocks_rqsted = rgd->rd_length + RES_DINODE +
1559*4882a593Smuzhiyun RES_INDIRECT;
1560*4882a593Smuzhiyun isize_blks = gfs2_get_inode_blocks(&ip->i_inode);
1561*4882a593Smuzhiyun if (isize_blks > atomic_read(&sdp->sd_log_thresh2))
1562*4882a593Smuzhiyun jblocks_rqsted +=
1563*4882a593Smuzhiyun atomic_read(&sdp->sd_log_thresh2);
1564*4882a593Smuzhiyun else
1565*4882a593Smuzhiyun jblocks_rqsted += isize_blks;
1566*4882a593Smuzhiyun revokes = jblocks_rqsted;
1567*4882a593Smuzhiyun if (meta)
1568*4882a593Smuzhiyun revokes += end - start;
1569*4882a593Smuzhiyun else if (ip->i_depth)
1570*4882a593Smuzhiyun revokes += sdp->sd_inptrs;
1571*4882a593Smuzhiyun ret = gfs2_trans_begin(sdp, jblocks_rqsted, revokes);
1572*4882a593Smuzhiyun if (ret)
1573*4882a593Smuzhiyun goto out_unlock;
1574*4882a593Smuzhiyun down_write(&ip->i_rw_mutex);
1575*4882a593Smuzhiyun }
1576*4882a593Smuzhiyun /* check if we will exceed the transaction blocks requested */
1577*4882a593Smuzhiyun tr = current->journal_info;
1578*4882a593Smuzhiyun if (tr->tr_num_buf_new + RES_STATFS +
1579*4882a593Smuzhiyun RES_QUOTA >= atomic_read(&sdp->sd_log_thresh2)) {
1580*4882a593Smuzhiyun /* We set blks_outside_rgrp to ensure the loop will
1581*4882a593Smuzhiyun be repeated for the same rgrp, but with a new
1582*4882a593Smuzhiyun transaction. */
1583*4882a593Smuzhiyun blks_outside_rgrp++;
1584*4882a593Smuzhiyun /* This next part is tricky. If the buffer was added
1585*4882a593Smuzhiyun to the transaction, we've already set some block
1586*4882a593Smuzhiyun pointers to 0, so we better follow through and free
1587*4882a593Smuzhiyun them, or we will introduce corruption (so break).
1588*4882a593Smuzhiyun This may be impossible, or at least rare, but I
1589*4882a593Smuzhiyun decided to cover the case regardless.
1590*4882a593Smuzhiyun
1591*4882a593Smuzhiyun If the buffer was not added to the transaction
1592*4882a593Smuzhiyun (this call), doing so would exceed our transaction
1593*4882a593Smuzhiyun size, so we need to end the transaction and start a
1594*4882a593Smuzhiyun new one (so goto). */
1595*4882a593Smuzhiyun
1596*4882a593Smuzhiyun if (buf_in_tr)
1597*4882a593Smuzhiyun break;
1598*4882a593Smuzhiyun goto out_unlock;
1599*4882a593Smuzhiyun }
1600*4882a593Smuzhiyun
1601*4882a593Smuzhiyun gfs2_trans_add_meta(ip->i_gl, bh);
1602*4882a593Smuzhiyun buf_in_tr = true;
1603*4882a593Smuzhiyun *p = 0;
1604*4882a593Smuzhiyun if (bstart + blen == bn) {
1605*4882a593Smuzhiyun blen++;
1606*4882a593Smuzhiyun continue;
1607*4882a593Smuzhiyun }
1608*4882a593Smuzhiyun if (bstart) {
1609*4882a593Smuzhiyun __gfs2_free_blocks(ip, rgd, bstart, (u32)blen, meta);
1610*4882a593Smuzhiyun (*btotal) += blen;
1611*4882a593Smuzhiyun gfs2_add_inode_blocks(&ip->i_inode, -blen);
1612*4882a593Smuzhiyun }
1613*4882a593Smuzhiyun bstart = bn;
1614*4882a593Smuzhiyun blen = 1;
1615*4882a593Smuzhiyun }
1616*4882a593Smuzhiyun if (bstart) {
1617*4882a593Smuzhiyun __gfs2_free_blocks(ip, rgd, bstart, (u32)blen, meta);
1618*4882a593Smuzhiyun (*btotal) += blen;
1619*4882a593Smuzhiyun gfs2_add_inode_blocks(&ip->i_inode, -blen);
1620*4882a593Smuzhiyun }
1621*4882a593Smuzhiyun out_unlock:
1622*4882a593Smuzhiyun if (!ret && blks_outside_rgrp) { /* If buffer still has non-zero blocks
1623*4882a593Smuzhiyun outside the rgrp we just processed,
1624*4882a593Smuzhiyun do it all over again. */
1625*4882a593Smuzhiyun if (current->journal_info) {
1626*4882a593Smuzhiyun struct buffer_head *dibh;
1627*4882a593Smuzhiyun
1628*4882a593Smuzhiyun ret = gfs2_meta_inode_buffer(ip, &dibh);
1629*4882a593Smuzhiyun if (ret)
1630*4882a593Smuzhiyun goto out;
1631*4882a593Smuzhiyun
1632*4882a593Smuzhiyun /* Every transaction boundary, we rewrite the dinode
1633*4882a593Smuzhiyun to keep its di_blocks current in case of failure. */
1634*4882a593Smuzhiyun ip->i_inode.i_mtime = ip->i_inode.i_ctime =
1635*4882a593Smuzhiyun current_time(&ip->i_inode);
1636*4882a593Smuzhiyun gfs2_trans_add_meta(ip->i_gl, dibh);
1637*4882a593Smuzhiyun gfs2_dinode_out(ip, dibh->b_data);
1638*4882a593Smuzhiyun brelse(dibh);
1639*4882a593Smuzhiyun up_write(&ip->i_rw_mutex);
1640*4882a593Smuzhiyun gfs2_trans_end(sdp);
1641*4882a593Smuzhiyun buf_in_tr = false;
1642*4882a593Smuzhiyun }
1643*4882a593Smuzhiyun gfs2_glock_dq_uninit(rd_gh);
1644*4882a593Smuzhiyun cond_resched();
1645*4882a593Smuzhiyun goto more_rgrps;
1646*4882a593Smuzhiyun }
1647*4882a593Smuzhiyun out:
1648*4882a593Smuzhiyun return ret;
1649*4882a593Smuzhiyun }
1650*4882a593Smuzhiyun
mp_eq_to_hgt(struct metapath * mp,__u16 * list,unsigned int h)1651*4882a593Smuzhiyun static bool mp_eq_to_hgt(struct metapath *mp, __u16 *list, unsigned int h)
1652*4882a593Smuzhiyun {
1653*4882a593Smuzhiyun if (memcmp(mp->mp_list, list, h * sizeof(mp->mp_list[0])))
1654*4882a593Smuzhiyun return false;
1655*4882a593Smuzhiyun return true;
1656*4882a593Smuzhiyun }
1657*4882a593Smuzhiyun
1658*4882a593Smuzhiyun /**
1659*4882a593Smuzhiyun * find_nonnull_ptr - find a non-null pointer given a metapath and height
1660*4882a593Smuzhiyun * @mp: starting metapath
1661*4882a593Smuzhiyun * @h: desired height to search
1662*4882a593Smuzhiyun *
1663*4882a593Smuzhiyun * Assumes the metapath is valid (with buffers) out to height h.
1664*4882a593Smuzhiyun * Returns: true if a non-null pointer was found in the metapath buffer
1665*4882a593Smuzhiyun * false if all remaining pointers are NULL in the buffer
1666*4882a593Smuzhiyun */
find_nonnull_ptr(struct gfs2_sbd * sdp,struct metapath * mp,unsigned int h,__u16 * end_list,unsigned int end_aligned)1667*4882a593Smuzhiyun static bool find_nonnull_ptr(struct gfs2_sbd *sdp, struct metapath *mp,
1668*4882a593Smuzhiyun unsigned int h,
1669*4882a593Smuzhiyun __u16 *end_list, unsigned int end_aligned)
1670*4882a593Smuzhiyun {
1671*4882a593Smuzhiyun struct buffer_head *bh = mp->mp_bh[h];
1672*4882a593Smuzhiyun __be64 *first, *ptr, *end;
1673*4882a593Smuzhiyun
1674*4882a593Smuzhiyun first = metaptr1(h, mp);
1675*4882a593Smuzhiyun ptr = first + mp->mp_list[h];
1676*4882a593Smuzhiyun end = (__be64 *)(bh->b_data + bh->b_size);
1677*4882a593Smuzhiyun if (end_list && mp_eq_to_hgt(mp, end_list, h)) {
1678*4882a593Smuzhiyun bool keep_end = h < end_aligned;
1679*4882a593Smuzhiyun end = first + end_list[h] + keep_end;
1680*4882a593Smuzhiyun }
1681*4882a593Smuzhiyun
1682*4882a593Smuzhiyun while (ptr < end) {
1683*4882a593Smuzhiyun if (*ptr) { /* if we have a non-null pointer */
1684*4882a593Smuzhiyun mp->mp_list[h] = ptr - first;
1685*4882a593Smuzhiyun h++;
1686*4882a593Smuzhiyun if (h < GFS2_MAX_META_HEIGHT)
1687*4882a593Smuzhiyun mp->mp_list[h] = 0;
1688*4882a593Smuzhiyun return true;
1689*4882a593Smuzhiyun }
1690*4882a593Smuzhiyun ptr++;
1691*4882a593Smuzhiyun }
1692*4882a593Smuzhiyun return false;
1693*4882a593Smuzhiyun }
1694*4882a593Smuzhiyun
1695*4882a593Smuzhiyun enum dealloc_states {
1696*4882a593Smuzhiyun DEALLOC_MP_FULL = 0, /* Strip a metapath with all buffers read in */
1697*4882a593Smuzhiyun DEALLOC_MP_LOWER = 1, /* lower the metapath strip height */
1698*4882a593Smuzhiyun DEALLOC_FILL_MP = 2, /* Fill in the metapath to the given height. */
1699*4882a593Smuzhiyun DEALLOC_DONE = 3, /* process complete */
1700*4882a593Smuzhiyun };
1701*4882a593Smuzhiyun
1702*4882a593Smuzhiyun static inline void
metapointer_range(struct metapath * mp,int height,__u16 * start_list,unsigned int start_aligned,__u16 * end_list,unsigned int end_aligned,__be64 ** start,__be64 ** end)1703*4882a593Smuzhiyun metapointer_range(struct metapath *mp, int height,
1704*4882a593Smuzhiyun __u16 *start_list, unsigned int start_aligned,
1705*4882a593Smuzhiyun __u16 *end_list, unsigned int end_aligned,
1706*4882a593Smuzhiyun __be64 **start, __be64 **end)
1707*4882a593Smuzhiyun {
1708*4882a593Smuzhiyun struct buffer_head *bh = mp->mp_bh[height];
1709*4882a593Smuzhiyun __be64 *first;
1710*4882a593Smuzhiyun
1711*4882a593Smuzhiyun first = metaptr1(height, mp);
1712*4882a593Smuzhiyun *start = first;
1713*4882a593Smuzhiyun if (mp_eq_to_hgt(mp, start_list, height)) {
1714*4882a593Smuzhiyun bool keep_start = height < start_aligned;
1715*4882a593Smuzhiyun *start = first + start_list[height] + keep_start;
1716*4882a593Smuzhiyun }
1717*4882a593Smuzhiyun *end = (__be64 *)(bh->b_data + bh->b_size);
1718*4882a593Smuzhiyun if (end_list && mp_eq_to_hgt(mp, end_list, height)) {
1719*4882a593Smuzhiyun bool keep_end = height < end_aligned;
1720*4882a593Smuzhiyun *end = first + end_list[height] + keep_end;
1721*4882a593Smuzhiyun }
1722*4882a593Smuzhiyun }
1723*4882a593Smuzhiyun
walk_done(struct gfs2_sbd * sdp,struct metapath * mp,int height,__u16 * end_list,unsigned int end_aligned)1724*4882a593Smuzhiyun static inline bool walk_done(struct gfs2_sbd *sdp,
1725*4882a593Smuzhiyun struct metapath *mp, int height,
1726*4882a593Smuzhiyun __u16 *end_list, unsigned int end_aligned)
1727*4882a593Smuzhiyun {
1728*4882a593Smuzhiyun __u16 end;
1729*4882a593Smuzhiyun
1730*4882a593Smuzhiyun if (end_list) {
1731*4882a593Smuzhiyun bool keep_end = height < end_aligned;
1732*4882a593Smuzhiyun if (!mp_eq_to_hgt(mp, end_list, height))
1733*4882a593Smuzhiyun return false;
1734*4882a593Smuzhiyun end = end_list[height] + keep_end;
1735*4882a593Smuzhiyun } else
1736*4882a593Smuzhiyun end = (height > 0) ? sdp->sd_inptrs : sdp->sd_diptrs;
1737*4882a593Smuzhiyun return mp->mp_list[height] >= end;
1738*4882a593Smuzhiyun }
1739*4882a593Smuzhiyun
1740*4882a593Smuzhiyun /**
1741*4882a593Smuzhiyun * punch_hole - deallocate blocks in a file
1742*4882a593Smuzhiyun * @ip: inode to truncate
1743*4882a593Smuzhiyun * @offset: the start of the hole
1744*4882a593Smuzhiyun * @length: the size of the hole (or 0 for truncate)
1745*4882a593Smuzhiyun *
1746*4882a593Smuzhiyun * Punch a hole into a file or truncate a file at a given position. This
1747*4882a593Smuzhiyun * function operates in whole blocks (@offset and @length are rounded
1748*4882a593Smuzhiyun * accordingly); partially filled blocks must be cleared otherwise.
1749*4882a593Smuzhiyun *
1750*4882a593Smuzhiyun * This function works from the bottom up, and from the right to the left. In
1751*4882a593Smuzhiyun * other words, it strips off the highest layer (data) before stripping any of
1752*4882a593Smuzhiyun * the metadata. Doing it this way is best in case the operation is interrupted
1753*4882a593Smuzhiyun * by power failure, etc. The dinode is rewritten in every transaction to
1754*4882a593Smuzhiyun * guarantee integrity.
1755*4882a593Smuzhiyun */
punch_hole(struct gfs2_inode * ip,u64 offset,u64 length)1756*4882a593Smuzhiyun static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length)
1757*4882a593Smuzhiyun {
1758*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1759*4882a593Smuzhiyun u64 maxsize = sdp->sd_heightsize[ip->i_height];
1760*4882a593Smuzhiyun struct metapath mp = {};
1761*4882a593Smuzhiyun struct buffer_head *dibh, *bh;
1762*4882a593Smuzhiyun struct gfs2_holder rd_gh;
1763*4882a593Smuzhiyun unsigned int bsize_shift = sdp->sd_sb.sb_bsize_shift;
1764*4882a593Smuzhiyun u64 lblock = (offset + (1 << bsize_shift) - 1) >> bsize_shift;
1765*4882a593Smuzhiyun __u16 start_list[GFS2_MAX_META_HEIGHT];
1766*4882a593Smuzhiyun __u16 __end_list[GFS2_MAX_META_HEIGHT], *end_list = NULL;
1767*4882a593Smuzhiyun unsigned int start_aligned, end_aligned;
1768*4882a593Smuzhiyun unsigned int strip_h = ip->i_height - 1;
1769*4882a593Smuzhiyun u32 btotal = 0;
1770*4882a593Smuzhiyun int ret, state;
1771*4882a593Smuzhiyun int mp_h; /* metapath buffers are read in to this height */
1772*4882a593Smuzhiyun u64 prev_bnr = 0;
1773*4882a593Smuzhiyun __be64 *start, *end;
1774*4882a593Smuzhiyun
1775*4882a593Smuzhiyun if (offset >= maxsize) {
1776*4882a593Smuzhiyun /*
1777*4882a593Smuzhiyun * The starting point lies beyond the allocated meta-data;
1778*4882a593Smuzhiyun * there are no blocks do deallocate.
1779*4882a593Smuzhiyun */
1780*4882a593Smuzhiyun return 0;
1781*4882a593Smuzhiyun }
1782*4882a593Smuzhiyun
1783*4882a593Smuzhiyun /*
1784*4882a593Smuzhiyun * The start position of the hole is defined by lblock, start_list, and
1785*4882a593Smuzhiyun * start_aligned. The end position of the hole is defined by lend,
1786*4882a593Smuzhiyun * end_list, and end_aligned.
1787*4882a593Smuzhiyun *
1788*4882a593Smuzhiyun * start_aligned and end_aligned define down to which height the start
1789*4882a593Smuzhiyun * and end positions are aligned to the metadata tree (i.e., the
1790*4882a593Smuzhiyun * position is a multiple of the metadata granularity at the height
1791*4882a593Smuzhiyun * above). This determines at which heights additional meta pointers
1792*4882a593Smuzhiyun * needs to be preserved for the remaining data.
1793*4882a593Smuzhiyun */
1794*4882a593Smuzhiyun
1795*4882a593Smuzhiyun if (length) {
1796*4882a593Smuzhiyun u64 end_offset = offset + length;
1797*4882a593Smuzhiyun u64 lend;
1798*4882a593Smuzhiyun
1799*4882a593Smuzhiyun /*
1800*4882a593Smuzhiyun * Clip the end at the maximum file size for the given height:
1801*4882a593Smuzhiyun * that's how far the metadata goes; files bigger than that
1802*4882a593Smuzhiyun * will have additional layers of indirection.
1803*4882a593Smuzhiyun */
1804*4882a593Smuzhiyun if (end_offset > maxsize)
1805*4882a593Smuzhiyun end_offset = maxsize;
1806*4882a593Smuzhiyun lend = end_offset >> bsize_shift;
1807*4882a593Smuzhiyun
1808*4882a593Smuzhiyun if (lblock >= lend)
1809*4882a593Smuzhiyun return 0;
1810*4882a593Smuzhiyun
1811*4882a593Smuzhiyun find_metapath(sdp, lend, &mp, ip->i_height);
1812*4882a593Smuzhiyun end_list = __end_list;
1813*4882a593Smuzhiyun memcpy(end_list, mp.mp_list, sizeof(mp.mp_list));
1814*4882a593Smuzhiyun
1815*4882a593Smuzhiyun for (mp_h = ip->i_height - 1; mp_h > 0; mp_h--) {
1816*4882a593Smuzhiyun if (end_list[mp_h])
1817*4882a593Smuzhiyun break;
1818*4882a593Smuzhiyun }
1819*4882a593Smuzhiyun end_aligned = mp_h;
1820*4882a593Smuzhiyun }
1821*4882a593Smuzhiyun
1822*4882a593Smuzhiyun find_metapath(sdp, lblock, &mp, ip->i_height);
1823*4882a593Smuzhiyun memcpy(start_list, mp.mp_list, sizeof(start_list));
1824*4882a593Smuzhiyun
1825*4882a593Smuzhiyun for (mp_h = ip->i_height - 1; mp_h > 0; mp_h--) {
1826*4882a593Smuzhiyun if (start_list[mp_h])
1827*4882a593Smuzhiyun break;
1828*4882a593Smuzhiyun }
1829*4882a593Smuzhiyun start_aligned = mp_h;
1830*4882a593Smuzhiyun
1831*4882a593Smuzhiyun ret = gfs2_meta_inode_buffer(ip, &dibh);
1832*4882a593Smuzhiyun if (ret)
1833*4882a593Smuzhiyun return ret;
1834*4882a593Smuzhiyun
1835*4882a593Smuzhiyun mp.mp_bh[0] = dibh;
1836*4882a593Smuzhiyun ret = lookup_metapath(ip, &mp);
1837*4882a593Smuzhiyun if (ret)
1838*4882a593Smuzhiyun goto out_metapath;
1839*4882a593Smuzhiyun
1840*4882a593Smuzhiyun /* issue read-ahead on metadata */
1841*4882a593Smuzhiyun for (mp_h = 0; mp_h < mp.mp_aheight - 1; mp_h++) {
1842*4882a593Smuzhiyun metapointer_range(&mp, mp_h, start_list, start_aligned,
1843*4882a593Smuzhiyun end_list, end_aligned, &start, &end);
1844*4882a593Smuzhiyun gfs2_metapath_ra(ip->i_gl, start, end);
1845*4882a593Smuzhiyun }
1846*4882a593Smuzhiyun
1847*4882a593Smuzhiyun if (mp.mp_aheight == ip->i_height)
1848*4882a593Smuzhiyun state = DEALLOC_MP_FULL; /* We have a complete metapath */
1849*4882a593Smuzhiyun else
1850*4882a593Smuzhiyun state = DEALLOC_FILL_MP; /* deal with partial metapath */
1851*4882a593Smuzhiyun
1852*4882a593Smuzhiyun ret = gfs2_rindex_update(sdp);
1853*4882a593Smuzhiyun if (ret)
1854*4882a593Smuzhiyun goto out_metapath;
1855*4882a593Smuzhiyun
1856*4882a593Smuzhiyun ret = gfs2_quota_hold(ip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
1857*4882a593Smuzhiyun if (ret)
1858*4882a593Smuzhiyun goto out_metapath;
1859*4882a593Smuzhiyun gfs2_holder_mark_uninitialized(&rd_gh);
1860*4882a593Smuzhiyun
1861*4882a593Smuzhiyun mp_h = strip_h;
1862*4882a593Smuzhiyun
1863*4882a593Smuzhiyun while (state != DEALLOC_DONE) {
1864*4882a593Smuzhiyun switch (state) {
1865*4882a593Smuzhiyun /* Truncate a full metapath at the given strip height.
1866*4882a593Smuzhiyun * Note that strip_h == mp_h in order to be in this state. */
1867*4882a593Smuzhiyun case DEALLOC_MP_FULL:
1868*4882a593Smuzhiyun bh = mp.mp_bh[mp_h];
1869*4882a593Smuzhiyun gfs2_assert_withdraw(sdp, bh);
1870*4882a593Smuzhiyun if (gfs2_assert_withdraw(sdp,
1871*4882a593Smuzhiyun prev_bnr != bh->b_blocknr)) {
1872*4882a593Smuzhiyun fs_emerg(sdp, "inode %llu, block:%llu, i_h:%u,"
1873*4882a593Smuzhiyun "s_h:%u, mp_h:%u\n",
1874*4882a593Smuzhiyun (unsigned long long)ip->i_no_addr,
1875*4882a593Smuzhiyun prev_bnr, ip->i_height, strip_h, mp_h);
1876*4882a593Smuzhiyun }
1877*4882a593Smuzhiyun prev_bnr = bh->b_blocknr;
1878*4882a593Smuzhiyun
1879*4882a593Smuzhiyun if (gfs2_metatype_check(sdp, bh,
1880*4882a593Smuzhiyun (mp_h ? GFS2_METATYPE_IN :
1881*4882a593Smuzhiyun GFS2_METATYPE_DI))) {
1882*4882a593Smuzhiyun ret = -EIO;
1883*4882a593Smuzhiyun goto out;
1884*4882a593Smuzhiyun }
1885*4882a593Smuzhiyun
1886*4882a593Smuzhiyun /*
1887*4882a593Smuzhiyun * Below, passing end_aligned as 0 gives us the
1888*4882a593Smuzhiyun * metapointer range excluding the end point: the end
1889*4882a593Smuzhiyun * point is the first metapath we must not deallocate!
1890*4882a593Smuzhiyun */
1891*4882a593Smuzhiyun
1892*4882a593Smuzhiyun metapointer_range(&mp, mp_h, start_list, start_aligned,
1893*4882a593Smuzhiyun end_list, 0 /* end_aligned */,
1894*4882a593Smuzhiyun &start, &end);
1895*4882a593Smuzhiyun ret = sweep_bh_for_rgrps(ip, &rd_gh, mp.mp_bh[mp_h],
1896*4882a593Smuzhiyun start, end,
1897*4882a593Smuzhiyun mp_h != ip->i_height - 1,
1898*4882a593Smuzhiyun &btotal);
1899*4882a593Smuzhiyun
1900*4882a593Smuzhiyun /* If we hit an error or just swept dinode buffer,
1901*4882a593Smuzhiyun just exit. */
1902*4882a593Smuzhiyun if (ret || !mp_h) {
1903*4882a593Smuzhiyun state = DEALLOC_DONE;
1904*4882a593Smuzhiyun break;
1905*4882a593Smuzhiyun }
1906*4882a593Smuzhiyun state = DEALLOC_MP_LOWER;
1907*4882a593Smuzhiyun break;
1908*4882a593Smuzhiyun
1909*4882a593Smuzhiyun /* lower the metapath strip height */
1910*4882a593Smuzhiyun case DEALLOC_MP_LOWER:
1911*4882a593Smuzhiyun /* We're done with the current buffer, so release it,
1912*4882a593Smuzhiyun unless it's the dinode buffer. Then back up to the
1913*4882a593Smuzhiyun previous pointer. */
1914*4882a593Smuzhiyun if (mp_h) {
1915*4882a593Smuzhiyun brelse(mp.mp_bh[mp_h]);
1916*4882a593Smuzhiyun mp.mp_bh[mp_h] = NULL;
1917*4882a593Smuzhiyun }
1918*4882a593Smuzhiyun /* If we can't get any lower in height, we've stripped
1919*4882a593Smuzhiyun off all we can. Next step is to back up and start
1920*4882a593Smuzhiyun stripping the previous level of metadata. */
1921*4882a593Smuzhiyun if (mp_h == 0) {
1922*4882a593Smuzhiyun strip_h--;
1923*4882a593Smuzhiyun memcpy(mp.mp_list, start_list, sizeof(start_list));
1924*4882a593Smuzhiyun mp_h = strip_h;
1925*4882a593Smuzhiyun state = DEALLOC_FILL_MP;
1926*4882a593Smuzhiyun break;
1927*4882a593Smuzhiyun }
1928*4882a593Smuzhiyun mp.mp_list[mp_h] = 0;
1929*4882a593Smuzhiyun mp_h--; /* search one metadata height down */
1930*4882a593Smuzhiyun mp.mp_list[mp_h]++;
1931*4882a593Smuzhiyun if (walk_done(sdp, &mp, mp_h, end_list, end_aligned))
1932*4882a593Smuzhiyun break;
1933*4882a593Smuzhiyun /* Here we've found a part of the metapath that is not
1934*4882a593Smuzhiyun * allocated. We need to search at that height for the
1935*4882a593Smuzhiyun * next non-null pointer. */
1936*4882a593Smuzhiyun if (find_nonnull_ptr(sdp, &mp, mp_h, end_list, end_aligned)) {
1937*4882a593Smuzhiyun state = DEALLOC_FILL_MP;
1938*4882a593Smuzhiyun mp_h++;
1939*4882a593Smuzhiyun }
1940*4882a593Smuzhiyun /* No more non-null pointers at this height. Back up
1941*4882a593Smuzhiyun to the previous height and try again. */
1942*4882a593Smuzhiyun break; /* loop around in the same state */
1943*4882a593Smuzhiyun
1944*4882a593Smuzhiyun /* Fill the metapath with buffers to the given height. */
1945*4882a593Smuzhiyun case DEALLOC_FILL_MP:
1946*4882a593Smuzhiyun /* Fill the buffers out to the current height. */
1947*4882a593Smuzhiyun ret = fillup_metapath(ip, &mp, mp_h);
1948*4882a593Smuzhiyun if (ret < 0)
1949*4882a593Smuzhiyun goto out;
1950*4882a593Smuzhiyun
1951*4882a593Smuzhiyun /* On the first pass, issue read-ahead on metadata. */
1952*4882a593Smuzhiyun if (mp.mp_aheight > 1 && strip_h == ip->i_height - 1) {
1953*4882a593Smuzhiyun unsigned int height = mp.mp_aheight - 1;
1954*4882a593Smuzhiyun
1955*4882a593Smuzhiyun /* No read-ahead for data blocks. */
1956*4882a593Smuzhiyun if (mp.mp_aheight - 1 == strip_h)
1957*4882a593Smuzhiyun height--;
1958*4882a593Smuzhiyun
1959*4882a593Smuzhiyun for (; height >= mp.mp_aheight - ret; height--) {
1960*4882a593Smuzhiyun metapointer_range(&mp, height,
1961*4882a593Smuzhiyun start_list, start_aligned,
1962*4882a593Smuzhiyun end_list, end_aligned,
1963*4882a593Smuzhiyun &start, &end);
1964*4882a593Smuzhiyun gfs2_metapath_ra(ip->i_gl, start, end);
1965*4882a593Smuzhiyun }
1966*4882a593Smuzhiyun }
1967*4882a593Smuzhiyun
1968*4882a593Smuzhiyun /* If buffers found for the entire strip height */
1969*4882a593Smuzhiyun if (mp.mp_aheight - 1 == strip_h) {
1970*4882a593Smuzhiyun state = DEALLOC_MP_FULL;
1971*4882a593Smuzhiyun break;
1972*4882a593Smuzhiyun }
1973*4882a593Smuzhiyun if (mp.mp_aheight < ip->i_height) /* We have a partial height */
1974*4882a593Smuzhiyun mp_h = mp.mp_aheight - 1;
1975*4882a593Smuzhiyun
1976*4882a593Smuzhiyun /* If we find a non-null block pointer, crawl a bit
1977*4882a593Smuzhiyun higher up in the metapath and try again, otherwise
1978*4882a593Smuzhiyun we need to look lower for a new starting point. */
1979*4882a593Smuzhiyun if (find_nonnull_ptr(sdp, &mp, mp_h, end_list, end_aligned))
1980*4882a593Smuzhiyun mp_h++;
1981*4882a593Smuzhiyun else
1982*4882a593Smuzhiyun state = DEALLOC_MP_LOWER;
1983*4882a593Smuzhiyun break;
1984*4882a593Smuzhiyun }
1985*4882a593Smuzhiyun }
1986*4882a593Smuzhiyun
1987*4882a593Smuzhiyun if (btotal) {
1988*4882a593Smuzhiyun if (current->journal_info == NULL) {
1989*4882a593Smuzhiyun ret = gfs2_trans_begin(sdp, RES_DINODE + RES_STATFS +
1990*4882a593Smuzhiyun RES_QUOTA, 0);
1991*4882a593Smuzhiyun if (ret)
1992*4882a593Smuzhiyun goto out;
1993*4882a593Smuzhiyun down_write(&ip->i_rw_mutex);
1994*4882a593Smuzhiyun }
1995*4882a593Smuzhiyun gfs2_statfs_change(sdp, 0, +btotal, 0);
1996*4882a593Smuzhiyun gfs2_quota_change(ip, -(s64)btotal, ip->i_inode.i_uid,
1997*4882a593Smuzhiyun ip->i_inode.i_gid);
1998*4882a593Smuzhiyun ip->i_inode.i_mtime = ip->i_inode.i_ctime = current_time(&ip->i_inode);
1999*4882a593Smuzhiyun gfs2_trans_add_meta(ip->i_gl, dibh);
2000*4882a593Smuzhiyun gfs2_dinode_out(ip, dibh->b_data);
2001*4882a593Smuzhiyun up_write(&ip->i_rw_mutex);
2002*4882a593Smuzhiyun gfs2_trans_end(sdp);
2003*4882a593Smuzhiyun }
2004*4882a593Smuzhiyun
2005*4882a593Smuzhiyun out:
2006*4882a593Smuzhiyun if (gfs2_holder_initialized(&rd_gh))
2007*4882a593Smuzhiyun gfs2_glock_dq_uninit(&rd_gh);
2008*4882a593Smuzhiyun if (current->journal_info) {
2009*4882a593Smuzhiyun up_write(&ip->i_rw_mutex);
2010*4882a593Smuzhiyun gfs2_trans_end(sdp);
2011*4882a593Smuzhiyun cond_resched();
2012*4882a593Smuzhiyun }
2013*4882a593Smuzhiyun gfs2_quota_unhold(ip);
2014*4882a593Smuzhiyun out_metapath:
2015*4882a593Smuzhiyun release_metapath(&mp);
2016*4882a593Smuzhiyun return ret;
2017*4882a593Smuzhiyun }
2018*4882a593Smuzhiyun
trunc_end(struct gfs2_inode * ip)2019*4882a593Smuzhiyun static int trunc_end(struct gfs2_inode *ip)
2020*4882a593Smuzhiyun {
2021*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
2022*4882a593Smuzhiyun struct buffer_head *dibh;
2023*4882a593Smuzhiyun int error;
2024*4882a593Smuzhiyun
2025*4882a593Smuzhiyun error = gfs2_trans_begin(sdp, RES_DINODE, 0);
2026*4882a593Smuzhiyun if (error)
2027*4882a593Smuzhiyun return error;
2028*4882a593Smuzhiyun
2029*4882a593Smuzhiyun down_write(&ip->i_rw_mutex);
2030*4882a593Smuzhiyun
2031*4882a593Smuzhiyun error = gfs2_meta_inode_buffer(ip, &dibh);
2032*4882a593Smuzhiyun if (error)
2033*4882a593Smuzhiyun goto out;
2034*4882a593Smuzhiyun
2035*4882a593Smuzhiyun if (!i_size_read(&ip->i_inode)) {
2036*4882a593Smuzhiyun ip->i_height = 0;
2037*4882a593Smuzhiyun ip->i_goal = ip->i_no_addr;
2038*4882a593Smuzhiyun gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
2039*4882a593Smuzhiyun gfs2_ordered_del_inode(ip);
2040*4882a593Smuzhiyun }
2041*4882a593Smuzhiyun ip->i_inode.i_mtime = ip->i_inode.i_ctime = current_time(&ip->i_inode);
2042*4882a593Smuzhiyun ip->i_diskflags &= ~GFS2_DIF_TRUNC_IN_PROG;
2043*4882a593Smuzhiyun
2044*4882a593Smuzhiyun gfs2_trans_add_meta(ip->i_gl, dibh);
2045*4882a593Smuzhiyun gfs2_dinode_out(ip, dibh->b_data);
2046*4882a593Smuzhiyun brelse(dibh);
2047*4882a593Smuzhiyun
2048*4882a593Smuzhiyun out:
2049*4882a593Smuzhiyun up_write(&ip->i_rw_mutex);
2050*4882a593Smuzhiyun gfs2_trans_end(sdp);
2051*4882a593Smuzhiyun return error;
2052*4882a593Smuzhiyun }
2053*4882a593Smuzhiyun
2054*4882a593Smuzhiyun /**
2055*4882a593Smuzhiyun * do_shrink - make a file smaller
2056*4882a593Smuzhiyun * @inode: the inode
2057*4882a593Smuzhiyun * @newsize: the size to make the file
2058*4882a593Smuzhiyun *
2059*4882a593Smuzhiyun * Called with an exclusive lock on @inode. The @size must
2060*4882a593Smuzhiyun * be equal to or smaller than the current inode size.
2061*4882a593Smuzhiyun *
2062*4882a593Smuzhiyun * Returns: errno
2063*4882a593Smuzhiyun */
2064*4882a593Smuzhiyun
do_shrink(struct inode * inode,u64 newsize)2065*4882a593Smuzhiyun static int do_shrink(struct inode *inode, u64 newsize)
2066*4882a593Smuzhiyun {
2067*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
2068*4882a593Smuzhiyun int error;
2069*4882a593Smuzhiyun
2070*4882a593Smuzhiyun error = trunc_start(inode, newsize);
2071*4882a593Smuzhiyun if (error < 0)
2072*4882a593Smuzhiyun return error;
2073*4882a593Smuzhiyun if (gfs2_is_stuffed(ip))
2074*4882a593Smuzhiyun return 0;
2075*4882a593Smuzhiyun
2076*4882a593Smuzhiyun error = punch_hole(ip, newsize, 0);
2077*4882a593Smuzhiyun if (error == 0)
2078*4882a593Smuzhiyun error = trunc_end(ip);
2079*4882a593Smuzhiyun
2080*4882a593Smuzhiyun return error;
2081*4882a593Smuzhiyun }
2082*4882a593Smuzhiyun
gfs2_trim_blocks(struct inode * inode)2083*4882a593Smuzhiyun void gfs2_trim_blocks(struct inode *inode)
2084*4882a593Smuzhiyun {
2085*4882a593Smuzhiyun int ret;
2086*4882a593Smuzhiyun
2087*4882a593Smuzhiyun ret = do_shrink(inode, inode->i_size);
2088*4882a593Smuzhiyun WARN_ON(ret != 0);
2089*4882a593Smuzhiyun }
2090*4882a593Smuzhiyun
2091*4882a593Smuzhiyun /**
2092*4882a593Smuzhiyun * do_grow - Touch and update inode size
2093*4882a593Smuzhiyun * @inode: The inode
2094*4882a593Smuzhiyun * @size: The new size
2095*4882a593Smuzhiyun *
2096*4882a593Smuzhiyun * This function updates the timestamps on the inode and
2097*4882a593Smuzhiyun * may also increase the size of the inode. This function
2098*4882a593Smuzhiyun * must not be called with @size any smaller than the current
2099*4882a593Smuzhiyun * inode size.
2100*4882a593Smuzhiyun *
2101*4882a593Smuzhiyun * Although it is not strictly required to unstuff files here,
2102*4882a593Smuzhiyun * earlier versions of GFS2 have a bug in the stuffed file reading
2103*4882a593Smuzhiyun * code which will result in a buffer overrun if the size is larger
2104*4882a593Smuzhiyun * than the max stuffed file size. In order to prevent this from
2105*4882a593Smuzhiyun * occurring, such files are unstuffed, but in other cases we can
2106*4882a593Smuzhiyun * just update the inode size directly.
2107*4882a593Smuzhiyun *
2108*4882a593Smuzhiyun * Returns: 0 on success, or -ve on error
2109*4882a593Smuzhiyun */
2110*4882a593Smuzhiyun
do_grow(struct inode * inode,u64 size)2111*4882a593Smuzhiyun static int do_grow(struct inode *inode, u64 size)
2112*4882a593Smuzhiyun {
2113*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
2114*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(inode);
2115*4882a593Smuzhiyun struct gfs2_alloc_parms ap = { .target = 1, };
2116*4882a593Smuzhiyun struct buffer_head *dibh;
2117*4882a593Smuzhiyun int error;
2118*4882a593Smuzhiyun int unstuff = 0;
2119*4882a593Smuzhiyun
2120*4882a593Smuzhiyun if (gfs2_is_stuffed(ip) && size > gfs2_max_stuffed_size(ip)) {
2121*4882a593Smuzhiyun error = gfs2_quota_lock_check(ip, &ap);
2122*4882a593Smuzhiyun if (error)
2123*4882a593Smuzhiyun return error;
2124*4882a593Smuzhiyun
2125*4882a593Smuzhiyun error = gfs2_inplace_reserve(ip, &ap);
2126*4882a593Smuzhiyun if (error)
2127*4882a593Smuzhiyun goto do_grow_qunlock;
2128*4882a593Smuzhiyun unstuff = 1;
2129*4882a593Smuzhiyun }
2130*4882a593Smuzhiyun
2131*4882a593Smuzhiyun error = gfs2_trans_begin(sdp, RES_DINODE + RES_STATFS + RES_RG_BIT +
2132*4882a593Smuzhiyun (unstuff &&
2133*4882a593Smuzhiyun gfs2_is_jdata(ip) ? RES_JDATA : 0) +
2134*4882a593Smuzhiyun (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF ?
2135*4882a593Smuzhiyun 0 : RES_QUOTA), 0);
2136*4882a593Smuzhiyun if (error)
2137*4882a593Smuzhiyun goto do_grow_release;
2138*4882a593Smuzhiyun
2139*4882a593Smuzhiyun if (unstuff) {
2140*4882a593Smuzhiyun error = gfs2_unstuff_dinode(ip, NULL);
2141*4882a593Smuzhiyun if (error)
2142*4882a593Smuzhiyun goto do_end_trans;
2143*4882a593Smuzhiyun }
2144*4882a593Smuzhiyun
2145*4882a593Smuzhiyun error = gfs2_meta_inode_buffer(ip, &dibh);
2146*4882a593Smuzhiyun if (error)
2147*4882a593Smuzhiyun goto do_end_trans;
2148*4882a593Smuzhiyun
2149*4882a593Smuzhiyun truncate_setsize(inode, size);
2150*4882a593Smuzhiyun ip->i_inode.i_mtime = ip->i_inode.i_ctime = current_time(&ip->i_inode);
2151*4882a593Smuzhiyun gfs2_trans_add_meta(ip->i_gl, dibh);
2152*4882a593Smuzhiyun gfs2_dinode_out(ip, dibh->b_data);
2153*4882a593Smuzhiyun brelse(dibh);
2154*4882a593Smuzhiyun
2155*4882a593Smuzhiyun do_end_trans:
2156*4882a593Smuzhiyun gfs2_trans_end(sdp);
2157*4882a593Smuzhiyun do_grow_release:
2158*4882a593Smuzhiyun if (unstuff) {
2159*4882a593Smuzhiyun gfs2_inplace_release(ip);
2160*4882a593Smuzhiyun do_grow_qunlock:
2161*4882a593Smuzhiyun gfs2_quota_unlock(ip);
2162*4882a593Smuzhiyun }
2163*4882a593Smuzhiyun return error;
2164*4882a593Smuzhiyun }
2165*4882a593Smuzhiyun
2166*4882a593Smuzhiyun /**
2167*4882a593Smuzhiyun * gfs2_setattr_size - make a file a given size
2168*4882a593Smuzhiyun * @inode: the inode
2169*4882a593Smuzhiyun * @newsize: the size to make the file
2170*4882a593Smuzhiyun *
2171*4882a593Smuzhiyun * The file size can grow, shrink, or stay the same size. This
2172*4882a593Smuzhiyun * is called holding i_rwsem and an exclusive glock on the inode
2173*4882a593Smuzhiyun * in question.
2174*4882a593Smuzhiyun *
2175*4882a593Smuzhiyun * Returns: errno
2176*4882a593Smuzhiyun */
2177*4882a593Smuzhiyun
gfs2_setattr_size(struct inode * inode,u64 newsize)2178*4882a593Smuzhiyun int gfs2_setattr_size(struct inode *inode, u64 newsize)
2179*4882a593Smuzhiyun {
2180*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
2181*4882a593Smuzhiyun int ret;
2182*4882a593Smuzhiyun
2183*4882a593Smuzhiyun BUG_ON(!S_ISREG(inode->i_mode));
2184*4882a593Smuzhiyun
2185*4882a593Smuzhiyun ret = inode_newsize_ok(inode, newsize);
2186*4882a593Smuzhiyun if (ret)
2187*4882a593Smuzhiyun return ret;
2188*4882a593Smuzhiyun
2189*4882a593Smuzhiyun inode_dio_wait(inode);
2190*4882a593Smuzhiyun
2191*4882a593Smuzhiyun ret = gfs2_qa_get(ip);
2192*4882a593Smuzhiyun if (ret)
2193*4882a593Smuzhiyun goto out;
2194*4882a593Smuzhiyun
2195*4882a593Smuzhiyun if (newsize >= inode->i_size) {
2196*4882a593Smuzhiyun ret = do_grow(inode, newsize);
2197*4882a593Smuzhiyun goto out;
2198*4882a593Smuzhiyun }
2199*4882a593Smuzhiyun
2200*4882a593Smuzhiyun ret = do_shrink(inode, newsize);
2201*4882a593Smuzhiyun out:
2202*4882a593Smuzhiyun gfs2_rs_delete(ip);
2203*4882a593Smuzhiyun gfs2_qa_put(ip);
2204*4882a593Smuzhiyun return ret;
2205*4882a593Smuzhiyun }
2206*4882a593Smuzhiyun
gfs2_truncatei_resume(struct gfs2_inode * ip)2207*4882a593Smuzhiyun int gfs2_truncatei_resume(struct gfs2_inode *ip)
2208*4882a593Smuzhiyun {
2209*4882a593Smuzhiyun int error;
2210*4882a593Smuzhiyun error = punch_hole(ip, i_size_read(&ip->i_inode), 0);
2211*4882a593Smuzhiyun if (!error)
2212*4882a593Smuzhiyun error = trunc_end(ip);
2213*4882a593Smuzhiyun return error;
2214*4882a593Smuzhiyun }
2215*4882a593Smuzhiyun
gfs2_file_dealloc(struct gfs2_inode * ip)2216*4882a593Smuzhiyun int gfs2_file_dealloc(struct gfs2_inode *ip)
2217*4882a593Smuzhiyun {
2218*4882a593Smuzhiyun return punch_hole(ip, 0, 0);
2219*4882a593Smuzhiyun }
2220*4882a593Smuzhiyun
2221*4882a593Smuzhiyun /**
2222*4882a593Smuzhiyun * gfs2_free_journal_extents - Free cached journal bmap info
2223*4882a593Smuzhiyun * @jd: The journal
2224*4882a593Smuzhiyun *
2225*4882a593Smuzhiyun */
2226*4882a593Smuzhiyun
gfs2_free_journal_extents(struct gfs2_jdesc * jd)2227*4882a593Smuzhiyun void gfs2_free_journal_extents(struct gfs2_jdesc *jd)
2228*4882a593Smuzhiyun {
2229*4882a593Smuzhiyun struct gfs2_journal_extent *jext;
2230*4882a593Smuzhiyun
2231*4882a593Smuzhiyun while(!list_empty(&jd->extent_list)) {
2232*4882a593Smuzhiyun jext = list_first_entry(&jd->extent_list, struct gfs2_journal_extent, list);
2233*4882a593Smuzhiyun list_del(&jext->list);
2234*4882a593Smuzhiyun kfree(jext);
2235*4882a593Smuzhiyun }
2236*4882a593Smuzhiyun }
2237*4882a593Smuzhiyun
2238*4882a593Smuzhiyun /**
2239*4882a593Smuzhiyun * gfs2_add_jextent - Add or merge a new extent to extent cache
2240*4882a593Smuzhiyun * @jd: The journal descriptor
2241*4882a593Smuzhiyun * @lblock: The logical block at start of new extent
2242*4882a593Smuzhiyun * @dblock: The physical block at start of new extent
2243*4882a593Smuzhiyun * @blocks: Size of extent in fs blocks
2244*4882a593Smuzhiyun *
2245*4882a593Smuzhiyun * Returns: 0 on success or -ENOMEM
2246*4882a593Smuzhiyun */
2247*4882a593Smuzhiyun
gfs2_add_jextent(struct gfs2_jdesc * jd,u64 lblock,u64 dblock,u64 blocks)2248*4882a593Smuzhiyun static int gfs2_add_jextent(struct gfs2_jdesc *jd, u64 lblock, u64 dblock, u64 blocks)
2249*4882a593Smuzhiyun {
2250*4882a593Smuzhiyun struct gfs2_journal_extent *jext;
2251*4882a593Smuzhiyun
2252*4882a593Smuzhiyun if (!list_empty(&jd->extent_list)) {
2253*4882a593Smuzhiyun jext = list_last_entry(&jd->extent_list, struct gfs2_journal_extent, list);
2254*4882a593Smuzhiyun if ((jext->dblock + jext->blocks) == dblock) {
2255*4882a593Smuzhiyun jext->blocks += blocks;
2256*4882a593Smuzhiyun return 0;
2257*4882a593Smuzhiyun }
2258*4882a593Smuzhiyun }
2259*4882a593Smuzhiyun
2260*4882a593Smuzhiyun jext = kzalloc(sizeof(struct gfs2_journal_extent), GFP_NOFS);
2261*4882a593Smuzhiyun if (jext == NULL)
2262*4882a593Smuzhiyun return -ENOMEM;
2263*4882a593Smuzhiyun jext->dblock = dblock;
2264*4882a593Smuzhiyun jext->lblock = lblock;
2265*4882a593Smuzhiyun jext->blocks = blocks;
2266*4882a593Smuzhiyun list_add_tail(&jext->list, &jd->extent_list);
2267*4882a593Smuzhiyun jd->nr_extents++;
2268*4882a593Smuzhiyun return 0;
2269*4882a593Smuzhiyun }
2270*4882a593Smuzhiyun
2271*4882a593Smuzhiyun /**
2272*4882a593Smuzhiyun * gfs2_map_journal_extents - Cache journal bmap info
2273*4882a593Smuzhiyun * @sdp: The super block
2274*4882a593Smuzhiyun * @jd: The journal to map
2275*4882a593Smuzhiyun *
2276*4882a593Smuzhiyun * Create a reusable "extent" mapping from all logical
2277*4882a593Smuzhiyun * blocks to all physical blocks for the given journal. This will save
2278*4882a593Smuzhiyun * us time when writing journal blocks. Most journals will have only one
2279*4882a593Smuzhiyun * extent that maps all their logical blocks. That's because gfs2.mkfs
2280*4882a593Smuzhiyun * arranges the journal blocks sequentially to maximize performance.
2281*4882a593Smuzhiyun * So the extent would map the first block for the entire file length.
2282*4882a593Smuzhiyun * However, gfs2_jadd can happen while file activity is happening, so
2283*4882a593Smuzhiyun * those journals may not be sequential. Less likely is the case where
2284*4882a593Smuzhiyun * the users created their own journals by mounting the metafs and
2285*4882a593Smuzhiyun * laying it out. But it's still possible. These journals might have
2286*4882a593Smuzhiyun * several extents.
2287*4882a593Smuzhiyun *
2288*4882a593Smuzhiyun * Returns: 0 on success, or error on failure
2289*4882a593Smuzhiyun */
2290*4882a593Smuzhiyun
gfs2_map_journal_extents(struct gfs2_sbd * sdp,struct gfs2_jdesc * jd)2291*4882a593Smuzhiyun int gfs2_map_journal_extents(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd)
2292*4882a593Smuzhiyun {
2293*4882a593Smuzhiyun u64 lblock = 0;
2294*4882a593Smuzhiyun u64 lblock_stop;
2295*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
2296*4882a593Smuzhiyun struct buffer_head bh;
2297*4882a593Smuzhiyun unsigned int shift = sdp->sd_sb.sb_bsize_shift;
2298*4882a593Smuzhiyun u64 size;
2299*4882a593Smuzhiyun int rc;
2300*4882a593Smuzhiyun ktime_t start, end;
2301*4882a593Smuzhiyun
2302*4882a593Smuzhiyun start = ktime_get();
2303*4882a593Smuzhiyun lblock_stop = i_size_read(jd->jd_inode) >> shift;
2304*4882a593Smuzhiyun size = (lblock_stop - lblock) << shift;
2305*4882a593Smuzhiyun jd->nr_extents = 0;
2306*4882a593Smuzhiyun WARN_ON(!list_empty(&jd->extent_list));
2307*4882a593Smuzhiyun
2308*4882a593Smuzhiyun do {
2309*4882a593Smuzhiyun bh.b_state = 0;
2310*4882a593Smuzhiyun bh.b_blocknr = 0;
2311*4882a593Smuzhiyun bh.b_size = size;
2312*4882a593Smuzhiyun rc = gfs2_block_map(jd->jd_inode, lblock, &bh, 0);
2313*4882a593Smuzhiyun if (rc || !buffer_mapped(&bh))
2314*4882a593Smuzhiyun goto fail;
2315*4882a593Smuzhiyun rc = gfs2_add_jextent(jd, lblock, bh.b_blocknr, bh.b_size >> shift);
2316*4882a593Smuzhiyun if (rc)
2317*4882a593Smuzhiyun goto fail;
2318*4882a593Smuzhiyun size -= bh.b_size;
2319*4882a593Smuzhiyun lblock += (bh.b_size >> ip->i_inode.i_blkbits);
2320*4882a593Smuzhiyun } while(size > 0);
2321*4882a593Smuzhiyun
2322*4882a593Smuzhiyun end = ktime_get();
2323*4882a593Smuzhiyun fs_info(sdp, "journal %d mapped with %u extents in %lldms\n", jd->jd_jid,
2324*4882a593Smuzhiyun jd->nr_extents, ktime_ms_delta(end, start));
2325*4882a593Smuzhiyun return 0;
2326*4882a593Smuzhiyun
2327*4882a593Smuzhiyun fail:
2328*4882a593Smuzhiyun fs_warn(sdp, "error %d mapping journal %u at offset %llu (extent %u)\n",
2329*4882a593Smuzhiyun rc, jd->jd_jid,
2330*4882a593Smuzhiyun (unsigned long long)(i_size_read(jd->jd_inode) - size),
2331*4882a593Smuzhiyun jd->nr_extents);
2332*4882a593Smuzhiyun fs_warn(sdp, "bmap=%d lblock=%llu block=%llu, state=0x%08lx, size=%llu\n",
2333*4882a593Smuzhiyun rc, (unsigned long long)lblock, (unsigned long long)bh.b_blocknr,
2334*4882a593Smuzhiyun bh.b_state, (unsigned long long)bh.b_size);
2335*4882a593Smuzhiyun gfs2_free_journal_extents(jd);
2336*4882a593Smuzhiyun return rc;
2337*4882a593Smuzhiyun }
2338*4882a593Smuzhiyun
2339*4882a593Smuzhiyun /**
2340*4882a593Smuzhiyun * gfs2_write_alloc_required - figure out if a write will require an allocation
2341*4882a593Smuzhiyun * @ip: the file being written to
2342*4882a593Smuzhiyun * @offset: the offset to write to
2343*4882a593Smuzhiyun * @len: the number of bytes being written
2344*4882a593Smuzhiyun *
2345*4882a593Smuzhiyun * Returns: 1 if an alloc is required, 0 otherwise
2346*4882a593Smuzhiyun */
2347*4882a593Smuzhiyun
gfs2_write_alloc_required(struct gfs2_inode * ip,u64 offset,unsigned int len)2348*4882a593Smuzhiyun int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset,
2349*4882a593Smuzhiyun unsigned int len)
2350*4882a593Smuzhiyun {
2351*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
2352*4882a593Smuzhiyun struct buffer_head bh;
2353*4882a593Smuzhiyun unsigned int shift;
2354*4882a593Smuzhiyun u64 lblock, lblock_stop, size;
2355*4882a593Smuzhiyun u64 end_of_file;
2356*4882a593Smuzhiyun
2357*4882a593Smuzhiyun if (!len)
2358*4882a593Smuzhiyun return 0;
2359*4882a593Smuzhiyun
2360*4882a593Smuzhiyun if (gfs2_is_stuffed(ip)) {
2361*4882a593Smuzhiyun if (offset + len > gfs2_max_stuffed_size(ip))
2362*4882a593Smuzhiyun return 1;
2363*4882a593Smuzhiyun return 0;
2364*4882a593Smuzhiyun }
2365*4882a593Smuzhiyun
2366*4882a593Smuzhiyun shift = sdp->sd_sb.sb_bsize_shift;
2367*4882a593Smuzhiyun BUG_ON(gfs2_is_dir(ip));
2368*4882a593Smuzhiyun end_of_file = (i_size_read(&ip->i_inode) + sdp->sd_sb.sb_bsize - 1) >> shift;
2369*4882a593Smuzhiyun lblock = offset >> shift;
2370*4882a593Smuzhiyun lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift;
2371*4882a593Smuzhiyun if (lblock_stop > end_of_file && ip != GFS2_I(sdp->sd_rindex))
2372*4882a593Smuzhiyun return 1;
2373*4882a593Smuzhiyun
2374*4882a593Smuzhiyun size = (lblock_stop - lblock) << shift;
2375*4882a593Smuzhiyun do {
2376*4882a593Smuzhiyun bh.b_state = 0;
2377*4882a593Smuzhiyun bh.b_size = size;
2378*4882a593Smuzhiyun gfs2_block_map(&ip->i_inode, lblock, &bh, 0);
2379*4882a593Smuzhiyun if (!buffer_mapped(&bh))
2380*4882a593Smuzhiyun return 1;
2381*4882a593Smuzhiyun size -= bh.b_size;
2382*4882a593Smuzhiyun lblock += (bh.b_size >> ip->i_inode.i_blkbits);
2383*4882a593Smuzhiyun } while(size > 0);
2384*4882a593Smuzhiyun
2385*4882a593Smuzhiyun return 0;
2386*4882a593Smuzhiyun }
2387*4882a593Smuzhiyun
stuffed_zero_range(struct inode * inode,loff_t offset,loff_t length)2388*4882a593Smuzhiyun static int stuffed_zero_range(struct inode *inode, loff_t offset, loff_t length)
2389*4882a593Smuzhiyun {
2390*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
2391*4882a593Smuzhiyun struct buffer_head *dibh;
2392*4882a593Smuzhiyun int error;
2393*4882a593Smuzhiyun
2394*4882a593Smuzhiyun if (offset >= inode->i_size)
2395*4882a593Smuzhiyun return 0;
2396*4882a593Smuzhiyun if (offset + length > inode->i_size)
2397*4882a593Smuzhiyun length = inode->i_size - offset;
2398*4882a593Smuzhiyun
2399*4882a593Smuzhiyun error = gfs2_meta_inode_buffer(ip, &dibh);
2400*4882a593Smuzhiyun if (error)
2401*4882a593Smuzhiyun return error;
2402*4882a593Smuzhiyun gfs2_trans_add_meta(ip->i_gl, dibh);
2403*4882a593Smuzhiyun memset(dibh->b_data + sizeof(struct gfs2_dinode) + offset, 0,
2404*4882a593Smuzhiyun length);
2405*4882a593Smuzhiyun brelse(dibh);
2406*4882a593Smuzhiyun return 0;
2407*4882a593Smuzhiyun }
2408*4882a593Smuzhiyun
gfs2_journaled_truncate_range(struct inode * inode,loff_t offset,loff_t length)2409*4882a593Smuzhiyun static int gfs2_journaled_truncate_range(struct inode *inode, loff_t offset,
2410*4882a593Smuzhiyun loff_t length)
2411*4882a593Smuzhiyun {
2412*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(inode);
2413*4882a593Smuzhiyun loff_t max_chunk = GFS2_JTRUNC_REVOKES * sdp->sd_vfs->s_blocksize;
2414*4882a593Smuzhiyun int error;
2415*4882a593Smuzhiyun
2416*4882a593Smuzhiyun while (length) {
2417*4882a593Smuzhiyun struct gfs2_trans *tr;
2418*4882a593Smuzhiyun loff_t chunk;
2419*4882a593Smuzhiyun unsigned int offs;
2420*4882a593Smuzhiyun
2421*4882a593Smuzhiyun chunk = length;
2422*4882a593Smuzhiyun if (chunk > max_chunk)
2423*4882a593Smuzhiyun chunk = max_chunk;
2424*4882a593Smuzhiyun
2425*4882a593Smuzhiyun offs = offset & ~PAGE_MASK;
2426*4882a593Smuzhiyun if (offs && chunk > PAGE_SIZE)
2427*4882a593Smuzhiyun chunk = offs + ((chunk - offs) & PAGE_MASK);
2428*4882a593Smuzhiyun
2429*4882a593Smuzhiyun truncate_pagecache_range(inode, offset, chunk);
2430*4882a593Smuzhiyun offset += chunk;
2431*4882a593Smuzhiyun length -= chunk;
2432*4882a593Smuzhiyun
2433*4882a593Smuzhiyun tr = current->journal_info;
2434*4882a593Smuzhiyun if (!test_bit(TR_TOUCHED, &tr->tr_flags))
2435*4882a593Smuzhiyun continue;
2436*4882a593Smuzhiyun
2437*4882a593Smuzhiyun gfs2_trans_end(sdp);
2438*4882a593Smuzhiyun error = gfs2_trans_begin(sdp, RES_DINODE, GFS2_JTRUNC_REVOKES);
2439*4882a593Smuzhiyun if (error)
2440*4882a593Smuzhiyun return error;
2441*4882a593Smuzhiyun }
2442*4882a593Smuzhiyun return 0;
2443*4882a593Smuzhiyun }
2444*4882a593Smuzhiyun
__gfs2_punch_hole(struct file * file,loff_t offset,loff_t length)2445*4882a593Smuzhiyun int __gfs2_punch_hole(struct file *file, loff_t offset, loff_t length)
2446*4882a593Smuzhiyun {
2447*4882a593Smuzhiyun struct inode *inode = file_inode(file);
2448*4882a593Smuzhiyun struct gfs2_inode *ip = GFS2_I(inode);
2449*4882a593Smuzhiyun struct gfs2_sbd *sdp = GFS2_SB(inode);
2450*4882a593Smuzhiyun unsigned int blocksize = i_blocksize(inode);
2451*4882a593Smuzhiyun loff_t start, end;
2452*4882a593Smuzhiyun int error;
2453*4882a593Smuzhiyun
2454*4882a593Smuzhiyun if (!gfs2_is_stuffed(ip)) {
2455*4882a593Smuzhiyun unsigned int start_off, end_len;
2456*4882a593Smuzhiyun
2457*4882a593Smuzhiyun start_off = offset & (blocksize - 1);
2458*4882a593Smuzhiyun end_len = (offset + length) & (blocksize - 1);
2459*4882a593Smuzhiyun if (start_off) {
2460*4882a593Smuzhiyun unsigned int len = length;
2461*4882a593Smuzhiyun if (length > blocksize - start_off)
2462*4882a593Smuzhiyun len = blocksize - start_off;
2463*4882a593Smuzhiyun error = gfs2_block_zero_range(inode, offset, len);
2464*4882a593Smuzhiyun if (error)
2465*4882a593Smuzhiyun goto out;
2466*4882a593Smuzhiyun if (start_off + length < blocksize)
2467*4882a593Smuzhiyun end_len = 0;
2468*4882a593Smuzhiyun }
2469*4882a593Smuzhiyun if (end_len) {
2470*4882a593Smuzhiyun error = gfs2_block_zero_range(inode,
2471*4882a593Smuzhiyun offset + length - end_len, end_len);
2472*4882a593Smuzhiyun if (error)
2473*4882a593Smuzhiyun goto out;
2474*4882a593Smuzhiyun }
2475*4882a593Smuzhiyun }
2476*4882a593Smuzhiyun
2477*4882a593Smuzhiyun start = round_down(offset, blocksize);
2478*4882a593Smuzhiyun end = round_up(offset + length, blocksize) - 1;
2479*4882a593Smuzhiyun error = filemap_write_and_wait_range(inode->i_mapping, start, end);
2480*4882a593Smuzhiyun if (error)
2481*4882a593Smuzhiyun return error;
2482*4882a593Smuzhiyun
2483*4882a593Smuzhiyun if (gfs2_is_jdata(ip))
2484*4882a593Smuzhiyun error = gfs2_trans_begin(sdp, RES_DINODE + 2 * RES_JDATA,
2485*4882a593Smuzhiyun GFS2_JTRUNC_REVOKES);
2486*4882a593Smuzhiyun else
2487*4882a593Smuzhiyun error = gfs2_trans_begin(sdp, RES_DINODE, 0);
2488*4882a593Smuzhiyun if (error)
2489*4882a593Smuzhiyun return error;
2490*4882a593Smuzhiyun
2491*4882a593Smuzhiyun if (gfs2_is_stuffed(ip)) {
2492*4882a593Smuzhiyun error = stuffed_zero_range(inode, offset, length);
2493*4882a593Smuzhiyun if (error)
2494*4882a593Smuzhiyun goto out;
2495*4882a593Smuzhiyun }
2496*4882a593Smuzhiyun
2497*4882a593Smuzhiyun if (gfs2_is_jdata(ip)) {
2498*4882a593Smuzhiyun BUG_ON(!current->journal_info);
2499*4882a593Smuzhiyun gfs2_journaled_truncate_range(inode, offset, length);
2500*4882a593Smuzhiyun } else
2501*4882a593Smuzhiyun truncate_pagecache_range(inode, offset, offset + length - 1);
2502*4882a593Smuzhiyun
2503*4882a593Smuzhiyun file_update_time(file);
2504*4882a593Smuzhiyun mark_inode_dirty(inode);
2505*4882a593Smuzhiyun
2506*4882a593Smuzhiyun if (current->journal_info)
2507*4882a593Smuzhiyun gfs2_trans_end(sdp);
2508*4882a593Smuzhiyun
2509*4882a593Smuzhiyun if (!gfs2_is_stuffed(ip))
2510*4882a593Smuzhiyun error = punch_hole(ip, offset, length);
2511*4882a593Smuzhiyun
2512*4882a593Smuzhiyun out:
2513*4882a593Smuzhiyun if (current->journal_info)
2514*4882a593Smuzhiyun gfs2_trans_end(sdp);
2515*4882a593Smuzhiyun return error;
2516*4882a593Smuzhiyun }
2517*4882a593Smuzhiyun
gfs2_map_blocks(struct iomap_writepage_ctx * wpc,struct inode * inode,loff_t offset)2518*4882a593Smuzhiyun static int gfs2_map_blocks(struct iomap_writepage_ctx *wpc, struct inode *inode,
2519*4882a593Smuzhiyun loff_t offset)
2520*4882a593Smuzhiyun {
2521*4882a593Smuzhiyun struct metapath mp = { .mp_aheight = 1, };
2522*4882a593Smuzhiyun int ret;
2523*4882a593Smuzhiyun
2524*4882a593Smuzhiyun if (WARN_ON_ONCE(gfs2_is_stuffed(GFS2_I(inode))))
2525*4882a593Smuzhiyun return -EIO;
2526*4882a593Smuzhiyun
2527*4882a593Smuzhiyun if (offset >= wpc->iomap.offset &&
2528*4882a593Smuzhiyun offset < wpc->iomap.offset + wpc->iomap.length)
2529*4882a593Smuzhiyun return 0;
2530*4882a593Smuzhiyun
2531*4882a593Smuzhiyun memset(&wpc->iomap, 0, sizeof(wpc->iomap));
2532*4882a593Smuzhiyun ret = gfs2_iomap_get(inode, offset, INT_MAX, 0, &wpc->iomap, &mp);
2533*4882a593Smuzhiyun release_metapath(&mp);
2534*4882a593Smuzhiyun return ret;
2535*4882a593Smuzhiyun }
2536*4882a593Smuzhiyun
2537*4882a593Smuzhiyun const struct iomap_writeback_ops gfs2_writeback_ops = {
2538*4882a593Smuzhiyun .map_blocks = gfs2_map_blocks,
2539*4882a593Smuzhiyun };
2540