Blame view

fs/udf/inode.c 60.4 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
  /*
   * inode.c
   *
   * PURPOSE
   *  Inode handling routines for the OSTA-UDF(tm) filesystem.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
   * 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
   *  12/06/98 blf  partition support in udf_iget, udf_block_map and udf_read_inode
   *  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>
  #include <linux/slab.h>
  
  #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 *);
647bd61a5   Cyrill Gorcunov   UDF: check for al...
52
  static int udf_alloc_i_data(struct inode *inode, size_t size);
60448b1d6   Jan Kara   udf: use sector_t...
53
  static struct buffer_head *inode_getblk(struct inode *, sector_t, int *,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
54
  					long *, int *);
ff116fc8d   Jan Kara   UDF: introduce st...
55
  static int8_t udf_insert_aext(struct inode *, struct extent_position,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
56
  			      kernel_lb_addr, uint32_t);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
  static void udf_split_extents(struct inode *, int *, int, int,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
58
  			      kernel_long_ad[EXTENT_MERGE_SIZE], int *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
  static void udf_prealloc_extents(struct inode *, int, int,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
60
  				 kernel_long_ad[EXTENT_MERGE_SIZE], int *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  static void udf_merge_extents(struct inode *,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
62
  			      kernel_long_ad[EXTENT_MERGE_SIZE], int *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
  static void udf_update_extents(struct inode *,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
64
65
  			       kernel_long_ad[EXTENT_MERGE_SIZE], int, int,
  			       struct extent_position *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
  static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
  
  /*
   * udf_delete_inode
   *
   * PURPOSE
   *	Clean-up before the specified inode is destroyed.
   *
   * DESCRIPTION
   *	This routine is called when the kernel destroys an inode structure
   *	ie. when iput() finds i_count == 0.
   *
   * HISTORY
   *	July 1, 1997 - Andrew E. Mileski
   *	Written, tested, and released.
   *
   *  Called at the last iput() if i_nlink is zero.
   */
cb00ea352   Cyrill Gorcunov   UDF: coding style...
84
  void udf_delete_inode(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
  {
fef266580   Mark Fasheh   [PATCH] update fi...
86
  	truncate_inode_pages(&inode->i_data, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87
88
89
90
91
92
93
94
95
96
97
98
  	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;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
99
        no_delete:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
101
  	clear_inode(inode);
  }
74584ae50   Jan Kara   udf: fix possible...
102
103
104
105
106
107
108
  /*
   * If we are going to release inode from memory, we discard preallocation and
   * 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.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
109
110
111
112
  void udf_clear_inode(struct inode *inode)
  {
  	if (!(inode->i_sb->s_flags & MS_RDONLY)) {
  		lock_kernel();
74584ae50   Jan Kara   udf: fix possible...
113
  		/* Discard preallocation for directories, symlinks, etc. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114
  		udf_discard_prealloc(inode);
74584ae50   Jan Kara   udf: fix possible...
115
  		udf_truncate_tail_extent(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
  		unlock_kernel();
74584ae50   Jan Kara   udf: fix possible...
117
  		write_inode_now(inode, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
120
121
122
123
124
125
126
127
128
129
130
131
  	kfree(UDF_I_DATA(inode));
  	UDF_I_DATA(inode) = NULL;
  }
  
  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);
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
132
133
  static int udf_prepare_write(struct file *file, struct page *page,
  			     unsigned from, unsigned to)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
135
136
137
138
139
  {
  	return block_prepare_write(page, from, to, udf_get_block);
  }
  
  static sector_t udf_bmap(struct address_space *mapping, sector_t block)
  {
cb00ea352   Cyrill Gorcunov   UDF: coding style...
140
  	return generic_block_bmap(mapping, block, udf_get_block);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
  }
f5e54d6e5   Christoph Hellwig   [PATCH] mark addr...
142
  const struct address_space_operations udf_aops = {
cb00ea352   Cyrill Gorcunov   UDF: coding style...
143
144
145
146
147
148
  	.readpage = udf_readpage,
  	.writepage = udf_writepage,
  	.sync_page = block_sync_page,
  	.prepare_write = udf_prepare_write,
  	.commit_write = generic_commit_write,
  	.bmap = udf_bmap,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
  };
cb00ea352   Cyrill Gorcunov   UDF: coding style...
150
  void udf_expand_file_adinicb(struct inode *inode, int newsize, int *err)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
153
154
155
156
157
158
159
160
  {
  	struct page *page;
  	char *kaddr;
  	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;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
161
  	if (!UDF_I_LENALLOC(inode)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
163
164
165
166
167
168
169
170
  		if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
  			UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
  		else
  			UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
  		mark_inode_dirty(inode);
  		return;
  	}
  
  	page = grab_cache_page(inode->i_mapping, 0);
cd7619d6b   Matt Mackall   [PATCH] Extermina...
171
  	BUG_ON(!PageLocked(page));
cb00ea352   Cyrill Gorcunov   UDF: coding style...
172
  	if (!PageUptodate(page)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
174
  		kaddr = kmap(page);
  		memset(kaddr + UDF_I_LENALLOC(inode), 0x00,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
175
  		       PAGE_CACHE_SIZE - UDF_I_LENALLOC(inode));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176
  		memcpy(kaddr, UDF_I_DATA(inode) + UDF_I_LENEATTR(inode),
cb00ea352   Cyrill Gorcunov   UDF: coding style...
177
  		       UDF_I_LENALLOC(inode));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
179
180
181
182
  		flush_dcache_page(page);
  		SetPageUptodate(page);
  		kunmap(page);
  	}
  	memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0x00,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
183
  	       UDF_I_LENALLOC(inode));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184
185
186
187
188
189
190
191
192
193
194
  	UDF_I_LENALLOC(inode) = 0;
  	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
  		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
  	else
  		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
  
  	inode->i_data.a_ops->writepage(page, &udf_wbc);
  	page_cache_release(page);
  
  	mark_inode_dirty(inode);
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
195
196
  struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block,
  					   int *err)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197
198
  {
  	int newblock;
ff116fc8d   Jan Kara   UDF: introduce st...
199
200
201
  	struct buffer_head *dbh = NULL;
  	kernel_lb_addr eloc;
  	uint32_t elen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202
  	uint8_t alloctype;
ff116fc8d   Jan Kara   UDF: introduce st...
203
  	struct extent_position epos;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
204
205
206
207
208
209
210
211
212
213
  
  	struct udf_fileident_bh sfibh, dfibh;
  	loff_t f_pos = udf_ext0_offset(inode) >> 2;
  	int size = (udf_ext0_offset(inode) + inode->i_size) >> 2;
  	struct fileIdentDesc cfi, *sfi, *dfi;
  
  	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
  		alloctype = ICBTAG_FLAG_AD_SHORT;
  	else
  		alloctype = ICBTAG_FLAG_AD_LONG;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
214
  	if (!inode->i_size) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215
216
217
218
219
220
221
  		UDF_I_ALLOCTYPE(inode) = alloctype;
  		mark_inode_dirty(inode);
  		return NULL;
  	}
  
  	/* alloc block, and copy data to it */
  	*block = udf_new_block(inode->i_sb, inode,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
222
223
  			       UDF_I_LOCATION(inode).partitionReferenceNum,
  			       UDF_I_LOCATION(inode).logicalBlockNum, err);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
225
226
227
  
  	if (!(*block))
  		return NULL;
  	newblock = udf_get_pblock(inode->i_sb, *block,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
228
229
  				  UDF_I_LOCATION(inode).partitionReferenceNum,
  				  0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
231
232
233
234
235
236
237
238
239
  	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);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
240
241
  	sfibh.soffset = sfibh.eoffset =
  	    (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2;
ff116fc8d   Jan Kara   UDF: introduce st...
242
  	sfibh.sbh = sfibh.ebh = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
244
  	dfibh.soffset = dfibh.eoffset = 0;
  	dfibh.sbh = dfibh.ebh = dbh;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
245
  	while ((f_pos < size)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246
  		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
247
248
249
250
  		sfi =
  		    udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL,
  				       NULL, NULL);
  		if (!sfi) {
3bf25cb40   Jan Kara   udf: use get_bh()
251
  			brelse(dbh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252
253
254
255
256
257
258
259
  			return NULL;
  		}
  		UDF_I_ALLOCTYPE(inode) = alloctype;
  		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,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
260
261
  				 sfi->fileIdent +
  				 le16_to_cpu(sfi->lengthOfImpUse))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
  			UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
3bf25cb40   Jan Kara   udf: use get_bh()
263
  			brelse(dbh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
264
265
266
267
  			return NULL;
  		}
  	}
  	mark_buffer_dirty_inode(dbh, inode);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
268
269
  	memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0,
  	       UDF_I_LENALLOC(inode));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
  	UDF_I_LENALLOC(inode) = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
271
  	eloc.logicalBlockNum = *block;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
272
273
  	eloc.partitionReferenceNum =
  	    UDF_I_LOCATION(inode).partitionReferenceNum;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
274
275
  	elen = inode->i_size;
  	UDF_I_LENEXTENTS(inode) = elen;
ff116fc8d   Jan Kara   UDF: introduce st...
276
277
278
279
  	epos.bh = NULL;
  	epos.block = UDF_I_LOCATION(inode);
  	epos.offset = udf_file_entry_alloc_offset(inode);
  	udf_add_aext(inode, &epos, eloc, elen, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
  	/* UniqueID stuff */
3bf25cb40   Jan Kara   udf: use get_bh()
281
  	brelse(epos.bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
283
284
  	mark_inode_dirty(inode);
  	return dbh;
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
285
286
  static int udf_get_block(struct inode *inode, sector_t block,
  			 struct buffer_head *bh_result, int create)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
287
288
289
290
  {
  	int err, new;
  	struct buffer_head *bh;
  	unsigned long phys;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
291
  	if (!create) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
293
294
295
296
297
298
299
300
301
302
303
304
305
  		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();
  
  	if (block < 0)
  		goto abort_negative;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
306
307
308
  	if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1) {
  		UDF_I_NEXT_ALLOC_BLOCK(inode)++;
  		UDF_I_NEXT_ALLOC_GOAL(inode)++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
310
311
312
313
  	}
  
  	err = 0;
  
  	bh = inode_getblk(inode, block, &err, &phys, &new);
2c2111c2b   Eric Sesterhenn   BUG_ON() Conversi...
314
  	BUG_ON(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
316
  	if (err)
  		goto abort;
2c2111c2b   Eric Sesterhenn   BUG_ON() Conversi...
317
  	BUG_ON(!phys);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318
319
320
321
  
  	if (new)
  		set_buffer_new(bh_result);
  	map_bh(bh_result, inode->i_sb, phys);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
322
        abort:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
323
324
  	unlock_kernel();
  	return err;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
325
        abort_negative:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326
327
328
  	udf_warning(inode->i_sb, "udf_get_block", "block < 0");
  	goto abort;
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
329
330
  static struct buffer_head *udf_getblk(struct inode *inode, long block,
  				      int create, int *err)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331
332
333
334
335
336
  {
  	struct buffer_head dummy;
  
  	dummy.b_state = 0;
  	dummy.b_blocknr = -1000;
  	*err = udf_get_block(inode, block, &dummy, create);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
337
  	if (!*err && buffer_mapped(&dummy)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
339
  		struct buffer_head *bh;
  		bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
340
  		if (buffer_new(&dummy)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
341
342
343
344
345
346
347
348
349
350
  			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;
  	}
  	return NULL;
  }
31170b6ad   Jan Kara   udf: support file...
351
352
  /* Extend the file by 'blocks' blocks, return the number of extents added */
  int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
353
  		    kernel_long_ad * last_ext, sector_t blocks)
31170b6ad   Jan Kara   udf: support file...
354
355
356
357
  {
  	sector_t add;
  	int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
  	struct super_block *sb = inode->i_sb;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
358
  	kernel_lb_addr prealloc_loc = { 0, 0 };
31170b6ad   Jan Kara   udf: support file...
359
360
361
362
363
364
365
366
367
  	int prealloc_len = 0;
  
  	/* The previous extent is fake and we should not extend by anything
  	 * - there's nothing to do... */
  	if (!blocks && fake)
  		return 0;
  	/* Round the last extent up to a multiple of block size */
  	if (last_ext->extLength & (sb->s_blocksize - 1)) {
  		last_ext->extLength =
cb00ea352   Cyrill Gorcunov   UDF: coding style...
368
369
370
  		    (last_ext->extLength & UDF_EXTENT_FLAG_MASK) |
  		    (((last_ext->extLength & UDF_EXTENT_LENGTH_MASK) +
  		      sb->s_blocksize - 1) & ~(sb->s_blocksize - 1));
31170b6ad   Jan Kara   udf: support file...
371
  		UDF_I_LENEXTENTS(inode) =
cb00ea352   Cyrill Gorcunov   UDF: coding style...
372
373
  		    (UDF_I_LENEXTENTS(inode) + sb->s_blocksize - 1) &
  		    ~(sb->s_blocksize - 1);
31170b6ad   Jan Kara   udf: support file...
374
375
  	}
  	/* Last extent are just preallocated blocks? */
cb00ea352   Cyrill Gorcunov   UDF: coding style...
376
377
  	if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
  	    EXT_NOT_RECORDED_ALLOCATED) {
31170b6ad   Jan Kara   udf: support file...
378
379
380
381
382
  		/* 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 |
cb00ea352   Cyrill Gorcunov   UDF: coding style...
383
  		    (last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
31170b6ad   Jan Kara   udf: support file...
384
  		last_ext->extLocation.logicalBlockNum = 0;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
385
  		last_ext->extLocation.partitionReferenceNum = 0;
31170b6ad   Jan Kara   udf: support file...
386
387
  	}
  	/* Can we merge with the previous extent? */
cb00ea352   Cyrill Gorcunov   UDF: coding style...
388
389
390
391
392
393
  	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;
31170b6ad   Jan Kara   udf: support file...
394
395
396
397
398
399
400
401
  		if (add > blocks)
  			add = blocks;
  		blocks -= add;
  		last_ext->extLength += add << sb->s_blocksize_bits;
  	}
  
  	if (fake) {
  		udf_add_aext(inode, last_pos, last_ext->extLocation,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
402
  			     last_ext->extLength, 1);
31170b6ad   Jan Kara   udf: support file...
403
  		count++;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
404
405
406
  	} else
  		udf_write_aext(inode, last_pos, last_ext->extLocation,
  			       last_ext->extLength, 1);
31170b6ad   Jan Kara   udf: support file...
407
408
409
410
411
412
  	/* Managed to do everything necessary? */
  	if (!blocks)
  		goto out;
  
  	/* All further extents will be NOT_RECORDED_NOT_ALLOCATED */
  	last_ext->extLocation.logicalBlockNum = 0;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
413
414
415
416
  	last_ext->extLocation.partitionReferenceNum = 0;
  	add = (1 << (30 - sb->s_blocksize_bits)) - 1;
  	last_ext->extLength =
  	    EXT_NOT_RECORDED_NOT_ALLOCATED | (add << sb->s_blocksize_bits);
31170b6ad   Jan Kara   udf: support file...
417
418
419
420
  	/* Create enough extents to cover the whole hole */
  	while (blocks > add) {
  		blocks -= add;
  		if (udf_add_aext(inode, last_pos, last_ext->extLocation,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
421
  				 last_ext->extLength, 1) == -1)
31170b6ad   Jan Kara   udf: support file...
422
423
424
425
426
  			return -1;
  		count++;
  	}
  	if (blocks) {
  		last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
cb00ea352   Cyrill Gorcunov   UDF: coding style...
427
  		    (blocks << sb->s_blocksize_bits);
31170b6ad   Jan Kara   udf: support file...
428
  		if (udf_add_aext(inode, last_pos, last_ext->extLocation,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
429
  				 last_ext->extLength, 1) == -1)
31170b6ad   Jan Kara   udf: support file...
430
431
432
  			return -1;
  		count++;
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
433
        out:
31170b6ad   Jan Kara   udf: support file...
434
435
  	/* Do we have some preallocated blocks saved? */
  	if (prealloc_len) {
cb00ea352   Cyrill Gorcunov   UDF: coding style...
436
437
  		if (udf_add_aext(inode, last_pos, prealloc_loc, prealloc_len, 1)
  		    == -1)
31170b6ad   Jan Kara   udf: support file...
438
439
440
441
442
443
444
445
446
447
448
449
450
451
  			return -1;
  		last_ext->extLocation = prealloc_loc;
  		last_ext->extLength = prealloc_len;
  		count++;
  	}
  	/* last_pos should point to the last written extent... */
  	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
  		last_pos->offset -= sizeof(short_ad);
  	else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
  		last_pos->offset -= sizeof(long_ad);
  	else
  		return -1;
  	return count;
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
452
453
  static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
  					int *err, long *phys, int *new)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
454
  {
31170b6ad   Jan Kara   udf: support file...
455
  	static sector_t last_block;
ff116fc8d   Jan Kara   UDF: introduce st...
456
  	struct buffer_head *result = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
457
  	kernel_long_ad laarr[EXTENT_MERGE_SIZE];
ff116fc8d   Jan Kara   UDF: introduce st...
458
  	struct extent_position prev_epos, cur_epos, next_epos;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459
  	int count = 0, startnum = 0, endnum = 0;
85d71244f   Jan Kara   Fix possible UDF ...
460
461
  	uint32_t elen = 0, tmpelen;
  	kernel_lb_addr eloc, tmpeloc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462
  	int c = 1;
60448b1d6   Jan Kara   udf: use sector_t...
463
464
465
  	loff_t lbcount = 0, b_off = 0;
  	uint32_t newblocknum, newblock;
  	sector_t offset = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
466
467
  	int8_t etype;
  	int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum;
31170b6ad   Jan Kara   udf: support file...
468
  	int lastblock = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
469

ff116fc8d   Jan Kara   UDF: introduce st...
470
471
472
473
  	prev_epos.offset = udf_file_entry_alloc_offset(inode);
  	prev_epos.block = UDF_I_LOCATION(inode);
  	prev_epos.bh = NULL;
  	cur_epos = next_epos = prev_epos;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
474
  	b_off = (loff_t) block << inode->i_sb->s_blocksize_bits;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
475
476
  
  	/* find the extent which contains the block we are looking for.
cb00ea352   Cyrill Gorcunov   UDF: coding style...
477
478
479
480
  	   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) {
3bf25cb40   Jan Kara   udf: use get_bh()
481
482
  			brelse(prev_epos.bh);
  			get_bh(cur_epos.bh);
ff116fc8d   Jan Kara   UDF: introduce st...
483
  			prev_epos.bh = cur_epos.bh;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
485
  		if (cur_epos.bh != next_epos.bh) {
3bf25cb40   Jan Kara   udf: use get_bh()
486
487
  			brelse(cur_epos.bh);
  			get_bh(next_epos.bh);
ff116fc8d   Jan Kara   UDF: introduce st...
488
  			cur_epos.bh = next_epos.bh;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
490
491
  		}
  
  		lbcount += elen;
ff116fc8d   Jan Kara   UDF: introduce st...
492
493
  		prev_epos.block = cur_epos.block;
  		cur_epos.block = next_epos.block;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
494

ff116fc8d   Jan Kara   UDF: introduce st...
495
496
  		prev_epos.offset = cur_epos.offset;
  		cur_epos.offset = next_epos.offset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
497

cb00ea352   Cyrill Gorcunov   UDF: coding style...
498
499
  		if ((etype =
  		     udf_next_aext(inode, &next_epos, &eloc, &elen, 1)) == -1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
500
501
502
503
504
505
506
507
508
  			break;
  
  		c = !c;
  
  		laarr[c].extLength = (etype << 30) | elen;
  		laarr[c].extLocation = eloc;
  
  		if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
  			pgoal = eloc.logicalBlockNum +
cb00ea352   Cyrill Gorcunov   UDF: coding style...
509
510
  			    ((elen + inode->i_sb->s_blocksize - 1) >>
  			     inode->i_sb->s_blocksize_bits);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
511

cb00ea352   Cyrill Gorcunov   UDF: coding style...
512
  		count++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
513
514
515
516
  	} while (lbcount + elen <= b_off);
  
  	b_off -= lbcount;
  	offset = b_off >> inode->i_sb->s_blocksize_bits;
85d71244f   Jan Kara   Fix possible UDF ...
517
518
519
520
521
522
  	/*
  	 * 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);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
523
524
  
  	/* if the extent is allocated and recorded, return the block
cb00ea352   Cyrill Gorcunov   UDF: coding style...
525
  	   if the extent is not a multiple of the blocksize, round up */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526

cb00ea352   Cyrill Gorcunov   UDF: coding style...
527
528
  	if (etype == (EXT_RECORDED_ALLOCATED >> 30)) {
  		if (elen & (inode->i_sb->s_blocksize - 1)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
529
  			elen = EXT_RECORDED_ALLOCATED |
cb00ea352   Cyrill Gorcunov   UDF: coding style...
530
531
  			    ((elen + inode->i_sb->s_blocksize - 1) &
  			     ~(inode->i_sb->s_blocksize - 1));
ff116fc8d   Jan Kara   UDF: introduce st...
532
  			etype = udf_write_aext(inode, &cur_epos, eloc, elen, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
533
  		}
3bf25cb40   Jan Kara   udf: use get_bh()
534
535
536
  		brelse(prev_epos.bh);
  		brelse(cur_epos.bh);
  		brelse(next_epos.bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
537
538
539
540
  		newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset);
  		*phys = newblock;
  		return NULL;
  	}
31170b6ad   Jan Kara   udf: support file...
541
542
  	last_block = block;
  	/* Are we beyond EOF? */
cb00ea352   Cyrill Gorcunov   UDF: coding style...
543
  	if (etype == -1) {
31170b6ad   Jan Kara   udf: support file...
544
545
546
547
548
549
  		int ret;
  
  		if (count) {
  			if (c)
  				laarr[0] = laarr[1];
  			startnum = 1;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
550
  		} else {
31170b6ad   Jan Kara   udf: support file...
551
  			/* Create a fake extent when there's not one */
cb00ea352   Cyrill Gorcunov   UDF: coding style...
552
553
  			memset(&laarr[0].extLocation, 0x00,
  			       sizeof(kernel_lb_addr));
31170b6ad   Jan Kara   udf: support file...
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
  			laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED;
  			/* Will udf_extend_file() create real extent from a fake one? */
  			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? */
cb00ea352   Cyrill Gorcunov   UDF: coding style...
573
574
  		if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) !=
  		    EXT_NOT_RECORDED_ALLOCATED) {
31170b6ad   Jan Kara   udf: support file...
575
576
577
578
579
  			/* Is there any real extent? - otherwise we overwrite
  			 * the fake one... */
  			if (count)
  				c = !c;
  			laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
cb00ea352   Cyrill Gorcunov   UDF: coding style...
580
581
582
583
584
  			    inode->i_sb->s_blocksize;
  			memset(&laarr[c].extLocation, 0x00,
  			       sizeof(kernel_lb_addr));
  			count++;
  			endnum++;
31170b6ad   Jan Kara   udf: support file...
585
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
586
  		endnum = c + 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
587
  		lastblock = 1;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
588
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
589
  		endnum = startnum = ((count > 2) ? 2 : count);
31170b6ad   Jan Kara   udf: support file...
590
  		/* if the current extent is in position 0, swap it with the previous */
cb00ea352   Cyrill Gorcunov   UDF: coding style...
591
  		if (!c && count != 1) {
31170b6ad   Jan Kara   udf: support file...
592
593
594
595
596
  			laarr[2] = laarr[0];
  			laarr[0] = laarr[1];
  			laarr[1] = laarr[2];
  			c = 1;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
597

31170b6ad   Jan Kara   udf: support file...
598
  		/* if the current block is located in an extent, read the next extent */
cb00ea352   Cyrill Gorcunov   UDF: coding style...
599
600
601
602
603
604
605
606
  		if ((etype =
  		     udf_next_aext(inode, &next_epos, &eloc, &elen, 0)) != -1) {
  			laarr[c + 1].extLength = (etype << 30) | elen;
  			laarr[c + 1].extLocation = eloc;
  			count++;
  			startnum++;
  			endnum++;
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
607
  			lastblock = 1;
31170b6ad   Jan Kara   udf: support file...
608
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
610
611
  
  	/* if the current extent is not recorded but allocated, get the
cb00ea352   Cyrill Gorcunov   UDF: coding style...
612
  	   block in the extent corresponding to the requested block */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
613
614
  	if ((laarr[c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
  		newblocknum = laarr[c].extLocation.logicalBlockNum + offset;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
615
  	else {			/* otherwise, allocate a new block */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
616
617
  		if (UDF_I_NEXT_ALLOC_BLOCK(inode) == block)
  			goal = UDF_I_NEXT_ALLOC_GOAL(inode);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
618
  		if (!goal) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
619
  			if (!(goal = pgoal))
cb00ea352   Cyrill Gorcunov   UDF: coding style...
620
621
  				goal =
  				    UDF_I_LOCATION(inode).logicalBlockNum + 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
622
623
624
  		}
  
  		if (!(newblocknum = udf_new_block(inode->i_sb, inode,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
625
626
627
  						  UDF_I_LOCATION(inode).
  						  partitionReferenceNum, goal,
  						  err))) {
3bf25cb40   Jan Kara   udf: use get_bh()
628
  			brelse(prev_epos.bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
629
630
631
632
633
634
635
  			*err = -ENOSPC;
  			return NULL;
  		}
  		UDF_I_LENEXTENTS(inode) += inode->i_sb->s_blocksize;
  	}
  
  	/* if the extent the requsted block is located in contains multiple blocks,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
636
637
  	   split the extent into at most three extents. blocks prior to requested
  	   block, requested block, and blocks after requested block */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
638
639
640
641
642
643
644
645
646
647
648
  	udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum);
  
  #ifdef UDF_PREALLOCATE
  	/* preallocate blocks */
  	udf_prealloc_extents(inode, c, lastblock, laarr, &endnum);
  #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
cb00ea352   Cyrill Gorcunov   UDF: coding style...
649
650
  	   of extents is greater than the old number, and deleting extents if
  	   the new number of extents is less than the old number */
ff116fc8d   Jan Kara   UDF: introduce st...
651
  	udf_update_extents(inode, laarr, startnum, endnum, &prev_epos);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
652

3bf25cb40   Jan Kara   udf: use get_bh()
653
  	brelse(prev_epos.bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654
655
  
  	if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
656
657
  					UDF_I_LOCATION(inode).
  					partitionReferenceNum, 0))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
  		return NULL;
  	}
  	*phys = newblock;
  	*err = 0;
  	*new = 1;
  	UDF_I_NEXT_ALLOC_BLOCK(inode) = block;
  	UDF_I_NEXT_ALLOC_GOAL(inode) = newblocknum;
  	inode->i_ctime = current_fs_time(inode->i_sb);
  
  	if (IS_SYNC(inode))
  		udf_sync_inode(inode);
  	else
  		mark_inode_dirty(inode);
  	return result;
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
673
674
675
676
  static void udf_split_extents(struct inode *inode, int *c, int offset,
  			      int newblocknum,
  			      kernel_long_ad laarr[EXTENT_MERGE_SIZE],
  			      int *endnum)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
677
678
  {
  	if ((laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30) ||
cb00ea352   Cyrill Gorcunov   UDF: coding style...
679
680
  	    (laarr[*c].extLength >> 30) ==
  	    (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
681
682
  		int curr = *c;
  		int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) +
cb00ea352   Cyrill Gorcunov   UDF: coding style...
683
684
  			    inode->i_sb->s_blocksize -
  			    1) >> inode->i_sb->s_blocksize_bits;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
685
  		int8_t etype = (laarr[curr].extLength >> 30);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
  		if (blen == 1) ;
  		else if (!offset || blen == offset + 1) {
  			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)) {
  				udf_free_blocks(inode->i_sb, inode,
  						laarr[curr].extLocation, 0,
  						offset);
  				laarr[curr].extLength =
  				    EXT_NOT_RECORDED_NOT_ALLOCATED | (offset <<
  								      inode->
  								      i_sb->
  								      s_blocksize_bits);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
705
  				laarr[curr].extLocation.logicalBlockNum = 0;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
706
707
708
  				laarr[curr].extLocation.partitionReferenceNum =
  				    0;
  			} else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
709
  				laarr[curr].extLength = (etype << 30) |
cb00ea352   Cyrill Gorcunov   UDF: coding style...
710
711
712
713
  				    (offset << inode->i_sb->s_blocksize_bits);
  			curr++;
  			(*c)++;
  			(*endnum)++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
714
  		}
647bd61a5   Cyrill Gorcunov   UDF: check for al...
715

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
716
717
718
  		laarr[curr].extLocation.logicalBlockNum = newblocknum;
  		if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
  			laarr[curr].extLocation.partitionReferenceNum =
cb00ea352   Cyrill Gorcunov   UDF: coding style...
719
  			    UDF_I_LOCATION(inode).partitionReferenceNum;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
720
  		laarr[curr].extLength = EXT_RECORDED_ALLOCATED |
cb00ea352   Cyrill Gorcunov   UDF: coding style...
721
722
  		    inode->i_sb->s_blocksize;
  		curr++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
723

cb00ea352   Cyrill Gorcunov   UDF: coding style...
724
  		if (blen != offset + 1) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
725
  			if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
cb00ea352   Cyrill Gorcunov   UDF: coding style...
726
727
728
729
730
731
732
  				laarr[curr].extLocation.logicalBlockNum +=
  				    (offset + 1);
  			laarr[curr].extLength =
  			    (etype << 30) | ((blen - (offset + 1)) << inode->
  					     i_sb->s_blocksize_bits);
  			curr++;
  			(*endnum)++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
733
734
735
736
737
  		}
  	}
  }
  
  static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
738
739
  				 kernel_long_ad laarr[EXTENT_MERGE_SIZE],
  				 int *endnum)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
740
741
  {
  	int start, length = 0, currlength = 0, i;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
742
  	if (*endnum >= (c + 1)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
743
744
745
746
  		if (!lastblock)
  			return;
  		else
  			start = c;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
747
748
749
750
751
752
753
754
755
756
  	} else {
  		if ((laarr[c + 1].extLength >> 30) ==
  		    (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
  			start = c + 1;
  			length = currlength =
  			    (((laarr[c + 1].
  			       extLength & UDF_EXTENT_LENGTH_MASK) +
  			      inode->i_sb->s_blocksize -
  			      1) >> inode->i_sb->s_blocksize_bits);
  		} else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
757
758
  			start = c;
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
759
760
  	for (i = start + 1; i <= *endnum; i++) {
  		if (i == *endnum) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
761
762
  			if (lastblock)
  				length += UDF_DEFAULT_PREALLOC_BLOCKS;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
763
764
765
766
767
768
  		} 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);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
769
770
771
  		else
  			break;
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
772
  	if (length) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
773
  		int next = laarr[start].extLocation.logicalBlockNum +
cb00ea352   Cyrill Gorcunov   UDF: coding style...
774
775
776
  		    (((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) +
  		      inode->i_sb->s_blocksize -
  		      1) >> inode->i_sb->s_blocksize_bits);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
777
  		int numalloc = udf_prealloc_blocks(inode->i_sb, inode,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
778
779
780
781
782
783
784
785
786
787
788
  						   laarr[start].extLocation.
  						   partitionReferenceNum,
  						   next,
  						   (UDF_DEFAULT_PREALLOC_BLOCKS
  						    >
  						    length ? length :
  						    UDF_DEFAULT_PREALLOC_BLOCKS)
  						   - currlength);
  
  		if (numalloc) {
  			if (start == (c + 1))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
789
  				laarr[start].extLength +=
cb00ea352   Cyrill Gorcunov   UDF: coding style...
790
791
792
793
794
795
796
797
798
799
800
801
802
  				    (numalloc << inode->i_sb->s_blocksize_bits);
  			else {
  				memmove(&laarr[c + 2], &laarr[c + 1],
  					sizeof(long_ad) * (*endnum - (c + 1)));
  				(*endnum)++;
  				laarr[c + 1].extLocation.logicalBlockNum = next;
  				laarr[c + 1].extLocation.partitionReferenceNum =
  				    laarr[c].extLocation.partitionReferenceNum;
  				laarr[c + 1].extLength =
  				    EXT_NOT_RECORDED_ALLOCATED | (numalloc <<
  								  inode->i_sb->
  								  s_blocksize_bits);
  				start = c + 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
803
  			}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
804
805
806
807
808
809
  			for (i = start + 1; numalloc && i < *endnum; i++) {
  				int elen =
  				    ((laarr[i].
  				      extLength & UDF_EXTENT_LENGTH_MASK) +
  				     inode->i_sb->s_blocksize -
  				     1) >> inode->i_sb->s_blocksize_bits;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
810

cb00ea352   Cyrill Gorcunov   UDF: coding style...
811
  				if (elen > numalloc) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
812
  					laarr[i].extLength -=
cb00ea352   Cyrill Gorcunov   UDF: coding style...
813
814
  					    (numalloc << inode->i_sb->
  					     s_blocksize_bits);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
815
  					numalloc = 0;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
816
  				} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
817
  					numalloc -= elen;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
818
819
820
821
822
823
824
  					if (*endnum > (i + 1))
  						memmove(&laarr[i],
  							&laarr[i + 1],
  							sizeof(long_ad) *
  							(*endnum - (i + 1)));
  					i--;
  					(*endnum)--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
825
826
  				}
  			}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
827
828
  			UDF_I_LENEXTENTS(inode) +=
  			    numalloc << inode->i_sb->s_blocksize_bits;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
829
830
831
832
833
  		}
  	}
  }
  
  static void udf_merge_extents(struct inode *inode,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
834
835
  			      kernel_long_ad laarr[EXTENT_MERGE_SIZE],
  			      int *endnum)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
836
837
  {
  	int i;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
  	for (i = 0; i < (*endnum - 1); i++) {
  		if ((laarr[i].extLength >> 30) ==
  		    (laarr[i + 1].extLength >> 30)) {
  			if (((laarr[i].extLength >> 30) ==
  			     (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
  			    ||
  			    ((laarr[i + 1].extLocation.logicalBlockNum -
  			      laarr[i].extLocation.logicalBlockNum) ==
  			     (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
  			       inode->i_sb->s_blocksize -
  			       1) >> inode->i_sb->s_blocksize_bits))) {
  				if (((laarr[i].
  				      extLength & UDF_EXTENT_LENGTH_MASK) +
  				     (laarr[i + 1].
  				      extLength & UDF_EXTENT_LENGTH_MASK) +
  				     inode->i_sb->s_blocksize -
  				     1) & ~UDF_EXTENT_LENGTH_MASK) {
  					laarr[i + 1].extLength =
  					    (laarr[i + 1].extLength -
  					     (laarr[i].
  					      extLength &
  					      UDF_EXTENT_LENGTH_MASK) +
  					     UDF_EXTENT_LENGTH_MASK) & ~(inode->
  									 i_sb->
  									 s_blocksize
  									 - 1);
  					laarr[i].extLength =
  					    (laarr[i].
  					     extLength & UDF_EXTENT_FLAG_MASK) +
  					    (UDF_EXTENT_LENGTH_MASK + 1) -
  					    inode->i_sb->s_blocksize;
  					laarr[i +
  					      1].extLocation.logicalBlockNum =
  					    laarr[i].extLocation.
  					    logicalBlockNum +
  					    ((laarr[i].
  					      extLength &
  					      UDF_EXTENT_LENGTH_MASK) >> inode->
  					     i_sb->s_blocksize_bits);
  				} else {
  					laarr[i].extLength =
  					    laarr[i + 1].extLength +
  					    (((laarr[i].
  					       extLength &
  					       UDF_EXTENT_LENGTH_MASK) +
  					      inode->i_sb->s_blocksize -
  					      1) & ~(inode->i_sb->s_blocksize -
  						     1));
  					if (*endnum > (i + 2))
  						memmove(&laarr[i + 1],
  							&laarr[i + 2],
  							sizeof(long_ad) *
  							(*endnum - (i + 2)));
  					i--;
  					(*endnum)--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
893
894
  				}
  			}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
895
896
897
898
899
900
901
902
903
904
905
  		} else
  		    if (((laarr[i].extLength >> 30) ==
  			 (EXT_NOT_RECORDED_ALLOCATED >> 30))
  			&& ((laarr[i + 1].extLength >> 30) ==
  			    (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))) {
  			udf_free_blocks(inode->i_sb, inode,
  					laarr[i].extLocation, 0,
  					((laarr[i].
  					  extLength & UDF_EXTENT_LENGTH_MASK) +
  					 inode->i_sb->s_blocksize -
  					 1) >> inode->i_sb->s_blocksize_bits);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
906
907
908
909
  			laarr[i].extLocation.logicalBlockNum = 0;
  			laarr[i].extLocation.partitionReferenceNum = 0;
  
  			if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
cb00ea352   Cyrill Gorcunov   UDF: coding style...
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
935
936
  			     (laarr[i + 1].extLength & UDF_EXTENT_LENGTH_MASK) +
  			     inode->i_sb->s_blocksize -
  			     1) & ~UDF_EXTENT_LENGTH_MASK) {
  				laarr[i + 1].extLength =
  				    (laarr[i + 1].extLength -
  				     (laarr[i].
  				      extLength & UDF_EXTENT_LENGTH_MASK) +
  				     UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->
  								 s_blocksize -
  								 1);
  				laarr[i].extLength =
  				    (laarr[i].
  				     extLength & UDF_EXTENT_FLAG_MASK) +
  				    (UDF_EXTENT_LENGTH_MASK + 1) -
  				    inode->i_sb->s_blocksize;
  			} else {
  				laarr[i].extLength = laarr[i + 1].extLength +
  				    (((laarr[i].
  				       extLength & UDF_EXTENT_LENGTH_MASK) +
  				      inode->i_sb->s_blocksize -
  				      1) & ~(inode->i_sb->s_blocksize - 1));
  				if (*endnum > (i + 2))
  					memmove(&laarr[i + 1], &laarr[i + 2],
  						sizeof(long_ad) * (*endnum -
  								   (i + 2)));
  				i--;
  				(*endnum)--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
937
  			}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
938
939
940
941
942
943
944
945
  		} else if ((laarr[i].extLength >> 30) ==
  			   (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
  			udf_free_blocks(inode->i_sb, inode,
  					laarr[i].extLocation, 0,
  					((laarr[i].
  					  extLength & UDF_EXTENT_LENGTH_MASK) +
  					 inode->i_sb->s_blocksize -
  					 1) >> inode->i_sb->s_blocksize_bits);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
946
947
  			laarr[i].extLocation.logicalBlockNum = 0;
  			laarr[i].extLocation.partitionReferenceNum = 0;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
948
949
950
951
  			laarr[i].extLength =
  			    (laarr[i].
  			     extLength & UDF_EXTENT_LENGTH_MASK) |
  			    EXT_NOT_RECORDED_NOT_ALLOCATED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
952
953
954
955
956
  		}
  	}
  }
  
  static void udf_update_extents(struct inode *inode,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
957
958
959
  			       kernel_long_ad laarr[EXTENT_MERGE_SIZE],
  			       int startnum, int endnum,
  			       struct extent_position *epos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
960
961
962
963
  {
  	int start = 0, i;
  	kernel_lb_addr tmploc;
  	uint32_t tmplen;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
964
965
  	if (startnum > endnum) {
  		for (i = 0; i < (startnum - endnum); i++)
ff116fc8d   Jan Kara   UDF: introduce st...
966
  			udf_delete_aext(inode, *epos, laarr[i].extLocation,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
967
968
969
  					laarr[i].extLength);
  	} else if (startnum < endnum) {
  		for (i = 0; i < (endnum - startnum); i++) {
ff116fc8d   Jan Kara   UDF: introduce st...
970
  			udf_insert_aext(inode, *epos, laarr[i].extLocation,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
971
  					laarr[i].extLength);
ff116fc8d   Jan Kara   UDF: introduce st...
972
  			udf_next_aext(inode, epos, &laarr[i].extLocation,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
973
974
  				      &laarr[i].extLength, 1);
  			start++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
975
976
  		}
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
977
  	for (i = start; i < endnum; i++) {
ff116fc8d   Jan Kara   UDF: introduce st...
978
979
  		udf_next_aext(inode, epos, &tmploc, &tmplen, 0);
  		udf_write_aext(inode, epos, laarr[i].extLocation,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
980
  			       laarr[i].extLength, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
981
982
  	}
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
983
984
  struct buffer_head *udf_bread(struct inode *inode, int block,
  			      int create, int *err)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
985
  {
cb00ea352   Cyrill Gorcunov   UDF: coding style...
986
  	struct buffer_head *bh = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
  
  	bh = udf_getblk(inode, block, create, err);
  	if (!bh)
  		return NULL;
  
  	if (buffer_uptodate(bh))
  		return bh;
  	ll_rw_block(READ, 1, &bh);
  	wait_on_buffer(bh);
  	if (buffer_uptodate(bh))
  		return bh;
  	brelse(bh);
  	*err = -EIO;
  	return NULL;
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1002
  void udf_truncate(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1003
1004
1005
1006
1007
  {
  	int offset;
  	int err;
  
  	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1008
  	      S_ISLNK(inode->i_mode)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1009
1010
1011
1012
1013
  		return;
  	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
  		return;
  
  	lock_kernel();
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1014
1015
1016
  	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) {
  		if (inode->i_sb->s_blocksize <
  		    (udf_file_entry_alloc_offset(inode) + inode->i_size)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1017
  			udf_expand_file_adinicb(inode, inode->i_size, &err);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1018
  			if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1019
1020
1021
  				inode->i_size = UDF_I_LENALLOC(inode);
  				unlock_kernel();
  				return;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1022
  			} else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1023
  				udf_truncate_extents(inode);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1024
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1025
  			offset = inode->i_size & (inode->i_sb->s_blocksize - 1);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1026
1027
1028
1029
  			memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) +
  			       offset, 0x00,
  			       inode->i_sb->s_blocksize - offset -
  			       udf_file_entry_alloc_offset(inode));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1030
1031
  			UDF_I_LENALLOC(inode) = inode->i_size;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1032
1033
1034
  	} else {
  		block_truncate_page(inode->i_mapping, inode->i_size,
  				    udf_get_block);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1035
  		udf_truncate_extents(inode);
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1036
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1037
1038
1039
  
  	inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
  	if (IS_SYNC(inode))
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1040
  		udf_sync_inode(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1041
1042
1043
1044
  	else
  		mark_inode_dirty(inode);
  	unlock_kernel();
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1045
  static void __udf_read_inode(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
  {
  	struct buffer_head *bh = NULL;
  	struct fileEntry *fe;
  	uint16_t ident;
  
  	/*
  	 * 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;
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1063
  	bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1064
  	if (!bh) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1065
1066
  		printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed !bh
  ",
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1067
  		       inode->i_ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1068
1069
1070
1071
1072
  		make_bad_inode(inode);
  		return;
  	}
  
  	if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE &&
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1073
1074
1075
1076
1077
  	    ident != TAG_IDENT_USE) {
  		printk(KERN_ERR
  		       "udf: udf_read_inode(ino %ld) failed ident=%d
  ",
  		       inode->i_ino, ident);
3bf25cb40   Jan Kara   udf: use get_bh()
1078
  		brelse(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1079
1080
1081
1082
1083
  		make_bad_inode(inode);
  		return;
  	}
  
  	fe = (struct fileEntry *)bh->b_data;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1084
  	if (le16_to_cpu(fe->icbTag.strategyType) == 4096) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1085
1086
  		struct buffer_head *ibh = NULL, *nbh = NULL;
  		struct indirectEntry *ie;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1087
1088
1089
1090
1091
  		ibh =
  		    udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 1,
  				     &ident);
  		if (ident == TAG_IDENT_IE) {
  			if (ibh) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1092
1093
  				kernel_lb_addr loc;
  				ie = (struct indirectEntry *)ibh->b_data;
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1094

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1095
  				loc = lelb_to_cpu(ie->indirectICB.extLocation);
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1096
1097
  
  				if (ie->indirectICB.extLength &&
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1098
1099
1100
1101
1102
1103
1104
1105
  				    (nbh =
  				     udf_read_ptagged(inode->i_sb, loc, 0,
  						      &ident))) {
  					if (ident == TAG_IDENT_FE
  					    || ident == TAG_IDENT_EFE) {
  						memcpy(&UDF_I_LOCATION(inode),
  						       &loc,
  						       sizeof(kernel_lb_addr));
3bf25cb40   Jan Kara   udf: use get_bh()
1106
1107
1108
  						brelse(bh);
  						brelse(ibh);
  						brelse(nbh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1109
1110
  						__udf_read_inode(inode);
  						return;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1111
  					} else {
3bf25cb40   Jan Kara   udf: use get_bh()
1112
1113
  						brelse(nbh);
  						brelse(ibh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1114
  					}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1115
  				} else
3bf25cb40   Jan Kara   udf: use get_bh()
1116
  					brelse(ibh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1117
  			}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1118
  		} else
3bf25cb40   Jan Kara   udf: use get_bh()
1119
  			brelse(ibh);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1120
  	} else if (le16_to_cpu(fe->icbTag.strategyType) != 4) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1121
1122
  		printk(KERN_ERR "udf: unsupported strategy type: %d
  ",
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1123
  		       le16_to_cpu(fe->icbTag.strategyType));
3bf25cb40   Jan Kara   udf: use get_bh()
1124
  		brelse(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1125
1126
1127
1128
  		make_bad_inode(inode);
  		return;
  	}
  	udf_fill_inode(inode, bh);
31170b6ad   Jan Kara   udf: support file...
1129

3bf25cb40   Jan Kara   udf: use get_bh()
1130
  	brelse(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
  }
  
  static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
  {
  	struct fileEntry *fe;
  	struct extendedFileEntry *efe;
  	time_t convtime;
  	long convtime_usec;
  	int offset;
  
  	fe = (struct fileEntry *)bh->b_data;
  	efe = (struct extendedFileEntry *)bh->b_data;
  
  	if (le16_to_cpu(fe->icbTag.strategyType) == 4)
  		UDF_I_STRAT4096(inode) = 0;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1146
  	else			/* if (le16_to_cpu(fe->icbTag.strategyType) == 4096) */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1147
  		UDF_I_STRAT4096(inode) = 1;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1148
1149
  	UDF_I_ALLOCTYPE(inode) =
  	    le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1150
1151
1152
1153
1154
1155
  	UDF_I_UNIQUE(inode) = 0;
  	UDF_I_LENEATTR(inode) = 0;
  	UDF_I_LENEXTENTS(inode) = 0;
  	UDF_I_LENALLOC(inode) = 0;
  	UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
  	UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1156
  	if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_EFE) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1157
1158
  		UDF_I_EFE(inode) = 1;
  		UDF_I_USE(inode) = 0;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1159
1160
1161
1162
  		if (udf_alloc_i_data
  		    (inode,
  		     inode->i_sb->s_blocksize -
  		     sizeof(struct extendedFileEntry))) {
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1163
1164
1165
  			make_bad_inode(inode);
  			return;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1166
1167
1168
1169
1170
  		memcpy(UDF_I_DATA(inode),
  		       bh->b_data + sizeof(struct extendedFileEntry),
  		       inode->i_sb->s_blocksize -
  		       sizeof(struct extendedFileEntry));
  	} else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_FE) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1171
1172
  		UDF_I_EFE(inode) = 0;
  		UDF_I_USE(inode) = 0;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1173
1174
1175
  		if (udf_alloc_i_data
  		    (inode,
  		     inode->i_sb->s_blocksize - sizeof(struct fileEntry))) {
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1176
1177
1178
  			make_bad_inode(inode);
  			return;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1179
1180
1181
  		memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct fileEntry),
  		       inode->i_sb->s_blocksize - sizeof(struct fileEntry));
  	} else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1182
1183
1184
  		UDF_I_EFE(inode) = 0;
  		UDF_I_USE(inode) = 1;
  		UDF_I_LENALLOC(inode) =
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1185
1186
1187
1188
1189
1190
  		    le32_to_cpu(((struct unallocSpaceEntry *)bh->b_data)->
  				lengthAllocDescs);
  		if (udf_alloc_i_data
  		    (inode,
  		     inode->i_sb->s_blocksize -
  		     sizeof(struct unallocSpaceEntry))) {
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1191
1192
1193
  			make_bad_inode(inode);
  			return;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1194
1195
1196
1197
  		memcpy(UDF_I_DATA(inode),
  		       bh->b_data + sizeof(struct unallocSpaceEntry),
  		       inode->i_sb->s_blocksize -
  		       sizeof(struct unallocSpaceEntry));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1198
1199
1200
1201
  		return;
  	}
  
  	inode->i_uid = le32_to_cpu(fe->uid);
4d6660eb3   Phillip Susi   [PATCH] udf: fix ...
1202
  	if (inode->i_uid == -1 || UDF_QUERY_FLAG(inode->i_sb,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1203
  						 UDF_FLAG_UID_IGNORE))
4d6660eb3   Phillip Susi   [PATCH] udf: fix ...
1204
  		inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1205
1206
  
  	inode->i_gid = le32_to_cpu(fe->gid);
4d6660eb3   Phillip Susi   [PATCH] udf: fix ...
1207
  	if (inode->i_gid == -1 || UDF_QUERY_FLAG(inode->i_sb,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1208
  						 UDF_FLAG_GID_IGNORE))
4d6660eb3   Phillip Susi   [PATCH] udf: fix ...
1209
  		inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1210
1211
1212
1213
  
  	inode->i_nlink = le16_to_cpu(fe->fileLinkCount);
  	if (!inode->i_nlink)
  		inode->i_nlink = 1;
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1214

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1215
1216
1217
1218
1219
  	inode->i_size = le64_to_cpu(fe->informationLength);
  	UDF_I_LENEXTENTS(inode) = inode->i_size;
  
  	inode->i_mode = udf_convert_permissions(fe);
  	inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1220
  	if (UDF_I_EFE(inode) == 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1221
  		inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1222
  		    (inode->i_sb->s_blocksize_bits - 9);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1223

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1224
1225
  		if (udf_stamp_to_time(&convtime, &convtime_usec,
  				      lets_to_cpu(fe->accessTime))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1226
1227
  			inode->i_atime.tv_sec = convtime;
  			inode->i_atime.tv_nsec = convtime_usec * 1000;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1228
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1229
1230
  			inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1231
1232
  		if (udf_stamp_to_time(&convtime, &convtime_usec,
  				      lets_to_cpu(fe->modificationTime))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1233
1234
  			inode->i_mtime.tv_sec = convtime;
  			inode->i_mtime.tv_nsec = convtime_usec * 1000;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1235
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1236
1237
  			inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1238
1239
  		if (udf_stamp_to_time(&convtime, &convtime_usec,
  				      lets_to_cpu(fe->attrTime))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1240
1241
  			inode->i_ctime.tv_sec = convtime;
  			inode->i_ctime.tv_nsec = convtime_usec * 1000;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1242
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1243
1244
1245
1246
1247
1248
1249
  			inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
  		}
  
  		UDF_I_UNIQUE(inode) = le64_to_cpu(fe->uniqueID);
  		UDF_I_LENEATTR(inode) = le32_to_cpu(fe->lengthExtendedAttr);
  		UDF_I_LENALLOC(inode) = le32_to_cpu(fe->lengthAllocDescs);
  		offset = sizeof(struct fileEntry) + UDF_I_LENEATTR(inode);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1250
  	} else {
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1251
  		inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1252
  		    (inode->i_sb->s_blocksize_bits - 9);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1253

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1254
1255
  		if (udf_stamp_to_time(&convtime, &convtime_usec,
  				      lets_to_cpu(efe->accessTime))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1256
1257
  			inode->i_atime.tv_sec = convtime;
  			inode->i_atime.tv_nsec = convtime_usec * 1000;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1258
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1259
1260
  			inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1261
1262
  		if (udf_stamp_to_time(&convtime, &convtime_usec,
  				      lets_to_cpu(efe->modificationTime))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1263
1264
  			inode->i_mtime.tv_sec = convtime;
  			inode->i_mtime.tv_nsec = convtime_usec * 1000;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1265
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1266
1267
  			inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1268
1269
  		if (udf_stamp_to_time(&convtime, &convtime_usec,
  				      lets_to_cpu(efe->createTime))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1270
1271
  			UDF_I_CRTIME(inode).tv_sec = convtime;
  			UDF_I_CRTIME(inode).tv_nsec = convtime_usec * 1000;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1272
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1273
1274
  			UDF_I_CRTIME(inode) = UDF_SB_RECORDTIME(inode->i_sb);
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1275
1276
  		if (udf_stamp_to_time(&convtime, &convtime_usec,
  				      lets_to_cpu(efe->attrTime))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1277
1278
  			inode->i_ctime.tv_sec = convtime;
  			inode->i_ctime.tv_nsec = convtime_usec * 1000;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1279
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1280
1281
1282
1283
1284
1285
  			inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
  		}
  
  		UDF_I_UNIQUE(inode) = le64_to_cpu(efe->uniqueID);
  		UDF_I_LENEATTR(inode) = le32_to_cpu(efe->lengthExtendedAttr);
  		UDF_I_LENALLOC(inode) = le32_to_cpu(efe->lengthAllocDescs);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1286
1287
  		offset =
  		    sizeof(struct extendedFileEntry) + UDF_I_LENEATTR(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1288
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1289
1290
  	switch (fe->icbTag.fileType) {
  	case ICBTAG_FILE_TYPE_DIRECTORY:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1291
1292
1293
1294
  		{
  			inode->i_op = &udf_dir_inode_operations;
  			inode->i_fop = &udf_dir_operations;
  			inode->i_mode |= S_IFDIR;
d8c76e6f4   Dave Hansen   [PATCH] r/o bind ...
1295
  			inc_nlink(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1296
1297
  			break;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1298
1299
1300
  	case ICBTAG_FILE_TYPE_REALTIME:
  	case ICBTAG_FILE_TYPE_REGULAR:
  	case ICBTAG_FILE_TYPE_UNDEF:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
  		{
  			if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
  				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;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1311
  	case ICBTAG_FILE_TYPE_BLOCK:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1312
1313
1314
1315
  		{
  			inode->i_mode |= S_IFBLK;
  			break;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1316
  	case ICBTAG_FILE_TYPE_CHAR:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1317
1318
1319
1320
  		{
  			inode->i_mode |= S_IFCHR;
  			break;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1321
  	case ICBTAG_FILE_TYPE_FIFO:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1322
1323
1324
1325
  		{
  			init_special_inode(inode, inode->i_mode | S_IFIFO, 0);
  			break;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1326
  	case ICBTAG_FILE_TYPE_SOCKET:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1327
1328
1329
1330
  		{
  			init_special_inode(inode, inode->i_mode | S_IFSOCK, 0);
  			break;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1331
  	case ICBTAG_FILE_TYPE_SYMLINK:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1332
1333
1334
  		{
  			inode->i_data.a_ops = &udf_symlink_aops;
  			inode->i_op = &page_symlink_inode_operations;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1335
  			inode->i_mode = S_IFLNK | S_IRWXUGO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1336
1337
  			break;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1338
  	default:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1339
  		{
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1340
1341
1342
1343
  			printk(KERN_ERR
  			       "udf: udf_fill_inode(ino %ld) failed unknown file type=%d
  ",
  			       inode->i_ino, fe->icbTag.fileType);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1344
1345
1346
1347
  			make_bad_inode(inode);
  			return;
  		}
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1348
1349
1350
  	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
  		struct deviceSpec *dsea = (struct deviceSpec *)
  		    udf_get_extendedattr(inode, 12, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1351

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1352
1353
1354
1355
1356
1357
  		if (dsea) {
  			init_special_inode(inode, inode->i_mode,
  					   MKDEV(le32_to_cpu
  						 (dsea->majorDeviceIdent),
  						 le32_to_cpu(dsea->
  							     minorDeviceIdent)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1358
  			/* Developer ID ??? */
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1359
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1360
1361
1362
1363
  			make_bad_inode(inode);
  		}
  	}
  }
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1364
1365
1366
  static int udf_alloc_i_data(struct inode *inode, size_t size)
  {
  	UDF_I_DATA(inode) = kmalloc(size, GFP_KERNEL);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1367
1368
1369
1370
  	if (!UDF_I_DATA(inode)) {
  		printk(KERN_ERR
  		       "udf:udf_alloc_i_data (ino %ld) no free memory
  ",
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1371
1372
1373
1374
1375
1376
  		       inode->i_ino);
  		return -ENOMEM;
  	}
  
  	return 0;
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1377
  static mode_t udf_convert_permissions(struct fileEntry *fe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1378
1379
1380
1381
1382
1383
1384
  {
  	mode_t mode;
  	uint32_t permissions;
  	uint32_t flags;
  
  	permissions = le32_to_cpu(fe->permissions);
  	flags = le16_to_cpu(fe->icbTag.flags);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1385
1386
1387
1388
1389
1390
  	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);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
  
  	return mode;
  }
  
  /*
   * udf_write_inode
   *
   * PURPOSE
   *	Write out the specified inode.
   *
   * DESCRIPTION
   *	This routine is called whenever an inode is synced.
   *	Currently this routine is just a placeholder.
   *
   * HISTORY
   *	July 1, 1997 - Andrew E. Mileski
   *	Written, tested, and released.
   */
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1409
  int udf_write_inode(struct inode *inode, int sync)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1410
1411
1412
1413
1414
1415
1416
  {
  	int ret;
  	lock_kernel();
  	ret = udf_update_inode(inode, sync);
  	unlock_kernel();
  	return ret;
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1417
  int udf_sync_inode(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1418
1419
1420
  {
  	return udf_update_inode(inode, 1);
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1421
  static int udf_update_inode(struct inode *inode, int do_sync)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
  {
  	struct buffer_head *bh = NULL;
  	struct fileEntry *fe;
  	struct extendedFileEntry *efe;
  	uint32_t udfperms;
  	uint16_t icbflags;
  	uint16_t crclen;
  	int i;
  	kernel_timestamp cpu_time;
  	int err = 0;
  
  	bh = udf_tread(inode->i_sb,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1434
1435
  		       udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode),
  					 0));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1436

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1437
  	if (!bh) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1438
1439
1440
1441
1442
1443
1444
1445
1446
  		udf_debug("bread failure
  ");
  		return -EIO;
  	}
  
  	memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
  
  	fe = (struct fileEntry *)bh->b_data;
  	efe = (struct extendedFileEntry *)bh->b_data;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1447
  	if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1448
  		struct unallocSpaceEntry *use =
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1449
  		    (struct unallocSpaceEntry *)bh->b_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1450
1451
  
  		use->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1452
1453
1454
1455
1456
1457
1458
1459
1460
  		memcpy(bh->b_data + sizeof(struct unallocSpaceEntry),
  		       UDF_I_DATA(inode),
  		       inode->i_sb->s_blocksize -
  		       sizeof(struct unallocSpaceEntry));
  		crclen =
  		    sizeof(struct unallocSpaceEntry) + UDF_I_LENALLOC(inode) -
  		    sizeof(tag);
  		use->descTag.tagLocation =
  		    cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1461
  		use->descTag.descCRCLength = cpu_to_le16(crclen);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1462
1463
  		use->descTag.descCRC =
  		    cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1464
1465
  
  		use->descTag.tagChecksum = 0;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1466
  		for (i = 0; i < 16; i++)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1467
  			if (i != 4)
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1468
1469
  				use->descTag.tagChecksum +=
  				    ((uint8_t *) & (use->descTag))[i];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1470
1471
  
  		mark_buffer_dirty(bh);
3bf25cb40   Jan Kara   udf: use get_bh()
1472
  		brelse(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1473
1474
  		return err;
  	}
4d6660eb3   Phillip Susi   [PATCH] udf: fix ...
1475
1476
  	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET))
  		fe->uid = cpu_to_le32(-1);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1477
1478
  	else
  		fe->uid = cpu_to_le32(inode->i_uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1479

4d6660eb3   Phillip Susi   [PATCH] udf: fix ...
1480
1481
  	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET))
  		fe->gid = cpu_to_le32(-1);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1482
1483
  	else
  		fe->gid = cpu_to_le32(inode->i_gid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1484

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1485
1486
  	udfperms = ((inode->i_mode & S_IRWXO)) |
  	    ((inode->i_mode & S_IRWXG) << 2) | ((inode->i_mode & S_IRWXU) << 4);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1487

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1488
1489
1490
1491
  	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));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1492
1493
1494
1495
1496
1497
1498
1499
  	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);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1500
  	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1501
  		regid *eid;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1502
1503
  		struct deviceSpec *dsea = (struct deviceSpec *)
  		    udf_get_extendedattr(inode, 12, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1504

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1505
  		if (!dsea) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1506
  			dsea = (struct deviceSpec *)
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1507
1508
1509
  			    udf_add_extendedattr(inode,
  						 sizeof(struct deviceSpec) +
  						 sizeof(regid), 12, 0x3);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1510
1511
  			dsea->attrType = cpu_to_le32(12);
  			dsea->attrSubtype = 1;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1512
1513
1514
  			dsea->attrLength =
  			    cpu_to_le32(sizeof(struct deviceSpec) +
  					sizeof(regid));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1515
1516
  			dsea->impUseLength = cpu_to_le32(sizeof(regid));
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1517
  		eid = (regid *) dsea->impUse;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1518
1519
1520
1521
1522
1523
1524
  		memset(eid, 0, sizeof(regid));
  		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));
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1525
1526
1527
1528
1529
1530
1531
  	if (UDF_I_EFE(inode) == 0) {
  		memcpy(bh->b_data + sizeof(struct fileEntry), UDF_I_DATA(inode),
  		       inode->i_sb->s_blocksize - sizeof(struct fileEntry));
  		fe->logicalBlocksRecorded =
  		    cpu_to_le64((inode->i_blocks +
  				 (1 << (inode->i_sb->s_blocksize_bits - 9)) -
  				 1) >> (inode->i_sb->s_blocksize_bits - 9));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
  
  		if (udf_time_to_stamp(&cpu_time, inode->i_atime))
  			fe->accessTime = cpu_to_lets(cpu_time);
  		if (udf_time_to_stamp(&cpu_time, inode->i_mtime))
  			fe->modificationTime = cpu_to_lets(cpu_time);
  		if (udf_time_to_stamp(&cpu_time, inode->i_ctime))
  			fe->attrTime = cpu_to_lets(cpu_time);
  		memset(&(fe->impIdent), 0, sizeof(regid));
  		strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);
  		fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
  		fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
  		fe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));
  		fe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));
  		fe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
  		fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE);
  		crclen = sizeof(struct fileEntry);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1548
1549
1550
1551
1552
  	} else {
  		memcpy(bh->b_data + sizeof(struct extendedFileEntry),
  		       UDF_I_DATA(inode),
  		       inode->i_sb->s_blocksize -
  		       sizeof(struct extendedFileEntry));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1553
  		efe->objectSize = cpu_to_le64(inode->i_size);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1554
1555
1556
1557
1558
1559
1560
1561
  		efe->logicalBlocksRecorded = cpu_to_le64((inode->i_blocks +
  							  (1 <<
  							   (inode->i_sb->
  							    s_blocksize_bits -
  							    9)) -
  							  1) >> (inode->i_sb->
  								 s_blocksize_bits
  								 - 9));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1562
1563
  
  		if (UDF_I_CRTIME(inode).tv_sec > inode->i_atime.tv_sec ||
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1564
1565
  		    (UDF_I_CRTIME(inode).tv_sec == inode->i_atime.tv_sec &&
  		     UDF_I_CRTIME(inode).tv_nsec > inode->i_atime.tv_nsec)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1566
1567
1568
  			UDF_I_CRTIME(inode) = inode->i_atime;
  		}
  		if (UDF_I_CRTIME(inode).tv_sec > inode->i_mtime.tv_sec ||
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1569
1570
  		    (UDF_I_CRTIME(inode).tv_sec == inode->i_mtime.tv_sec &&
  		     UDF_I_CRTIME(inode).tv_nsec > inode->i_mtime.tv_nsec)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1571
1572
1573
  			UDF_I_CRTIME(inode) = inode->i_mtime;
  		}
  		if (UDF_I_CRTIME(inode).tv_sec > inode->i_ctime.tv_sec ||
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1574
1575
  		    (UDF_I_CRTIME(inode).tv_sec == inode->i_ctime.tv_sec &&
  		     UDF_I_CRTIME(inode).tv_nsec > inode->i_ctime.tv_nsec)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
  			UDF_I_CRTIME(inode) = inode->i_ctime;
  		}
  
  		if (udf_time_to_stamp(&cpu_time, inode->i_atime))
  			efe->accessTime = cpu_to_lets(cpu_time);
  		if (udf_time_to_stamp(&cpu_time, inode->i_mtime))
  			efe->modificationTime = cpu_to_lets(cpu_time);
  		if (udf_time_to_stamp(&cpu_time, UDF_I_CRTIME(inode)))
  			efe->createTime = cpu_to_lets(cpu_time);
  		if (udf_time_to_stamp(&cpu_time, inode->i_ctime))
  			efe->attrTime = cpu_to_lets(cpu_time);
  
  		memset(&(efe->impIdent), 0, sizeof(regid));
  		strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER);
  		efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
  		efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
  		efe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));
  		efe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));
  		efe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
  		efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE);
  		crclen = sizeof(struct extendedFileEntry);
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1598
  	if (UDF_I_STRAT4096(inode)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1599
1600
1601
  		fe->icbTag.strategyType = cpu_to_le16(4096);
  		fe->icbTag.strategyParameter = cpu_to_le16(1);
  		fe->icbTag.numEntries = cpu_to_le16(2);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1602
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
  		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;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1621
1622
1623
1624
1625
1626
1627
  	icbflags = UDF_I_ALLOCTYPE(inode) |
  	    ((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));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1628
1629
1630
1631
1632
1633
1634
  
  	fe->icbTag.flags = cpu_to_le16(icbflags);
  	if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
  		fe->descTag.descVersion = cpu_to_le16(3);
  	else
  		fe->descTag.descVersion = cpu_to_le16(2);
  	fe->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb));
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1635
1636
  	fe->descTag.tagLocation =
  	    cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1637
1638
  	crclen += UDF_I_LENEATTR(inode) + UDF_I_LENALLOC(inode) - sizeof(tag);
  	fe->descTag.descCRCLength = cpu_to_le16(crclen);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1639
1640
  	fe->descTag.descCRC =
  	    cpu_to_le16(udf_crc((char *)fe + sizeof(tag), crclen, 0));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1641
1642
  
  	fe->descTag.tagChecksum = 0;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1643
  	for (i = 0; i < 16; i++)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1644
  		if (i != 4)
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1645
1646
  			fe->descTag.tagChecksum +=
  			    ((uint8_t *) & (fe->descTag))[i];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1647
1648
1649
  
  	/* write the data blocks */
  	mark_buffer_dirty(bh);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1650
  	if (do_sync) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1651
  		sync_dirty_buffer(bh);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1652
  		if (buffer_req(bh) && !buffer_uptodate(bh)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1653
1654
  			printk("IO error syncing udf inode [%s:%08lx]
  ",
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1655
  			       inode->i_sb->s_id, inode->i_ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1656
1657
1658
  			err = -EIO;
  		}
  	}
3bf25cb40   Jan Kara   udf: use get_bh()
1659
  	brelse(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1660
1661
  	return err;
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1662
  struct inode *udf_iget(struct super_block *sb, kernel_lb_addr ino)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
  {
  	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) {
  		memcpy(&UDF_I_LOCATION(inode), &ino, sizeof(kernel_lb_addr));
  		__udf_read_inode(inode);
  		unlock_new_inode(inode);
  	}
  
  	if (is_bad_inode(inode))
  		goto out_iput;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1678
1679
  	if (ino.logicalBlockNum >=
  	    UDF_SB_PARTLEN(sb, ino.partitionReferenceNum)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1680
1681
  		udf_debug("block=%d, partition=%d out of range
  ",
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1682
  			  ino.logicalBlockNum, ino.partitionReferenceNum);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1683
1684
1685
1686
1687
  		make_bad_inode(inode);
  		goto out_iput;
  	}
  
  	return inode;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1688
        out_iput:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1689
1690
1691
  	iput(inode);
  	return NULL;
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1692
1693
  int8_t udf_add_aext(struct inode * inode, struct extent_position * epos,
  		    kernel_lb_addr eloc, uint32_t elen, int inc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1694
1695
1696
1697
1698
1699
1700
  {
  	int adsize;
  	short_ad *sad = NULL;
  	long_ad *lad = NULL;
  	struct allocExtDesc *aed;
  	int8_t etype;
  	uint8_t *ptr;
ff116fc8d   Jan Kara   UDF: introduce st...
1701
  	if (!epos->bh)
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1702
1703
1704
  		ptr =
  		    UDF_I_DATA(inode) + epos->offset -
  		    udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1705
  	else
ff116fc8d   Jan Kara   UDF: introduce st...
1706
  		ptr = epos->bh->b_data + epos->offset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1707
1708
1709
1710
1711
1712
1713
  
  	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
  		adsize = sizeof(short_ad);
  	else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
  		adsize = sizeof(long_ad);
  	else
  		return -1;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1714
  	if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1715
1716
1717
  		char *sptr, *dptr;
  		struct buffer_head *nbh;
  		int err, loffset;
ff116fc8d   Jan Kara   UDF: introduce st...
1718
  		kernel_lb_addr obloc = epos->block;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1719

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1720
1721
1722
1723
1724
  		if (!
  		    (epos->block.logicalBlockNum =
  		     udf_new_block(inode->i_sb, NULL,
  				   obloc.partitionReferenceNum,
  				   obloc.logicalBlockNum, &err))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1725
1726
  			return -1;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1727
1728
1729
1730
1731
  		if (!
  		    (nbh =
  		     udf_tgetblk(inode->i_sb,
  				 udf_get_lb_pblock(inode->i_sb, epos->block,
  						   0)))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
  			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))
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1742
1743
1744
  			aed->previousAllocExtLocation =
  			    cpu_to_le32(obloc.logicalBlockNum);
  		if (epos->offset + adsize > inode->i_sb->s_blocksize) {
ff116fc8d   Jan Kara   UDF: introduce st...
1745
  			loffset = epos->offset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1746
1747
1748
1749
  			aed->lengthAllocDescs = cpu_to_le32(adsize);
  			sptr = ptr - adsize;
  			dptr = nbh->b_data + sizeof(struct allocExtDesc);
  			memcpy(dptr, sptr, adsize);
ff116fc8d   Jan Kara   UDF: introduce st...
1750
  			epos->offset = sizeof(struct allocExtDesc) + adsize;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1751
  		} else {
ff116fc8d   Jan Kara   UDF: introduce st...
1752
  			loffset = epos->offset + adsize;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1753
1754
  			aed->lengthAllocDescs = cpu_to_le32(0);
  			sptr = ptr;
ff116fc8d   Jan Kara   UDF: introduce st...
1755
  			epos->offset = sizeof(struct allocExtDesc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1756

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1757
  			if (epos->bh) {
ff116fc8d   Jan Kara   UDF: introduce st...
1758
  				aed = (struct allocExtDesc *)epos->bh->b_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1759
  				aed->lengthAllocDescs =
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1760
1761
1762
1763
  				    cpu_to_le32(le32_to_cpu
  						(aed->lengthAllocDescs) +
  						adsize);
  			} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1764
1765
1766
1767
1768
1769
  				UDF_I_LENALLOC(inode) += adsize;
  				mark_inode_dirty(inode);
  			}
  		}
  		if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
  			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1770
  				    epos->block.logicalBlockNum, sizeof(tag));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1771
1772
  		else
  			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1773
1774
1775
  				    epos->block.logicalBlockNum, sizeof(tag));
  		switch (UDF_I_ALLOCTYPE(inode)) {
  		case ICBTAG_FLAG_AD_SHORT:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1776
  			{
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1777
1778
1779
1780
1781
1782
  				sad = (short_ad *) sptr;
  				sad->extLength =
  				    cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
  						inode->i_sb->s_blocksize);
  				sad->extPosition =
  				    cpu_to_le32(epos->block.logicalBlockNum);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1783
1784
  				break;
  			}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1785
  		case ICBTAG_FLAG_AD_LONG:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1786
  			{
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1787
1788
1789
1790
  				lad = (long_ad *) sptr;
  				lad->extLength =
  				    cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
  						inode->i_sb->s_blocksize);
ff116fc8d   Jan Kara   UDF: introduce st...
1791
  				lad->extLocation = cpu_to_lelb(epos->block);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1792
1793
1794
1795
  				memset(lad->impUse, 0x00, sizeof(lad->impUse));
  				break;
  			}
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1796
1797
1798
  		if (epos->bh) {
  			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
  			    || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
ff116fc8d   Jan Kara   UDF: introduce st...
1799
  				udf_update_tag(epos->bh->b_data, loffset);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1800
  			else
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1801
1802
  				udf_update_tag(epos->bh->b_data,
  					       sizeof(struct allocExtDesc));
ff116fc8d   Jan Kara   UDF: introduce st...
1803
  			mark_buffer_dirty_inode(epos->bh, inode);
3bf25cb40   Jan Kara   udf: use get_bh()
1804
  			brelse(epos->bh);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1805
  		} else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1806
  			mark_inode_dirty(inode);
ff116fc8d   Jan Kara   UDF: introduce st...
1807
  		epos->bh = nbh;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1808
  	}
ff116fc8d   Jan Kara   UDF: introduce st...
1809
  	etype = udf_write_aext(inode, epos, eloc, elen, inc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1810

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1811
  	if (!epos->bh) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1812
1813
  		UDF_I_LENALLOC(inode) += adsize;
  		mark_inode_dirty(inode);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1814
  	} else {
ff116fc8d   Jan Kara   UDF: introduce st...
1815
  		aed = (struct allocExtDesc *)epos->bh->b_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1816
  		aed->lengthAllocDescs =
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1817
1818
1819
1820
1821
  		    cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
  		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
  		    || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
  			udf_update_tag(epos->bh->b_data,
  				       epos->offset + (inc ? 0 : adsize));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1822
  		else
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1823
1824
  			udf_update_tag(epos->bh->b_data,
  				       sizeof(struct allocExtDesc));
ff116fc8d   Jan Kara   UDF: introduce st...
1825
  		mark_buffer_dirty_inode(epos->bh, inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1826
1827
1828
1829
  	}
  
  	return etype;
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1830
1831
  int8_t udf_write_aext(struct inode * inode, struct extent_position * epos,
  		      kernel_lb_addr eloc, uint32_t elen, int inc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1832
1833
1834
  {
  	int adsize;
  	uint8_t *ptr;
ff116fc8d   Jan Kara   UDF: introduce st...
1835
  	if (!epos->bh)
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1836
1837
1838
  		ptr =
  		    UDF_I_DATA(inode) + epos->offset -
  		    udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1839
  	else
ff116fc8d   Jan Kara   UDF: introduce st...
1840
  		ptr = epos->bh->b_data + epos->offset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1841

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1842
1843
  	switch (UDF_I_ALLOCTYPE(inode)) {
  	case ICBTAG_FLAG_AD_SHORT:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1844
  		{
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1845
  			short_ad *sad = (short_ad *) ptr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1846
1847
1848
1849
1850
  			sad->extLength = cpu_to_le32(elen);
  			sad->extPosition = cpu_to_le32(eloc.logicalBlockNum);
  			adsize = sizeof(short_ad);
  			break;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1851
  	case ICBTAG_FLAG_AD_LONG:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1852
  		{
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1853
  			long_ad *lad = (long_ad *) ptr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1854
1855
1856
1857
1858
1859
  			lad->extLength = cpu_to_le32(elen);
  			lad->extLocation = cpu_to_lelb(eloc);
  			memset(lad->impUse, 0x00, sizeof(lad->impUse));
  			adsize = sizeof(long_ad);
  			break;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1860
1861
  	default:
  		return -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1862
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1863
1864
1865
1866
1867
  	if (epos->bh) {
  		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
  		    || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) {
  			struct allocExtDesc *aed =
  			    (struct allocExtDesc *)epos->bh->b_data;
ff116fc8d   Jan Kara   UDF: introduce st...
1868
  			udf_update_tag(epos->bh->b_data,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1869
1870
  				       le32_to_cpu(aed->lengthAllocDescs) +
  				       sizeof(struct allocExtDesc));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1871
  		}
ff116fc8d   Jan Kara   UDF: introduce st...
1872
  		mark_buffer_dirty_inode(epos->bh, inode);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1873
  	} else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1874
1875
1876
  		mark_inode_dirty(inode);
  
  	if (inc)
ff116fc8d   Jan Kara   UDF: introduce st...
1877
  		epos->offset += adsize;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1878
1879
  	return (elen >> 30);
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1880
1881
  int8_t udf_next_aext(struct inode * inode, struct extent_position * epos,
  		     kernel_lb_addr * eloc, uint32_t * elen, int inc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1882
1883
  {
  	int8_t etype;
ff116fc8d   Jan Kara   UDF: introduce st...
1884
  	while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) ==
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1885
  	       (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) {
ff116fc8d   Jan Kara   UDF: introduce st...
1886
1887
  		epos->block = *eloc;
  		epos->offset = sizeof(struct allocExtDesc);
3bf25cb40   Jan Kara   udf: use get_bh()
1888
  		brelse(epos->bh);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1889
1890
1891
1892
1893
  		if (!
  		    (epos->bh =
  		     udf_tread(inode->i_sb,
  			       udf_get_lb_pblock(inode->i_sb, epos->block,
  						 0)))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1894
1895
  			udf_debug("reading block %d failed!
  ",
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1896
1897
  				  udf_get_lb_pblock(inode->i_sb, epos->block,
  						    0));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1898
1899
1900
1901
1902
1903
  			return -1;
  		}
  	}
  
  	return etype;
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1904
1905
  int8_t udf_current_aext(struct inode * inode, struct extent_position * epos,
  			kernel_lb_addr * eloc, uint32_t * elen, int inc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1906
1907
1908
1909
  {
  	int alen;
  	int8_t etype;
  	uint8_t *ptr;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1910
  	if (!epos->bh) {
ff116fc8d   Jan Kara   UDF: introduce st...
1911
1912
  		if (!epos->offset)
  			epos->offset = udf_file_entry_alloc_offset(inode);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1913
1914
1915
1916
1917
1918
  		ptr =
  		    UDF_I_DATA(inode) + epos->offset -
  		    udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
  		alen =
  		    udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode);
  	} else {
ff116fc8d   Jan Kara   UDF: introduce st...
1919
1920
1921
  		if (!epos->offset)
  			epos->offset = sizeof(struct allocExtDesc);
  		ptr = epos->bh->b_data + epos->offset;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1922
1923
1924
1925
  		alen =
  		    sizeof(struct allocExtDesc) +
  		    le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->
  				lengthAllocDescs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1926
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1927
1928
  	switch (UDF_I_ALLOCTYPE(inode)) {
  	case ICBTAG_FLAG_AD_SHORT:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1929
1930
  		{
  			short_ad *sad;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1931
1932
1933
1934
  			if (!
  			    (sad =
  			     udf_get_fileshortad(ptr, alen, &epos->offset,
  						 inc)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1935
1936
1937
1938
  				return -1;
  
  			etype = le32_to_cpu(sad->extLength) >> 30;
  			eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1939
1940
1941
1942
1943
  			eloc->partitionReferenceNum =
  			    UDF_I_LOCATION(inode).partitionReferenceNum;
  			*elen =
  			    le32_to_cpu(sad->
  					extLength) & UDF_EXTENT_LENGTH_MASK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1944
1945
  			break;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1946
  	case ICBTAG_FLAG_AD_LONG:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1947
1948
  		{
  			long_ad *lad;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1949
1950
1951
  			if (!
  			    (lad =
  			     udf_get_filelongad(ptr, alen, &epos->offset, inc)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1952
1953
1954
1955
  				return -1;
  
  			etype = le32_to_cpu(lad->extLength) >> 30;
  			*eloc = lelb_to_cpu(lad->extLocation);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1956
1957
1958
  			*elen =
  			    le32_to_cpu(lad->
  					extLength) & UDF_EXTENT_LENGTH_MASK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1959
1960
  			break;
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1961
  	default:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1962
  		{
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1963
1964
1965
  			udf_debug("alloc_type = %d unsupported
  ",
  				  UDF_I_ALLOCTYPE(inode));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1966
1967
1968
1969
1970
1971
1972
1973
  			return -1;
  		}
  	}
  
  	return etype;
  }
  
  static int8_t
ff116fc8d   Jan Kara   UDF: introduce st...
1974
1975
  udf_insert_aext(struct inode *inode, struct extent_position epos,
  		kernel_lb_addr neloc, uint32_t nelen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1976
1977
1978
1979
  {
  	kernel_lb_addr oeloc;
  	uint32_t oelen;
  	int8_t etype;
ff116fc8d   Jan Kara   UDF: introduce st...
1980
  	if (epos.bh)
3bf25cb40   Jan Kara   udf: use get_bh()
1981
  		get_bh(epos.bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1982

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1983
  	while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1) {
ff116fc8d   Jan Kara   UDF: introduce st...
1984
  		udf_write_aext(inode, &epos, neloc, nelen, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1985
1986
1987
1988
  
  		neloc = oeloc;
  		nelen = (etype << 30) | oelen;
  	}
ff116fc8d   Jan Kara   UDF: introduce st...
1989
  	udf_add_aext(inode, &epos, neloc, nelen, 1);
3bf25cb40   Jan Kara   udf: use get_bh()
1990
  	brelse(epos.bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1991
1992
  	return (nelen >> 30);
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1993
1994
  int8_t udf_delete_aext(struct inode * inode, struct extent_position epos,
  		       kernel_lb_addr eloc, uint32_t elen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1995
  {
ff116fc8d   Jan Kara   UDF: introduce st...
1996
1997
  	struct extent_position oepos;
  	int adsize;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1998
1999
  	int8_t etype;
  	struct allocExtDesc *aed;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2000
  	if (epos.bh) {
3bf25cb40   Jan Kara   udf: use get_bh()
2001
2002
  		get_bh(epos.bh);
  		get_bh(epos.bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2003
2004
2005
2006
2007
2008
2009
2010
  	}
  
  	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
  		adsize = sizeof(short_ad);
  	else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
  		adsize = sizeof(long_ad);
  	else
  		adsize = 0;
ff116fc8d   Jan Kara   UDF: introduce st...
2011
2012
  	oepos = epos;
  	if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2013
  		return -1;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2014
  	while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) {
ff116fc8d   Jan Kara   UDF: introduce st...
2015
  		udf_write_aext(inode, &oepos, eloc, (etype << 30) | elen, 1);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2016
  		if (oepos.bh != epos.bh) {
ff116fc8d   Jan Kara   UDF: introduce st...
2017
  			oepos.block = epos.block;
3bf25cb40   Jan Kara   udf: use get_bh()
2018
2019
  			brelse(oepos.bh);
  			get_bh(epos.bh);
ff116fc8d   Jan Kara   UDF: introduce st...
2020
2021
  			oepos.bh = epos.bh;
  			oepos.offset = epos.offset - adsize;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2022
2023
2024
2025
  		}
  	}
  	memset(&eloc, 0x00, sizeof(kernel_lb_addr));
  	elen = 0;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2026
  	if (epos.bh != oepos.bh) {
ff116fc8d   Jan Kara   UDF: introduce st...
2027
2028
2029
  		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);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2030
  		if (!oepos.bh) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2031
2032
  			UDF_I_LENALLOC(inode) -= (adsize * 2);
  			mark_inode_dirty(inode);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2033
  		} else {
ff116fc8d   Jan Kara   UDF: introduce st...
2034
  			aed = (struct allocExtDesc *)oepos.bh->b_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2035
  			aed->lengthAllocDescs =
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2036
2037
2038
2039
2040
2041
  			    cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) -
  					(2 * adsize));
  			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
  			    || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
  				udf_update_tag(oepos.bh->b_data,
  					       oepos.offset - (2 * adsize));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2042
  			else
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2043
2044
  				udf_update_tag(oepos.bh->b_data,
  					       sizeof(struct allocExtDesc));
ff116fc8d   Jan Kara   UDF: introduce st...
2045
  			mark_buffer_dirty_inode(oepos.bh, inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2046
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2047
  	} else {
ff116fc8d   Jan Kara   UDF: introduce st...
2048
  		udf_write_aext(inode, &oepos, eloc, elen, 1);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2049
  		if (!oepos.bh) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2050
2051
  			UDF_I_LENALLOC(inode) -= adsize;
  			mark_inode_dirty(inode);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2052
  		} else {
ff116fc8d   Jan Kara   UDF: introduce st...
2053
  			aed = (struct allocExtDesc *)oepos.bh->b_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2054
  			aed->lengthAllocDescs =
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2055
2056
2057
2058
2059
2060
  			    cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) -
  					adsize);
  			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT)
  			    || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
  				udf_update_tag(oepos.bh->b_data,
  					       epos.offset - adsize);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2061
  			else
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2062
2063
  				udf_update_tag(oepos.bh->b_data,
  					       sizeof(struct allocExtDesc));
ff116fc8d   Jan Kara   UDF: introduce st...
2064
  			mark_buffer_dirty_inode(oepos.bh, inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2065
2066
  		}
  	}
647bd61a5   Cyrill Gorcunov   UDF: check for al...
2067

3bf25cb40   Jan Kara   udf: use get_bh()
2068
2069
  	brelse(epos.bh);
  	brelse(oepos.bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2070
2071
  	return (elen >> 30);
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2072
2073
2074
  int8_t inode_bmap(struct inode * inode, sector_t block,
  		  struct extent_position * pos, kernel_lb_addr * eloc,
  		  uint32_t * elen, sector_t * offset)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2075
  {
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2076
2077
  	loff_t lbcount = 0, bcount =
  	    (loff_t) block << inode->i_sb->s_blocksize_bits;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2078
  	int8_t etype;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2079
  	if (block < 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2080
2081
2082
2083
  		printk(KERN_ERR "udf: inode_bmap: block < 0
  ");
  		return -1;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2084

ff116fc8d   Jan Kara   UDF: introduce st...
2085
2086
2087
  	pos->offset = 0;
  	pos->block = UDF_I_LOCATION(inode);
  	pos->bh = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2088
  	*elen = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2089

cb00ea352   Cyrill Gorcunov   UDF: coding style...
2090
2091
2092
2093
  	do {
  		if ((etype = udf_next_aext(inode, pos, eloc, elen, 1)) == -1) {
  			*offset =
  			    (bcount - lbcount) >> inode->i_sb->s_blocksize_bits;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2094
2095
2096
2097
2098
  			UDF_I_LENEXTENTS(inode) = lbcount;
  			return -1;
  		}
  		lbcount += *elen;
  	} while (lbcount <= bcount);
60448b1d6   Jan Kara   udf: use sector_t...
2099
  	*offset = (bcount + *elen - lbcount) >> inode->i_sb->s_blocksize_bits;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2100
2101
2102
  
  	return etype;
  }
60448b1d6   Jan Kara   udf: use sector_t...
2103
  long udf_block_map(struct inode *inode, sector_t block)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2104
  {
ff116fc8d   Jan Kara   UDF: introduce st...
2105
2106
  	kernel_lb_addr eloc;
  	uint32_t elen;
60448b1d6   Jan Kara   udf: use sector_t...
2107
  	sector_t offset;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2108
  	struct extent_position epos = { NULL, 0, {0, 0} };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2109
2110
2111
  	int ret;
  
  	lock_kernel();
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2112
2113
  	if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) ==
  	    (EXT_RECORDED_ALLOCATED >> 30))
60448b1d6   Jan Kara   udf: use sector_t...
2114
  		ret = udf_get_lb_pblock(inode->i_sb, eloc, offset);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2115
2116
2117
2118
  	else
  		ret = 0;
  
  	unlock_kernel();
3bf25cb40   Jan Kara   udf: use get_bh()
2119
  	brelse(epos.bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2120
2121
2122
2123
2124
2125
  
  	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV))
  		return udf_fixed_to_variable(ret);
  	else
  		return ret;
  }