bmap.c 28.5 KB
Newer Older
David Teigland's avatar
David Teigland committed
1
2
/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3
 * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
David Teigland's avatar
David Teigland committed
4
5
6
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
7
 * of the GNU General Public License version 2.
David Teigland's avatar
David Teigland committed
8
9
10
11
12
13
 */

#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
14
#include <linux/gfs2_ondisk.h>
15
#include <linux/crc32.h>
16
#include <linux/lm_interface.h>
David Teigland's avatar
David Teigland committed
17
18

#include "gfs2.h"
19
#include "incore.h"
David Teigland's avatar
David Teigland committed
20
21
22
23
24
25
26
#include "bmap.h"
#include "glock.h"
#include "inode.h"
#include "meta_io.h"
#include "quota.h"
#include "rgrp.h"
#include "trans.h"
27
#include "dir.h"
28
#include "util.h"
Steven Whitehouse's avatar
Steven Whitehouse committed
29
#include "ops_address.h"
David Teigland's avatar
David Teigland committed
30
31
32
33
34
35
36
37
38
39

/* This doesn't need to be that large as max 64 bit pointers in a 4k
 * block is 512, so __u16 is fine for that. It saves stack space to
 * keep it small.
 */
struct metapath {
	__u16 mp_list[GFS2_MAX_META_HEIGHT];
};

typedef int (*block_call_t) (struct gfs2_inode *ip, struct buffer_head *dibh,
40
41
			     struct buffer_head *bh, __be64 *top,
			     __be64 *bottom, unsigned int height,
David Teigland's avatar
David Teigland committed
42
43
44
45
46
47
48
			     void *data);

struct strip_mine {
	int sm_first;
	unsigned int sm_height;
};

49
50
51
52
53
54
55
56
57
58
59
/**
 * gfs2_unstuffer_page - unstuff a stuffed inode into a block cached by a page
 * @ip: the inode
 * @dibh: the dinode buffer
 * @block: the block number that was allocated
 * @private: any locked page held by the caller process
 *
 * Returns: errno
 */

static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh,
60
			       u64 block, struct page *page)
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
{
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
	struct inode *inode = &ip->i_inode;
	struct buffer_head *bh;
	int release = 0;

	if (!page || page->index) {
		page = grab_cache_page(inode->i_mapping, 0);
		if (!page)
			return -ENOMEM;
		release = 1;
	}

	if (!PageUptodate(page)) {
		void *kaddr = kmap(page);

		memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode),
		       ip->i_di.di_size);
		memset(kaddr + ip->i_di.di_size, 0,
		       PAGE_CACHE_SIZE - ip->i_di.di_size);
		kunmap(page);

		SetPageUptodate(page);
	}

	if (!page_has_buffers(page))
		create_empty_buffers(page, 1 << inode->i_blkbits,
				     (1 << BH_Uptodate));

	bh = page_buffers(page);

	if (!buffer_mapped(bh))
		map_bh(bh, inode->i_sb, block);

	set_buffer_uptodate(bh);
96
	if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip))
97
98
99
100
101
102
103
104
105
106
107
		gfs2_trans_add_bh(ip->i_gl, bh, 0);
	mark_buffer_dirty(bh);

	if (release) {
		unlock_page(page);
		page_cache_release(page);
	}

	return 0;
}

David Teigland's avatar
David Teigland committed
108
109
110
111
112
113
114
115
116
117
118
119
/**
 * gfs2_unstuff_dinode - Unstuff a dinode when the data has grown too big
 * @ip: The GFS2 inode to unstuff
 * @unstuffer: the routine that handles unstuffing a non-zero length file
 * @private: private data for the unstuffer
 *
 * This routine unstuffs a dinode and returns it to a "normal" state such
 * that the height can be grown in the traditional way.
 *
 * Returns: errno
 */

120
int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page)
David Teigland's avatar
David Teigland committed
121
122
{
	struct buffer_head *bh, *dibh;
123
	struct gfs2_dinode *di;
124
	u64 block = 0;
125
	int isdir = gfs2_is_dir(ip);
David Teigland's avatar
David Teigland committed
126
127
128
129
130
131
132
	int error;

	down_write(&ip->i_rw_mutex);

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (error)
		goto out;
133

David Teigland's avatar
David Teigland committed
134
135
136
137
	if (ip->i_di.di_size) {
		/* Get a free block, fill it with the stuffed data,
		   and write it out to disk */

138
		if (isdir) {
David Teigland's avatar
David Teigland committed
139
140
			block = gfs2_alloc_meta(ip);

141
			error = gfs2_dir_get_new_buffer(ip, block, &bh);
David Teigland's avatar
David Teigland committed
142
143
			if (error)
				goto out_brelse;
144
			gfs2_buffer_copy_tail(bh, sizeof(struct gfs2_meta_header),
David Teigland's avatar
David Teigland committed
145
146
147
148
149
					      dibh, sizeof(struct gfs2_dinode));
			brelse(bh);
		} else {
			block = gfs2_alloc_data(ip);

150
			error = gfs2_unstuffer_page(ip, dibh, block, page);
David Teigland's avatar
David Teigland committed
151
152
153
154
155
156
157
			if (error)
				goto out_brelse;
		}
	}

	/*  Set up the pointer to the new block  */

158
	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
159
	di = (struct gfs2_dinode *)dibh->b_data;
David Teigland's avatar
David Teigland committed
160
161
162
	gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));

	if (ip->i_di.di_size) {
163
		*(__be64 *)(di + 1) = cpu_to_be64(block);
David Teigland's avatar
David Teigland committed
164
		ip->i_di.di_blocks++;
165
		gfs2_set_inode_blocks(&ip->i_inode);
166
		di->di_blocks = cpu_to_be64(ip->i_di.di_blocks);
David Teigland's avatar
David Teigland committed
167
168
169
	}

	ip->i_di.di_height = 1;
170
	di->di_height = cpu_to_be16(1);
David Teigland's avatar
David Teigland committed
171

172
out_brelse:
David Teigland's avatar
David Teigland committed
173
	brelse(dibh);
174
out:
David Teigland's avatar
David Teigland committed
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
	up_write(&ip->i_rw_mutex);
	return error;
}

/**
 * calc_tree_height - Calculate the height of a metadata tree
 * @ip: The GFS2 inode
 * @size: The proposed size of the file
 *
 * Work out how tall a metadata tree needs to be in order to accommodate a
 * file of a particular size. If size is less than the current size of
 * the inode, then the current size of the inode is used instead of the
 * supplied one.
 *
 * Returns: the height the tree should be
 */

192
static unsigned int calc_tree_height(struct gfs2_inode *ip, u64 size)
David Teigland's avatar
David Teigland committed
193
{
194
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
195
	u64 *arr;
David Teigland's avatar
David Teigland committed
196
197
198
199
200
	unsigned int max, height;

	if (ip->i_di.di_size > size)
		size = ip->i_di.di_size;

201
	if (gfs2_is_dir(ip)) {
David Teigland's avatar
David Teigland committed
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
		arr = sdp->sd_jheightsize;
		max = sdp->sd_max_jheight;
	} else {
		arr = sdp->sd_heightsize;
		max = sdp->sd_max_height;
	}

	for (height = 0; height < max; height++)
		if (arr[height] >= size)
			break;

	return height;
}

/**
 * build_height - Build a metadata tree of the requested height
 * @ip: The GFS2 inode
 * @height: The height to build to
 *
 *
 * Returns: errno
 */

225
static int build_height(struct inode *inode, unsigned height)
David Teigland's avatar
David Teigland committed
226
{
227
	struct gfs2_inode *ip = GFS2_I(inode);
228
229
230
	unsigned new_height = height - ip->i_di.di_height;
	struct buffer_head *dibh;
	struct buffer_head *blocks[GFS2_MAX_META_HEIGHT];
231
	struct gfs2_dinode *di;
David Teigland's avatar
David Teigland committed
232
	int error;
233
	__be64 *bp;
234
235
	u64 bn;
	unsigned n;
David Teigland's avatar
David Teigland committed
236

237
238
	if (height <= ip->i_di.di_height)
		return 0;
David Teigland's avatar
David Teigland committed
239

240
241
242
	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (error)
		return error;
David Teigland's avatar
David Teigland committed
243

244
245
246
247
248
	for(n = 0; n < new_height; n++) {
		bn = gfs2_alloc_meta(ip);
		blocks[n] = gfs2_meta_new(ip->i_gl, bn);
		gfs2_trans_add_bh(ip->i_gl, blocks[n], 1);
	}
249

250
251
252
253
254
	n = 0;
	bn = blocks[0]->b_blocknr;
	if (new_height > 1) {
		for(; n < new_height-1; n++) {
			gfs2_metatype_set(blocks[n], GFS2_METATYPE_IN,
David Teigland's avatar
David Teigland committed
255
					  GFS2_FORMAT_IN);
256
257
			gfs2_buffer_clear_tail(blocks[n],
					       sizeof(struct gfs2_meta_header));
258
			bp = (__be64 *)(blocks[n]->b_data +
259
260
261
262
				     sizeof(struct gfs2_meta_header));
			*bp = cpu_to_be64(blocks[n+1]->b_blocknr);
			brelse(blocks[n]);
			blocks[n] = NULL;
David Teigland's avatar
David Teigland committed
263
264
		}
	}
265
266
267
268
269
	gfs2_metatype_set(blocks[n], GFS2_METATYPE_IN, GFS2_FORMAT_IN);
	gfs2_buffer_copy_tail(blocks[n], sizeof(struct gfs2_meta_header),
			      dibh, sizeof(struct gfs2_dinode));
	brelse(blocks[n]);
	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
270
	di = (struct gfs2_dinode *)dibh->b_data;
271
	gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
272
	*(__be64 *)(di + 1) = cpu_to_be64(bn);
273
274
	ip->i_di.di_height += new_height;
	ip->i_di.di_blocks += new_height;
275
	gfs2_set_inode_blocks(&ip->i_inode);
276
277
	di->di_height = cpu_to_be16(ip->i_di.di_height);
	di->di_blocks = cpu_to_be64(ip->i_di.di_blocks);
278
279
	brelse(dibh);
	return error;
David Teigland's avatar
David Teigland committed
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
}

/**
 * find_metapath - Find path through the metadata tree
 * @ip: The inode pointer
 * @mp: The metapath to return the result in
 * @block: The disk block to look up
 *
 *   This routine returns a struct metapath structure that defines a path
 *   through the metadata of inode "ip" to get to block "block".
 *
 *   Example:
 *   Given:  "ip" is a height 3 file, "offset" is 101342453, and this is a
 *   filesystem with a blocksize of 4096.
 *
 *   find_metapath() would return a struct metapath structure set to:
 *   mp_offset = 101342453, mp_height = 3, mp_list[0] = 0, mp_list[1] = 48,
 *   and mp_list[2] = 165.
 *
 *   That means that in order to get to the block containing the byte at
 *   offset 101342453, we would load the indirect block pointed to by pointer
 *   0 in the dinode.  We would then load the indirect block pointed to by
 *   pointer 48 in that indirect block.  We would then load the data block
 *   pointed to by pointer 165 in that indirect block.
 *
 *             ----------------------------------------
 *             | Dinode |                             |
 *             |        |                            4|
 *             |        |0 1 2 3 4 5                 9|
 *             |        |                            6|
 *             ----------------------------------------
 *                       |
 *                       |
 *                       V
 *             ----------------------------------------
 *             | Indirect Block                       |
 *             |                                     5|
 *             |            4 4 4 4 4 5 5            1|
 *             |0           5 6 7 8 9 0 1            2|
 *             ----------------------------------------
 *                                |
 *                                |
 *                                V
 *             ----------------------------------------
 *             | Indirect Block                       |
 *             |                         1 1 1 1 1   5|
 *             |                         6 6 6 6 6   1|
 *             |0                        3 4 5 6 7   2|
 *             ----------------------------------------
 *                                           |
 *                                           |
 *                                           V
 *             ----------------------------------------
 *             | Data block containing offset         |
 *             |            101342453                 |
 *             |                                      |
 *             |                                      |
 *             ----------------------------------------
 *
 */

341
static void find_metapath(struct gfs2_inode *ip, u64 block,
342
			  struct metapath *mp)
David Teigland's avatar
David Teigland committed
343
{
344
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
345
	u64 b = block;
David Teigland's avatar
David Teigland committed
346
347
348
	unsigned int i;

	for (i = ip->i_di.di_height; i--;)
349
		mp->mp_list[i] = do_div(b, sdp->sd_inptrs);
David Teigland's avatar
David Teigland committed
350
351
352
353
354
355
356
357
358
359
360
361
362
363

}

/**
 * metapointer - Return pointer to start of metadata in a buffer
 * @bh: The buffer
 * @height: The metadata height (0 = dinode)
 * @mp: The metapath
 *
 * Return a pointer to the block number of the next height of the metadata
 * tree given a buffer containing the pointer to the current height of the
 * metadata tree.
 */

364
static inline __be64 *metapointer(struct buffer_head *bh, int *boundary,
Steven Whitehouse's avatar
Steven Whitehouse committed
365
			       unsigned int height, const struct metapath *mp)
David Teigland's avatar
David Teigland committed
366
367
368
{
	unsigned int head_size = (height > 0) ?
		sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_dinode);
369
	__be64 *ptr;
Steven Whitehouse's avatar
Steven Whitehouse committed
370
	*boundary = 0;
371
372
	ptr = ((__be64 *)(bh->b_data + head_size)) + mp->mp_list[height];
	if (ptr + 1 == (__be64 *)(bh->b_data + bh->b_size))
Steven Whitehouse's avatar
Steven Whitehouse committed
373
374
		*boundary = 1;
	return ptr;
David Teigland's avatar
David Teigland committed
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
}

/**
 * lookup_block - Get the next metadata block in metadata tree
 * @ip: The GFS2 inode
 * @bh: Buffer containing the pointers to metadata blocks
 * @height: The height of the tree (0 = dinode)
 * @mp: The metapath
 * @create: Non-zero if we may create a new meatdata block
 * @new: Used to indicate if we did create a new metadata block
 * @block: the returned disk block number
 *
 * Given a metatree, complete to a particular height, checks to see if the next
 * height of the tree exists. If not the next height of the tree is created.
 * The block number of the next height of the metadata tree is returned.
 *
 */

Steven Whitehouse's avatar
Steven Whitehouse committed
393
394
static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh,
			unsigned int height, struct metapath *mp, int create,
395
			int *new, u64 *block)
David Teigland's avatar
David Teigland committed
396
{
Steven Whitehouse's avatar
Steven Whitehouse committed
397
	int boundary;
398
	__be64 *ptr = metapointer(bh, &boundary, height, mp);
David Teigland's avatar
David Teigland committed
399
400
401

	if (*ptr) {
		*block = be64_to_cpu(*ptr);
Steven Whitehouse's avatar
Steven Whitehouse committed
402
		return boundary;
David Teigland's avatar
David Teigland committed
403
404
405
406
407
	}

	*block = 0;

	if (!create)
Steven Whitehouse's avatar
Steven Whitehouse committed
408
		return 0;
David Teigland's avatar
David Teigland committed
409

Steven Whitehouse's avatar
Steven Whitehouse committed
410
	if (height == ip->i_di.di_height - 1 && !gfs2_is_dir(ip))
David Teigland's avatar
David Teigland committed
411
412
413
414
		*block = gfs2_alloc_data(ip);
	else
		*block = gfs2_alloc_meta(ip);

415
	gfs2_trans_add_bh(ip->i_gl, bh, 1);
David Teigland's avatar
David Teigland committed
416
417
418

	*ptr = cpu_to_be64(*block);
	ip->i_di.di_blocks++;
419
	gfs2_set_inode_blocks(&ip->i_inode);
David Teigland's avatar
David Teigland committed
420
421

	*new = 1;
Steven Whitehouse's avatar
Steven Whitehouse committed
422
	return 0;
David Teigland's avatar
David Teigland committed
423
424
}

425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
static inline void bmap_lock(struct inode *inode, int create)
{
	struct gfs2_inode *ip = GFS2_I(inode);
	if (create)
		down_write(&ip->i_rw_mutex);
	else
		down_read(&ip->i_rw_mutex);
}

static inline void bmap_unlock(struct inode *inode, int create)
{
	struct gfs2_inode *ip = GFS2_I(inode);
	if (create)
		up_write(&ip->i_rw_mutex);
	else
		up_read(&ip->i_rw_mutex);
}

David Teigland's avatar
David Teigland committed
443
/**
444
 * gfs2_block_map - Map a block from an inode to a disk block
Steven Whitehouse's avatar
Steven Whitehouse committed
445
 * @inode: The inode
David Teigland's avatar
David Teigland committed
446
 * @lblock: The logical block number
447
 * @bh_map: The bh to be mapped
David Teigland's avatar
David Teigland committed
448
449
450
451
452
453
454
 *
 * Find the block number on the current device which corresponds to an
 * inode's block. If the block had to be created, "new" will be set.
 *
 * Returns: errno
 */

455
456
int gfs2_block_map(struct inode *inode, u64 lblock, int create,
		   struct buffer_head *bh_map)
David Teigland's avatar
David Teigland committed
457
{
458
459
	struct gfs2_inode *ip = GFS2_I(inode);
	struct gfs2_sbd *sdp = GFS2_SB(inode);
David Teigland's avatar
David Teigland committed
460
461
462
463
464
465
	struct buffer_head *bh;
	unsigned int bsize;
	unsigned int height;
	unsigned int end_of_metadata;
	unsigned int x;
	int error = 0;
466
467
468
	int new = 0;
	u64 dblock = 0;
	int boundary;
469
	unsigned int maxlen = bh_map->b_size >> inode->i_blkbits;
470
471
	struct metapath mp;
	u64 size;
David Teigland's avatar
David Teigland committed
472

473
474
	BUG_ON(maxlen == 0);

David Teigland's avatar
David Teigland committed
475
	if (gfs2_assert_warn(sdp, !gfs2_is_stuffed(ip)))
476
		return 0;
David Teigland's avatar
David Teigland committed
477

478
479
480
481
	bmap_lock(inode, create);
	clear_buffer_mapped(bh_map);
	clear_buffer_new(bh_map);
	clear_buffer_boundary(bh_map);
482
	bsize = gfs2_is_dir(ip) ? sdp->sd_jbsize : sdp->sd_sb.sb_bsize;
483
484
485
486
487
488
489
490
491
492
493
494
	size = (lblock + 1) * bsize;

	if (size > ip->i_di.di_size) {
		height = calc_tree_height(ip, size);
		if (ip->i_di.di_height < height) {
			if (!create)
				goto out_ok;
	
			error = build_height(inode, height);
			if (error)
				goto out_fail;
		}
David Teigland's avatar
David Teigland committed
495
496
	}

497
	find_metapath(ip, lblock, &mp);
David Teigland's avatar
David Teigland committed
498
499
500
	end_of_metadata = ip->i_di.di_height - 1;
	error = gfs2_meta_inode_buffer(ip, &bh);
	if (error)
501
		goto out_fail;
David Teigland's avatar
David Teigland committed
502
503

	for (x = 0; x < end_of_metadata; x++) {
504
		lookup_block(ip, bh, x, &mp, create, &new, &dblock);
David Teigland's avatar
David Teigland committed
505
		brelse(bh);
506
		if (!dblock)
507
			goto out_ok;
David Teigland's avatar
David Teigland committed
508

509
		error = gfs2_meta_indirect_buffer(ip, x+1, dblock, new, &bh);
David Teigland's avatar
David Teigland committed
510
		if (error)
511
			goto out_fail;
David Teigland's avatar
David Teigland committed
512
513
	}

514
	boundary = lookup_block(ip, bh, end_of_metadata, &mp, create, &new, &dblock);
515
516
517
	if (dblock) {
		map_bh(bh_map, inode->i_sb, dblock);
		if (boundary)
518
			set_buffer_boundary(bh_map);
519
520
521
522
523
		if (new) {
			struct buffer_head *dibh;
			error = gfs2_meta_inode_buffer(ip, &dibh);
			if (!error) {
				gfs2_trans_add_bh(ip->i_gl, dibh, 1);
524
				gfs2_dinode_out(ip, dibh->b_data);
525
526
527
528
529
530
531
532
				brelse(dibh);
			}
			set_buffer_new(bh_map);
			goto out_brelse;
		}
		while(--maxlen && !buffer_boundary(bh_map)) {
			u64 eblock;

533
534
			mp.mp_list[end_of_metadata]++;
			boundary = lookup_block(ip, bh, end_of_metadata, &mp, 0, &new, &eblock);
535
536
			if (eblock != ++dblock)
				break;
537
			bh_map->b_size += (1 << inode->i_blkbits);
538
539
			if (boundary)
				set_buffer_boundary(bh_map);
David Teigland's avatar
David Teigland committed
540
541
		}
	}
542
543
out_brelse:
	brelse(bh);
544
545
546
out_ok:
	error = 0;
out_fail:
Steven Whitehouse's avatar
Steven Whitehouse committed
547
	bmap_unlock(inode, create);
548
	return error;
Steven Whitehouse's avatar
Steven Whitehouse committed
549
550
551
552
}

int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen)
{
553
	struct buffer_head bh = { .b_state = 0, .b_blocknr = 0 };
554
	int ret;
Steven Whitehouse's avatar
Steven Whitehouse committed
555
556
557
558
559
560
	int create = *new;

	BUG_ON(!extlen);
	BUG_ON(!dblock);
	BUG_ON(!new);

561
	bh.b_size = 1 << (inode->i_blkbits + 5);
562
	ret = gfs2_block_map(inode, lblock, create, &bh);
563
564
565
566
567
568
569
	*extlen = bh.b_size >> inode->i_blkbits;
	*dblock = bh.b_blocknr;
	if (buffer_new(&bh))
		*new = 1;
	else
		*new = 0;
	return ret;
David Teigland's avatar
David Teigland committed
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
}

/**
 * recursive_scan - recursively scan through the end of a file
 * @ip: the inode
 * @dibh: the dinode buffer
 * @mp: the path through the metadata to the point to start
 * @height: the height the recursion is at
 * @block: the indirect block to look at
 * @first: 1 if this is the first block
 * @bc: the call to make for each piece of metadata
 * @data: data opaque to this function to pass to @bc
 *
 * When this is first called @height and @block should be zero and
 * @first should be 1.
 *
 * Returns: errno
 */

static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh,
			  struct metapath *mp, unsigned int height,
591
			  u64 block, int first, block_call_t bc,
David Teigland's avatar
David Teigland committed
592
593
			  void *data)
{
594
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
David Teigland's avatar
David Teigland committed
595
	struct buffer_head *bh = NULL;
596
	__be64 *top, *bottom;
597
	u64 bn;
David Teigland's avatar
David Teigland committed
598
599
600
601
602
603
604
605
606
	int error;
	int mh_size = sizeof(struct gfs2_meta_header);

	if (!height) {
		error = gfs2_meta_inode_buffer(ip, &bh);
		if (error)
			return error;
		dibh = bh;

607
608
		top = (__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + mp->mp_list[0];
		bottom = (__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + sdp->sd_diptrs;
David Teigland's avatar
David Teigland committed
609
610
611
612
613
	} else {
		error = gfs2_meta_indirect_buffer(ip, height, block, 0, &bh);
		if (error)
			return error;

614
		top = (__be64 *)(bh->b_data + mh_size) +
Jan Engelhardt's avatar
Jan Engelhardt committed
615
				  (first ? mp->mp_list[height] : 0);
David Teigland's avatar
David Teigland committed
616

617
		bottom = (__be64 *)(bh->b_data + mh_size) + sdp->sd_inptrs;
David Teigland's avatar
David Teigland committed
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
	}

	error = bc(ip, dibh, bh, top, bottom, height, data);
	if (error)
		goto out;

	if (height < ip->i_di.di_height - 1)
		for (; top < bottom; top++, first = 0) {
			if (!*top)
				continue;

			bn = be64_to_cpu(*top);

			error = recursive_scan(ip, dibh, mp, height + 1, bn,
					       first, bc, data);
			if (error)
				break;
		}

637
out:
David Teigland's avatar
David Teigland committed
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
	brelse(bh);
	return error;
}

/**
 * do_strip - Look for a layer a particular layer of the file and strip it off
 * @ip: the inode
 * @dibh: the dinode buffer
 * @bh: A buffer of pointers
 * @top: The first pointer in the buffer
 * @bottom: One more than the last pointer
 * @height: the height this buffer is at
 * @data: a pointer to a struct strip_mine
 *
 * Returns: errno
 */

static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh,
656
		    struct buffer_head *bh, __be64 *top, __be64 *bottom,
David Teigland's avatar
David Teigland committed
657
658
		    unsigned int height, void *data)
{
659
660
	struct strip_mine *sm = data;
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
David Teigland's avatar
David Teigland committed
661
	struct gfs2_rgrp_list rlist;
662
663
	u64 bn, bstart;
	u32 blen;
664
	__be64 *p;
David Teigland's avatar
David Teigland committed
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
	unsigned int rg_blocks = 0;
	int metadata;
	unsigned int revokes = 0;
	int x;
	int error;

	if (!*top)
		sm->sm_first = 0;

	if (height != sm->sm_height)
		return 0;

	if (sm->sm_first) {
		top++;
		sm->sm_first = 0;
	}

682
	metadata = (height != ip->i_di.di_height - 1);
David Teigland's avatar
David Teigland committed
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
	if (metadata)
		revokes = (height) ? sdp->sd_inptrs : sdp->sd_diptrs;

	error = gfs2_rindex_hold(sdp, &ip->i_alloc.al_ri_gh);
	if (error)
		return error;

	memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));
	bstart = 0;
	blen = 0;

	for (p = top; p < bottom; p++) {
		if (!*p)
			continue;

		bn = be64_to_cpu(*p);

		if (bstart + blen == bn)
			blen++;
		else {
			if (bstart)
				gfs2_rlist_add(sdp, &rlist, bstart);

			bstart = bn;
			blen = 1;
		}
	}

	if (bstart)
		gfs2_rlist_add(sdp, &rlist, bstart);
	else
		goto out; /* Nothing to do */

	gfs2_rlist_alloc(&rlist, LM_ST_EXCLUSIVE, 0);

	for (x = 0; x < rlist.rl_rgrps; x++) {
		struct gfs2_rgrpd *rgd;
720
		rgd = rlist.rl_ghs[x].gh_gl->gl_object;
David Teigland's avatar
David Teigland committed
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
		rg_blocks += rgd->rd_ri.ri_length;
	}

	error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
	if (error)
		goto out_rlist;

	error = gfs2_trans_begin(sdp, rg_blocks + RES_DINODE +
				 RES_INDIRECT + RES_STATFS + RES_QUOTA,
				 revokes);
	if (error)
		goto out_rg_gunlock;

	down_write(&ip->i_rw_mutex);

736
737
	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
	gfs2_trans_add_bh(ip->i_gl, bh, 1);
David Teigland's avatar
David Teigland committed
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765

	bstart = 0;
	blen = 0;

	for (p = top; p < bottom; p++) {
		if (!*p)
			continue;

		bn = be64_to_cpu(*p);

		if (bstart + blen == bn)
			blen++;
		else {
			if (bstart) {
				if (metadata)
					gfs2_free_meta(ip, bstart, blen);
				else
					gfs2_free_data(ip, bstart, blen);
			}

			bstart = bn;
			blen = 1;
		}

		*p = 0;
		if (!ip->i_di.di_blocks)
			gfs2_consist_inode(ip);
		ip->i_di.di_blocks--;
766
		gfs2_set_inode_blocks(&ip->i_inode);
David Teigland's avatar
David Teigland committed
767
768
769
770
771
772
773
774
	}
	if (bstart) {
		if (metadata)
			gfs2_free_meta(ip, bstart, blen);
		else
			gfs2_free_data(ip, bstart, blen);
	}

775
	ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
David Teigland's avatar
David Teigland committed
776

777
	gfs2_dinode_out(ip, dibh->b_data);
David Teigland's avatar
David Teigland committed
778
779
780
781
782

	up_write(&ip->i_rw_mutex);

	gfs2_trans_end(sdp);

783
out_rg_gunlock:
David Teigland's avatar
David Teigland committed
784
	gfs2_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs);
785
out_rlist:
David Teigland's avatar
David Teigland committed
786
	gfs2_rlist_free(&rlist);
787
out:
David Teigland's avatar
David Teigland committed
788
789
790
791
792
793
794
795
796
797
798
799
800
801
	gfs2_glock_dq_uninit(&ip->i_alloc.al_ri_gh);
	return error;
}

/**
 * do_grow - Make a file look bigger than it is
 * @ip: the inode
 * @size: the size to set the file to
 *
 * Called with an exclusive lock on @ip.
 *
 * Returns: errno
 */

802
static int do_grow(struct gfs2_inode *ip, u64 size)
David Teigland's avatar
David Teigland committed
803
{
804
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
David Teigland's avatar
David Teigland committed
805
806
807
808
809
810
811
812
813
814
815
	struct gfs2_alloc *al;
	struct buffer_head *dibh;
	unsigned int h;
	int error;

	al = gfs2_alloc_get(ip);

	error = gfs2_quota_lock(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
	if (error)
		goto out;

816
	error = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid);
David Teigland's avatar
David Teigland committed
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
	if (error)
		goto out_gunlock_q;

	al->al_requested = sdp->sd_max_height + RES_DATA;

	error = gfs2_inplace_reserve(ip);
	if (error)
		goto out_gunlock_q;

	error = gfs2_trans_begin(sdp,
			sdp->sd_max_height + al->al_rgd->rd_ri.ri_length +
			RES_JDATA + RES_DINODE + RES_STATFS + RES_QUOTA, 0);
	if (error)
		goto out_ipres;

	if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) {
		if (gfs2_is_stuffed(ip)) {
834
			error = gfs2_unstuff_dinode(ip, NULL);
David Teigland's avatar
David Teigland committed
835
836
837
838
839
840
841
			if (error)
				goto out_end_trans;
		}

		h = calc_tree_height(ip, size);
		if (ip->i_di.di_height < h) {
			down_write(&ip->i_rw_mutex);
842
			error = build_height(&ip->i_inode, h);
David Teigland's avatar
David Teigland committed
843
844
845
846
847
848
849
			up_write(&ip->i_rw_mutex);
			if (error)
				goto out_end_trans;
		}
	}

	ip->i_di.di_size = size;
850
	ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
David Teigland's avatar
David Teigland committed
851
852
853
854
855

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (error)
		goto out_end_trans;

856
	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
857
	gfs2_dinode_out(ip, dibh->b_data);
David Teigland's avatar
David Teigland committed
858
859
	brelse(dibh);

860
out_end_trans:
David Teigland's avatar
David Teigland committed
861
	gfs2_trans_end(sdp);
862
out_ipres:
David Teigland's avatar
David Teigland committed
863
	gfs2_inplace_release(ip);
864
out_gunlock_q:
David Teigland's avatar
David Teigland committed
865
	gfs2_quota_unlock(ip);
866
out:
David Teigland's avatar
David Teigland committed
867
868
869
870
	gfs2_alloc_put(ip);
	return error;
}

Steven Whitehouse's avatar
Steven Whitehouse committed
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934

/**
 * gfs2_block_truncate_page - Deal with zeroing out data for truncate
 *
 * This is partly borrowed from ext3.
 */
static int gfs2_block_truncate_page(struct address_space *mapping)
{
	struct inode *inode = mapping->host;
	struct gfs2_inode *ip = GFS2_I(inode);
	struct gfs2_sbd *sdp = GFS2_SB(inode);
	loff_t from = inode->i_size;
	unsigned long index = from >> PAGE_CACHE_SHIFT;
	unsigned offset = from & (PAGE_CACHE_SIZE-1);
	unsigned blocksize, iblock, length, pos;
	struct buffer_head *bh;
	struct page *page;
	int err;

	page = grab_cache_page(mapping, index);
	if (!page)
		return 0;

	blocksize = inode->i_sb->s_blocksize;
	length = blocksize - (offset & (blocksize - 1));
	iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);

	if (!page_has_buffers(page))
		create_empty_buffers(page, blocksize, 0);

	/* Find the buffer that contains "offset" */
	bh = page_buffers(page);
	pos = blocksize;
	while (offset >= pos) {
		bh = bh->b_this_page;
		iblock++;
		pos += blocksize;
	}

	err = 0;

	if (!buffer_mapped(bh)) {
		gfs2_get_block(inode, iblock, bh, 0);
		/* unmapped? It's a hole - nothing to do */
		if (!buffer_mapped(bh))
			goto unlock;
	}

	/* Ok, it's mapped. Make sure it's up-to-date */
	if (PageUptodate(page))
		set_buffer_uptodate(bh);

	if (!buffer_uptodate(bh)) {
		err = -EIO;
		ll_rw_block(READ, 1, &bh);
		wait_on_buffer(bh);
		/* Uhhuh. Read error. Complain and punt. */
		if (!buffer_uptodate(bh))
			goto unlock;
	}

	if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip))
		gfs2_trans_add_bh(ip->i_gl, bh, 0);

Nate Diller's avatar
Nate Diller committed
935
	zero_user_page(page, offset, length, KM_USER0);
Steven Whitehouse's avatar
Steven Whitehouse committed
936
937
938
939
940
941
942

unlock:
	unlock_page(page);
	page_cache_release(page);
	return err;
}

943
static int trunc_start(struct gfs2_inode *ip, u64 size)
David Teigland's avatar
David Teigland committed
944
{
945
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
David Teigland's avatar
David Teigland committed
946
947
948
949
950
	struct buffer_head *dibh;
	int journaled = gfs2_is_jdata(ip);
	int error;

	error = gfs2_trans_begin(sdp,
Jan Engelhardt's avatar
Jan Engelhardt committed
951
				 RES_DINODE + (journaled ? RES_JDATA : 0), 0);
David Teigland's avatar
David Teigland committed
952
953
954
955
956
957
958
959
960
	if (error)
		return error;

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (error)
		goto out;

	if (gfs2_is_stuffed(ip)) {
		ip->i_di.di_size = size;
961
		ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
962
		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
963
		gfs2_dinode_out(ip, dibh->b_data);
David Teigland's avatar
David Teigland committed
964
965
966
967
		gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size);
		error = 1;

	} else {
968
		if (size & (u64)(sdp->sd_sb.sb_bsize - 1))
969
			error = gfs2_block_truncate_page(ip->i_inode.i_mapping);
David Teigland's avatar
David Teigland committed
970
971
972

		if (!error) {
			ip->i_di.di_size = size;
973
			ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
David Teigland's avatar
David Teigland committed
974
			ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG;
975
			gfs2_trans_add_bh(ip->i_gl, dibh, 1);
976
			gfs2_dinode_out(ip, dibh->b_data);
David Teigland's avatar
David Teigland committed
977
978
979
980
981
		}
	}

	brelse(dibh);

982
out:
David Teigland's avatar
David Teigland committed
983
984
985
986
	gfs2_trans_end(sdp);
	return error;
}

987
static int trunc_dealloc(struct gfs2_inode *ip, u64 size)
David Teigland's avatar
David Teigland committed
988
989
{
	unsigned int height = ip->i_di.di_height;
990
	u64 lblock;
David Teigland's avatar
David Teigland committed
991
992
993
994
995
	struct metapath mp;
	int error;

	if (!size)
		lblock = 0;
996
	else
997
		lblock = (size - 1) >> GFS2_SB(&ip->i_inode)->sd_sb.sb_bsize_shift;
David Teigland's avatar
David Teigland committed
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017

	find_metapath(ip, lblock, &mp);
	gfs2_alloc_get(ip);

	error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
	if (error)
		goto out;

	while (height--) {
		struct strip_mine sm;
		sm.sm_first = !!size;
		sm.sm_height = height;

		error = recursive_scan(ip, NULL, &mp, 0, 0, 1, do_strip, &sm);
		if (error)
			break;
	}

	gfs2_quota_unhold(ip);

1018
out:
David Teigland's avatar
David Teigland committed
1019
1020
1021
1022
1023
1024
	gfs2_alloc_put(ip);
	return error;
}

static int trunc_end(struct gfs2_inode *ip)
{
1025
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
David Teigland's avatar
David Teigland committed
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
	struct buffer_head *dibh;
	int error;

	error = gfs2_trans_begin(sdp, RES_DINODE, 0);
	if (error)
		return error;

	down_write(&ip->i_rw_mutex);

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (error)
		goto out;

	if (!ip->i_di.di_size) {
		ip->i_di.di_height = 0;
		ip->i_di.di_goal_meta =
			ip->i_di.di_goal_data =
			ip->i_num.no_addr;
		gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
	}
1046
	ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC;
David Teigland's avatar
David Teigland committed
1047
1048
	ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG;

1049
	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
1050
	gfs2_dinode_out(ip, dibh->b_data);
David Teigland's avatar
David Teigland committed
1051
1052
	brelse(dibh);

1053
out:
David Teigland's avatar
David Teigland committed
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
	up_write(&ip->i_rw_mutex);
	gfs2_trans_end(sdp);
	return error;
}

/**
 * do_shrink - make a file smaller
 * @ip: the inode
 * @size: the size to make the file
 * @truncator: function to truncate the last partial block
 *
 * Called with an exclusive lock on @ip.
 *
 * Returns: errno
 */

1070
static int do_shrink(struct gfs2_inode *ip, u64 size)
David Teigland's avatar
David Teigland committed
1071
1072
1073
{
	int error;

1074
	error = trunc_start(ip, size);
David Teigland's avatar
David Teigland committed
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
	if (error < 0)
		return error;
	if (error > 0)
		return 0;

	error = trunc_dealloc(ip, size);
	if (!error)
		error = trunc_end(ip);

	return error;
}

/**
1088
 * gfs2_truncatei - make a file a given size
David Teigland's avatar
David Teigland committed
1089
1090
1091
1092
1093
1094
1095
1096
1097
 * @ip: the inode
 * @size: the size to make the file
 * @truncator: function to truncate the last partial block
 *
 * The file size can grow, shrink, or stay the same size.
 *
 * Returns: errno
 */

1098
int gfs2_truncatei(struct gfs2_inode *ip, u64 size)
David Teigland's avatar
David Teigland committed
1099
1100
1101
{
	int error;

1102
	if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_inode.i_mode)))
David Teigland's avatar
David Teigland committed
1103
1104
1105
1106
1107
		return -EINVAL;

	if (size > ip->i_di.di_size)
		error = do_grow(ip, size);
	else
1108
		error = do_shrink(ip, size);
David Teigland's avatar
David Teigland committed
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138

	return error;
}

int gfs2_truncatei_resume(struct gfs2_inode *ip)
{
	int error;
	error = trunc_dealloc(ip, ip->i_di.di_size);
	if (!error)
		error = trunc_end(ip);
	return error;
}

int gfs2_file_dealloc(struct gfs2_inode *ip)
{
	return trunc_dealloc(ip, 0);
}

/**
 * gfs2_write_calc_reserv - calculate number of blocks needed to write to a file
 * @ip: the file
 * @len: the number of bytes to be written to the file
 * @data_blocks: returns the number of data blocks required
 * @ind_blocks: returns the number of indirect blocks required
 *
 */

void gfs2_write_calc_reserv(struct gfs2_inode *ip, unsigned int len,
			    unsigned int *data_blocks, unsigned int *ind_blocks)
{
1139
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
David Teigland's avatar
David Teigland committed
1140
1141
	unsigned int tmp;

1142
	if (gfs2_is_dir(ip)) {
1143
		*data_blocks = DIV_ROUND_UP(len, sdp->sd_jbsize) + 2;
David Teigland's avatar
David Teigland committed
1144
1145
1146
1147
1148
1149
1150
		*ind_blocks = 3 * (sdp->sd_max_jheight - 1);
	} else {
		*data_blocks = (len >> sdp->sd_sb.sb_bsize_shift) + 3;
		*ind_blocks = 3 * (sdp->sd_max_height - 1);
	}

	for (tmp = *data_blocks; tmp > sdp->sd_diptrs;) {
1151
		tmp = DIV_ROUND_UP(tmp, sdp->sd_inptrs);
David Teigland's avatar
David Teigland committed
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
		*ind_blocks += tmp;
	}
}

/**
 * gfs2_write_alloc_required - figure out if a write will require an allocation
 * @ip: the file being written to
 * @offset: the offset to write to
 * @len: the number of bytes being written
 * @alloc_required: set to 1 if an alloc is required, 0 otherwise
 *
 * Returns: errno
 */

1166
int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset,
David Teigland's avatar
David Teigland committed
1167
1168
			      unsigned int len, int *alloc_required)
{
1169
	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1170
1171
	u64 lblock, lblock_stop, dblock;
	u32 extlen;
David Teigland's avatar
David Teigland committed
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
	int new = 0;
	int error = 0;

	*alloc_required = 0;

	if (!len)
		return 0;

	if (gfs2_is_stuffed(ip)) {
		if (offset + len >
		    sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode))
			*alloc_required = 1;
		return 0;
	}

1187
	if (gfs2_is_dir(ip)) {
David Teigland's avatar
David Teigland committed
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
		unsigned int bsize = sdp->sd_jbsize;
		lblock = offset;
		do_div(lblock, bsize);
		lblock_stop = offset + len + bsize - 1;
		do_div(lblock_stop, bsize);
	} else {
		unsigned int shift = sdp->sd_sb.sb_bsize_shift;
		lblock = offset >> shift;
		lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift;
	}

	for (; lblock < lblock_stop; lblock += extlen) {
1200
		error = gfs2_extent_map(&ip->i_inode, lblock, &new, &dblock, &extlen);
David Teigland's avatar
David Teigland committed
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
		if (error)
			return error;

		if (!dblock) {
			*alloc_required = 1;
			return 0;
		}
	}

	return 0;
}