inode.c 58.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * inode.c
 *
 * PURPOSE
 *  Inode handling routines for the OSTA-UDF(tm) filesystem.
 *
 * COPYRIGHT
 *  This file is distributed under the terms of the GNU General Public
 *  License (GPL). Copies of the GPL can be obtained from:
 *    ftp://prep.ai.mit.edu/pub/gnu/GPL
 *  Each contributing author retains all rights to their own work.
 *
 *  (C) 1998 Dave Boynton
 *  (C) 1998-2004 Ben Fennema
 *  (C) 1999-2000 Stelias Computing Inc
 *
 * HISTORY
 *
 *  10/04/98 dgb  Added rudimentary directory functions
 *  10/07/98      Fully working udf_block_map! It works!
 *  11/25/98      bmap altered to better support extents
M
Marcin Slusarz 已提交
22 23
 *  12/06/98 blf  partition support in udf_iget, udf_block_map
 *                and udf_read_inode
L
Linus Torvalds 已提交
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
 *  12/12/98      rewrote udf_block_map to handle next extents and descs across
 *                block boundaries (which is not actually allowed)
 *  12/20/98      added support for strategy 4096
 *  03/07/99      rewrote udf_block_map (again)
 *                New funcs, inode_bmap, udf_next_aext
 *  04/19/99      Support for writing device EA's for major/minor #
 */

#include "udfdecl.h"
#include <linux/mm.h>
#include <linux/smp_lock.h>
#include <linux/module.h>
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
#include <linux/writeback.h>
39
#include <linux/quotaops.h>
L
Linus Torvalds 已提交
40
#include <linux/slab.h>
41
#include <linux/crc-itu-t.h>
L
Linus Torvalds 已提交
42 43 44 45 46 47 48 49 50 51 52 53 54

#include "udf_i.h"
#include "udf_sb.h"

MODULE_AUTHOR("Ben Fennema");
MODULE_DESCRIPTION("Universal Disk Format Filesystem");
MODULE_LICENSE("GPL");

#define EXTENT_MERGE_SIZE 5

static mode_t udf_convert_permissions(struct fileEntry *);
static int udf_update_inode(struct inode *, int);
static void udf_fill_inode(struct inode *, struct buffer_head *);
55
static int udf_alloc_i_data(struct inode *inode, size_t size);
56
static struct buffer_head *inode_getblk(struct inode *, sector_t, int *,
57
					sector_t *, int *);
J
Jan Kara 已提交
58
static int8_t udf_insert_aext(struct inode *, struct extent_position,
59
			      struct kernel_lb_addr, uint32_t);
L
Linus Torvalds 已提交
60
static void udf_split_extents(struct inode *, int *, int, int,
61
			      struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
L
Linus Torvalds 已提交
62
static void udf_prealloc_extents(struct inode *, int, int,
63
				 struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
L
Linus Torvalds 已提交
64
static void udf_merge_extents(struct inode *,
65
			      struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
L
Linus Torvalds 已提交
66
static void udf_update_extents(struct inode *,
67
			       struct kernel_long_ad[EXTENT_MERGE_SIZE], int, int,
68
			       struct extent_position *);
L
Linus Torvalds 已提交
69 70
static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);

71

72
void udf_delete_inode(struct inode *inode)
L
Linus Torvalds 已提交
73
{
74
	if (!is_bad_inode(inode))
75
		dquot_initialize(inode);
76

77 78
	truncate_inode_pages(&inode->i_data, 0);

L
Linus Torvalds 已提交
79 80 81 82 83 84 85 86 87 88 89 90
	if (is_bad_inode(inode))
		goto no_delete;

	inode->i_size = 0;
	udf_truncate(inode);
	lock_kernel();

	udf_update_inode(inode, IS_SYNC(inode));
	udf_free_inode(inode);

	unlock_kernel();
	return;
91 92

no_delete:
L
Linus Torvalds 已提交
93 94 95
	clear_inode(inode);
}

J
Jan Kara 已提交
96
/*
97 98 99 100
 * If we are going to release inode from memory, we truncate last inode extent
 * to proper length. We could use drop_inode() but it's called under inode_lock
 * and thus we cannot mark inode dirty there.  We use clear_inode() but we have
 * to make sure to write inode as it's not written automatically.
J
Jan Kara 已提交
101
 */
L
Linus Torvalds 已提交
102 103
void udf_clear_inode(struct inode *inode)
{
J
Jan Kara 已提交
104 105 106 107 108
	struct udf_inode_info *iinfo = UDF_I(inode);

	if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB &&
	    inode->i_size != iinfo->i_lenExtents) {
		printk(KERN_WARNING "UDF-fs (%s): Inode %lu (mode %o) has "
109
			"inode size %llu different from extent length %llu. "
J
Jan Kara 已提交
110 111 112 113
			"Filesystem need not be standards compliant.\n",
			inode->i_sb->s_id, inode->i_ino, inode->i_mode,
			(unsigned long long)inode->i_size,
			(unsigned long long)iinfo->i_lenExtents);
L
Linus Torvalds 已提交
114
	}
115

116
	dquot_drop(inode);
117 118
	kfree(iinfo->i_ext.i_data);
	iinfo->i_ext.i_data = NULL;
L
Linus Torvalds 已提交
119 120 121 122 123 124 125 126 127 128 129 130
}

static int udf_writepage(struct page *page, struct writeback_control *wbc)
{
	return block_write_full_page(page, udf_get_block, wbc);
}

static int udf_readpage(struct file *file, struct page *page)
{
	return block_read_full_page(page, udf_get_block);
}

N
Nick Piggin 已提交
131 132 133
static int udf_write_begin(struct file *file, struct address_space *mapping,
			loff_t pos, unsigned len, unsigned flags,
			struct page **pagep, void **fsdata)
L
Linus Torvalds 已提交
134
{
N
Nick Piggin 已提交
135 136 137
	*pagep = NULL;
	return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
				udf_get_block);
L
Linus Torvalds 已提交
138 139 140 141
}

static sector_t udf_bmap(struct address_space *mapping, sector_t block)
{
142
	return generic_block_bmap(mapping, block, udf_get_block);
L
Linus Torvalds 已提交
143 144
}

145
const struct address_space_operations udf_aops = {
146 147 148
	.readpage	= udf_readpage,
	.writepage	= udf_writepage,
	.sync_page	= block_sync_page,
N
Nick Piggin 已提交
149 150
	.write_begin		= udf_write_begin,
	.write_end		= generic_write_end,
151
	.bmap		= udf_bmap,
L
Linus Torvalds 已提交
152 153
};

154
void udf_expand_file_adinicb(struct inode *inode, int newsize, int *err)
L
Linus Torvalds 已提交
155 156 157
{
	struct page *page;
	char *kaddr;
158
	struct udf_inode_info *iinfo = UDF_I(inode);
L
Linus Torvalds 已提交
159 160 161 162 163 164 165 166
	struct writeback_control udf_wbc = {
		.sync_mode = WB_SYNC_NONE,
		.nr_to_write = 1,
	};

	/* from now on we have normal address_space methods */
	inode->i_data.a_ops = &udf_aops;

167
	if (!iinfo->i_lenAlloc) {
L
Linus Torvalds 已提交
168
		if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
169
			iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT;
L
Linus Torvalds 已提交
170
		else
171
			iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
L
Linus Torvalds 已提交
172 173 174 175 176
		mark_inode_dirty(inode);
		return;
	}

	page = grab_cache_page(inode->i_mapping, 0);
M
Matt Mackall 已提交
177 178
	BUG_ON(!PageLocked(page));

179
	if (!PageUptodate(page)) {
L
Linus Torvalds 已提交
180
		kaddr = kmap(page);
181 182 183 184
		memset(kaddr + iinfo->i_lenAlloc, 0x00,
		       PAGE_CACHE_SIZE - iinfo->i_lenAlloc);
		memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr,
			iinfo->i_lenAlloc);
L
Linus Torvalds 已提交
185 186 187 188
		flush_dcache_page(page);
		SetPageUptodate(page);
		kunmap(page);
	}
189 190 191
	memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0x00,
	       iinfo->i_lenAlloc);
	iinfo->i_lenAlloc = 0;
L
Linus Torvalds 已提交
192
	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
193
		iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT;
L
Linus Torvalds 已提交
194
	else
195
		iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
L
Linus Torvalds 已提交
196 197 198 199 200 201 202

	inode->i_data.a_ops->writepage(page, &udf_wbc);
	page_cache_release(page);

	mark_inode_dirty(inode);
}

203 204
struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block,
					   int *err)
L
Linus Torvalds 已提交
205 206
{
	int newblock;
J
Jan Kara 已提交
207
	struct buffer_head *dbh = NULL;
208
	struct kernel_lb_addr eloc;
L
Linus Torvalds 已提交
209
	uint8_t alloctype;
J
Jan Kara 已提交
210
	struct extent_position epos;
L
Linus Torvalds 已提交
211 212

	struct udf_fileident_bh sfibh, dfibh;
213 214
	loff_t f_pos = udf_ext0_offset(inode);
	int size = udf_ext0_offset(inode) + inode->i_size;
L
Linus Torvalds 已提交
215
	struct fileIdentDesc cfi, *sfi, *dfi;
216
	struct udf_inode_info *iinfo = UDF_I(inode);
L
Linus Torvalds 已提交
217 218 219 220 221 222

	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
		alloctype = ICBTAG_FLAG_AD_SHORT;
	else
		alloctype = ICBTAG_FLAG_AD_LONG;

223
	if (!inode->i_size) {
224
		iinfo->i_alloc_type = alloctype;
L
Linus Torvalds 已提交
225 226 227 228 229 230
		mark_inode_dirty(inode);
		return NULL;
	}

	/* alloc block, and copy data to it */
	*block = udf_new_block(inode->i_sb, inode,
231 232
			       iinfo->i_location.partitionReferenceNum,
			       iinfo->i_location.logicalBlockNum, err);
L
Linus Torvalds 已提交
233 234 235
	if (!(*block))
		return NULL;
	newblock = udf_get_pblock(inode->i_sb, *block,
236
				  iinfo->i_location.partitionReferenceNum,
237
				0);
L
Linus Torvalds 已提交
238 239 240 241 242 243 244 245 246 247 248
	if (!newblock)
		return NULL;
	dbh = udf_tgetblk(inode->i_sb, newblock);
	if (!dbh)
		return NULL;
	lock_buffer(dbh);
	memset(dbh->b_data, 0x00, inode->i_sb->s_blocksize);
	set_buffer_uptodate(dbh);
	unlock_buffer(dbh);
	mark_buffer_dirty_inode(dbh, inode);

M
Marcin Slusarz 已提交
249
	sfibh.soffset = sfibh.eoffset =
250
			f_pos & (inode->i_sb->s_blocksize - 1);
J
Jan Kara 已提交
251
	sfibh.sbh = sfibh.ebh = NULL;
L
Linus Torvalds 已提交
252 253
	dfibh.soffset = dfibh.eoffset = 0;
	dfibh.sbh = dfibh.ebh = dbh;
254
	while (f_pos < size) {
255
		iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
M
Marcin Slusarz 已提交
256 257
		sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL,
					 NULL, NULL, NULL);
258
		if (!sfi) {
J
Jan Kara 已提交
259
			brelse(dbh);
L
Linus Torvalds 已提交
260 261
			return NULL;
		}
262
		iinfo->i_alloc_type = alloctype;
L
Linus Torvalds 已提交
263 264 265 266 267
		sfi->descTag.tagLocation = cpu_to_le32(*block);
		dfibh.soffset = dfibh.eoffset;
		dfibh.eoffset += (sfibh.eoffset - sfibh.soffset);
		dfi = (struct fileIdentDesc *)(dbh->b_data + dfibh.soffset);
		if (udf_write_fi(inode, sfi, dfi, &dfibh, sfi->impUse,
M
Marcin Slusarz 已提交
268 269
				 sfi->fileIdent +
					le16_to_cpu(sfi->lengthOfImpUse))) {
270
			iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
J
Jan Kara 已提交
271
			brelse(dbh);
L
Linus Torvalds 已提交
272 273 274 275 276
			return NULL;
		}
	}
	mark_buffer_dirty_inode(dbh, inode);

277 278 279
	memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0,
		iinfo->i_lenAlloc);
	iinfo->i_lenAlloc = 0;
L
Linus Torvalds 已提交
280
	eloc.logicalBlockNum = *block;
M
Marcin Slusarz 已提交
281
	eloc.partitionReferenceNum =
282
				iinfo->i_location.partitionReferenceNum;
J
Jan Kara 已提交
283
	iinfo->i_lenExtents = inode->i_size;
J
Jan Kara 已提交
284
	epos.bh = NULL;
285
	epos.block = iinfo->i_location;
J
Jan Kara 已提交
286
	epos.offset = udf_file_entry_alloc_offset(inode);
J
Jan Kara 已提交
287
	udf_add_aext(inode, &epos, &eloc, inode->i_size, 0);
L
Linus Torvalds 已提交
288 289
	/* UniqueID stuff */

J
Jan Kara 已提交
290
	brelse(epos.bh);
L
Linus Torvalds 已提交
291 292 293 294
	mark_inode_dirty(inode);
	return dbh;
}

295 296
static int udf_get_block(struct inode *inode, sector_t block,
			 struct buffer_head *bh_result, int create)
L
Linus Torvalds 已提交
297 298 299
{
	int err, new;
	struct buffer_head *bh;
300
	sector_t phys = 0;
301
	struct udf_inode_info *iinfo;
L
Linus Torvalds 已提交
302

303
	if (!create) {
L
Linus Torvalds 已提交
304 305 306 307 308 309 310 311 312 313 314 315
		phys = udf_block_map(inode, block);
		if (phys)
			map_bh(bh_result, inode->i_sb, phys);
		return 0;
	}

	err = -EIO;
	new = 0;
	bh = NULL;

	lock_kernel();

316 317 318 319
	iinfo = UDF_I(inode);
	if (block == iinfo->i_next_alloc_block + 1) {
		iinfo->i_next_alloc_block++;
		iinfo->i_next_alloc_goal++;
L
Linus Torvalds 已提交
320 321 322 323 324
	}

	err = 0;

	bh = inode_getblk(inode, block, &err, &phys, &new);
E
Eric Sesterhenn 已提交
325
	BUG_ON(bh);
L
Linus Torvalds 已提交
326 327
	if (err)
		goto abort;
E
Eric Sesterhenn 已提交
328
	BUG_ON(!phys);
L
Linus Torvalds 已提交
329 330 331 332

	if (new)
		set_buffer_new(bh_result);
	map_bh(bh_result, inode->i_sb, phys);
333 334

abort:
L
Linus Torvalds 已提交
335 336 337 338
	unlock_kernel();
	return err;
}

339 340
static struct buffer_head *udf_getblk(struct inode *inode, long block,
				      int create, int *err)
L
Linus Torvalds 已提交
341
{
342
	struct buffer_head *bh;
L
Linus Torvalds 已提交
343 344 345 346 347
	struct buffer_head dummy;

	dummy.b_state = 0;
	dummy.b_blocknr = -1000;
	*err = udf_get_block(inode, block, &dummy, create);
348
	if (!*err && buffer_mapped(&dummy)) {
L
Linus Torvalds 已提交
349
		bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
350
		if (buffer_new(&dummy)) {
L
Linus Torvalds 已提交
351 352 353 354 355 356 357 358
			lock_buffer(bh);
			memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
			set_buffer_uptodate(bh);
			unlock_buffer(bh);
			mark_buffer_dirty_inode(bh, inode);
		}
		return bh;
	}
359

L
Linus Torvalds 已提交
360 361 362
	return NULL;
}

J
Jan Kara 已提交
363 364
/* Extend the file by 'blocks' blocks, return the number of extents added */
int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
365
		    struct kernel_long_ad *last_ext, sector_t blocks)
J
Jan Kara 已提交
366 367 368 369
{
	sector_t add;
	int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
	struct super_block *sb = inode->i_sb;
370
	struct kernel_lb_addr prealloc_loc = {};
J
Jan Kara 已提交
371
	int prealloc_len = 0;
372
	struct udf_inode_info *iinfo;
J
Jan Kara 已提交
373 374 375 376 377

	/* The previous extent is fake and we should not extend by anything
	 * - there's nothing to do... */
	if (!blocks && fake)
		return 0;
378

379
	iinfo = UDF_I(inode);
J
Jan Kara 已提交
380 381 382
	/* Round the last extent up to a multiple of block size */
	if (last_ext->extLength & (sb->s_blocksize - 1)) {
		last_ext->extLength =
383 384 385
			(last_ext->extLength & UDF_EXTENT_FLAG_MASK) |
			(((last_ext->extLength & UDF_EXTENT_LENGTH_MASK) +
			  sb->s_blocksize - 1) & ~(sb->s_blocksize - 1));
386 387
		iinfo->i_lenExtents =
			(iinfo->i_lenExtents + sb->s_blocksize - 1) &
388
			~(sb->s_blocksize - 1);
J
Jan Kara 已提交
389
	}
390

J
Jan Kara 已提交
391
	/* Last extent are just preallocated blocks? */
M
Marcin Slusarz 已提交
392 393
	if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
						EXT_NOT_RECORDED_ALLOCATED) {
J
Jan Kara 已提交
394 395 396 397 398
		/* Save the extent so that we can reattach it to the end */
		prealloc_loc = last_ext->extLocation;
		prealloc_len = last_ext->extLength;
		/* Mark the extent as a hole */
		last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
399
			(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
J
Jan Kara 已提交
400
		last_ext->extLocation.logicalBlockNum = 0;
M
Marcin Slusarz 已提交
401
		last_ext->extLocation.partitionReferenceNum = 0;
J
Jan Kara 已提交
402
	}
403

J
Jan Kara 已提交
404
	/* Can we merge with the previous extent? */
M
Marcin Slusarz 已提交
405 406 407 408 409
	if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
					EXT_NOT_RECORDED_NOT_ALLOCATED) {
		add = ((1 << 30) - sb->s_blocksize -
			(last_ext->extLength & UDF_EXTENT_LENGTH_MASK)) >>
			sb->s_blocksize_bits;
J
Jan Kara 已提交
410 411 412 413 414 415 416
		if (add > blocks)
			add = blocks;
		blocks -= add;
		last_ext->extLength += add << sb->s_blocksize_bits;
	}

	if (fake) {
417
		udf_add_aext(inode, last_pos, &last_ext->extLocation,
418
			     last_ext->extLength, 1);
J
Jan Kara 已提交
419
		count++;
M
Marcin Slusarz 已提交
420
	} else
421
		udf_write_aext(inode, last_pos, &last_ext->extLocation,
M
Marcin Slusarz 已提交
422
				last_ext->extLength, 1);
423

J
Jan Kara 已提交
424 425 426 427 428 429
	/* Managed to do everything necessary? */
	if (!blocks)
		goto out;

	/* All further extents will be NOT_RECORDED_NOT_ALLOCATED */
	last_ext->extLocation.logicalBlockNum = 0;
M
Marcin Slusarz 已提交
430
	last_ext->extLocation.partitionReferenceNum = 0;
431
	add = (1 << (30-sb->s_blocksize_bits)) - 1;
M
Marcin Slusarz 已提交
432 433
	last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
				(add << sb->s_blocksize_bits);
434

J
Jan Kara 已提交
435 436 437
	/* Create enough extents to cover the whole hole */
	while (blocks > add) {
		blocks -= add;
438
		if (udf_add_aext(inode, last_pos, &last_ext->extLocation,
439
				 last_ext->extLength, 1) == -1)
J
Jan Kara 已提交
440 441 442 443 444
			return -1;
		count++;
	}
	if (blocks) {
		last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
445
			(blocks << sb->s_blocksize_bits);
446
		if (udf_add_aext(inode, last_pos, &last_ext->extLocation,
447
				 last_ext->extLength, 1) == -1)
J
Jan Kara 已提交
448 449 450
			return -1;
		count++;
	}
451 452

out:
J
Jan Kara 已提交
453 454
	/* Do we have some preallocated blocks saved? */
	if (prealloc_len) {
455
		if (udf_add_aext(inode, last_pos, &prealloc_loc,
M
Marcin Slusarz 已提交
456
				 prealloc_len, 1) == -1)
J
Jan Kara 已提交
457 458 459 460 461
			return -1;
		last_ext->extLocation = prealloc_loc;
		last_ext->extLength = prealloc_len;
		count++;
	}
462

J
Jan Kara 已提交
463
	/* last_pos should point to the last written extent... */
464
	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
465
		last_pos->offset -= sizeof(struct short_ad);
466
	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
467
		last_pos->offset -= sizeof(struct long_ad);
J
Jan Kara 已提交
468 469
	else
		return -1;
470

J
Jan Kara 已提交
471 472 473
	return count;
}

474
static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
475
					int *err, sector_t *phys, int *new)
L
Linus Torvalds 已提交
476
{
J
Jan Kara 已提交
477
	static sector_t last_block;
J
Jan Kara 已提交
478
	struct buffer_head *result = NULL;
479
	struct kernel_long_ad laarr[EXTENT_MERGE_SIZE];
J
Jan Kara 已提交
480
	struct extent_position prev_epos, cur_epos, next_epos;
L
Linus Torvalds 已提交
481
	int count = 0, startnum = 0, endnum = 0;
J
Jan Kara 已提交
482
	uint32_t elen = 0, tmpelen;
483
	struct kernel_lb_addr eloc, tmpeloc;
L
Linus Torvalds 已提交
484
	int c = 1;
485 486 487
	loff_t lbcount = 0, b_off = 0;
	uint32_t newblocknum, newblock;
	sector_t offset = 0;
L
Linus Torvalds 已提交
488
	int8_t etype;
489 490
	struct udf_inode_info *iinfo = UDF_I(inode);
	int goal = 0, pgoal = iinfo->i_location.logicalBlockNum;
J
Jan Kara 已提交
491
	int lastblock = 0;
L
Linus Torvalds 已提交
492

J
Jan Kara 已提交
493
	prev_epos.offset = udf_file_entry_alloc_offset(inode);
494
	prev_epos.block = iinfo->i_location;
J
Jan Kara 已提交
495 496
	prev_epos.bh = NULL;
	cur_epos = next_epos = prev_epos;
497
	b_off = (loff_t)block << inode->i_sb->s_blocksize_bits;
L
Linus Torvalds 已提交
498 499

	/* find the extent which contains the block we are looking for.
500 501 502 503
	   alternate between laarr[0] and laarr[1] for locations of the
	   current extent, and the previous extent */
	do {
		if (prev_epos.bh != cur_epos.bh) {
J
Jan Kara 已提交
504 505
			brelse(prev_epos.bh);
			get_bh(cur_epos.bh);
J
Jan Kara 已提交
506
			prev_epos.bh = cur_epos.bh;
L
Linus Torvalds 已提交
507
		}
508
		if (cur_epos.bh != next_epos.bh) {
J
Jan Kara 已提交
509 510
			brelse(cur_epos.bh);
			get_bh(next_epos.bh);
J
Jan Kara 已提交
511
			cur_epos.bh = next_epos.bh;
L
Linus Torvalds 已提交
512 513 514 515
		}

		lbcount += elen;

J
Jan Kara 已提交
516 517
		prev_epos.block = cur_epos.block;
		cur_epos.block = next_epos.block;
L
Linus Torvalds 已提交
518

J
Jan Kara 已提交
519 520
		prev_epos.offset = cur_epos.offset;
		cur_epos.offset = next_epos.offset;
L
Linus Torvalds 已提交
521

M
Marcin Slusarz 已提交
522 523
		etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 1);
		if (etype == -1)
L
Linus Torvalds 已提交
524 525 526 527 528 529 530 531 532
			break;

		c = !c;

		laarr[c].extLength = (etype << 30) | elen;
		laarr[c].extLocation = eloc;

		if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
			pgoal = eloc.logicalBlockNum +
533 534
				((elen + inode->i_sb->s_blocksize - 1) >>
				 inode->i_sb->s_blocksize_bits);
L
Linus Torvalds 已提交
535

536
		count++;
L
Linus Torvalds 已提交
537 538 539 540
	} while (lbcount + elen <= b_off);

	b_off -= lbcount;
	offset = b_off >> inode->i_sb->s_blocksize_bits;
J
Jan Kara 已提交
541 542 543 544 545 546
	/*
	 * Move prev_epos and cur_epos into indirect extent if we are at
	 * the pointer to it
	 */
	udf_next_aext(inode, &prev_epos, &tmpeloc, &tmpelen, 0);
	udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, 0);
L
Linus Torvalds 已提交
547 548

	/* if the extent is allocated and recorded, return the block
549
	   if the extent is not a multiple of the blocksize, round up */
L
Linus Torvalds 已提交
550

551 552
	if (etype == (EXT_RECORDED_ALLOCATED >> 30)) {
		if (elen & (inode->i_sb->s_blocksize - 1)) {
L
Linus Torvalds 已提交
553
			elen = EXT_RECORDED_ALLOCATED |
554 555
				((elen + inode->i_sb->s_blocksize - 1) &
				 ~(inode->i_sb->s_blocksize - 1));
556
			etype = udf_write_aext(inode, &cur_epos, &eloc, elen, 1);
L
Linus Torvalds 已提交
557
		}
J
Jan Kara 已提交
558 559 560
		brelse(prev_epos.bh);
		brelse(cur_epos.bh);
		brelse(next_epos.bh);
561
		newblock = udf_get_lb_pblock(inode->i_sb, &eloc, offset);
L
Linus Torvalds 已提交
562 563 564 565
		*phys = newblock;
		return NULL;
	}

J
Jan Kara 已提交
566 567
	last_block = block;
	/* Are we beyond EOF? */
568
	if (etype == -1) {
J
Jan Kara 已提交
569 570 571 572 573 574
		int ret;

		if (count) {
			if (c)
				laarr[0] = laarr[1];
			startnum = 1;
575
		} else {
J
Jan Kara 已提交
576
			/* Create a fake extent when there's not one */
M
Marcin Slusarz 已提交
577
			memset(&laarr[0].extLocation, 0x00,
578
				sizeof(struct kernel_lb_addr));
J
Jan Kara 已提交
579
			laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED;
M
Marcin Slusarz 已提交
580 581
			/* Will udf_extend_file() create real extent from
			   a fake one? */
J
Jan Kara 已提交
582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
			startnum = (offset > 0);
		}
		/* Create extents for the hole between EOF and offset */
		ret = udf_extend_file(inode, &prev_epos, laarr, offset);
		if (ret == -1) {
			brelse(prev_epos.bh);
			brelse(cur_epos.bh);
			brelse(next_epos.bh);
			/* We don't really know the error here so we just make
			 * something up */
			*err = -ENOSPC;
			return NULL;
		}
		c = 0;
		offset = 0;
		count += ret;
		/* We are not covered by a preallocated extent? */
M
Marcin Slusarz 已提交
599 600
		if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) !=
						EXT_NOT_RECORDED_ALLOCATED) {
J
Jan Kara 已提交
601 602 603 604 605
			/* Is there any real extent? - otherwise we overwrite
			 * the fake one... */
			if (count)
				c = !c;
			laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
606
				inode->i_sb->s_blocksize;
M
Marcin Slusarz 已提交
607
			memset(&laarr[c].extLocation, 0x00,
608
				sizeof(struct kernel_lb_addr));
609 610
			count++;
			endnum++;
J
Jan Kara 已提交
611
		}
612
		endnum = c + 1;
L
Linus Torvalds 已提交
613
		lastblock = 1;
614
	} else {
L
Linus Torvalds 已提交
615 616
		endnum = startnum = ((count > 2) ? 2 : count);

M
Marcin Slusarz 已提交
617 618
		/* if the current extent is in position 0,
		   swap it with the previous */
619
		if (!c && count != 1) {
J
Jan Kara 已提交
620 621 622 623 624
			laarr[2] = laarr[0];
			laarr[0] = laarr[1];
			laarr[1] = laarr[2];
			c = 1;
		}
L
Linus Torvalds 已提交
625

M
Marcin Slusarz 已提交
626 627 628 629
		/* if the current block is located in an extent,
		   read the next extent */
		etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 0);
		if (etype != -1) {
630 631 632 633 634
			laarr[c + 1].extLength = (etype << 30) | elen;
			laarr[c + 1].extLocation = eloc;
			count++;
			startnum++;
			endnum++;
M
Marcin Slusarz 已提交
635
		} else
L
Linus Torvalds 已提交
636 637 638 639
			lastblock = 1;
	}

	/* if the current extent is not recorded but allocated, get the
640
	 * block in the extent corresponding to the requested block */
M
Marcin Slusarz 已提交
641
	if ((laarr[c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
L
Linus Torvalds 已提交
642
		newblocknum = laarr[c].extLocation.logicalBlockNum + offset;
M
Marcin Slusarz 已提交
643
	else { /* otherwise, allocate a new block */
644 645
		if (iinfo->i_next_alloc_block == block)
			goal = iinfo->i_next_alloc_goal;
L
Linus Torvalds 已提交
646

647
		if (!goal) {
M
Marcin Slusarz 已提交
648
			if (!(goal = pgoal)) /* XXX: what was intended here? */
649
				goal = iinfo->i_location.logicalBlockNum + 1;
L
Linus Torvalds 已提交
650 651
		}

M
Marcin Slusarz 已提交
652
		newblocknum = udf_new_block(inode->i_sb, inode,
653
				iinfo->i_location.partitionReferenceNum,
M
Marcin Slusarz 已提交
654 655
				goal, err);
		if (!newblocknum) {
J
Jan Kara 已提交
656
			brelse(prev_epos.bh);
L
Linus Torvalds 已提交
657 658 659
			*err = -ENOSPC;
			return NULL;
		}
660
		iinfo->i_lenExtents += inode->i_sb->s_blocksize;
L
Linus Torvalds 已提交
661 662
	}

M
Marcin Slusarz 已提交
663 664 665 666
	/* if the extent the requsted block is located in contains multiple
	 * blocks, split the extent into at most three extents. blocks prior
	 * to requested block, requested block, and blocks after requested
	 * block */
L
Linus Torvalds 已提交
667 668 669
	udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum);

#ifdef UDF_PREALLOCATE
670 671 672 673 674 675
	/* We preallocate blocks only for regular files. It also makes sense
	 * for directories but there's a problem when to drop the
	 * preallocation. We might use some delayed work for that but I feel
	 * it's overengineering for a filesystem like UDF. */
	if (S_ISREG(inode->i_mode))
		udf_prealloc_extents(inode, c, lastblock, laarr, &endnum);
L
Linus Torvalds 已提交
676 677 678 679 680 681
#endif

	/* merge any continuous blocks in laarr */
	udf_merge_extents(inode, laarr, &endnum);

	/* write back the new extents, inserting new extents if the new number
682 683
	 * of extents is greater than the old number, and deleting extents if
	 * the new number of extents is less than the old number */
J
Jan Kara 已提交
684
	udf_update_extents(inode, laarr, startnum, endnum, &prev_epos);
L
Linus Torvalds 已提交
685

J
Jan Kara 已提交
686
	brelse(prev_epos.bh);
L
Linus Torvalds 已提交
687

M
Marcin Slusarz 已提交
688
	newblock = udf_get_pblock(inode->i_sb, newblocknum,
689
				iinfo->i_location.partitionReferenceNum, 0);
M
Marcin Slusarz 已提交
690
	if (!newblock)
L
Linus Torvalds 已提交
691 692 693 694
		return NULL;
	*phys = newblock;
	*err = 0;
	*new = 1;
695 696
	iinfo->i_next_alloc_block = block;
	iinfo->i_next_alloc_goal = newblocknum;
L
Linus Torvalds 已提交
697 698 699 700 701 702
	inode->i_ctime = current_fs_time(inode->i_sb);

	if (IS_SYNC(inode))
		udf_sync_inode(inode);
	else
		mark_inode_dirty(inode);
703

L
Linus Torvalds 已提交
704 705 706
	return result;
}

707 708
static void udf_split_extents(struct inode *inode, int *c, int offset,
			      int newblocknum,
709
			      struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
710
			      int *endnum)
L
Linus Torvalds 已提交
711
{
M
Marcin Slusarz 已提交
712 713 714
	unsigned long blocksize = inode->i_sb->s_blocksize;
	unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;

L
Linus Torvalds 已提交
715
	if ((laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30) ||
M
Marcin Slusarz 已提交
716 717
	    (laarr[*c].extLength >> 30) ==
				(EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) {
L
Linus Torvalds 已提交
718 719
		int curr = *c;
		int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) +
M
Marcin Slusarz 已提交
720
			    blocksize - 1) >> blocksize_bits;
L
Linus Torvalds 已提交
721 722
		int8_t etype = (laarr[curr].extLength >> 30);

M
Marcin Slusarz 已提交
723
		if (blen == 1)
724
			;
M
Marcin Slusarz 已提交
725
		else if (!offset || blen == offset + 1) {
726 727 728 729 730 731 732 733 734
			laarr[curr + 2] = laarr[curr + 1];
			laarr[curr + 1] = laarr[curr];
		} else {
			laarr[curr + 3] = laarr[curr + 1];
			laarr[curr + 2] = laarr[curr + 1] = laarr[curr];
		}

		if (offset) {
			if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
M
Marcin Slusarz 已提交
735
				udf_free_blocks(inode->i_sb, inode,
736
						&laarr[curr].extLocation,
M
Marcin Slusarz 已提交
737 738 739 740
						0, offset);
				laarr[curr].extLength =
					EXT_NOT_RECORDED_NOT_ALLOCATED |
					(offset << blocksize_bits);
L
Linus Torvalds 已提交
741
				laarr[curr].extLocation.logicalBlockNum = 0;
M
Marcin Slusarz 已提交
742 743 744
				laarr[curr].extLocation.
						partitionReferenceNum = 0;
			} else
L
Linus Torvalds 已提交
745
				laarr[curr].extLength = (etype << 30) |
M
Marcin Slusarz 已提交
746
					(offset << blocksize_bits);
747 748 749
			curr++;
			(*c)++;
			(*endnum)++;
L
Linus Torvalds 已提交
750
		}
751

L
Linus Torvalds 已提交
752 753 754
		laarr[curr].extLocation.logicalBlockNum = newblocknum;
		if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
			laarr[curr].extLocation.partitionReferenceNum =
755
				UDF_I(inode)->i_location.partitionReferenceNum;
L
Linus Torvalds 已提交
756
		laarr[curr].extLength = EXT_RECORDED_ALLOCATED |
M
Marcin Slusarz 已提交
757
			blocksize;
758
		curr++;
L
Linus Torvalds 已提交
759

760
		if (blen != offset + 1) {
L
Linus Torvalds 已提交
761
			if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
M
Marcin Slusarz 已提交
762 763
				laarr[curr].extLocation.logicalBlockNum +=
								offset + 1;
764
			laarr[curr].extLength = (etype << 30) |
M
Marcin Slusarz 已提交
765
				((blen - (offset + 1)) << blocksize_bits);
766 767
			curr++;
			(*endnum)++;
L
Linus Torvalds 已提交
768 769 770 771 772
		}
	}
}

static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
773
				 struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
774
				 int *endnum)
L
Linus Torvalds 已提交
775 776 777
{
	int start, length = 0, currlength = 0, i;

778
	if (*endnum >= (c + 1)) {
L
Linus Torvalds 已提交
779 780 781 782
		if (!lastblock)
			return;
		else
			start = c;
783
	} else {
M
Marcin Slusarz 已提交
784 785
		if ((laarr[c + 1].extLength >> 30) ==
					(EXT_NOT_RECORDED_ALLOCATED >> 30)) {
786
			start = c + 1;
M
Marcin Slusarz 已提交
787 788 789 790 791 792
			length = currlength =
				(((laarr[c + 1].extLength &
					UDF_EXTENT_LENGTH_MASK) +
				inode->i_sb->s_blocksize - 1) >>
				inode->i_sb->s_blocksize_bits);
		} else
L
Linus Torvalds 已提交
793 794 795
			start = c;
	}

796 797
	for (i = start + 1; i <= *endnum; i++) {
		if (i == *endnum) {
L
Linus Torvalds 已提交
798 799
			if (lastblock)
				length += UDF_DEFAULT_PREALLOC_BLOCKS;
M
Marcin Slusarz 已提交
800 801 802 803 804 805 806
		} else if ((laarr[i].extLength >> 30) ==
				(EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) {
			length += (((laarr[i].extLength &
						UDF_EXTENT_LENGTH_MASK) +
				    inode->i_sb->s_blocksize - 1) >>
				    inode->i_sb->s_blocksize_bits);
		} else
L
Linus Torvalds 已提交
807 808 809
			break;
	}

810
	if (length) {
L
Linus Torvalds 已提交
811
		int next = laarr[start].extLocation.logicalBlockNum +
812
			(((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) +
M
Marcin Slusarz 已提交
813 814
			  inode->i_sb->s_blocksize - 1) >>
			  inode->i_sb->s_blocksize_bits);
L
Linus Torvalds 已提交
815
		int numalloc = udf_prealloc_blocks(inode->i_sb, inode,
M
Marcin Slusarz 已提交
816 817 818 819
				laarr[start].extLocation.partitionReferenceNum,
				next, (UDF_DEFAULT_PREALLOC_BLOCKS > length ?
				length : UDF_DEFAULT_PREALLOC_BLOCKS) -
				currlength);
820
		if (numalloc) 	{
M
Marcin Slusarz 已提交
821
			if (start == (c + 1))
L
Linus Torvalds 已提交
822
				laarr[start].extLength +=
M
Marcin Slusarz 已提交
823 824 825
					(numalloc <<
					 inode->i_sb->s_blocksize_bits);
			else {
826
				memmove(&laarr[c + 2], &laarr[c + 1],
827
					sizeof(struct long_ad) * (*endnum - (c + 1)));
828 829 830
				(*endnum)++;
				laarr[c + 1].extLocation.logicalBlockNum = next;
				laarr[c + 1].extLocation.partitionReferenceNum =
M
Marcin Slusarz 已提交
831 832 833 834 835 836
					laarr[c].extLocation.
							partitionReferenceNum;
				laarr[c + 1].extLength =
					EXT_NOT_RECORDED_ALLOCATED |
					(numalloc <<
					 inode->i_sb->s_blocksize_bits);
837
				start = c + 1;
L
Linus Torvalds 已提交
838 839
			}

840
			for (i = start + 1; numalloc && i < *endnum; i++) {
M
Marcin Slusarz 已提交
841 842 843 844
				int elen = ((laarr[i].extLength &
						UDF_EXTENT_LENGTH_MASK) +
					    inode->i_sb->s_blocksize - 1) >>
					    inode->i_sb->s_blocksize_bits;
L
Linus Torvalds 已提交
845

846
				if (elen > numalloc) {
L
Linus Torvalds 已提交
847
					laarr[i].extLength -=
M
Marcin Slusarz 已提交
848 849
						(numalloc <<
						 inode->i_sb->s_blocksize_bits);
L
Linus Torvalds 已提交
850
					numalloc = 0;
851
				} else {
L
Linus Torvalds 已提交
852
					numalloc -= elen;
853
					if (*endnum > (i + 1))
M
Marcin Slusarz 已提交
854 855
						memmove(&laarr[i],
							&laarr[i + 1],
856
							sizeof(struct long_ad) *
M
Marcin Slusarz 已提交
857
							(*endnum - (i + 1)));
858 859
					i--;
					(*endnum)--;
L
Linus Torvalds 已提交
860 861
				}
			}
862
			UDF_I(inode)->i_lenExtents +=
M
Marcin Slusarz 已提交
863
				numalloc << inode->i_sb->s_blocksize_bits;
L
Linus Torvalds 已提交
864 865 866 867 868
		}
	}
}

static void udf_merge_extents(struct inode *inode,
869
			      struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
870
			      int *endnum)
L
Linus Torvalds 已提交
871 872
{
	int i;
M
Marcin Slusarz 已提交
873 874
	unsigned long blocksize = inode->i_sb->s_blocksize;
	unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
L
Linus Torvalds 已提交
875

876
	for (i = 0; i < (*endnum - 1); i++) {
877 878
		struct kernel_long_ad *li /*l[i]*/ = &laarr[i];
		struct kernel_long_ad *lip1 /*l[i plus 1]*/ = &laarr[i + 1];
M
Marcin Slusarz 已提交
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

		if (((li->extLength >> 30) == (lip1->extLength >> 30)) &&
			(((li->extLength >> 30) ==
				(EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) ||
			((lip1->extLocation.logicalBlockNum -
			  li->extLocation.logicalBlockNum) ==
			(((li->extLength & UDF_EXTENT_LENGTH_MASK) +
			blocksize - 1) >> blocksize_bits)))) {

			if (((li->extLength & UDF_EXTENT_LENGTH_MASK) +
				(lip1->extLength & UDF_EXTENT_LENGTH_MASK) +
				blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) {
				lip1->extLength = (lip1->extLength -
						  (li->extLength &
						   UDF_EXTENT_LENGTH_MASK) +
						   UDF_EXTENT_LENGTH_MASK) &
							~(blocksize - 1);
				li->extLength = (li->extLength &
						 UDF_EXTENT_FLAG_MASK) +
						(UDF_EXTENT_LENGTH_MASK + 1) -
						blocksize;
				lip1->extLocation.logicalBlockNum =
					li->extLocation.logicalBlockNum +
					((li->extLength &
						UDF_EXTENT_LENGTH_MASK) >>
						blocksize_bits);
			} else {
				li->extLength = lip1->extLength +
					(((li->extLength &
						UDF_EXTENT_LENGTH_MASK) +
					 blocksize - 1) & ~(blocksize - 1));
				if (*endnum > (i + 2))
					memmove(&laarr[i + 1], &laarr[i + 2],
912
						sizeof(struct long_ad) *
M
Marcin Slusarz 已提交
913 914 915
						(*endnum - (i + 2)));
				i--;
				(*endnum)--;
L
Linus Torvalds 已提交
916
			}
M
Marcin Slusarz 已提交
917 918 919 920
		} else if (((li->extLength >> 30) ==
				(EXT_NOT_RECORDED_ALLOCATED >> 30)) &&
			   ((lip1->extLength >> 30) ==
				(EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))) {
921
			udf_free_blocks(inode->i_sb, inode, &li->extLocation, 0,
M
Marcin Slusarz 已提交
922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939
					((li->extLength &
					  UDF_EXTENT_LENGTH_MASK) +
					 blocksize - 1) >> blocksize_bits);
			li->extLocation.logicalBlockNum = 0;
			li->extLocation.partitionReferenceNum = 0;

			if (((li->extLength & UDF_EXTENT_LENGTH_MASK) +
			     (lip1->extLength & UDF_EXTENT_LENGTH_MASK) +
			     blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) {
				lip1->extLength = (lip1->extLength -
						   (li->extLength &
						   UDF_EXTENT_LENGTH_MASK) +
						   UDF_EXTENT_LENGTH_MASK) &
						   ~(blocksize - 1);
				li->extLength = (li->extLength &
						 UDF_EXTENT_FLAG_MASK) +
						(UDF_EXTENT_LENGTH_MASK + 1) -
						blocksize;
940
			} else {
M
Marcin Slusarz 已提交
941 942 943 944
				li->extLength = lip1->extLength +
					(((li->extLength &
						UDF_EXTENT_LENGTH_MASK) +
					  blocksize - 1) & ~(blocksize - 1));
945 946
				if (*endnum > (i + 2))
					memmove(&laarr[i + 1], &laarr[i + 2],
947
						sizeof(struct long_ad) *
M
Marcin Slusarz 已提交
948
						(*endnum - (i + 2)));
949 950
				i--;
				(*endnum)--;
L
Linus Torvalds 已提交
951
			}
M
Marcin Slusarz 已提交
952 953 954
		} else if ((li->extLength >> 30) ==
					(EXT_NOT_RECORDED_ALLOCATED >> 30)) {
			udf_free_blocks(inode->i_sb, inode,
955
					&li->extLocation, 0,
M
Marcin Slusarz 已提交
956 957 958 959 960 961 962 963
					((li->extLength &
						UDF_EXTENT_LENGTH_MASK) +
					 blocksize - 1) >> blocksize_bits);
			li->extLocation.logicalBlockNum = 0;
			li->extLocation.partitionReferenceNum = 0;
			li->extLength = (li->extLength &
						UDF_EXTENT_LENGTH_MASK) |
						EXT_NOT_RECORDED_NOT_ALLOCATED;
L
Linus Torvalds 已提交
964 965 966 967 968
		}
	}
}

static void udf_update_extents(struct inode *inode,
969
			       struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
970 971
			       int startnum, int endnum,
			       struct extent_position *epos)
L
Linus Torvalds 已提交
972 973
{
	int start = 0, i;
974
	struct kernel_lb_addr tmploc;
L
Linus Torvalds 已提交
975 976
	uint32_t tmplen;

977 978
	if (startnum > endnum) {
		for (i = 0; i < (startnum - endnum); i++)
J
Jan Kara 已提交
979
			udf_delete_aext(inode, *epos, laarr[i].extLocation,
980 981 982
					laarr[i].extLength);
	} else if (startnum < endnum) {
		for (i = 0; i < (endnum - startnum); i++) {
J
Jan Kara 已提交
983
			udf_insert_aext(inode, *epos, laarr[i].extLocation,
984
					laarr[i].extLength);
J
Jan Kara 已提交
985
			udf_next_aext(inode, epos, &laarr[i].extLocation,
986 987
				      &laarr[i].extLength, 1);
			start++;
L
Linus Torvalds 已提交
988 989 990
		}
	}

991
	for (i = start; i < endnum; i++) {
J
Jan Kara 已提交
992
		udf_next_aext(inode, epos, &tmploc, &tmplen, 0);
993
		udf_write_aext(inode, epos, &laarr[i].extLocation,
994
			       laarr[i].extLength, 1);
L
Linus Torvalds 已提交
995 996 997
	}
}

998 999
struct buffer_head *udf_bread(struct inode *inode, int block,
			      int create, int *err)
L
Linus Torvalds 已提交
1000
{
1001
	struct buffer_head *bh = NULL;
L
Linus Torvalds 已提交
1002 1003 1004 1005 1006 1007 1008

	bh = udf_getblk(inode, block, create, err);
	if (!bh)
		return NULL;

	if (buffer_uptodate(bh))
		return bh;
1009

L
Linus Torvalds 已提交
1010
	ll_rw_block(READ, 1, &bh);
1011

L
Linus Torvalds 已提交
1012 1013 1014
	wait_on_buffer(bh);
	if (buffer_uptodate(bh))
		return bh;
1015

L
Linus Torvalds 已提交
1016 1017 1018 1019 1020
	brelse(bh);
	*err = -EIO;
	return NULL;
}

1021
void udf_truncate(struct inode *inode)
L
Linus Torvalds 已提交
1022 1023 1024
{
	int offset;
	int err;
1025
	struct udf_inode_info *iinfo;
L
Linus Torvalds 已提交
1026 1027

	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
1028
	      S_ISLNK(inode->i_mode)))
L
Linus Torvalds 已提交
1029 1030 1031 1032 1033
		return;
	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
		return;

	lock_kernel();
1034 1035
	iinfo = UDF_I(inode);
	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
M
Marcin Slusarz 已提交
1036 1037 1038
		if (inode->i_sb->s_blocksize <
				(udf_file_entry_alloc_offset(inode) +
				 inode->i_size)) {
L
Linus Torvalds 已提交
1039
			udf_expand_file_adinicb(inode, inode->i_size, &err);
1040 1041
			if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
				inode->i_size = iinfo->i_lenAlloc;
L
Linus Torvalds 已提交
1042 1043
				unlock_kernel();
				return;
M
Marcin Slusarz 已提交
1044
			} else
L
Linus Torvalds 已提交
1045
				udf_truncate_extents(inode);
1046
		} else {
L
Linus Torvalds 已提交
1047
			offset = inode->i_size & (inode->i_sb->s_blocksize - 1);
1048
			memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr + offset,
1049
				0x00, inode->i_sb->s_blocksize -
M
Marcin Slusarz 已提交
1050
				offset - udf_file_entry_alloc_offset(inode));
1051
			iinfo->i_lenAlloc = inode->i_size;
L
Linus Torvalds 已提交
1052
		}
1053
	} else {
M
Marcin Slusarz 已提交
1054 1055
		block_truncate_page(inode->i_mapping, inode->i_size,
				    udf_get_block);
L
Linus Torvalds 已提交
1056
		udf_truncate_extents(inode);
1057
	}
L
Linus Torvalds 已提交
1058 1059 1060

	inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
	if (IS_SYNC(inode))
1061
		udf_sync_inode(inode);
L
Linus Torvalds 已提交
1062 1063 1064 1065 1066
	else
		mark_inode_dirty(inode);
	unlock_kernel();
}

1067
static void __udf_read_inode(struct inode *inode)
L
Linus Torvalds 已提交
1068 1069 1070 1071
{
	struct buffer_head *bh = NULL;
	struct fileEntry *fe;
	uint16_t ident;
1072
	struct udf_inode_info *iinfo = UDF_I(inode);
L
Linus Torvalds 已提交
1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085

	/*
	 * Set defaults, but the inode is still incomplete!
	 * Note: get_new_inode() sets the following on a new inode:
	 *      i_sb = sb
	 *      i_no = ino
	 *      i_flags = sb->s_flags
	 *      i_state = 0
	 * clean_inode(): zero fills and sets
	 *      i_count = 1
	 *      i_nlink = 1
	 *      i_op = NULL;
	 */
1086
	bh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 0, &ident);
1087
	if (!bh) {
L
Linus Torvalds 已提交
1088
		printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed !bh\n",
1089
		       inode->i_ino);
L
Linus Torvalds 已提交
1090 1091 1092 1093 1094
		make_bad_inode(inode);
		return;
	}

	if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE &&
1095
	    ident != TAG_IDENT_USE) {
M
Marcin Slusarz 已提交
1096 1097
		printk(KERN_ERR "udf: udf_read_inode(ino %ld) "
				"failed ident=%d\n", inode->i_ino, ident);
J
Jan Kara 已提交
1098
		brelse(bh);
L
Linus Torvalds 已提交
1099 1100 1101 1102 1103 1104
		make_bad_inode(inode);
		return;
	}

	fe = (struct fileEntry *)bh->b_data;

1105
	if (fe->icbTag.strategyType == cpu_to_le16(4096)) {
1106
		struct buffer_head *ibh;
L
Linus Torvalds 已提交
1107

1108
		ibh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 1,
M
Marcin Slusarz 已提交
1109
					&ident);
1110 1111
		if (ident == TAG_IDENT_IE && ibh) {
			struct buffer_head *nbh = NULL;
1112
			struct kernel_lb_addr loc;
1113 1114 1115 1116 1117 1118
			struct indirectEntry *ie;

			ie = (struct indirectEntry *)ibh->b_data;
			loc = lelb_to_cpu(ie->indirectICB.extLocation);

			if (ie->indirectICB.extLength &&
1119
				(nbh = udf_read_ptagged(inode->i_sb, &loc, 0,
1120 1121 1122 1123 1124
							&ident))) {
				if (ident == TAG_IDENT_FE ||
					ident == TAG_IDENT_EFE) {
					memcpy(&iinfo->i_location,
						&loc,
1125
						sizeof(struct kernel_lb_addr));
1126
					brelse(bh);
J
Jan Kara 已提交
1127
					brelse(ibh);
1128 1129 1130
					brelse(nbh);
					__udf_read_inode(inode);
					return;
1131
				}
1132
				brelse(nbh);
L
Linus Torvalds 已提交
1133
			}
1134
		}
1135
		brelse(ibh);
1136
	} else if (fe->icbTag.strategyType != cpu_to_le16(4)) {
L
Linus Torvalds 已提交
1137
		printk(KERN_ERR "udf: unsupported strategy type: %d\n",
1138
		       le16_to_cpu(fe->icbTag.strategyType));
J
Jan Kara 已提交
1139
		brelse(bh);
L
Linus Torvalds 已提交
1140 1141 1142 1143
		make_bad_inode(inode);
		return;
	}
	udf_fill_inode(inode, bh);
J
Jan Kara 已提交
1144

J
Jan Kara 已提交
1145
	brelse(bh);
L
Linus Torvalds 已提交
1146 1147 1148 1149 1150 1151 1152
}

static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
{
	struct fileEntry *fe;
	struct extendedFileEntry *efe;
	int offset;
M
Marcin Slusarz 已提交
1153
	struct udf_sb_info *sbi = UDF_SB(inode->i_sb);
1154
	struct udf_inode_info *iinfo = UDF_I(inode);
L
Linus Torvalds 已提交
1155 1156 1157 1158

	fe = (struct fileEntry *)bh->b_data;
	efe = (struct extendedFileEntry *)bh->b_data;

1159
	if (fe->icbTag.strategyType == cpu_to_le16(4))
1160
		iinfo->i_strat4096 = 0;
1161
	else /* if (fe->icbTag.strategyType == cpu_to_le16(4096)) */
1162
		iinfo->i_strat4096 = 1;
L
Linus Torvalds 已提交
1163

1164
	iinfo->i_alloc_type = le16_to_cpu(fe->icbTag.flags) &
M
Marcin Slusarz 已提交
1165
							ICBTAG_FLAG_AD_MASK;
1166 1167 1168 1169 1170 1171
	iinfo->i_unique = 0;
	iinfo->i_lenEAttr = 0;
	iinfo->i_lenExtents = 0;
	iinfo->i_lenAlloc = 0;
	iinfo->i_next_alloc_block = 0;
	iinfo->i_next_alloc_goal = 0;
1172
	if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_EFE)) {
1173 1174
		iinfo->i_efe = 1;
		iinfo->i_use = 0;
M
Marcin Slusarz 已提交
1175 1176
		if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize -
					sizeof(struct extendedFileEntry))) {
1177 1178 1179
			make_bad_inode(inode);
			return;
		}
1180
		memcpy(iinfo->i_ext.i_data,
M
Marcin Slusarz 已提交
1181 1182 1183
		       bh->b_data + sizeof(struct extendedFileEntry),
		       inode->i_sb->s_blocksize -
					sizeof(struct extendedFileEntry));
1184
	} else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) {
1185 1186
		iinfo->i_efe = 0;
		iinfo->i_use = 0;
M
Marcin Slusarz 已提交
1187 1188
		if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize -
						sizeof(struct fileEntry))) {
1189 1190 1191
			make_bad_inode(inode);
			return;
		}
1192
		memcpy(iinfo->i_ext.i_data,
1193
		       bh->b_data + sizeof(struct fileEntry),
1194
		       inode->i_sb->s_blocksize - sizeof(struct fileEntry));
1195
	} else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) {
1196 1197 1198
		iinfo->i_efe = 0;
		iinfo->i_use = 1;
		iinfo->i_lenAlloc = le32_to_cpu(
M
Marcin Slusarz 已提交
1199 1200 1201 1202
				((struct unallocSpaceEntry *)bh->b_data)->
				 lengthAllocDescs);
		if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize -
					sizeof(struct unallocSpaceEntry))) {
1203 1204 1205
			make_bad_inode(inode);
			return;
		}
1206
		memcpy(iinfo->i_ext.i_data,
M
Marcin Slusarz 已提交
1207 1208 1209
		       bh->b_data + sizeof(struct unallocSpaceEntry),
		       inode->i_sb->s_blocksize -
					sizeof(struct unallocSpaceEntry));
L
Linus Torvalds 已提交
1210 1211 1212 1213
		return;
	}

	inode->i_uid = le32_to_cpu(fe->uid);
1214 1215 1216
	if (inode->i_uid == -1 ||
	    UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) ||
	    UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_SET))
1217
		inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
L
Linus Torvalds 已提交
1218 1219

	inode->i_gid = le32_to_cpu(fe->gid);
1220 1221 1222
	if (inode->i_gid == -1 ||
	    UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_IGNORE) ||
	    UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET))
1223
		inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
L
Linus Torvalds 已提交
1224 1225 1226 1227

	inode->i_nlink = le16_to_cpu(fe->fileLinkCount);
	if (!inode->i_nlink)
		inode->i_nlink = 1;
1228

L
Linus Torvalds 已提交
1229
	inode->i_size = le64_to_cpu(fe->informationLength);
1230
	iinfo->i_lenExtents = inode->i_size;
L
Linus Torvalds 已提交
1231

1232
	if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY &&
1233
			sbi->s_fmode != UDF_INVALID_MODE)
1234 1235
		inode->i_mode = sbi->s_fmode;
	else if (fe->icbTag.fileType == ICBTAG_FILE_TYPE_DIRECTORY &&
1236
			sbi->s_dmode != UDF_INVALID_MODE)
1237 1238 1239 1240
		inode->i_mode = sbi->s_dmode;
	else
		inode->i_mode = udf_convert_permissions(fe);
	inode->i_mode &= ~sbi->s_umask;
L
Linus Torvalds 已提交
1241

1242
	if (iinfo->i_efe == 0) {
L
Linus Torvalds 已提交
1243
		inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
1244
			(inode->i_sb->s_blocksize_bits - 9);
L
Linus Torvalds 已提交
1245

1246
		if (!udf_disk_stamp_to_time(&inode->i_atime, fe->accessTime))
1247 1248
			inode->i_atime = sbi->s_record_time;

1249 1250
		if (!udf_disk_stamp_to_time(&inode->i_mtime,
					    fe->modificationTime))
1251 1252
			inode->i_mtime = sbi->s_record_time;

1253
		if (!udf_disk_stamp_to_time(&inode->i_ctime, fe->attrTime))
1254
			inode->i_ctime = sbi->s_record_time;
L
Linus Torvalds 已提交
1255

1256 1257 1258 1259
		iinfo->i_unique = le64_to_cpu(fe->uniqueID);
		iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr);
		iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs);
		offset = sizeof(struct fileEntry) + iinfo->i_lenEAttr;
1260
	} else {
1261
		inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
1262
		    (inode->i_sb->s_blocksize_bits - 9);
L
Linus Torvalds 已提交
1263

1264
		if (!udf_disk_stamp_to_time(&inode->i_atime, efe->accessTime))
1265 1266
			inode->i_atime = sbi->s_record_time;

1267 1268
		if (!udf_disk_stamp_to_time(&inode->i_mtime,
					    efe->modificationTime))
1269 1270
			inode->i_mtime = sbi->s_record_time;

1271
		if (!udf_disk_stamp_to_time(&iinfo->i_crtime, efe->createTime))
1272 1273
			iinfo->i_crtime = sbi->s_record_time;

1274
		if (!udf_disk_stamp_to_time(&inode->i_ctime, efe->attrTime))
1275
			inode->i_ctime = sbi->s_record_time;
L
Linus Torvalds 已提交
1276

1277 1278 1279
		iinfo->i_unique = le64_to_cpu(efe->uniqueID);
		iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr);
		iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs);
M
Marcin Slusarz 已提交
1280
		offset = sizeof(struct extendedFileEntry) +
1281
							iinfo->i_lenEAttr;
L
Linus Torvalds 已提交
1282 1283
	}

1284 1285
	switch (fe->icbTag.fileType) {
	case ICBTAG_FILE_TYPE_DIRECTORY:
1286 1287 1288 1289 1290
		inode->i_op = &udf_dir_inode_operations;
		inode->i_fop = &udf_dir_operations;
		inode->i_mode |= S_IFDIR;
		inc_nlink(inode);
		break;
1291 1292 1293
	case ICBTAG_FILE_TYPE_REALTIME:
	case ICBTAG_FILE_TYPE_REGULAR:
	case ICBTAG_FILE_TYPE_UNDEF:
J
Jan Kara 已提交
1294
	case ICBTAG_FILE_TYPE_VAT20:
1295
		if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
1296 1297 1298 1299 1300 1301 1302
			inode->i_data.a_ops = &udf_adinicb_aops;
		else
			inode->i_data.a_ops = &udf_aops;
		inode->i_op = &udf_file_inode_operations;
		inode->i_fop = &udf_file_operations;
		inode->i_mode |= S_IFREG;
		break;
1303
	case ICBTAG_FILE_TYPE_BLOCK:
1304 1305
		inode->i_mode |= S_IFBLK;
		break;
1306
	case ICBTAG_FILE_TYPE_CHAR:
1307 1308
		inode->i_mode |= S_IFCHR;
		break;
1309
	case ICBTAG_FILE_TYPE_FIFO:
1310 1311
		init_special_inode(inode, inode->i_mode | S_IFIFO, 0);
		break;
1312
	case ICBTAG_FILE_TYPE_SOCKET:
1313 1314
		init_special_inode(inode, inode->i_mode | S_IFSOCK, 0);
		break;
1315
	case ICBTAG_FILE_TYPE_SYMLINK:
1316
		inode->i_data.a_ops = &udf_symlink_aops;
1317
		inode->i_op = &udf_symlink_inode_operations;
1318 1319
		inode->i_mode = S_IFLNK | S_IRWXUGO;
		break;
1320 1321 1322 1323 1324 1325 1326 1327 1328
	case ICBTAG_FILE_TYPE_MAIN:
		udf_debug("METADATA FILE-----\n");
		break;
	case ICBTAG_FILE_TYPE_MIRROR:
		udf_debug("METADATA MIRROR FILE-----\n");
		break;
	case ICBTAG_FILE_TYPE_BITMAP:
		udf_debug("METADATA BITMAP FILE-----\n");
		break;
1329
	default:
M
Marcin Slusarz 已提交
1330 1331 1332
		printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown "
				"file type=%d\n", inode->i_ino,
				fe->icbTag.fileType);
1333 1334
		make_bad_inode(inode);
		return;
L
Linus Torvalds 已提交
1335
	}
1336
	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
M
Marcin Slusarz 已提交
1337 1338
		struct deviceSpec *dsea =
			(struct deviceSpec *)udf_get_extendedattr(inode, 12, 1);
1339 1340
		if (dsea) {
			init_special_inode(inode, inode->i_mode,
M
Marcin Slusarz 已提交
1341 1342
				MKDEV(le32_to_cpu(dsea->majorDeviceIdent),
				      le32_to_cpu(dsea->minorDeviceIdent)));
L
Linus Torvalds 已提交
1343
			/* Developer ID ??? */
M
Marcin Slusarz 已提交
1344
		} else
L
Linus Torvalds 已提交
1345 1346 1347 1348
			make_bad_inode(inode);
	}
}

1349 1350
static int udf_alloc_i_data(struct inode *inode, size_t size)
{
1351 1352
	struct udf_inode_info *iinfo = UDF_I(inode);
	iinfo->i_ext.i_data = kmalloc(size, GFP_KERNEL);
1353

1354
	if (!iinfo->i_ext.i_data) {
M
Marcin Slusarz 已提交
1355 1356
		printk(KERN_ERR "udf:udf_alloc_i_data (ino %ld) "
				"no free memory\n", inode->i_ino);
1357 1358 1359 1360 1361 1362
		return -ENOMEM;
	}

	return 0;
}

1363
static mode_t udf_convert_permissions(struct fileEntry *fe)
L
Linus Torvalds 已提交
1364 1365 1366 1367 1368 1369 1370 1371
{
	mode_t mode;
	uint32_t permissions;
	uint32_t flags;

	permissions = le32_to_cpu(fe->permissions);
	flags = le16_to_cpu(fe->icbTag.flags);

M
Marcin Slusarz 已提交
1372 1373 1374 1375 1376 1377
	mode =	((permissions) & S_IRWXO) |
		((permissions >> 2) & S_IRWXG) |
		((permissions >> 4) & S_IRWXU) |
		((flags & ICBTAG_FLAG_SETUID) ? S_ISUID : 0) |
		((flags & ICBTAG_FLAG_SETGID) ? S_ISGID : 0) |
		((flags & ICBTAG_FLAG_STICKY) ? S_ISVTX : 0);
L
Linus Torvalds 已提交
1378 1379 1380 1381

	return mode;
}

1382
int udf_write_inode(struct inode *inode, struct writeback_control *wbc)
L
Linus Torvalds 已提交
1383 1384
{
	int ret;
1385

L
Linus Torvalds 已提交
1386
	lock_kernel();
1387
	ret = udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
L
Linus Torvalds 已提交
1388
	unlock_kernel();
1389

L
Linus Torvalds 已提交
1390 1391 1392
	return ret;
}

1393
int udf_sync_inode(struct inode *inode)
L
Linus Torvalds 已提交
1394 1395 1396 1397
{
	return udf_update_inode(inode, 1);
}

1398
static int udf_update_inode(struct inode *inode, int do_sync)
L
Linus Torvalds 已提交
1399 1400 1401 1402 1403 1404 1405 1406
{
	struct buffer_head *bh = NULL;
	struct fileEntry *fe;
	struct extendedFileEntry *efe;
	uint32_t udfperms;
	uint16_t icbflags;
	uint16_t crclen;
	int err = 0;
M
Marcin Slusarz 已提交
1407
	struct udf_sb_info *sbi = UDF_SB(inode->i_sb);
M
Marcin Slusarz 已提交
1408
	unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
1409
	struct udf_inode_info *iinfo = UDF_I(inode);
L
Linus Torvalds 已提交
1410

1411 1412
	bh = udf_tgetblk(inode->i_sb,
			udf_get_lb_pblock(inode->i_sb, &iinfo->i_location, 0));
1413
	if (!bh) {
1414 1415
		udf_debug("getblk failure\n");
		return -ENOMEM;
L
Linus Torvalds 已提交
1416 1417
	}

1418 1419
	lock_buffer(bh);
	memset(bh->b_data, 0, inode->i_sb->s_blocksize);
L
Linus Torvalds 已提交
1420 1421 1422
	fe = (struct fileEntry *)bh->b_data;
	efe = (struct extendedFileEntry *)bh->b_data;

1423
	if (iinfo->i_use) {
L
Linus Torvalds 已提交
1424
		struct unallocSpaceEntry *use =
1425
			(struct unallocSpaceEntry *)bh->b_data;
L
Linus Torvalds 已提交
1426

1427
		use->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc);
M
Marcin Slusarz 已提交
1428
		memcpy(bh->b_data + sizeof(struct unallocSpaceEntry),
1429
		       iinfo->i_ext.i_data, inode->i_sb->s_blocksize -
M
Marcin Slusarz 已提交
1430
					sizeof(struct unallocSpaceEntry));
1431 1432 1433
		use->descTag.tagIdent = cpu_to_le16(TAG_IDENT_USE);
		use->descTag.tagLocation =
				cpu_to_le32(iinfo->i_location.logicalBlockNum);
M
Marcin Slusarz 已提交
1434
		crclen = sizeof(struct unallocSpaceEntry) +
1435
				iinfo->i_lenAlloc - sizeof(struct tag);
L
Linus Torvalds 已提交
1436
		use->descTag.descCRCLength = cpu_to_le16(crclen);
1437
		use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use +
1438
							   sizeof(struct tag),
1439
							   crclen));
1440
		use->descTag.tagChecksum = udf_tag_checksum(&use->descTag);
L
Linus Torvalds 已提交
1441

1442
		goto out;
L
Linus Torvalds 已提交
1443 1444
	}

1445 1446
	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET))
		fe->uid = cpu_to_le32(-1);
1447 1448
	else
		fe->uid = cpu_to_le32(inode->i_uid);
L
Linus Torvalds 已提交
1449

1450 1451
	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET))
		fe->gid = cpu_to_le32(-1);
1452 1453
	else
		fe->gid = cpu_to_le32(inode->i_gid);
L
Linus Torvalds 已提交
1454

M
Marcin Slusarz 已提交
1455 1456 1457
	udfperms = ((inode->i_mode & S_IRWXO)) |
		   ((inode->i_mode & S_IRWXG) << 2) |
		   ((inode->i_mode & S_IRWXU) << 4);
L
Linus Torvalds 已提交
1458

M
Marcin Slusarz 已提交
1459 1460 1461 1462
	udfperms |= (le32_to_cpu(fe->permissions) &
		    (FE_PERM_O_DELETE | FE_PERM_O_CHATTR |
		     FE_PERM_G_DELETE | FE_PERM_G_CHATTR |
		     FE_PERM_U_DELETE | FE_PERM_U_CHATTR));
L
Linus Torvalds 已提交
1463 1464 1465 1466 1467 1468 1469 1470 1471
	fe->permissions = cpu_to_le32(udfperms);

	if (S_ISDIR(inode->i_mode))
		fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1);
	else
		fe->fileLinkCount = cpu_to_le16(inode->i_nlink);

	fe->informationLength = cpu_to_le64(inode->i_size);

1472
	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
1473
		struct regid *eid;
1474 1475
		struct deviceSpec *dsea =
			(struct deviceSpec *)udf_get_extendedattr(inode, 12, 1);
1476
		if (!dsea) {
L
Linus Torvalds 已提交
1477
			dsea = (struct deviceSpec *)
1478 1479
				udf_add_extendedattr(inode,
						     sizeof(struct deviceSpec) +
1480
						     sizeof(struct regid), 12, 0x3);
L
Linus Torvalds 已提交
1481 1482
			dsea->attrType = cpu_to_le32(12);
			dsea->attrSubtype = 1;
M
Marcin Slusarz 已提交
1483 1484
			dsea->attrLength = cpu_to_le32(
						sizeof(struct deviceSpec) +
1485 1486
						sizeof(struct regid));
			dsea->impUseLength = cpu_to_le32(sizeof(struct regid));
L
Linus Torvalds 已提交
1487
		}
1488 1489
		eid = (struct regid *)dsea->impUse;
		memset(eid, 0, sizeof(struct regid));
L
Linus Torvalds 已提交
1490 1491 1492 1493 1494 1495 1496
		strcpy(eid->ident, UDF_ID_DEVELOPER);
		eid->identSuffix[0] = UDF_OS_CLASS_UNIX;
		eid->identSuffix[1] = UDF_OS_ID_LINUX;
		dsea->majorDeviceIdent = cpu_to_le32(imajor(inode));
		dsea->minorDeviceIdent = cpu_to_le32(iminor(inode));
	}

1497
	if (iinfo->i_efe == 0) {
1498
		memcpy(bh->b_data + sizeof(struct fileEntry),
1499
		       iinfo->i_ext.i_data,
1500
		       inode->i_sb->s_blocksize - sizeof(struct fileEntry));
1501
		fe->logicalBlocksRecorded = cpu_to_le64(
M
Marcin Slusarz 已提交
1502 1503
			(inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >>
			(blocksize_bits - 9));
L
Linus Torvalds 已提交
1504

1505 1506 1507
		udf_time_to_disk_stamp(&fe->accessTime, inode->i_atime);
		udf_time_to_disk_stamp(&fe->modificationTime, inode->i_mtime);
		udf_time_to_disk_stamp(&fe->attrTime, inode->i_ctime);
1508
		memset(&(fe->impIdent), 0, sizeof(struct regid));
L
Linus Torvalds 已提交
1509 1510 1511
		strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);
		fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
		fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
1512 1513 1514
		fe->uniqueID = cpu_to_le64(iinfo->i_unique);
		fe->lengthExtendedAttr = cpu_to_le32(iinfo->i_lenEAttr);
		fe->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc);
L
Linus Torvalds 已提交
1515 1516
		fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE);
		crclen = sizeof(struct fileEntry);
1517
	} else {
M
Marcin Slusarz 已提交
1518
		memcpy(bh->b_data + sizeof(struct extendedFileEntry),
1519
		       iinfo->i_ext.i_data,
M
Marcin Slusarz 已提交
1520 1521
		       inode->i_sb->s_blocksize -
					sizeof(struct extendedFileEntry));
L
Linus Torvalds 已提交
1522
		efe->objectSize = cpu_to_le64(inode->i_size);
1523
		efe->logicalBlocksRecorded = cpu_to_le64(
M
Marcin Slusarz 已提交
1524 1525
			(inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >>
			(blocksize_bits - 9));
L
Linus Torvalds 已提交
1526

1527 1528 1529 1530
		if (iinfo->i_crtime.tv_sec > inode->i_atime.tv_sec ||
		    (iinfo->i_crtime.tv_sec == inode->i_atime.tv_sec &&
		     iinfo->i_crtime.tv_nsec > inode->i_atime.tv_nsec))
			iinfo->i_crtime = inode->i_atime;
M
Marcin Slusarz 已提交
1531

1532 1533 1534 1535
		if (iinfo->i_crtime.tv_sec > inode->i_mtime.tv_sec ||
		    (iinfo->i_crtime.tv_sec == inode->i_mtime.tv_sec &&
		     iinfo->i_crtime.tv_nsec > inode->i_mtime.tv_nsec))
			iinfo->i_crtime = inode->i_mtime;
M
Marcin Slusarz 已提交
1536

1537 1538 1539 1540
		if (iinfo->i_crtime.tv_sec > inode->i_ctime.tv_sec ||
		    (iinfo->i_crtime.tv_sec == inode->i_ctime.tv_sec &&
		     iinfo->i_crtime.tv_nsec > inode->i_ctime.tv_nsec))
			iinfo->i_crtime = inode->i_ctime;
L
Linus Torvalds 已提交
1541

1542 1543 1544 1545
		udf_time_to_disk_stamp(&efe->accessTime, inode->i_atime);
		udf_time_to_disk_stamp(&efe->modificationTime, inode->i_mtime);
		udf_time_to_disk_stamp(&efe->createTime, iinfo->i_crtime);
		udf_time_to_disk_stamp(&efe->attrTime, inode->i_ctime);
L
Linus Torvalds 已提交
1546

1547
		memset(&(efe->impIdent), 0, sizeof(struct regid));
L
Linus Torvalds 已提交
1548 1549 1550
		strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER);
		efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
		efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
1551 1552 1553
		efe->uniqueID = cpu_to_le64(iinfo->i_unique);
		efe->lengthExtendedAttr = cpu_to_le32(iinfo->i_lenEAttr);
		efe->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc);
L
Linus Torvalds 已提交
1554 1555 1556
		efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE);
		crclen = sizeof(struct extendedFileEntry);
	}
1557
	if (iinfo->i_strat4096) {
L
Linus Torvalds 已提交
1558 1559 1560
		fe->icbTag.strategyType = cpu_to_le16(4096);
		fe->icbTag.strategyParameter = cpu_to_le16(1);
		fe->icbTag.numEntries = cpu_to_le16(2);
1561
	} else {
L
Linus Torvalds 已提交
1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580
		fe->icbTag.strategyType = cpu_to_le16(4);
		fe->icbTag.numEntries = cpu_to_le16(1);
	}

	if (S_ISDIR(inode->i_mode))
		fe->icbTag.fileType = ICBTAG_FILE_TYPE_DIRECTORY;
	else if (S_ISREG(inode->i_mode))
		fe->icbTag.fileType = ICBTAG_FILE_TYPE_REGULAR;
	else if (S_ISLNK(inode->i_mode))
		fe->icbTag.fileType = ICBTAG_FILE_TYPE_SYMLINK;
	else if (S_ISBLK(inode->i_mode))
		fe->icbTag.fileType = ICBTAG_FILE_TYPE_BLOCK;
	else if (S_ISCHR(inode->i_mode))
		fe->icbTag.fileType = ICBTAG_FILE_TYPE_CHAR;
	else if (S_ISFIFO(inode->i_mode))
		fe->icbTag.fileType = ICBTAG_FILE_TYPE_FIFO;
	else if (S_ISSOCK(inode->i_mode))
		fe->icbTag.fileType = ICBTAG_FILE_TYPE_SOCKET;

1581
	icbflags =	iinfo->i_alloc_type |
1582 1583 1584 1585 1586 1587
			((inode->i_mode & S_ISUID) ? ICBTAG_FLAG_SETUID : 0) |
			((inode->i_mode & S_ISGID) ? ICBTAG_FLAG_SETGID : 0) |
			((inode->i_mode & S_ISVTX) ? ICBTAG_FLAG_STICKY : 0) |
			(le16_to_cpu(fe->icbTag.flags) &
				~(ICBTAG_FLAG_AD_MASK | ICBTAG_FLAG_SETUID |
				ICBTAG_FLAG_SETGID | ICBTAG_FLAG_STICKY));
L
Linus Torvalds 已提交
1588 1589

	fe->icbTag.flags = cpu_to_le16(icbflags);
M
Marcin Slusarz 已提交
1590
	if (sbi->s_udfrev >= 0x0200)
L
Linus Torvalds 已提交
1591 1592 1593
		fe->descTag.descVersion = cpu_to_le16(3);
	else
		fe->descTag.descVersion = cpu_to_le16(2);
M
Marcin Slusarz 已提交
1594
	fe->descTag.tagSerialNum = cpu_to_le16(sbi->s_serial_number);
M
Marcin Slusarz 已提交
1595
	fe->descTag.tagLocation = cpu_to_le32(
1596
					iinfo->i_location.logicalBlockNum);
1597
	crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - sizeof(struct tag);
L
Linus Torvalds 已提交
1598
	fe->descTag.descCRCLength = cpu_to_le16(crclen);
1599
	fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(struct tag),
1600
						  crclen));
1601
	fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag);
L
Linus Torvalds 已提交
1602

1603
out:
1604
	set_buffer_uptodate(bh);
1605 1606
	unlock_buffer(bh);

L
Linus Torvalds 已提交
1607 1608
	/* write the data blocks */
	mark_buffer_dirty(bh);
1609
	if (do_sync) {
L
Linus Torvalds 已提交
1610
		sync_dirty_buffer(bh);
1611
		if (buffer_write_io_error(bh)) {
M
Marcin Slusarz 已提交
1612 1613 1614
			printk(KERN_WARNING "IO error syncing udf inode "
				"[%s:%08lx]\n", inode->i_sb->s_id,
				inode->i_ino);
L
Linus Torvalds 已提交
1615 1616 1617
			err = -EIO;
		}
	}
J
Jan Kara 已提交
1618
	brelse(bh);
1619

L
Linus Torvalds 已提交
1620 1621 1622
	return err;
}

1623
struct inode *udf_iget(struct super_block *sb, struct kernel_lb_addr *ino)
L
Linus Torvalds 已提交
1624 1625 1626 1627 1628 1629 1630 1631
{
	unsigned long block = udf_get_lb_pblock(sb, ino, 0);
	struct inode *inode = iget_locked(sb, block);

	if (!inode)
		return NULL;

	if (inode->i_state & I_NEW) {
1632
		memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr));
L
Linus Torvalds 已提交
1633 1634 1635 1636 1637 1638 1639
		__udf_read_inode(inode);
		unlock_new_inode(inode);
	}

	if (is_bad_inode(inode))
		goto out_iput;

1640 1641
	if (ino->logicalBlockNum >= UDF_SB(sb)->
			s_partmaps[ino->partitionReferenceNum].s_partition_len) {
L
Linus Torvalds 已提交
1642
		udf_debug("block=%d, partition=%d out of range\n",
1643
			  ino->logicalBlockNum, ino->partitionReferenceNum);
L
Linus Torvalds 已提交
1644 1645 1646 1647 1648 1649
		make_bad_inode(inode);
		goto out_iput;
	}

	return inode;

1650
 out_iput:
L
Linus Torvalds 已提交
1651 1652 1653 1654
	iput(inode);
	return NULL;
}

M
Marcin Slusarz 已提交
1655
int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
1656
		    struct kernel_lb_addr *eloc, uint32_t elen, int inc)
L
Linus Torvalds 已提交
1657 1658
{
	int adsize;
1659 1660
	struct short_ad *sad = NULL;
	struct long_ad *lad = NULL;
L
Linus Torvalds 已提交
1661 1662 1663
	struct allocExtDesc *aed;
	int8_t etype;
	uint8_t *ptr;
1664
	struct udf_inode_info *iinfo = UDF_I(inode);
L
Linus Torvalds 已提交
1665

J
Jan Kara 已提交
1666
	if (!epos->bh)
1667
		ptr = iinfo->i_ext.i_data + epos->offset -
M
Marcin Slusarz 已提交
1668
			udf_file_entry_alloc_offset(inode) +
1669
			iinfo->i_lenEAttr;
L
Linus Torvalds 已提交
1670
	else
J
Jan Kara 已提交
1671
		ptr = epos->bh->b_data + epos->offset;
L
Linus Torvalds 已提交
1672

1673
	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
1674
		adsize = sizeof(struct short_ad);
1675
	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
1676
		adsize = sizeof(struct long_ad);
L
Linus Torvalds 已提交
1677 1678 1679
	else
		return -1;

1680
	if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) {
A
Al Viro 已提交
1681
		unsigned char *sptr, *dptr;
L
Linus Torvalds 已提交
1682 1683
		struct buffer_head *nbh;
		int err, loffset;
1684
		struct kernel_lb_addr obloc = epos->block;
L
Linus Torvalds 已提交
1685

M
Marcin Slusarz 已提交
1686 1687 1688 1689
		epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL,
						obloc.partitionReferenceNum,
						obloc.logicalBlockNum, &err);
		if (!epos->block.logicalBlockNum)
L
Linus Torvalds 已提交
1690
			return -1;
M
Marcin Slusarz 已提交
1691
		nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
1692
								 &epos->block,
M
Marcin Slusarz 已提交
1693 1694
								 0));
		if (!nbh)
L
Linus Torvalds 已提交
1695 1696 1697 1698 1699 1700 1701 1702 1703
			return -1;
		lock_buffer(nbh);
		memset(nbh->b_data, 0x00, inode->i_sb->s_blocksize);
		set_buffer_uptodate(nbh);
		unlock_buffer(nbh);
		mark_buffer_dirty_inode(nbh, inode);

		aed = (struct allocExtDesc *)(nbh->b_data);
		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
M
Marcin Slusarz 已提交
1704 1705
			aed->previousAllocExtLocation =
					cpu_to_le32(obloc.logicalBlockNum);
1706
		if (epos->offset + adsize > inode->i_sb->s_blocksize) {
J
Jan Kara 已提交
1707
			loffset = epos->offset;
L
Linus Torvalds 已提交
1708 1709 1710 1711
			aed->lengthAllocDescs = cpu_to_le32(adsize);
			sptr = ptr - adsize;
			dptr = nbh->b_data + sizeof(struct allocExtDesc);
			memcpy(dptr, sptr, adsize);
J
Jan Kara 已提交
1712
			epos->offset = sizeof(struct allocExtDesc) + adsize;
1713
		} else {
J
Jan Kara 已提交
1714
			loffset = epos->offset + adsize;
L
Linus Torvalds 已提交
1715 1716
			aed->lengthAllocDescs = cpu_to_le32(0);
			sptr = ptr;
J
Jan Kara 已提交
1717
			epos->offset = sizeof(struct allocExtDesc);
L
Linus Torvalds 已提交
1718

1719
			if (epos->bh) {
J
Jan Kara 已提交
1720
				aed = (struct allocExtDesc *)epos->bh->b_data;
1721
				le32_add_cpu(&aed->lengthAllocDescs, adsize);
1722
			} else {
1723
				iinfo->i_lenAlloc += adsize;
L
Linus Torvalds 已提交
1724 1725 1726
				mark_inode_dirty(inode);
			}
		}
M
Marcin Slusarz 已提交
1727
		if (UDF_SB(inode->i_sb)->s_udfrev >= 0x0200)
L
Linus Torvalds 已提交
1728
			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
1729
				    epos->block.logicalBlockNum, sizeof(struct tag));
L
Linus Torvalds 已提交
1730 1731
		else
			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
1732
				    epos->block.logicalBlockNum, sizeof(struct tag));
1733
		switch (iinfo->i_alloc_type) {
1734
		case ICBTAG_FLAG_AD_SHORT:
1735
			sad = (struct short_ad *)sptr;
1736 1737
			sad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
						     inode->i_sb->s_blocksize);
M
Marcin Slusarz 已提交
1738 1739
			sad->extPosition =
				cpu_to_le32(epos->block.logicalBlockNum);
1740
			break;
1741
		case ICBTAG_FLAG_AD_LONG:
1742
			lad = (struct long_ad *)sptr;
1743 1744 1745 1746 1747
			lad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
						     inode->i_sb->s_blocksize);
			lad->extLocation = cpu_to_lelb(epos->block);
			memset(lad->impUse, 0x00, sizeof(lad->impUse));
			break;
L
Linus Torvalds 已提交
1748
		}
1749
		if (epos->bh) {
1750
			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
M
Marcin Slusarz 已提交
1751
			    UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
J
Jan Kara 已提交
1752
				udf_update_tag(epos->bh->b_data, loffset);
L
Linus Torvalds 已提交
1753
			else
M
Marcin Slusarz 已提交
1754 1755
				udf_update_tag(epos->bh->b_data,
						sizeof(struct allocExtDesc));
J
Jan Kara 已提交
1756
			mark_buffer_dirty_inode(epos->bh, inode);
J
Jan Kara 已提交
1757
			brelse(epos->bh);
1758
		} else {
L
Linus Torvalds 已提交
1759
			mark_inode_dirty(inode);
1760
		}
J
Jan Kara 已提交
1761
		epos->bh = nbh;
L
Linus Torvalds 已提交
1762 1763
	}

J
Jan Kara 已提交
1764
	etype = udf_write_aext(inode, epos, eloc, elen, inc);
L
Linus Torvalds 已提交
1765

1766
	if (!epos->bh) {
1767
		iinfo->i_lenAlloc += adsize;
L
Linus Torvalds 已提交
1768
		mark_inode_dirty(inode);
1769
	} else {
J
Jan Kara 已提交
1770
		aed = (struct allocExtDesc *)epos->bh->b_data;
1771
		le32_add_cpu(&aed->lengthAllocDescs, adsize);
M
Marcin Slusarz 已提交
1772 1773 1774 1775
		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
				UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
			udf_update_tag(epos->bh->b_data,
					epos->offset + (inc ? 0 : adsize));
L
Linus Torvalds 已提交
1776
		else
M
Marcin Slusarz 已提交
1777 1778
			udf_update_tag(epos->bh->b_data,
					sizeof(struct allocExtDesc));
J
Jan Kara 已提交
1779
		mark_buffer_dirty_inode(epos->bh, inode);
L
Linus Torvalds 已提交
1780 1781 1782 1783 1784
	}

	return etype;
}

M
Marcin Slusarz 已提交
1785
int8_t udf_write_aext(struct inode *inode, struct extent_position *epos,
1786
		      struct kernel_lb_addr *eloc, uint32_t elen, int inc)
L
Linus Torvalds 已提交
1787 1788 1789
{
	int adsize;
	uint8_t *ptr;
1790 1791
	struct short_ad *sad;
	struct long_ad *lad;
1792
	struct udf_inode_info *iinfo = UDF_I(inode);
L
Linus Torvalds 已提交
1793

J
Jan Kara 已提交
1794
	if (!epos->bh)
1795
		ptr = iinfo->i_ext.i_data + epos->offset -
M
Marcin Slusarz 已提交
1796
			udf_file_entry_alloc_offset(inode) +
1797
			iinfo->i_lenEAttr;
L
Linus Torvalds 已提交
1798
	else
J
Jan Kara 已提交
1799
		ptr = epos->bh->b_data + epos->offset;
L
Linus Torvalds 已提交
1800

1801
	switch (iinfo->i_alloc_type) {
1802
	case ICBTAG_FLAG_AD_SHORT:
1803
		sad = (struct short_ad *)ptr;
1804
		sad->extLength = cpu_to_le32(elen);
1805
		sad->extPosition = cpu_to_le32(eloc->logicalBlockNum);
1806
		adsize = sizeof(struct short_ad);
1807
		break;
1808
	case ICBTAG_FLAG_AD_LONG:
1809
		lad = (struct long_ad *)ptr;
1810
		lad->extLength = cpu_to_le32(elen);
1811
		lad->extLocation = cpu_to_lelb(*eloc);
1812
		memset(lad->impUse, 0x00, sizeof(lad->impUse));
1813
		adsize = sizeof(struct long_ad);
1814
		break;
1815 1816
	default:
		return -1;
L
Linus Torvalds 已提交
1817 1818
	}

1819
	if (epos->bh) {
1820
		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
M
Marcin Slusarz 已提交
1821
		    UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) {
M
Marcin Slusarz 已提交
1822 1823
			struct allocExtDesc *aed =
				(struct allocExtDesc *)epos->bh->b_data;
J
Jan Kara 已提交
1824
			udf_update_tag(epos->bh->b_data,
M
Marcin Slusarz 已提交
1825 1826
				       le32_to_cpu(aed->lengthAllocDescs) +
				       sizeof(struct allocExtDesc));
L
Linus Torvalds 已提交
1827
		}
J
Jan Kara 已提交
1828
		mark_buffer_dirty_inode(epos->bh, inode);
1829
	} else {
L
Linus Torvalds 已提交
1830
		mark_inode_dirty(inode);
1831
	}
L
Linus Torvalds 已提交
1832 1833

	if (inc)
J
Jan Kara 已提交
1834
		epos->offset += adsize;
1835

L
Linus Torvalds 已提交
1836 1837 1838
	return (elen >> 30);
}

M
Marcin Slusarz 已提交
1839
int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
1840
		     struct kernel_lb_addr *eloc, uint32_t *elen, int inc)
L
Linus Torvalds 已提交
1841 1842 1843
{
	int8_t etype;

J
Jan Kara 已提交
1844
	while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) ==
1845
	       (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) {
M
Marcin Slusarz 已提交
1846
		int block;
J
Jan Kara 已提交
1847 1848
		epos->block = *eloc;
		epos->offset = sizeof(struct allocExtDesc);
J
Jan Kara 已提交
1849
		brelse(epos->bh);
1850
		block = udf_get_lb_pblock(inode->i_sb, &epos->block, 0);
M
Marcin Slusarz 已提交
1851 1852 1853
		epos->bh = udf_tread(inode->i_sb, block);
		if (!epos->bh) {
			udf_debug("reading block %d failed!\n", block);
L
Linus Torvalds 已提交
1854 1855 1856 1857 1858 1859 1860
			return -1;
		}
	}

	return etype;
}

M
Marcin Slusarz 已提交
1861
int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
1862
			struct kernel_lb_addr *eloc, uint32_t *elen, int inc)
L
Linus Torvalds 已提交
1863 1864 1865 1866
{
	int alen;
	int8_t etype;
	uint8_t *ptr;
1867 1868
	struct short_ad *sad;
	struct long_ad *lad;
1869
	struct udf_inode_info *iinfo = UDF_I(inode);
1870

1871
	if (!epos->bh) {
J
Jan Kara 已提交
1872 1873
		if (!epos->offset)
			epos->offset = udf_file_entry_alloc_offset(inode);
1874
		ptr = iinfo->i_ext.i_data + epos->offset -
M
Marcin Slusarz 已提交
1875
			udf_file_entry_alloc_offset(inode) +
1876
			iinfo->i_lenEAttr;
M
Marcin Slusarz 已提交
1877
		alen = udf_file_entry_alloc_offset(inode) +
1878
							iinfo->i_lenAlloc;
1879
	} else {
J
Jan Kara 已提交
1880 1881 1882
		if (!epos->offset)
			epos->offset = sizeof(struct allocExtDesc);
		ptr = epos->bh->b_data + epos->offset;
1883
		alen = sizeof(struct allocExtDesc) +
M
Marcin Slusarz 已提交
1884 1885
			le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->
							lengthAllocDescs);
L
Linus Torvalds 已提交
1886 1887
	}

1888
	switch (iinfo->i_alloc_type) {
1889
	case ICBTAG_FLAG_AD_SHORT:
M
Marcin Slusarz 已提交
1890 1891
		sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc);
		if (!sad)
1892 1893 1894
			return -1;
		etype = le32_to_cpu(sad->extLength) >> 30;
		eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
M
Marcin Slusarz 已提交
1895
		eloc->partitionReferenceNum =
1896
				iinfo->i_location.partitionReferenceNum;
1897 1898
		*elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK;
		break;
1899
	case ICBTAG_FLAG_AD_LONG:
M
Marcin Slusarz 已提交
1900 1901
		lad = udf_get_filelongad(ptr, alen, &epos->offset, inc);
		if (!lad)
L
Linus Torvalds 已提交
1902
			return -1;
1903 1904 1905 1906 1907
		etype = le32_to_cpu(lad->extLength) >> 30;
		*eloc = lelb_to_cpu(lad->extLocation);
		*elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK;
		break;
	default:
M
Marcin Slusarz 已提交
1908
		udf_debug("alloc_type = %d unsupported\n",
1909
				iinfo->i_alloc_type);
1910
		return -1;
L
Linus Torvalds 已提交
1911 1912 1913 1914 1915
	}

	return etype;
}

1916
static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos,
1917
			      struct kernel_lb_addr neloc, uint32_t nelen)
L
Linus Torvalds 已提交
1918
{
1919
	struct kernel_lb_addr oeloc;
L
Linus Torvalds 已提交
1920 1921 1922
	uint32_t oelen;
	int8_t etype;

J
Jan Kara 已提交
1923
	if (epos.bh)
J
Jan Kara 已提交
1924
		get_bh(epos.bh);
L
Linus Torvalds 已提交
1925

1926
	while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1) {
1927
		udf_write_aext(inode, &epos, &neloc, nelen, 1);
L
Linus Torvalds 已提交
1928 1929 1930
		neloc = oeloc;
		nelen = (etype << 30) | oelen;
	}
1931
	udf_add_aext(inode, &epos, &neloc, nelen, 1);
J
Jan Kara 已提交
1932
	brelse(epos.bh);
1933

L
Linus Torvalds 已提交
1934 1935 1936
	return (nelen >> 30);
}

M
Marcin Slusarz 已提交
1937
int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
1938
		       struct kernel_lb_addr eloc, uint32_t elen)
L
Linus Torvalds 已提交
1939
{
J
Jan Kara 已提交
1940 1941
	struct extent_position oepos;
	int adsize;
L
Linus Torvalds 已提交
1942 1943
	int8_t etype;
	struct allocExtDesc *aed;
1944
	struct udf_inode_info *iinfo;
L
Linus Torvalds 已提交
1945

1946
	if (epos.bh) {
J
Jan Kara 已提交
1947 1948
		get_bh(epos.bh);
		get_bh(epos.bh);
L
Linus Torvalds 已提交
1949 1950
	}

1951 1952
	iinfo = UDF_I(inode);
	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
1953
		adsize = sizeof(struct short_ad);
1954
	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
1955
		adsize = sizeof(struct long_ad);
L
Linus Torvalds 已提交
1956 1957 1958
	else
		adsize = 0;

J
Jan Kara 已提交
1959 1960
	oepos = epos;
	if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1)
L
Linus Torvalds 已提交
1961 1962
		return -1;

1963
	while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) {
1964
		udf_write_aext(inode, &oepos, &eloc, (etype << 30) | elen, 1);
1965
		if (oepos.bh != epos.bh) {
J
Jan Kara 已提交
1966
			oepos.block = epos.block;
J
Jan Kara 已提交
1967 1968
			brelse(oepos.bh);
			get_bh(epos.bh);
J
Jan Kara 已提交
1969 1970
			oepos.bh = epos.bh;
			oepos.offset = epos.offset - adsize;
L
Linus Torvalds 已提交
1971 1972
		}
	}
1973
	memset(&eloc, 0x00, sizeof(struct kernel_lb_addr));
L
Linus Torvalds 已提交
1974 1975
	elen = 0;

1976
	if (epos.bh != oepos.bh) {
1977 1978 1979
		udf_free_blocks(inode->i_sb, inode, &epos.block, 0, 1);
		udf_write_aext(inode, &oepos, &eloc, elen, 1);
		udf_write_aext(inode, &oepos, &eloc, elen, 1);
1980
		if (!oepos.bh) {
1981
			iinfo->i_lenAlloc -= (adsize * 2);
L
Linus Torvalds 已提交
1982
			mark_inode_dirty(inode);
1983
		} else {
J
Jan Kara 已提交
1984
			aed = (struct allocExtDesc *)oepos.bh->b_data;
1985
			le32_add_cpu(&aed->lengthAllocDescs, -(2 * adsize));
1986
			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
M
Marcin Slusarz 已提交
1987
			    UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
M
Marcin Slusarz 已提交
1988 1989
				udf_update_tag(oepos.bh->b_data,
						oepos.offset - (2 * adsize));
L
Linus Torvalds 已提交
1990
			else
M
Marcin Slusarz 已提交
1991 1992
				udf_update_tag(oepos.bh->b_data,
						sizeof(struct allocExtDesc));
J
Jan Kara 已提交
1993
			mark_buffer_dirty_inode(oepos.bh, inode);
L
Linus Torvalds 已提交
1994
		}
1995
	} else {
1996
		udf_write_aext(inode, &oepos, &eloc, elen, 1);
1997
		if (!oepos.bh) {
1998
			iinfo->i_lenAlloc -= adsize;
L
Linus Torvalds 已提交
1999
			mark_inode_dirty(inode);
2000
		} else {
J
Jan Kara 已提交
2001
			aed = (struct allocExtDesc *)oepos.bh->b_data;
2002
			le32_add_cpu(&aed->lengthAllocDescs, -adsize);
2003
			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
M
Marcin Slusarz 已提交
2004
			    UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
M
Marcin Slusarz 已提交
2005 2006
				udf_update_tag(oepos.bh->b_data,
						epos.offset - adsize);
L
Linus Torvalds 已提交
2007
			else
M
Marcin Slusarz 已提交
2008 2009
				udf_update_tag(oepos.bh->b_data,
						sizeof(struct allocExtDesc));
J
Jan Kara 已提交
2010
			mark_buffer_dirty_inode(oepos.bh, inode);
L
Linus Torvalds 已提交
2011 2012
		}
	}
2013

J
Jan Kara 已提交
2014 2015
	brelse(epos.bh);
	brelse(oepos.bh);
2016

L
Linus Torvalds 已提交
2017 2018 2019
	return (elen >> 30);
}

M
Marcin Slusarz 已提交
2020
int8_t inode_bmap(struct inode *inode, sector_t block,
2021
		  struct extent_position *pos, struct kernel_lb_addr *eloc,
M
Marcin Slusarz 已提交
2022
		  uint32_t *elen, sector_t *offset)
L
Linus Torvalds 已提交
2023
{
M
Marcin Slusarz 已提交
2024
	unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
2025
	loff_t lbcount = 0, bcount =
M
Marcin Slusarz 已提交
2026
	    (loff_t) block << blocksize_bits;
L
Linus Torvalds 已提交
2027
	int8_t etype;
2028
	struct udf_inode_info *iinfo;
L
Linus Torvalds 已提交
2029

2030
	iinfo = UDF_I(inode);
J
Jan Kara 已提交
2031
	pos->offset = 0;
2032
	pos->block = iinfo->i_location;
J
Jan Kara 已提交
2033
	pos->bh = NULL;
L
Linus Torvalds 已提交
2034 2035
	*elen = 0;

2036
	do {
M
Marcin Slusarz 已提交
2037 2038 2039
		etype = udf_next_aext(inode, pos, eloc, elen, 1);
		if (etype == -1) {
			*offset = (bcount - lbcount) >> blocksize_bits;
2040
			iinfo->i_lenExtents = lbcount;
L
Linus Torvalds 已提交
2041 2042 2043 2044 2045
			return -1;
		}
		lbcount += *elen;
	} while (lbcount <= bcount);

M
Marcin Slusarz 已提交
2046
	*offset = (bcount + *elen - lbcount) >> blocksize_bits;
L
Linus Torvalds 已提交
2047 2048 2049 2050

	return etype;
}

2051
long udf_block_map(struct inode *inode, sector_t block)
L
Linus Torvalds 已提交
2052
{
2053
	struct kernel_lb_addr eloc;
J
Jan Kara 已提交
2054
	uint32_t elen;
2055
	sector_t offset;
2056
	struct extent_position epos = {};
L
Linus Torvalds 已提交
2057 2058 2059 2060
	int ret;

	lock_kernel();

M
Marcin Slusarz 已提交
2061 2062
	if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) ==
						(EXT_RECORDED_ALLOCATED >> 30))
2063
		ret = udf_get_lb_pblock(inode->i_sb, &eloc, offset);
L
Linus Torvalds 已提交
2064 2065 2066 2067
	else
		ret = 0;

	unlock_kernel();
J
Jan Kara 已提交
2068
	brelse(epos.bh);
L
Linus Torvalds 已提交
2069 2070 2071 2072 2073 2074

	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV))
		return udf_fixed_to_variable(ret);
	else
		return ret;
}