Blame view

fs/udf/inode.c 61.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
   * 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
4b11111ab   Marcin Slusarz   udf: fix coding s...
22
23
   *  12/06/98 blf  partition support in udf_iget, udf_block_map
   *                and udf_read_inode
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
25
26
27
28
29
30
31
32
33
   *  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>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
36
37
38
  #include <linux/module.h>
  #include <linux/pagemap.h>
  #include <linux/buffer_head.h>
  #include <linux/writeback.h>
  #include <linux/slab.h>
f845fced9   Bob Copeland   udf: use crc_itu_...
39
  #include <linux/crc-itu-t.h>
bc1123239   Namjae Jeon   udf: Add readpage...
40
  #include <linux/mpage.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
42
43
44
45
46
47
48
49
  
  #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
faa17292f   Al Viro   udf: propagate um...
50
  static umode_t udf_convert_permissions(struct fileEntry *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
52
  static int udf_update_inode(struct inode *, int);
  static void udf_fill_inode(struct inode *, struct buffer_head *);
49521de11   Jan Kara   udf: Remove BKL f...
53
  static int udf_sync_inode(struct inode *inode);
647bd61a5   Cyrill Gorcunov   UDF: check for al...
54
  static int udf_alloc_i_data(struct inode *inode, size_t size);
7b0b0933a   Jan Kara   udf: Cleanup call...
55
  static sector_t inode_getblk(struct inode *, sector_t, int *, int *);
ff116fc8d   Jan Kara   UDF: introduce st...
56
  static int8_t udf_insert_aext(struct inode *, struct extent_position,
5ca4e4be8   Pekka Enberg   Remove struct typ...
57
  			      struct kernel_lb_addr, uint32_t);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
  static void udf_split_extents(struct inode *, int *, int, int,
5ca4e4be8   Pekka Enberg   Remove struct typ...
59
  			      struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60
  static void udf_prealloc_extents(struct inode *, int, int,
5ca4e4be8   Pekka Enberg   Remove struct typ...
61
  				 struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62
  static void udf_merge_extents(struct inode *,
5ca4e4be8   Pekka Enberg   Remove struct typ...
63
  			      struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
  static void udf_update_extents(struct inode *,
5ca4e4be8   Pekka Enberg   Remove struct typ...
65
  			       struct kernel_long_ad[EXTENT_MERGE_SIZE], int, int,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
66
  			       struct extent_position *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
  static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
b1e321266   Christoph Hellwig   udf: kill useless...
68

3aac2b62e   Al Viro   switch udf to ->e...
69
  void udf_evict_inode(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
  {
2c948b3f8   Jan Kara   udf: Avoid IO in ...
71
  	struct udf_inode_info *iinfo = UDF_I(inode);
3aac2b62e   Al Viro   switch udf to ->e...
72
  	int want_delete = 0;
3aac2b62e   Al Viro   switch udf to ->e...
73
74
  	if (!inode->i_nlink && !is_bad_inode(inode)) {
  		want_delete = 1;
7e49b6f24   Jan Kara   udf: Convert UDF ...
75
  		udf_setsize(inode, 0);
3aac2b62e   Al Viro   switch udf to ->e...
76
  		udf_update_inode(inode, IS_SYNC(inode));
7e49b6f24   Jan Kara   udf: Convert UDF ...
77
78
  	} else
  		truncate_inode_pages(&inode->i_data, 0);
3aac2b62e   Al Viro   switch udf to ->e...
79
80
  	invalidate_inode_buffers(inode);
  	end_writeback(inode);
2c948b3f8   Jan Kara   udf: Avoid IO in ...
81
82
  	if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB &&
  	    inode->i_size != iinfo->i_lenExtents) {
78ace70c4   Joe Perches   udf: Convert prin...
83
84
85
86
87
  		udf_warn(inode->i_sb, "Inode %lu (mode %o) has inode size %llu different from extent length %llu. Filesystem need not be standards compliant.
  ",
  			 inode->i_ino, inode->i_mode,
  			 (unsigned long long)inode->i_size,
  			 (unsigned long long)iinfo->i_lenExtents);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
  	}
48d6d8ff7   Marcin Slusarz   udf: cache struct...
89
90
  	kfree(iinfo->i_ext.i_data);
  	iinfo->i_ext.i_data = NULL;
3aac2b62e   Al Viro   switch udf to ->e...
91
  	if (want_delete) {
3aac2b62e   Al Viro   switch udf to ->e...
92
  		udf_free_inode(inode);
3aac2b62e   Al Viro   switch udf to ->e...
93
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
96
97
98
99
100
101
102
  }
  
  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)
  {
bc1123239   Namjae Jeon   udf: Add readpage...
103
104
105
106
107
108
109
  	return mpage_readpage(page, udf_get_block);
  }
  
  static int udf_readpages(struct file *file, struct address_space *mapping,
  			struct list_head *pages, unsigned nr_pages)
  {
  	return mpage_readpages(mapping, pages, nr_pages, udf_get_block);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
  }
be021ee41   Nick Piggin   udf: convert to n...
111
112
113
  static int udf_write_begin(struct file *file, struct address_space *mapping,
  			loff_t pos, unsigned len, unsigned flags,
  			struct page **pagep, void **fsdata)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114
  {
155130a4f   Christoph Hellwig   get rid of block_...
115
116
117
118
  	int ret;
  
  	ret = block_write_begin(mapping, pos, len, flags, pagep, udf_get_block);
  	if (unlikely(ret)) {
7e49b6f24   Jan Kara   udf: Convert UDF ...
119
120
121
122
123
124
125
126
127
128
129
130
  		struct inode *inode = mapping->host;
  		struct udf_inode_info *iinfo = UDF_I(inode);
  		loff_t isize = inode->i_size;
  
  		if (pos + len > isize) {
  			truncate_pagecache(inode, pos + len, isize);
  			if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
  				down_write(&iinfo->i_data_sem);
  				udf_truncate_extents(inode);
  				up_write(&iinfo->i_data_sem);
  			}
  		}
155130a4f   Christoph Hellwig   get rid of block_...
131
132
133
  	}
  
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
135
136
137
  }
  
  static sector_t udf_bmap(struct address_space *mapping, sector_t block)
  {
cb00ea352   Cyrill Gorcunov   UDF: coding style...
138
  	return generic_block_bmap(mapping, block, udf_get_block);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
  }
f5e54d6e5   Christoph Hellwig   [PATCH] mark addr...
140
  const struct address_space_operations udf_aops = {
28de7948a   Cyrill Gorcunov   UDF: coding style...
141
  	.readpage	= udf_readpage,
bc1123239   Namjae Jeon   udf: Add readpage...
142
  	.readpages	= udf_readpages,
28de7948a   Cyrill Gorcunov   UDF: coding style...
143
  	.writepage	= udf_writepage,
be021ee41   Nick Piggin   udf: convert to n...
144
145
  	.write_begin		= udf_write_begin,
  	.write_end		= generic_write_end,
28de7948a   Cyrill Gorcunov   UDF: coding style...
146
  	.bmap		= udf_bmap,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
  };
d2eb8c359   Jan Kara   udf: Fix deadlock...
148
149
150
151
152
153
  /*
   * Expand file stored in ICB to a normal one-block-file
   *
   * This function requires i_data_sem for writing and releases it.
   * This function requires i_mutex held
   */
7e49b6f24   Jan Kara   udf: Convert UDF ...
154
  int udf_expand_file_adinicb(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155
156
157
  {
  	struct page *page;
  	char *kaddr;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
158
  	struct udf_inode_info *iinfo = UDF_I(inode);
7e49b6f24   Jan Kara   udf: Convert UDF ...
159
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
161
162
163
  	struct writeback_control udf_wbc = {
  		.sync_mode = WB_SYNC_NONE,
  		.nr_to_write = 1,
  	};
48d6d8ff7   Marcin Slusarz   udf: cache struct...
164
  	if (!iinfo->i_lenAlloc) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
  		if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
48d6d8ff7   Marcin Slusarz   udf: cache struct...
166
  			iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167
  		else
48d6d8ff7   Marcin Slusarz   udf: cache struct...
168
  			iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
7e49b6f24   Jan Kara   udf: Convert UDF ...
169
170
  		/* from now on we have normal address_space methods */
  		inode->i_data.a_ops = &udf_aops;
d2eb8c359   Jan Kara   udf: Fix deadlock...
171
  		up_write(&iinfo->i_data_sem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
  		mark_inode_dirty(inode);
7e49b6f24   Jan Kara   udf: Convert UDF ...
173
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
  	}
d2eb8c359   Jan Kara   udf: Fix deadlock...
175
176
177
178
179
  	/*
  	 * Release i_data_sem so that we can lock a page - page lock ranks
  	 * above i_data_sem. i_mutex still protects us against file changes.
  	 */
  	up_write(&iinfo->i_data_sem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
180

7e49b6f24   Jan Kara   udf: Convert UDF ...
181
182
183
  	page = find_or_create_page(inode->i_mapping, 0, GFP_NOFS);
  	if (!page)
  		return -ENOMEM;
cd7619d6b   Matt Mackall   [PATCH] Extermina...
184

cb00ea352   Cyrill Gorcunov   UDF: coding style...
185
  	if (!PageUptodate(page)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
  		kaddr = kmap(page);
48d6d8ff7   Marcin Slusarz   udf: cache struct...
187
188
189
190
  		memset(kaddr + iinfo->i_lenAlloc, 0x00,
  		       PAGE_CACHE_SIZE - iinfo->i_lenAlloc);
  		memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr,
  			iinfo->i_lenAlloc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
192
193
194
  		flush_dcache_page(page);
  		SetPageUptodate(page);
  		kunmap(page);
  	}
d2eb8c359   Jan Kara   udf: Fix deadlock...
195
  	down_write(&iinfo->i_data_sem);
48d6d8ff7   Marcin Slusarz   udf: cache struct...
196
197
198
  	memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0x00,
  	       iinfo->i_lenAlloc);
  	iinfo->i_lenAlloc = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199
  	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
48d6d8ff7   Marcin Slusarz   udf: cache struct...
200
  		iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
  	else
48d6d8ff7   Marcin Slusarz   udf: cache struct...
202
  		iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
7e49b6f24   Jan Kara   udf: Convert UDF ...
203
204
  	/* from now on we have normal address_space methods */
  	inode->i_data.a_ops = &udf_aops;
d2eb8c359   Jan Kara   udf: Fix deadlock...
205
  	up_write(&iinfo->i_data_sem);
7e49b6f24   Jan Kara   udf: Convert UDF ...
206
207
208
209
210
  	err = inode->i_data.a_ops->writepage(page, &udf_wbc);
  	if (err) {
  		/* Restore everything back so that we don't lose data... */
  		lock_page(page);
  		kaddr = kmap(page);
d2eb8c359   Jan Kara   udf: Fix deadlock...
211
  		down_write(&iinfo->i_data_sem);
7e49b6f24   Jan Kara   udf: Convert UDF ...
212
213
214
215
216
217
  		memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr, kaddr,
  		       inode->i_size);
  		kunmap(page);
  		unlock_page(page);
  		iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
  		inode->i_data.a_ops = &udf_adinicb_aops;
d2eb8c359   Jan Kara   udf: Fix deadlock...
218
  		up_write(&iinfo->i_data_sem);
7e49b6f24   Jan Kara   udf: Convert UDF ...
219
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220
  	page_cache_release(page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221
  	mark_inode_dirty(inode);
7e49b6f24   Jan Kara   udf: Convert UDF ...
222
223
  
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
225
226
  struct buffer_head *udf_expand_dir_adinicb(struct inode *inode, int *block,
  					   int *err)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
227
228
  {
  	int newblock;
ff116fc8d   Jan Kara   UDF: introduce st...
229
  	struct buffer_head *dbh = NULL;
5ca4e4be8   Pekka Enberg   Remove struct typ...
230
  	struct kernel_lb_addr eloc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
231
  	uint8_t alloctype;
ff116fc8d   Jan Kara   UDF: introduce st...
232
  	struct extent_position epos;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
234
  
  	struct udf_fileident_bh sfibh, dfibh;
af793295b   Jan Kara   udf: cleanup dire...
235
236
  	loff_t f_pos = udf_ext0_offset(inode);
  	int size = udf_ext0_offset(inode) + inode->i_size;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
237
  	struct fileIdentDesc cfi, *sfi, *dfi;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
238
  	struct udf_inode_info *iinfo = UDF_I(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
239
240
241
242
243
  
  	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...
244
  	if (!inode->i_size) {
48d6d8ff7   Marcin Slusarz   udf: cache struct...
245
  		iinfo->i_alloc_type = alloctype;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246
247
248
249
250
251
  		mark_inode_dirty(inode);
  		return NULL;
  	}
  
  	/* alloc block, and copy data to it */
  	*block = udf_new_block(inode->i_sb, inode,
48d6d8ff7   Marcin Slusarz   udf: cache struct...
252
253
  			       iinfo->i_location.partitionReferenceNum,
  			       iinfo->i_location.logicalBlockNum, err);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
254
255
256
  	if (!(*block))
  		return NULL;
  	newblock = udf_get_pblock(inode->i_sb, *block,
48d6d8ff7   Marcin Slusarz   udf: cache struct...
257
  				  iinfo->i_location.partitionReferenceNum,
c0b344385   Marcin Slusarz   udf: remove UDF_I...
258
  				0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
259
260
261
262
263
264
265
266
267
268
  	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);
4b11111ab   Marcin Slusarz   udf: fix coding s...
269
  	sfibh.soffset = sfibh.eoffset =
af793295b   Jan Kara   udf: cleanup dire...
270
  			f_pos & (inode->i_sb->s_blocksize - 1);
ff116fc8d   Jan Kara   UDF: introduce st...
271
  	sfibh.sbh = sfibh.ebh = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
273
  	dfibh.soffset = dfibh.eoffset = 0;
  	dfibh.sbh = dfibh.ebh = dbh;
af793295b   Jan Kara   udf: cleanup dire...
274
  	while (f_pos < size) {
48d6d8ff7   Marcin Slusarz   udf: cache struct...
275
  		iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
4b11111ab   Marcin Slusarz   udf: fix coding s...
276
277
  		sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL,
  					 NULL, NULL, NULL);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
278
  		if (!sfi) {
3bf25cb40   Jan Kara   udf: use get_bh()
279
  			brelse(dbh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
281
  			return NULL;
  		}
48d6d8ff7   Marcin Slusarz   udf: cache struct...
282
  		iinfo->i_alloc_type = alloctype;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
283
284
285
286
287
  		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,
4b11111ab   Marcin Slusarz   udf: fix coding s...
288
289
  				 sfi->fileIdent +
  					le16_to_cpu(sfi->lengthOfImpUse))) {
48d6d8ff7   Marcin Slusarz   udf: cache struct...
290
  			iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
3bf25cb40   Jan Kara   udf: use get_bh()
291
  			brelse(dbh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
293
294
295
  			return NULL;
  		}
  	}
  	mark_buffer_dirty_inode(dbh, inode);
48d6d8ff7   Marcin Slusarz   udf: cache struct...
296
297
298
  	memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0,
  		iinfo->i_lenAlloc);
  	iinfo->i_lenAlloc = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299
  	eloc.logicalBlockNum = *block;
4b11111ab   Marcin Slusarz   udf: fix coding s...
300
  	eloc.partitionReferenceNum =
48d6d8ff7   Marcin Slusarz   udf: cache struct...
301
  				iinfo->i_location.partitionReferenceNum;
2c948b3f8   Jan Kara   udf: Avoid IO in ...
302
  	iinfo->i_lenExtents = inode->i_size;
ff116fc8d   Jan Kara   UDF: introduce st...
303
  	epos.bh = NULL;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
304
  	epos.block = iinfo->i_location;
ff116fc8d   Jan Kara   UDF: introduce st...
305
  	epos.offset = udf_file_entry_alloc_offset(inode);
2c948b3f8   Jan Kara   udf: Avoid IO in ...
306
  	udf_add_aext(inode, &epos, &eloc, inode->i_size, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
  	/* UniqueID stuff */
3bf25cb40   Jan Kara   udf: use get_bh()
308
  	brelse(epos.bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
310
311
  	mark_inode_dirty(inode);
  	return dbh;
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
312
313
  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
314
315
  {
  	int err, new;
1ed161718   Marcin Slusarz   udf: fix 3 signed...
316
  	sector_t phys = 0;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
317
  	struct udf_inode_info *iinfo;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318

cb00ea352   Cyrill Gorcunov   UDF: coding style...
319
  	if (!create) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
321
322
323
324
325
326
327
  		phys = udf_block_map(inode, block);
  		if (phys)
  			map_bh(bh_result, inode->i_sb, phys);
  		return 0;
  	}
  
  	err = -EIO;
  	new = 0;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
328
  	iinfo = UDF_I(inode);
4d0fb621d   Alessio Igor Bogani   udf: Replace bkl ...
329
330
  
  	down_write(&iinfo->i_data_sem);
48d6d8ff7   Marcin Slusarz   udf: cache struct...
331
332
333
  	if (block == iinfo->i_next_alloc_block + 1) {
  		iinfo->i_next_alloc_block++;
  		iinfo->i_next_alloc_goal++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
335

7b0b0933a   Jan Kara   udf: Cleanup call...
336
337
  	phys = inode_getblk(inode, block, &err, &new);
  	if (!phys)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
  		goto abort;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339
340
341
342
  
  	if (new)
  		set_buffer_new(bh_result);
  	map_bh(bh_result, inode->i_sb, phys);
28de7948a   Cyrill Gorcunov   UDF: coding style...
343
344
  
  abort:
4d0fb621d   Alessio Igor Bogani   udf: Replace bkl ...
345
  	up_write(&iinfo->i_data_sem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
346
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
347
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
348
349
  static struct buffer_head *udf_getblk(struct inode *inode, long block,
  				      int create, int *err)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350
  {
28de7948a   Cyrill Gorcunov   UDF: coding style...
351
  	struct buffer_head *bh;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352
353
354
355
356
  	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...
357
  	if (!*err && buffer_mapped(&dummy)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
358
  		bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
359
  		if (buffer_new(&dummy)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360
361
362
363
364
365
366
367
  			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;
  	}
28de7948a   Cyrill Gorcunov   UDF: coding style...
368

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
369
370
  	return NULL;
  }
31170b6ad   Jan Kara   udf: support file...
371
  /* Extend the file by 'blocks' blocks, return the number of extents added */
7e49b6f24   Jan Kara   udf: Convert UDF ...
372
373
374
375
  static int udf_do_extend_file(struct inode *inode,
  			      struct extent_position *last_pos,
  			      struct kernel_long_ad *last_ext,
  			      sector_t blocks)
31170b6ad   Jan Kara   udf: support file...
376
377
378
379
  {
  	sector_t add;
  	int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
  	struct super_block *sb = inode->i_sb;
5ca4e4be8   Pekka Enberg   Remove struct typ...
380
  	struct kernel_lb_addr prealloc_loc = {};
31170b6ad   Jan Kara   udf: support file...
381
  	int prealloc_len = 0;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
382
  	struct udf_inode_info *iinfo;
7e49b6f24   Jan Kara   udf: Convert UDF ...
383
  	int err;
31170b6ad   Jan Kara   udf: support file...
384
385
386
387
388
  
  	/* The previous extent is fake and we should not extend by anything
  	 * - there's nothing to do... */
  	if (!blocks && fake)
  		return 0;
28de7948a   Cyrill Gorcunov   UDF: coding style...
389

48d6d8ff7   Marcin Slusarz   udf: cache struct...
390
  	iinfo = UDF_I(inode);
31170b6ad   Jan Kara   udf: support file...
391
392
393
  	/* Round the last extent up to a multiple of block size */
  	if (last_ext->extLength & (sb->s_blocksize - 1)) {
  		last_ext->extLength =
28de7948a   Cyrill Gorcunov   UDF: coding style...
394
395
396
  			(last_ext->extLength & UDF_EXTENT_FLAG_MASK) |
  			(((last_ext->extLength & UDF_EXTENT_LENGTH_MASK) +
  			  sb->s_blocksize - 1) & ~(sb->s_blocksize - 1));
48d6d8ff7   Marcin Slusarz   udf: cache struct...
397
398
  		iinfo->i_lenExtents =
  			(iinfo->i_lenExtents + sb->s_blocksize - 1) &
28de7948a   Cyrill Gorcunov   UDF: coding style...
399
  			~(sb->s_blocksize - 1);
31170b6ad   Jan Kara   udf: support file...
400
  	}
28de7948a   Cyrill Gorcunov   UDF: coding style...
401

31170b6ad   Jan Kara   udf: support file...
402
  	/* Last extent are just preallocated blocks? */
4b11111ab   Marcin Slusarz   udf: fix coding s...
403
404
  	if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) ==
  						EXT_NOT_RECORDED_ALLOCATED) {
31170b6ad   Jan Kara   udf: support file...
405
406
407
408
409
  		/* 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 |
28de7948a   Cyrill Gorcunov   UDF: coding style...
410
  			(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
31170b6ad   Jan Kara   udf: support file...
411
  		last_ext->extLocation.logicalBlockNum = 0;
4b11111ab   Marcin Slusarz   udf: fix coding s...
412
  		last_ext->extLocation.partitionReferenceNum = 0;
31170b6ad   Jan Kara   udf: support file...
413
  	}
28de7948a   Cyrill Gorcunov   UDF: coding style...
414

31170b6ad   Jan Kara   udf: support file...
415
  	/* Can we merge with the previous extent? */
4b11111ab   Marcin Slusarz   udf: fix coding s...
416
417
418
419
420
  	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...
421
422
423
424
425
426
427
  		if (add > blocks)
  			add = blocks;
  		blocks -= add;
  		last_ext->extLength += add << sb->s_blocksize_bits;
  	}
  
  	if (fake) {
97e961fdb   Pekka Enberg   Fix the udf code ...
428
  		udf_add_aext(inode, last_pos, &last_ext->extLocation,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
429
  			     last_ext->extLength, 1);
31170b6ad   Jan Kara   udf: support file...
430
  		count++;
4b11111ab   Marcin Slusarz   udf: fix coding s...
431
  	} else
97e961fdb   Pekka Enberg   Fix the udf code ...
432
  		udf_write_aext(inode, last_pos, &last_ext->extLocation,
4b11111ab   Marcin Slusarz   udf: fix coding s...
433
  				last_ext->extLength, 1);
28de7948a   Cyrill Gorcunov   UDF: coding style...
434

31170b6ad   Jan Kara   udf: support file...
435
436
437
438
439
440
  	/* Managed to do everything necessary? */
  	if (!blocks)
  		goto out;
  
  	/* All further extents will be NOT_RECORDED_NOT_ALLOCATED */
  	last_ext->extLocation.logicalBlockNum = 0;
4b11111ab   Marcin Slusarz   udf: fix coding s...
441
  	last_ext->extLocation.partitionReferenceNum = 0;
28de7948a   Cyrill Gorcunov   UDF: coding style...
442
  	add = (1 << (30-sb->s_blocksize_bits)) - 1;
4b11111ab   Marcin Slusarz   udf: fix coding s...
443
444
  	last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
  				(add << sb->s_blocksize_bits);
28de7948a   Cyrill Gorcunov   UDF: coding style...
445

31170b6ad   Jan Kara   udf: support file...
446
447
448
  	/* Create enough extents to cover the whole hole */
  	while (blocks > add) {
  		blocks -= add;
7e49b6f24   Jan Kara   udf: Convert UDF ...
449
450
451
452
  		err = udf_add_aext(inode, last_pos, &last_ext->extLocation,
  				   last_ext->extLength, 1);
  		if (err)
  			return err;
31170b6ad   Jan Kara   udf: support file...
453
454
455
456
  		count++;
  	}
  	if (blocks) {
  		last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
28de7948a   Cyrill Gorcunov   UDF: coding style...
457
  			(blocks << sb->s_blocksize_bits);
7e49b6f24   Jan Kara   udf: Convert UDF ...
458
459
460
461
  		err = udf_add_aext(inode, last_pos, &last_ext->extLocation,
  				   last_ext->extLength, 1);
  		if (err)
  			return err;
31170b6ad   Jan Kara   udf: support file...
462
463
  		count++;
  	}
28de7948a   Cyrill Gorcunov   UDF: coding style...
464
465
  
  out:
31170b6ad   Jan Kara   udf: support file...
466
467
  	/* Do we have some preallocated blocks saved? */
  	if (prealloc_len) {
7e49b6f24   Jan Kara   udf: Convert UDF ...
468
469
470
471
  		err = udf_add_aext(inode, last_pos, &prealloc_loc,
  				   prealloc_len, 1);
  		if (err)
  			return err;
31170b6ad   Jan Kara   udf: support file...
472
473
474
475
  		last_ext->extLocation = prealloc_loc;
  		last_ext->extLength = prealloc_len;
  		count++;
  	}
28de7948a   Cyrill Gorcunov   UDF: coding style...
476

31170b6ad   Jan Kara   udf: support file...
477
  	/* last_pos should point to the last written extent... */
48d6d8ff7   Marcin Slusarz   udf: cache struct...
478
  	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
5ca4e4be8   Pekka Enberg   Remove struct typ...
479
  		last_pos->offset -= sizeof(struct short_ad);
48d6d8ff7   Marcin Slusarz   udf: cache struct...
480
  	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
5ca4e4be8   Pekka Enberg   Remove struct typ...
481
  		last_pos->offset -= sizeof(struct long_ad);
31170b6ad   Jan Kara   udf: support file...
482
  	else
7e49b6f24   Jan Kara   udf: Convert UDF ...
483
  		return -EIO;
28de7948a   Cyrill Gorcunov   UDF: coding style...
484

31170b6ad   Jan Kara   udf: support file...
485
486
  	return count;
  }
7e49b6f24   Jan Kara   udf: Convert UDF ...
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
  static int udf_extend_file(struct inode *inode, loff_t newsize)
  {
  
  	struct extent_position epos;
  	struct kernel_lb_addr eloc;
  	uint32_t elen;
  	int8_t etype;
  	struct super_block *sb = inode->i_sb;
  	sector_t first_block = newsize >> sb->s_blocksize_bits, offset;
  	int adsize;
  	struct udf_inode_info *iinfo = UDF_I(inode);
  	struct kernel_long_ad extent;
  	int err;
  
  	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
  		adsize = sizeof(struct short_ad);
  	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
  		adsize = sizeof(struct long_ad);
  	else
  		BUG();
  
  	etype = inode_bmap(inode, first_block, &epos, &eloc, &elen, &offset);
  
  	/* File has extent covering the new size (could happen when extending
  	 * inside a block)? */
  	if (etype != -1)
  		return 0;
  	if (newsize & (sb->s_blocksize - 1))
  		offset++;
  	/* Extended file just to the boundary of the last file block? */
  	if (offset == 0)
  		return 0;
  
  	/* Truncate is extending the file by 'offset' blocks */
  	if ((!epos.bh && epos.offset == udf_file_entry_alloc_offset(inode)) ||
  	    (epos.bh && epos.offset == sizeof(struct allocExtDesc))) {
  		/* File has no extents at all or has empty last
  		 * indirect extent! Create a fake extent... */
  		extent.extLocation.logicalBlockNum = 0;
  		extent.extLocation.partitionReferenceNum = 0;
  		extent.extLength = EXT_NOT_RECORDED_NOT_ALLOCATED;
  	} else {
  		epos.offset -= adsize;
  		etype = udf_next_aext(inode, &epos, &extent.extLocation,
  				      &extent.extLength, 0);
  		extent.extLength |= etype << 30;
  	}
  	err = udf_do_extend_file(inode, &epos, &extent, offset);
  	if (err < 0)
  		goto out;
  	err = 0;
  	iinfo->i_lenExtents = newsize;
  out:
  	brelse(epos.bh);
  	return err;
  }
7b0b0933a   Jan Kara   udf: Cleanup call...
543
544
  static sector_t inode_getblk(struct inode *inode, sector_t block,
  			     int *err, int *new)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
545
  {
31170b6ad   Jan Kara   udf: support file...
546
  	static sector_t last_block;
5ca4e4be8   Pekka Enberg   Remove struct typ...
547
  	struct kernel_long_ad laarr[EXTENT_MERGE_SIZE];
ff116fc8d   Jan Kara   UDF: introduce st...
548
  	struct extent_position prev_epos, cur_epos, next_epos;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
549
  	int count = 0, startnum = 0, endnum = 0;
85d71244f   Jan Kara   Fix possible UDF ...
550
  	uint32_t elen = 0, tmpelen;
5ca4e4be8   Pekka Enberg   Remove struct typ...
551
  	struct kernel_lb_addr eloc, tmpeloc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
552
  	int c = 1;
60448b1d6   Jan Kara   udf: use sector_t...
553
554
555
  	loff_t lbcount = 0, b_off = 0;
  	uint32_t newblocknum, newblock;
  	sector_t offset = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
556
  	int8_t etype;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
557
558
  	struct udf_inode_info *iinfo = UDF_I(inode);
  	int goal = 0, pgoal = iinfo->i_location.logicalBlockNum;
31170b6ad   Jan Kara   udf: support file...
559
  	int lastblock = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
560

7b0b0933a   Jan Kara   udf: Cleanup call...
561
562
  	*err = 0;
  	*new = 0;
ff116fc8d   Jan Kara   UDF: introduce st...
563
  	prev_epos.offset = udf_file_entry_alloc_offset(inode);
48d6d8ff7   Marcin Slusarz   udf: cache struct...
564
  	prev_epos.block = iinfo->i_location;
ff116fc8d   Jan Kara   UDF: introduce st...
565
566
  	prev_epos.bh = NULL;
  	cur_epos = next_epos = prev_epos;
28de7948a   Cyrill Gorcunov   UDF: coding style...
567
  	b_off = (loff_t)block << inode->i_sb->s_blocksize_bits;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
568
569
  
  	/* find the extent which contains the block we are looking for.
cb00ea352   Cyrill Gorcunov   UDF: coding style...
570
571
572
573
  	   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()
574
575
  			brelse(prev_epos.bh);
  			get_bh(cur_epos.bh);
ff116fc8d   Jan Kara   UDF: introduce st...
576
  			prev_epos.bh = cur_epos.bh;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
577
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
578
  		if (cur_epos.bh != next_epos.bh) {
3bf25cb40   Jan Kara   udf: use get_bh()
579
580
  			brelse(cur_epos.bh);
  			get_bh(next_epos.bh);
ff116fc8d   Jan Kara   UDF: introduce st...
581
  			cur_epos.bh = next_epos.bh;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
582
583
584
  		}
  
  		lbcount += elen;
ff116fc8d   Jan Kara   UDF: introduce st...
585
586
  		prev_epos.block = cur_epos.block;
  		cur_epos.block = next_epos.block;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
587

ff116fc8d   Jan Kara   UDF: introduce st...
588
589
  		prev_epos.offset = cur_epos.offset;
  		cur_epos.offset = next_epos.offset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
590

4b11111ab   Marcin Slusarz   udf: fix coding s...
591
592
  		etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 1);
  		if (etype == -1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
593
594
595
596
597
598
599
600
601
  			break;
  
  		c = !c;
  
  		laarr[c].extLength = (etype << 30) | elen;
  		laarr[c].extLocation = eloc;
  
  		if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
  			pgoal = eloc.logicalBlockNum +
28de7948a   Cyrill Gorcunov   UDF: coding style...
602
603
  				((elen + inode->i_sb->s_blocksize - 1) >>
  				 inode->i_sb->s_blocksize_bits);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
604

cb00ea352   Cyrill Gorcunov   UDF: coding style...
605
  		count++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
606
607
608
609
  	} while (lbcount + elen <= b_off);
  
  	b_off -= lbcount;
  	offset = b_off >> inode->i_sb->s_blocksize_bits;
85d71244f   Jan Kara   Fix possible UDF ...
610
611
612
613
614
615
  	/*
  	 * 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
616
617
  
  	/* if the extent is allocated and recorded, return the block
cb00ea352   Cyrill Gorcunov   UDF: coding style...
618
  	   if the extent is not a multiple of the blocksize, round up */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
619

cb00ea352   Cyrill Gorcunov   UDF: coding style...
620
621
  	if (etype == (EXT_RECORDED_ALLOCATED >> 30)) {
  		if (elen & (inode->i_sb->s_blocksize - 1)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
622
  			elen = EXT_RECORDED_ALLOCATED |
28de7948a   Cyrill Gorcunov   UDF: coding style...
623
624
  				((elen + inode->i_sb->s_blocksize - 1) &
  				 ~(inode->i_sb->s_blocksize - 1));
7e49b6f24   Jan Kara   udf: Convert UDF ...
625
  			udf_write_aext(inode, &cur_epos, &eloc, elen, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
626
  		}
3bf25cb40   Jan Kara   udf: use get_bh()
627
628
629
  		brelse(prev_epos.bh);
  		brelse(cur_epos.bh);
  		brelse(next_epos.bh);
97e961fdb   Pekka Enberg   Fix the udf code ...
630
  		newblock = udf_get_lb_pblock(inode->i_sb, &eloc, offset);
7b0b0933a   Jan Kara   udf: Cleanup call...
631
  		return newblock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
632
  	}
31170b6ad   Jan Kara   udf: support file...
633
634
  	last_block = block;
  	/* Are we beyond EOF? */
cb00ea352   Cyrill Gorcunov   UDF: coding style...
635
  	if (etype == -1) {
31170b6ad   Jan Kara   udf: support file...
636
637
638
639
640
641
  		int ret;
  
  		if (count) {
  			if (c)
  				laarr[0] = laarr[1];
  			startnum = 1;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
642
  		} else {
31170b6ad   Jan Kara   udf: support file...
643
  			/* Create a fake extent when there's not one */
4b11111ab   Marcin Slusarz   udf: fix coding s...
644
  			memset(&laarr[0].extLocation, 0x00,
5ca4e4be8   Pekka Enberg   Remove struct typ...
645
  				sizeof(struct kernel_lb_addr));
31170b6ad   Jan Kara   udf: support file...
646
  			laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED;
7e49b6f24   Jan Kara   udf: Convert UDF ...
647
  			/* Will udf_do_extend_file() create real extent from
4b11111ab   Marcin Slusarz   udf: fix coding s...
648
  			   a fake one? */
31170b6ad   Jan Kara   udf: support file...
649
650
651
  			startnum = (offset > 0);
  		}
  		/* Create extents for the hole between EOF and offset */
7e49b6f24   Jan Kara   udf: Convert UDF ...
652
653
  		ret = udf_do_extend_file(inode, &prev_epos, laarr, offset);
  		if (ret < 0) {
31170b6ad   Jan Kara   udf: support file...
654
655
656
  			brelse(prev_epos.bh);
  			brelse(cur_epos.bh);
  			brelse(next_epos.bh);
7e49b6f24   Jan Kara   udf: Convert UDF ...
657
  			*err = ret;
7b0b0933a   Jan Kara   udf: Cleanup call...
658
  			return 0;
31170b6ad   Jan Kara   udf: support file...
659
660
661
662
663
  		}
  		c = 0;
  		offset = 0;
  		count += ret;
  		/* We are not covered by a preallocated extent? */
4b11111ab   Marcin Slusarz   udf: fix coding s...
664
665
  		if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) !=
  						EXT_NOT_RECORDED_ALLOCATED) {
31170b6ad   Jan Kara   udf: support file...
666
667
668
669
670
  			/* Is there any real extent? - otherwise we overwrite
  			 * the fake one... */
  			if (count)
  				c = !c;
  			laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
28de7948a   Cyrill Gorcunov   UDF: coding style...
671
  				inode->i_sb->s_blocksize;
4b11111ab   Marcin Slusarz   udf: fix coding s...
672
  			memset(&laarr[c].extLocation, 0x00,
5ca4e4be8   Pekka Enberg   Remove struct typ...
673
  				sizeof(struct kernel_lb_addr));
cb00ea352   Cyrill Gorcunov   UDF: coding style...
674
675
  			count++;
  			endnum++;
31170b6ad   Jan Kara   udf: support file...
676
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
677
  		endnum = c + 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
678
  		lastblock = 1;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
679
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
680
  		endnum = startnum = ((count > 2) ? 2 : count);
4b11111ab   Marcin Slusarz   udf: fix coding s...
681
682
  		/* if the current extent is in position 0,
  		   swap it with the previous */
cb00ea352   Cyrill Gorcunov   UDF: coding style...
683
  		if (!c && count != 1) {
31170b6ad   Jan Kara   udf: support file...
684
685
686
687
688
  			laarr[2] = laarr[0];
  			laarr[0] = laarr[1];
  			laarr[1] = laarr[2];
  			c = 1;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
689

4b11111ab   Marcin Slusarz   udf: fix coding s...
690
691
692
693
  		/* if the current block is located in an extent,
  		   read the next extent */
  		etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 0);
  		if (etype != -1) {
cb00ea352   Cyrill Gorcunov   UDF: coding style...
694
695
696
697
698
  			laarr[c + 1].extLength = (etype << 30) | elen;
  			laarr[c + 1].extLocation = eloc;
  			count++;
  			startnum++;
  			endnum++;
4b11111ab   Marcin Slusarz   udf: fix coding s...
699
  		} else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
700
701
  			lastblock = 1;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
702
703
  
  	/* if the current extent is not recorded but allocated, get the
28de7948a   Cyrill Gorcunov   UDF: coding style...
704
  	 * block in the extent corresponding to the requested block */
4b11111ab   Marcin Slusarz   udf: fix coding s...
705
  	if ((laarr[c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
706
  		newblocknum = laarr[c].extLocation.logicalBlockNum + offset;
4b11111ab   Marcin Slusarz   udf: fix coding s...
707
  	else { /* otherwise, allocate a new block */
48d6d8ff7   Marcin Slusarz   udf: cache struct...
708
709
  		if (iinfo->i_next_alloc_block == block)
  			goal = iinfo->i_next_alloc_goal;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
710

cb00ea352   Cyrill Gorcunov   UDF: coding style...
711
  		if (!goal) {
4b11111ab   Marcin Slusarz   udf: fix coding s...
712
  			if (!(goal = pgoal)) /* XXX: what was intended here? */
48d6d8ff7   Marcin Slusarz   udf: cache struct...
713
  				goal = iinfo->i_location.logicalBlockNum + 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
714
  		}
4b11111ab   Marcin Slusarz   udf: fix coding s...
715
  		newblocknum = udf_new_block(inode->i_sb, inode,
48d6d8ff7   Marcin Slusarz   udf: cache struct...
716
  				iinfo->i_location.partitionReferenceNum,
4b11111ab   Marcin Slusarz   udf: fix coding s...
717
718
  				goal, err);
  		if (!newblocknum) {
3bf25cb40   Jan Kara   udf: use get_bh()
719
  			brelse(prev_epos.bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
720
  			*err = -ENOSPC;
7b0b0933a   Jan Kara   udf: Cleanup call...
721
  			return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
722
  		}
48d6d8ff7   Marcin Slusarz   udf: cache struct...
723
  		iinfo->i_lenExtents += inode->i_sb->s_blocksize;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
724
  	}
4b11111ab   Marcin Slusarz   udf: fix coding s...
725
726
727
728
  	/* if the extent the requsted block is located in contains multiple
  	 * blocks, split the extent into at most three extents. blocks prior
  	 * to requested block, requested block, and blocks after requested
  	 * block */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
729
730
731
  	udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum);
  
  #ifdef UDF_PREALLOCATE
81056dd04   Jan Kara   udf: Perform prea...
732
733
734
735
736
737
  	/* We preallocate blocks only for regular files. It also makes sense
  	 * for directories but there's a problem when to drop the
  	 * preallocation. We might use some delayed work for that but I feel
  	 * it's overengineering for a filesystem like UDF. */
  	if (S_ISREG(inode->i_mode))
  		udf_prealloc_extents(inode, c, lastblock, laarr, &endnum);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
738
739
740
741
742
743
  #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
28de7948a   Cyrill Gorcunov   UDF: coding style...
744
745
  	 * 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...
746
  	udf_update_extents(inode, laarr, startnum, endnum, &prev_epos);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
747

3bf25cb40   Jan Kara   udf: use get_bh()
748
  	brelse(prev_epos.bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
749

4b11111ab   Marcin Slusarz   udf: fix coding s...
750
  	newblock = udf_get_pblock(inode->i_sb, newblocknum,
48d6d8ff7   Marcin Slusarz   udf: cache struct...
751
  				iinfo->i_location.partitionReferenceNum, 0);
7b0b0933a   Jan Kara   udf: Cleanup call...
752
753
754
755
  	if (!newblock) {
  		*err = -EIO;
  		return 0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
756
  	*new = 1;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
757
758
  	iinfo->i_next_alloc_block = block;
  	iinfo->i_next_alloc_goal = newblocknum;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
759
760
761
762
763
764
  	inode->i_ctime = current_fs_time(inode->i_sb);
  
  	if (IS_SYNC(inode))
  		udf_sync_inode(inode);
  	else
  		mark_inode_dirty(inode);
28de7948a   Cyrill Gorcunov   UDF: coding style...
765

7b0b0933a   Jan Kara   udf: Cleanup call...
766
  	return newblock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
767
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
768
769
  static void udf_split_extents(struct inode *inode, int *c, int offset,
  			      int newblocknum,
5ca4e4be8   Pekka Enberg   Remove struct typ...
770
  			      struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
cb00ea352   Cyrill Gorcunov   UDF: coding style...
771
  			      int *endnum)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
772
  {
4b11111ab   Marcin Slusarz   udf: fix coding s...
773
774
  	unsigned long blocksize = inode->i_sb->s_blocksize;
  	unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
775
  	if ((laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30) ||
4b11111ab   Marcin Slusarz   udf: fix coding s...
776
777
  	    (laarr[*c].extLength >> 30) ==
  				(EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
778
779
  		int curr = *c;
  		int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) +
4b11111ab   Marcin Slusarz   udf: fix coding s...
780
  			    blocksize - 1) >> blocksize_bits;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
781
  		int8_t etype = (laarr[curr].extLength >> 30);
4b11111ab   Marcin Slusarz   udf: fix coding s...
782
  		if (blen == 1)
28de7948a   Cyrill Gorcunov   UDF: coding style...
783
  			;
4b11111ab   Marcin Slusarz   udf: fix coding s...
784
  		else if (!offset || blen == offset + 1) {
cb00ea352   Cyrill Gorcunov   UDF: coding style...
785
786
787
788
789
790
791
792
793
  			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)) {
4b11111ab   Marcin Slusarz   udf: fix coding s...
794
  				udf_free_blocks(inode->i_sb, inode,
97e961fdb   Pekka Enberg   Fix the udf code ...
795
  						&laarr[curr].extLocation,
4b11111ab   Marcin Slusarz   udf: fix coding s...
796
797
798
799
  						0, offset);
  				laarr[curr].extLength =
  					EXT_NOT_RECORDED_NOT_ALLOCATED |
  					(offset << blocksize_bits);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
800
  				laarr[curr].extLocation.logicalBlockNum = 0;
4b11111ab   Marcin Slusarz   udf: fix coding s...
801
802
803
  				laarr[curr].extLocation.
  						partitionReferenceNum = 0;
  			} else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
804
  				laarr[curr].extLength = (etype << 30) |
4b11111ab   Marcin Slusarz   udf: fix coding s...
805
  					(offset << blocksize_bits);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
806
807
808
  			curr++;
  			(*c)++;
  			(*endnum)++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
809
  		}
647bd61a5   Cyrill Gorcunov   UDF: check for al...
810

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
811
812
813
  		laarr[curr].extLocation.logicalBlockNum = newblocknum;
  		if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
  			laarr[curr].extLocation.partitionReferenceNum =
c0b344385   Marcin Slusarz   udf: remove UDF_I...
814
  				UDF_I(inode)->i_location.partitionReferenceNum;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
815
  		laarr[curr].extLength = EXT_RECORDED_ALLOCATED |
4b11111ab   Marcin Slusarz   udf: fix coding s...
816
  			blocksize;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
817
  		curr++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
818

cb00ea352   Cyrill Gorcunov   UDF: coding style...
819
  		if (blen != offset + 1) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
820
  			if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
4b11111ab   Marcin Slusarz   udf: fix coding s...
821
822
  				laarr[curr].extLocation.logicalBlockNum +=
  								offset + 1;
28de7948a   Cyrill Gorcunov   UDF: coding style...
823
  			laarr[curr].extLength = (etype << 30) |
4b11111ab   Marcin Slusarz   udf: fix coding s...
824
  				((blen - (offset + 1)) << blocksize_bits);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
825
826
  			curr++;
  			(*endnum)++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
827
828
829
830
831
  		}
  	}
  }
  
  static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
5ca4e4be8   Pekka Enberg   Remove struct typ...
832
  				 struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
cb00ea352   Cyrill Gorcunov   UDF: coding style...
833
  				 int *endnum)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
834
835
  {
  	int start, length = 0, currlength = 0, i;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
836
  	if (*endnum >= (c + 1)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
837
838
839
840
  		if (!lastblock)
  			return;
  		else
  			start = c;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
841
  	} else {
4b11111ab   Marcin Slusarz   udf: fix coding s...
842
843
  		if ((laarr[c + 1].extLength >> 30) ==
  					(EXT_NOT_RECORDED_ALLOCATED >> 30)) {
cb00ea352   Cyrill Gorcunov   UDF: coding style...
844
  			start = c + 1;
4b11111ab   Marcin Slusarz   udf: fix coding s...
845
846
847
848
849
850
  			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
851
852
  			start = c;
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
853
854
  	for (i = start + 1; i <= *endnum; i++) {
  		if (i == *endnum) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
855
856
  			if (lastblock)
  				length += UDF_DEFAULT_PREALLOC_BLOCKS;
4b11111ab   Marcin Slusarz   udf: fix coding s...
857
858
859
860
861
862
863
  		} else if ((laarr[i].extLength >> 30) ==
  				(EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) {
  			length += (((laarr[i].extLength &
  						UDF_EXTENT_LENGTH_MASK) +
  				    inode->i_sb->s_blocksize - 1) >>
  				    inode->i_sb->s_blocksize_bits);
  		} else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
864
865
  			break;
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
866
  	if (length) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
867
  		int next = laarr[start].extLocation.logicalBlockNum +
28de7948a   Cyrill Gorcunov   UDF: coding style...
868
  			(((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) +
4b11111ab   Marcin Slusarz   udf: fix coding s...
869
870
  			  inode->i_sb->s_blocksize - 1) >>
  			  inode->i_sb->s_blocksize_bits);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
871
  		int numalloc = udf_prealloc_blocks(inode->i_sb, inode,
4b11111ab   Marcin Slusarz   udf: fix coding s...
872
873
874
875
  				laarr[start].extLocation.partitionReferenceNum,
  				next, (UDF_DEFAULT_PREALLOC_BLOCKS > length ?
  				length : UDF_DEFAULT_PREALLOC_BLOCKS) -
  				currlength);
28de7948a   Cyrill Gorcunov   UDF: coding style...
876
  		if (numalloc) 	{
4b11111ab   Marcin Slusarz   udf: fix coding s...
877
  			if (start == (c + 1))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
878
  				laarr[start].extLength +=
4b11111ab   Marcin Slusarz   udf: fix coding s...
879
880
881
  					(numalloc <<
  					 inode->i_sb->s_blocksize_bits);
  			else {
cb00ea352   Cyrill Gorcunov   UDF: coding style...
882
  				memmove(&laarr[c + 2], &laarr[c + 1],
5ca4e4be8   Pekka Enberg   Remove struct typ...
883
  					sizeof(struct long_ad) * (*endnum - (c + 1)));
cb00ea352   Cyrill Gorcunov   UDF: coding style...
884
885
886
  				(*endnum)++;
  				laarr[c + 1].extLocation.logicalBlockNum = next;
  				laarr[c + 1].extLocation.partitionReferenceNum =
4b11111ab   Marcin Slusarz   udf: fix coding s...
887
888
889
890
891
892
  					laarr[c].extLocation.
  							partitionReferenceNum;
  				laarr[c + 1].extLength =
  					EXT_NOT_RECORDED_ALLOCATED |
  					(numalloc <<
  					 inode->i_sb->s_blocksize_bits);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
893
  				start = c + 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
894
  			}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
895
  			for (i = start + 1; numalloc && i < *endnum; i++) {
4b11111ab   Marcin Slusarz   udf: fix coding s...
896
897
898
899
  				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
900

cb00ea352   Cyrill Gorcunov   UDF: coding style...
901
  				if (elen > numalloc) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
902
  					laarr[i].extLength -=
4b11111ab   Marcin Slusarz   udf: fix coding s...
903
904
  						(numalloc <<
  						 inode->i_sb->s_blocksize_bits);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
905
  					numalloc = 0;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
906
  				} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
907
  					numalloc -= elen;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
908
  					if (*endnum > (i + 1))
4b11111ab   Marcin Slusarz   udf: fix coding s...
909
910
  						memmove(&laarr[i],
  							&laarr[i + 1],
5ca4e4be8   Pekka Enberg   Remove struct typ...
911
  							sizeof(struct long_ad) *
4b11111ab   Marcin Slusarz   udf: fix coding s...
912
  							(*endnum - (i + 1)));
cb00ea352   Cyrill Gorcunov   UDF: coding style...
913
914
  					i--;
  					(*endnum)--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
915
916
  				}
  			}
c0b344385   Marcin Slusarz   udf: remove UDF_I...
917
  			UDF_I(inode)->i_lenExtents +=
4b11111ab   Marcin Slusarz   udf: fix coding s...
918
  				numalloc << inode->i_sb->s_blocksize_bits;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
919
920
921
922
923
  		}
  	}
  }
  
  static void udf_merge_extents(struct inode *inode,
5ca4e4be8   Pekka Enberg   Remove struct typ...
924
  			      struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
cb00ea352   Cyrill Gorcunov   UDF: coding style...
925
  			      int *endnum)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
926
927
  {
  	int i;
4b11111ab   Marcin Slusarz   udf: fix coding s...
928
929
  	unsigned long blocksize = inode->i_sb->s_blocksize;
  	unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
930

cb00ea352   Cyrill Gorcunov   UDF: coding style...
931
  	for (i = 0; i < (*endnum - 1); i++) {
5ca4e4be8   Pekka Enberg   Remove struct typ...
932
933
  		struct kernel_long_ad *li /*l[i]*/ = &laarr[i];
  		struct kernel_long_ad *lip1 /*l[i plus 1]*/ = &laarr[i + 1];
4b11111ab   Marcin Slusarz   udf: fix coding s...
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
  
  		if (((li->extLength >> 30) == (lip1->extLength >> 30)) &&
  			(((li->extLength >> 30) ==
  				(EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) ||
  			((lip1->extLocation.logicalBlockNum -
  			  li->extLocation.logicalBlockNum) ==
  			(((li->extLength & UDF_EXTENT_LENGTH_MASK) +
  			blocksize - 1) >> blocksize_bits)))) {
  
  			if (((li->extLength & UDF_EXTENT_LENGTH_MASK) +
  				(lip1->extLength & UDF_EXTENT_LENGTH_MASK) +
  				blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) {
  				lip1->extLength = (lip1->extLength -
  						  (li->extLength &
  						   UDF_EXTENT_LENGTH_MASK) +
  						   UDF_EXTENT_LENGTH_MASK) &
  							~(blocksize - 1);
  				li->extLength = (li->extLength &
  						 UDF_EXTENT_FLAG_MASK) +
  						(UDF_EXTENT_LENGTH_MASK + 1) -
  						blocksize;
  				lip1->extLocation.logicalBlockNum =
  					li->extLocation.logicalBlockNum +
  					((li->extLength &
  						UDF_EXTENT_LENGTH_MASK) >>
  						blocksize_bits);
  			} else {
  				li->extLength = lip1->extLength +
  					(((li->extLength &
  						UDF_EXTENT_LENGTH_MASK) +
  					 blocksize - 1) & ~(blocksize - 1));
  				if (*endnum > (i + 2))
  					memmove(&laarr[i + 1], &laarr[i + 2],
5ca4e4be8   Pekka Enberg   Remove struct typ...
967
  						sizeof(struct long_ad) *
4b11111ab   Marcin Slusarz   udf: fix coding s...
968
969
970
  						(*endnum - (i + 2)));
  				i--;
  				(*endnum)--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
971
  			}
4b11111ab   Marcin Slusarz   udf: fix coding s...
972
973
974
975
  		} else if (((li->extLength >> 30) ==
  				(EXT_NOT_RECORDED_ALLOCATED >> 30)) &&
  			   ((lip1->extLength >> 30) ==
  				(EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))) {
97e961fdb   Pekka Enberg   Fix the udf code ...
976
  			udf_free_blocks(inode->i_sb, inode, &li->extLocation, 0,
4b11111ab   Marcin Slusarz   udf: fix coding s...
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
  					((li->extLength &
  					  UDF_EXTENT_LENGTH_MASK) +
  					 blocksize - 1) >> blocksize_bits);
  			li->extLocation.logicalBlockNum = 0;
  			li->extLocation.partitionReferenceNum = 0;
  
  			if (((li->extLength & UDF_EXTENT_LENGTH_MASK) +
  			     (lip1->extLength & UDF_EXTENT_LENGTH_MASK) +
  			     blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK) {
  				lip1->extLength = (lip1->extLength -
  						   (li->extLength &
  						   UDF_EXTENT_LENGTH_MASK) +
  						   UDF_EXTENT_LENGTH_MASK) &
  						   ~(blocksize - 1);
  				li->extLength = (li->extLength &
  						 UDF_EXTENT_FLAG_MASK) +
  						(UDF_EXTENT_LENGTH_MASK + 1) -
  						blocksize;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
995
  			} else {
4b11111ab   Marcin Slusarz   udf: fix coding s...
996
997
998
999
  				li->extLength = lip1->extLength +
  					(((li->extLength &
  						UDF_EXTENT_LENGTH_MASK) +
  					  blocksize - 1) & ~(blocksize - 1));
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1000
1001
  				if (*endnum > (i + 2))
  					memmove(&laarr[i + 1], &laarr[i + 2],
5ca4e4be8   Pekka Enberg   Remove struct typ...
1002
  						sizeof(struct long_ad) *
4b11111ab   Marcin Slusarz   udf: fix coding s...
1003
  						(*endnum - (i + 2)));
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1004
1005
  				i--;
  				(*endnum)--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1006
  			}
4b11111ab   Marcin Slusarz   udf: fix coding s...
1007
1008
1009
  		} else if ((li->extLength >> 30) ==
  					(EXT_NOT_RECORDED_ALLOCATED >> 30)) {
  			udf_free_blocks(inode->i_sb, inode,
97e961fdb   Pekka Enberg   Fix the udf code ...
1010
  					&li->extLocation, 0,
4b11111ab   Marcin Slusarz   udf: fix coding s...
1011
1012
1013
1014
1015
1016
1017
1018
  					((li->extLength &
  						UDF_EXTENT_LENGTH_MASK) +
  					 blocksize - 1) >> blocksize_bits);
  			li->extLocation.logicalBlockNum = 0;
  			li->extLocation.partitionReferenceNum = 0;
  			li->extLength = (li->extLength &
  						UDF_EXTENT_LENGTH_MASK) |
  						EXT_NOT_RECORDED_NOT_ALLOCATED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1019
1020
1021
1022
1023
  		}
  	}
  }
  
  static void udf_update_extents(struct inode *inode,
5ca4e4be8   Pekka Enberg   Remove struct typ...
1024
  			       struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1025
1026
  			       int startnum, int endnum,
  			       struct extent_position *epos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1027
1028
  {
  	int start = 0, i;
5ca4e4be8   Pekka Enberg   Remove struct typ...
1029
  	struct kernel_lb_addr tmploc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1030
  	uint32_t tmplen;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1031
1032
  	if (startnum > endnum) {
  		for (i = 0; i < (startnum - endnum); i++)
ff116fc8d   Jan Kara   UDF: introduce st...
1033
  			udf_delete_aext(inode, *epos, laarr[i].extLocation,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1034
1035
1036
  					laarr[i].extLength);
  	} else if (startnum < endnum) {
  		for (i = 0; i < (endnum - startnum); i++) {
ff116fc8d   Jan Kara   UDF: introduce st...
1037
  			udf_insert_aext(inode, *epos, laarr[i].extLocation,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1038
  					laarr[i].extLength);
ff116fc8d   Jan Kara   UDF: introduce st...
1039
  			udf_next_aext(inode, epos, &laarr[i].extLocation,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1040
1041
  				      &laarr[i].extLength, 1);
  			start++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1042
1043
  		}
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1044
  	for (i = start; i < endnum; i++) {
ff116fc8d   Jan Kara   UDF: introduce st...
1045
  		udf_next_aext(inode, epos, &tmploc, &tmplen, 0);
97e961fdb   Pekka Enberg   Fix the udf code ...
1046
  		udf_write_aext(inode, epos, &laarr[i].extLocation,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1047
  			       laarr[i].extLength, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1048
1049
  	}
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1050
1051
  struct buffer_head *udf_bread(struct inode *inode, int block,
  			      int create, int *err)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1052
  {
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1053
  	struct buffer_head *bh = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1054
1055
1056
1057
1058
1059
1060
  
  	bh = udf_getblk(inode, block, create, err);
  	if (!bh)
  		return NULL;
  
  	if (buffer_uptodate(bh))
  		return bh;
28de7948a   Cyrill Gorcunov   UDF: coding style...
1061

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1062
  	ll_rw_block(READ, 1, &bh);
28de7948a   Cyrill Gorcunov   UDF: coding style...
1063

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1064
1065
1066
  	wait_on_buffer(bh);
  	if (buffer_uptodate(bh))
  		return bh;
28de7948a   Cyrill Gorcunov   UDF: coding style...
1067

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1068
1069
1070
1071
  	brelse(bh);
  	*err = -EIO;
  	return NULL;
  }
7e49b6f24   Jan Kara   udf: Convert UDF ...
1072
  int udf_setsize(struct inode *inode, loff_t newsize)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1073
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1074
  	int err;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1075
  	struct udf_inode_info *iinfo;
7e49b6f24   Jan Kara   udf: Convert UDF ...
1076
  	int bsize = 1 << inode->i_blkbits;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1077
1078
  
  	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1079
  	      S_ISLNK(inode->i_mode)))
7e49b6f24   Jan Kara   udf: Convert UDF ...
1080
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1081
  	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
7e49b6f24   Jan Kara   udf: Convert UDF ...
1082
  		return -EPERM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1083

48d6d8ff7   Marcin Slusarz   udf: cache struct...
1084
  	iinfo = UDF_I(inode);
7e49b6f24   Jan Kara   udf: Convert UDF ...
1085
  	if (newsize > inode->i_size) {
4d0fb621d   Alessio Igor Bogani   udf: Replace bkl ...
1086
  		down_write(&iinfo->i_data_sem);
7e49b6f24   Jan Kara   udf: Convert UDF ...
1087
1088
1089
1090
  		if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
  			if (bsize <
  			    (udf_file_entry_alloc_offset(inode) + newsize)) {
  				err = udf_expand_file_adinicb(inode);
d2eb8c359   Jan Kara   udf: Fix deadlock...
1091
  				if (err)
7e49b6f24   Jan Kara   udf: Convert UDF ...
1092
  					return err;
d2eb8c359   Jan Kara   udf: Fix deadlock...
1093
  				down_write(&iinfo->i_data_sem);
4b11111ab   Marcin Slusarz   udf: fix coding s...
1094
  			} else
7e49b6f24   Jan Kara   udf: Convert UDF ...
1095
1096
1097
1098
1099
1100
  				iinfo->i_lenAlloc = newsize;
  		}
  		err = udf_extend_file(inode, newsize);
  		if (err) {
  			up_write(&iinfo->i_data_sem);
  			return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1101
  		}
7e49b6f24   Jan Kara   udf: Convert UDF ...
1102
  		truncate_setsize(inode, newsize);
4d0fb621d   Alessio Igor Bogani   udf: Replace bkl ...
1103
  		up_write(&iinfo->i_data_sem);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1104
  	} else {
7e49b6f24   Jan Kara   udf: Convert UDF ...
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
  		if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
  			down_write(&iinfo->i_data_sem);
  			memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr + newsize,
  			       0x00, bsize - newsize -
  			       udf_file_entry_alloc_offset(inode));
  			iinfo->i_lenAlloc = newsize;
  			truncate_setsize(inode, newsize);
  			up_write(&iinfo->i_data_sem);
  			goto update_time;
  		}
  		err = block_truncate_page(inode->i_mapping, newsize,
  					  udf_get_block);
  		if (err)
  			return err;
4d0fb621d   Alessio Igor Bogani   udf: Replace bkl ...
1119
  		down_write(&iinfo->i_data_sem);
7e49b6f24   Jan Kara   udf: Convert UDF ...
1120
  		truncate_setsize(inode, newsize);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1121
  		udf_truncate_extents(inode);
4d0fb621d   Alessio Igor Bogani   udf: Replace bkl ...
1122
  		up_write(&iinfo->i_data_sem);
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1123
  	}
7e49b6f24   Jan Kara   udf: Convert UDF ...
1124
  update_time:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1125
1126
  	inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
  	if (IS_SYNC(inode))
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1127
  		udf_sync_inode(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1128
1129
  	else
  		mark_inode_dirty(inode);
7e49b6f24   Jan Kara   udf: Convert UDF ...
1130
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1131
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1132
  static void __udf_read_inode(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1133
1134
1135
1136
  {
  	struct buffer_head *bh = NULL;
  	struct fileEntry *fe;
  	uint16_t ident;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1137
  	struct udf_inode_info *iinfo = UDF_I(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
  
  	/*
  	 * 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;
  	 */
97e961fdb   Pekka Enberg   Fix the udf code ...
1151
  	bh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 0, &ident);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1152
  	if (!bh) {
78ace70c4   Joe Perches   udf: Convert prin...
1153
1154
  		udf_err(inode->i_sb, "(ino %ld) failed !bh
  ", inode->i_ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1155
1156
1157
1158
1159
  		make_bad_inode(inode);
  		return;
  	}
  
  	if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE &&
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1160
  	    ident != TAG_IDENT_USE) {
78ace70c4   Joe Perches   udf: Convert prin...
1161
1162
1163
  		udf_err(inode->i_sb, "(ino %ld) failed ident=%d
  ",
  			inode->i_ino, ident);
3bf25cb40   Jan Kara   udf: use get_bh()
1164
  		brelse(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1165
1166
1167
1168
1169
  		make_bad_inode(inode);
  		return;
  	}
  
  	fe = (struct fileEntry *)bh->b_data;
5e0f00173   Marcin Slusarz   udf: convert byte...
1170
  	if (fe->icbTag.strategyType == cpu_to_le16(4096)) {
1ab927857   marcin.slusarz@gmail.com   udf: simplify __u...
1171
  		struct buffer_head *ibh;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1172

97e961fdb   Pekka Enberg   Fix the udf code ...
1173
  		ibh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 1,
4b11111ab   Marcin Slusarz   udf: fix coding s...
1174
  					&ident);
1ab927857   marcin.slusarz@gmail.com   udf: simplify __u...
1175
1176
  		if (ident == TAG_IDENT_IE && ibh) {
  			struct buffer_head *nbh = NULL;
5ca4e4be8   Pekka Enberg   Remove struct typ...
1177
  			struct kernel_lb_addr loc;
1ab927857   marcin.slusarz@gmail.com   udf: simplify __u...
1178
1179
1180
1181
1182
1183
  			struct indirectEntry *ie;
  
  			ie = (struct indirectEntry *)ibh->b_data;
  			loc = lelb_to_cpu(ie->indirectICB.extLocation);
  
  			if (ie->indirectICB.extLength &&
97e961fdb   Pekka Enberg   Fix the udf code ...
1184
  				(nbh = udf_read_ptagged(inode->i_sb, &loc, 0,
1ab927857   marcin.slusarz@gmail.com   udf: simplify __u...
1185
1186
1187
1188
1189
  							&ident))) {
  				if (ident == TAG_IDENT_FE ||
  					ident == TAG_IDENT_EFE) {
  					memcpy(&iinfo->i_location,
  						&loc,
5ca4e4be8   Pekka Enberg   Remove struct typ...
1190
  						sizeof(struct kernel_lb_addr));
1ab927857   marcin.slusarz@gmail.com   udf: simplify __u...
1191
  					brelse(bh);
3bf25cb40   Jan Kara   udf: use get_bh()
1192
  					brelse(ibh);
1ab927857   marcin.slusarz@gmail.com   udf: simplify __u...
1193
1194
1195
  					brelse(nbh);
  					__udf_read_inode(inode);
  					return;
28de7948a   Cyrill Gorcunov   UDF: coding style...
1196
  				}
1ab927857   marcin.slusarz@gmail.com   udf: simplify __u...
1197
  				brelse(nbh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1198
  			}
28de7948a   Cyrill Gorcunov   UDF: coding style...
1199
  		}
1ab927857   marcin.slusarz@gmail.com   udf: simplify __u...
1200
  		brelse(ibh);
5e0f00173   Marcin Slusarz   udf: convert byte...
1201
  	} else if (fe->icbTag.strategyType != cpu_to_le16(4)) {
78ace70c4   Joe Perches   udf: Convert prin...
1202
1203
1204
  		udf_err(inode->i_sb, "unsupported strategy type: %d
  ",
  			le16_to_cpu(fe->icbTag.strategyType));
3bf25cb40   Jan Kara   udf: use get_bh()
1205
  		brelse(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1206
1207
1208
1209
  		make_bad_inode(inode);
  		return;
  	}
  	udf_fill_inode(inode, bh);
31170b6ad   Jan Kara   udf: support file...
1210

3bf25cb40   Jan Kara   udf: use get_bh()
1211
  	brelse(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1212
1213
1214
1215
1216
1217
  }
  
  static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
  {
  	struct fileEntry *fe;
  	struct extendedFileEntry *efe;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1218
  	int offset;
6c79e987d   Marcin Slusarz   udf: remove some ...
1219
  	struct udf_sb_info *sbi = UDF_SB(inode->i_sb);
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1220
  	struct udf_inode_info *iinfo = UDF_I(inode);
bfe868486   Miklos Szeredi   filesystems: add ...
1221
  	unsigned int link_count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1222
1223
1224
  
  	fe = (struct fileEntry *)bh->b_data;
  	efe = (struct extendedFileEntry *)bh->b_data;
5e0f00173   Marcin Slusarz   udf: convert byte...
1225
  	if (fe->icbTag.strategyType == cpu_to_le16(4))
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1226
  		iinfo->i_strat4096 = 0;
5e0f00173   Marcin Slusarz   udf: convert byte...
1227
  	else /* if (fe->icbTag.strategyType == cpu_to_le16(4096)) */
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1228
  		iinfo->i_strat4096 = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1229

48d6d8ff7   Marcin Slusarz   udf: cache struct...
1230
  	iinfo->i_alloc_type = le16_to_cpu(fe->icbTag.flags) &
4b11111ab   Marcin Slusarz   udf: fix coding s...
1231
  							ICBTAG_FLAG_AD_MASK;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1232
1233
1234
1235
1236
1237
  	iinfo->i_unique = 0;
  	iinfo->i_lenEAttr = 0;
  	iinfo->i_lenExtents = 0;
  	iinfo->i_lenAlloc = 0;
  	iinfo->i_next_alloc_block = 0;
  	iinfo->i_next_alloc_goal = 0;
5e0f00173   Marcin Slusarz   udf: convert byte...
1238
  	if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_EFE)) {
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1239
1240
  		iinfo->i_efe = 1;
  		iinfo->i_use = 0;
4b11111ab   Marcin Slusarz   udf: fix coding s...
1241
1242
  		if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize -
  					sizeof(struct extendedFileEntry))) {
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1243
1244
1245
  			make_bad_inode(inode);
  			return;
  		}
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1246
  		memcpy(iinfo->i_ext.i_data,
4b11111ab   Marcin Slusarz   udf: fix coding s...
1247
1248
1249
  		       bh->b_data + sizeof(struct extendedFileEntry),
  		       inode->i_sb->s_blocksize -
  					sizeof(struct extendedFileEntry));
5e0f00173   Marcin Slusarz   udf: convert byte...
1250
  	} else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) {
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1251
1252
  		iinfo->i_efe = 0;
  		iinfo->i_use = 0;
4b11111ab   Marcin Slusarz   udf: fix coding s...
1253
1254
  		if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize -
  						sizeof(struct fileEntry))) {
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1255
1256
1257
  			make_bad_inode(inode);
  			return;
  		}
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1258
  		memcpy(iinfo->i_ext.i_data,
c0b344385   Marcin Slusarz   udf: remove UDF_I...
1259
  		       bh->b_data + sizeof(struct fileEntry),
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1260
  		       inode->i_sb->s_blocksize - sizeof(struct fileEntry));
5e0f00173   Marcin Slusarz   udf: convert byte...
1261
  	} else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) {
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1262
1263
1264
  		iinfo->i_efe = 0;
  		iinfo->i_use = 1;
  		iinfo->i_lenAlloc = le32_to_cpu(
4b11111ab   Marcin Slusarz   udf: fix coding s...
1265
1266
1267
1268
  				((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...
1269
1270
1271
  			make_bad_inode(inode);
  			return;
  		}
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1272
  		memcpy(iinfo->i_ext.i_data,
4b11111ab   Marcin Slusarz   udf: fix coding s...
1273
1274
1275
  		       bh->b_data + sizeof(struct unallocSpaceEntry),
  		       inode->i_sb->s_blocksize -
  					sizeof(struct unallocSpaceEntry));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1276
1277
  		return;
  	}
c03cad241   Jan Kara   udf: Protect defa...
1278
  	read_lock(&sbi->s_cred_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1279
  	inode->i_uid = le32_to_cpu(fe->uid);
ca76d2d80   Cyrill Gorcunov   UDF: fix UID and ...
1280
1281
1282
  	if (inode->i_uid == -1 ||
  	    UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) ||
  	    UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_SET))
4d6660eb3   Phillip Susi   [PATCH] udf: fix ...
1283
  		inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1284
1285
  
  	inode->i_gid = le32_to_cpu(fe->gid);
ca76d2d80   Cyrill Gorcunov   UDF: fix UID and ...
1286
1287
1288
  	if (inode->i_gid == -1 ||
  	    UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_IGNORE) ||
  	    UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET))
4d6660eb3   Phillip Susi   [PATCH] udf: fix ...
1289
  		inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1290

7ac9bcd5d   Marcin Slusarz   udf: implement mo...
1291
  	if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY &&
87bc730c0   Marcin Slusarz   udf: fix default ...
1292
  			sbi->s_fmode != UDF_INVALID_MODE)
7ac9bcd5d   Marcin Slusarz   udf: implement mo...
1293
1294
  		inode->i_mode = sbi->s_fmode;
  	else if (fe->icbTag.fileType == ICBTAG_FILE_TYPE_DIRECTORY &&
87bc730c0   Marcin Slusarz   udf: fix default ...
1295
  			sbi->s_dmode != UDF_INVALID_MODE)
7ac9bcd5d   Marcin Slusarz   udf: implement mo...
1296
1297
1298
1299
  		inode->i_mode = sbi->s_dmode;
  	else
  		inode->i_mode = udf_convert_permissions(fe);
  	inode->i_mode &= ~sbi->s_umask;
c03cad241   Jan Kara   udf: Protect defa...
1300
  	read_unlock(&sbi->s_cred_lock);
bfe868486   Miklos Szeredi   filesystems: add ...
1301
1302
1303
1304
  	link_count = le16_to_cpu(fe->fileLinkCount);
  	if (!link_count)
  		link_count = 1;
  	set_nlink(inode, link_count);
c03cad241   Jan Kara   udf: Protect defa...
1305
1306
1307
  
  	inode->i_size = le64_to_cpu(fe->informationLength);
  	iinfo->i_lenExtents = inode->i_size;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1308

48d6d8ff7   Marcin Slusarz   udf: cache struct...
1309
  	if (iinfo->i_efe == 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1310
  		inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
28de7948a   Cyrill Gorcunov   UDF: coding style...
1311
  			(inode->i_sb->s_blocksize_bits - 9);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1312

56774805d   Marcin Slusarz   udf: convert udf_...
1313
  		if (!udf_disk_stamp_to_time(&inode->i_atime, fe->accessTime))
cbf5676a0   marcin.slusarz@gmail.com   udf: convert udf_...
1314
  			inode->i_atime = sbi->s_record_time;
56774805d   Marcin Slusarz   udf: convert udf_...
1315
1316
  		if (!udf_disk_stamp_to_time(&inode->i_mtime,
  					    fe->modificationTime))
cbf5676a0   marcin.slusarz@gmail.com   udf: convert udf_...
1317
  			inode->i_mtime = sbi->s_record_time;
56774805d   Marcin Slusarz   udf: convert udf_...
1318
  		if (!udf_disk_stamp_to_time(&inode->i_ctime, fe->attrTime))
cbf5676a0   marcin.slusarz@gmail.com   udf: convert udf_...
1319
  			inode->i_ctime = sbi->s_record_time;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1320

48d6d8ff7   Marcin Slusarz   udf: cache struct...
1321
1322
1323
1324
  		iinfo->i_unique = le64_to_cpu(fe->uniqueID);
  		iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr);
  		iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs);
  		offset = sizeof(struct fileEntry) + iinfo->i_lenEAttr;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1325
  	} else {
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1326
  		inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1327
  		    (inode->i_sb->s_blocksize_bits - 9);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1328

56774805d   Marcin Slusarz   udf: convert udf_...
1329
  		if (!udf_disk_stamp_to_time(&inode->i_atime, efe->accessTime))
cbf5676a0   marcin.slusarz@gmail.com   udf: convert udf_...
1330
  			inode->i_atime = sbi->s_record_time;
56774805d   Marcin Slusarz   udf: convert udf_...
1331
1332
  		if (!udf_disk_stamp_to_time(&inode->i_mtime,
  					    efe->modificationTime))
cbf5676a0   marcin.slusarz@gmail.com   udf: convert udf_...
1333
  			inode->i_mtime = sbi->s_record_time;
56774805d   Marcin Slusarz   udf: convert udf_...
1334
  		if (!udf_disk_stamp_to_time(&iinfo->i_crtime, efe->createTime))
cbf5676a0   marcin.slusarz@gmail.com   udf: convert udf_...
1335
  			iinfo->i_crtime = sbi->s_record_time;
56774805d   Marcin Slusarz   udf: convert udf_...
1336
  		if (!udf_disk_stamp_to_time(&inode->i_ctime, efe->attrTime))
cbf5676a0   marcin.slusarz@gmail.com   udf: convert udf_...
1337
  			inode->i_ctime = sbi->s_record_time;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1338

48d6d8ff7   Marcin Slusarz   udf: cache struct...
1339
1340
1341
  		iinfo->i_unique = le64_to_cpu(efe->uniqueID);
  		iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr);
  		iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs);
4b11111ab   Marcin Slusarz   udf: fix coding s...
1342
  		offset = sizeof(struct extendedFileEntry) +
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1343
  							iinfo->i_lenEAttr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1344
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1345
1346
  	switch (fe->icbTag.fileType) {
  	case ICBTAG_FILE_TYPE_DIRECTORY:
28de7948a   Cyrill Gorcunov   UDF: coding style...
1347
1348
1349
1350
1351
  		inode->i_op = &udf_dir_inode_operations;
  		inode->i_fop = &udf_dir_operations;
  		inode->i_mode |= S_IFDIR;
  		inc_nlink(inode);
  		break;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1352
1353
1354
  	case ICBTAG_FILE_TYPE_REALTIME:
  	case ICBTAG_FILE_TYPE_REGULAR:
  	case ICBTAG_FILE_TYPE_UNDEF:
742e1795e   Jan Kara   udf: Allow loadin...
1355
  	case ICBTAG_FILE_TYPE_VAT20:
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1356
  		if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
28de7948a   Cyrill Gorcunov   UDF: coding style...
1357
1358
1359
1360
1361
1362
1363
  			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...
1364
  	case ICBTAG_FILE_TYPE_BLOCK:
28de7948a   Cyrill Gorcunov   UDF: coding style...
1365
1366
  		inode->i_mode |= S_IFBLK;
  		break;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1367
  	case ICBTAG_FILE_TYPE_CHAR:
28de7948a   Cyrill Gorcunov   UDF: coding style...
1368
1369
  		inode->i_mode |= S_IFCHR;
  		break;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1370
  	case ICBTAG_FILE_TYPE_FIFO:
28de7948a   Cyrill Gorcunov   UDF: coding style...
1371
1372
  		init_special_inode(inode, inode->i_mode | S_IFIFO, 0);
  		break;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1373
  	case ICBTAG_FILE_TYPE_SOCKET:
28de7948a   Cyrill Gorcunov   UDF: coding style...
1374
1375
  		init_special_inode(inode, inode->i_mode | S_IFSOCK, 0);
  		break;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1376
  	case ICBTAG_FILE_TYPE_SYMLINK:
28de7948a   Cyrill Gorcunov   UDF: coding style...
1377
  		inode->i_data.a_ops = &udf_symlink_aops;
c15d0fc0f   Dmitry Monakhov   udf: add speciffi...
1378
  		inode->i_op = &udf_symlink_inode_operations;
28de7948a   Cyrill Gorcunov   UDF: coding style...
1379
1380
  		inode->i_mode = S_IFLNK | S_IRWXUGO;
  		break;
bfb257a59   Jan Kara   udf: Add read-onl...
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
  	case ICBTAG_FILE_TYPE_MAIN:
  		udf_debug("METADATA FILE-----
  ");
  		break;
  	case ICBTAG_FILE_TYPE_MIRROR:
  		udf_debug("METADATA MIRROR FILE-----
  ");
  		break;
  	case ICBTAG_FILE_TYPE_BITMAP:
  		udf_debug("METADATA BITMAP FILE-----
  ");
  		break;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1393
  	default:
78ace70c4   Joe Perches   udf: Convert prin...
1394
1395
1396
  		udf_err(inode->i_sb, "(ino %ld) failed unknown file type=%d
  ",
  			inode->i_ino, fe->icbTag.fileType);
28de7948a   Cyrill Gorcunov   UDF: coding style...
1397
1398
  		make_bad_inode(inode);
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1399
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1400
  	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
4b11111ab   Marcin Slusarz   udf: fix coding s...
1401
1402
  		struct deviceSpec *dsea =
  			(struct deviceSpec *)udf_get_extendedattr(inode, 12, 1);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1403
1404
  		if (dsea) {
  			init_special_inode(inode, inode->i_mode,
4b11111ab   Marcin Slusarz   udf: fix coding s...
1405
1406
  				MKDEV(le32_to_cpu(dsea->majorDeviceIdent),
  				      le32_to_cpu(dsea->minorDeviceIdent)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1407
  			/* Developer ID ??? */
4b11111ab   Marcin Slusarz   udf: fix coding s...
1408
  		} else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1409
  			make_bad_inode(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1410
1411
  	}
  }
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1412
1413
  static int udf_alloc_i_data(struct inode *inode, size_t size)
  {
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1414
1415
  	struct udf_inode_info *iinfo = UDF_I(inode);
  	iinfo->i_ext.i_data = kmalloc(size, GFP_KERNEL);
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1416

48d6d8ff7   Marcin Slusarz   udf: cache struct...
1417
  	if (!iinfo->i_ext.i_data) {
78ace70c4   Joe Perches   udf: Convert prin...
1418
1419
1420
  		udf_err(inode->i_sb, "(ino %ld) no free memory
  ",
  			inode->i_ino);
647bd61a5   Cyrill Gorcunov   UDF: check for al...
1421
1422
1423
1424
1425
  		return -ENOMEM;
  	}
  
  	return 0;
  }
faa17292f   Al Viro   udf: propagate um...
1426
  static umode_t udf_convert_permissions(struct fileEntry *fe)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1427
  {
faa17292f   Al Viro   udf: propagate um...
1428
  	umode_t mode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1429
1430
1431
1432
1433
  	uint32_t permissions;
  	uint32_t flags;
  
  	permissions = le32_to_cpu(fe->permissions);
  	flags = le16_to_cpu(fe->icbTag.flags);
4b11111ab   Marcin Slusarz   udf: fix coding s...
1434
1435
1436
1437
1438
1439
  	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
1440
1441
1442
  
  	return mode;
  }
a9185b41a   Christoph Hellwig   pass writeback_co...
1443
  int udf_write_inode(struct inode *inode, struct writeback_control *wbc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1444
  {
49521de11   Jan Kara   udf: Remove BKL f...
1445
  	return udf_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1446
  }
49521de11   Jan Kara   udf: Remove BKL f...
1447
  static int udf_sync_inode(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1448
1449
1450
  {
  	return udf_update_inode(inode, 1);
  }
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1451
  static int udf_update_inode(struct inode *inode, int do_sync)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1452
1453
1454
1455
1456
1457
1458
  {
  	struct buffer_head *bh = NULL;
  	struct fileEntry *fe;
  	struct extendedFileEntry *efe;
  	uint32_t udfperms;
  	uint16_t icbflags;
  	uint16_t crclen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1459
  	int err = 0;
6c79e987d   Marcin Slusarz   udf: remove some ...
1460
  	struct udf_sb_info *sbi = UDF_SB(inode->i_sb);
4b11111ab   Marcin Slusarz   udf: fix coding s...
1461
  	unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1462
  	struct udf_inode_info *iinfo = UDF_I(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1463

5833ded9b   Jan Kara   udf: Do not read ...
1464
1465
  	bh = udf_tgetblk(inode->i_sb,
  			udf_get_lb_pblock(inode->i_sb, &iinfo->i_location, 0));
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1466
  	if (!bh) {
aae917cd1   Jan Kara   udf: Fix unalloc ...
1467
1468
1469
  		udf_debug("getblk failure
  ");
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1470
  	}
aae917cd1   Jan Kara   udf: Fix unalloc ...
1471
1472
  	lock_buffer(bh);
  	memset(bh->b_data, 0, inode->i_sb->s_blocksize);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1473
1474
  	fe = (struct fileEntry *)bh->b_data;
  	efe = (struct extendedFileEntry *)bh->b_data;
aae917cd1   Jan Kara   udf: Fix unalloc ...
1475
  	if (iinfo->i_use) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1476
  		struct unallocSpaceEntry *use =
28de7948a   Cyrill Gorcunov   UDF: coding style...
1477
  			(struct unallocSpaceEntry *)bh->b_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1478

48d6d8ff7   Marcin Slusarz   udf: cache struct...
1479
  		use->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc);
4b11111ab   Marcin Slusarz   udf: fix coding s...
1480
  		memcpy(bh->b_data + sizeof(struct unallocSpaceEntry),
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1481
  		       iinfo->i_ext.i_data, inode->i_sb->s_blocksize -
4b11111ab   Marcin Slusarz   udf: fix coding s...
1482
  					sizeof(struct unallocSpaceEntry));
aae917cd1   Jan Kara   udf: Fix unalloc ...
1483
1484
1485
  		use->descTag.tagIdent = cpu_to_le16(TAG_IDENT_USE);
  		use->descTag.tagLocation =
  				cpu_to_le32(iinfo->i_location.logicalBlockNum);
4b11111ab   Marcin Slusarz   udf: fix coding s...
1486
  		crclen = sizeof(struct unallocSpaceEntry) +
5ca4e4be8   Pekka Enberg   Remove struct typ...
1487
  				iinfo->i_lenAlloc - sizeof(struct tag);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1488
  		use->descTag.descCRCLength = cpu_to_le16(crclen);
f845fced9   Bob Copeland   udf: use crc_itu_...
1489
  		use->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)use +
5ca4e4be8   Pekka Enberg   Remove struct typ...
1490
  							   sizeof(struct tag),
f845fced9   Bob Copeland   udf: use crc_itu_...
1491
  							   crclen));
3f2587bb2   Marcin Slusarz   udf: create commo...
1492
  		use->descTag.tagChecksum = udf_tag_checksum(&use->descTag);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1493

aae917cd1   Jan Kara   udf: Fix unalloc ...
1494
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1495
  	}
4d6660eb3   Phillip Susi   [PATCH] udf: fix ...
1496
1497
  	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET))
  		fe->uid = cpu_to_le32(-1);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1498
1499
  	else
  		fe->uid = cpu_to_le32(inode->i_uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1500

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

4b11111ab   Marcin Slusarz   udf: fix coding s...
1506
1507
1508
  	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
1509

4b11111ab   Marcin Slusarz   udf: fix coding s...
1510
1511
1512
1513
  	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
1514
1515
1516
1517
1518
1519
1520
1521
  	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...
1522
  	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
5ca4e4be8   Pekka Enberg   Remove struct typ...
1523
  		struct regid *eid;
28de7948a   Cyrill Gorcunov   UDF: coding style...
1524
1525
  		struct deviceSpec *dsea =
  			(struct deviceSpec *)udf_get_extendedattr(inode, 12, 1);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1526
  		if (!dsea) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1527
  			dsea = (struct deviceSpec *)
28de7948a   Cyrill Gorcunov   UDF: coding style...
1528
1529
  				udf_add_extendedattr(inode,
  						     sizeof(struct deviceSpec) +
5ca4e4be8   Pekka Enberg   Remove struct typ...
1530
  						     sizeof(struct regid), 12, 0x3);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1531
1532
  			dsea->attrType = cpu_to_le32(12);
  			dsea->attrSubtype = 1;
4b11111ab   Marcin Slusarz   udf: fix coding s...
1533
1534
  			dsea->attrLength = cpu_to_le32(
  						sizeof(struct deviceSpec) +
5ca4e4be8   Pekka Enberg   Remove struct typ...
1535
1536
  						sizeof(struct regid));
  			dsea->impUseLength = cpu_to_le32(sizeof(struct regid));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1537
  		}
5ca4e4be8   Pekka Enberg   Remove struct typ...
1538
1539
  		eid = (struct regid *)dsea->impUse;
  		memset(eid, 0, sizeof(struct regid));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1540
1541
1542
1543
1544
1545
  		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));
  	}
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1546
  	if (iinfo->i_efe == 0) {
c0b344385   Marcin Slusarz   udf: remove UDF_I...
1547
  		memcpy(bh->b_data + sizeof(struct fileEntry),
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1548
  		       iinfo->i_ext.i_data,
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1549
  		       inode->i_sb->s_blocksize - sizeof(struct fileEntry));
28de7948a   Cyrill Gorcunov   UDF: coding style...
1550
  		fe->logicalBlocksRecorded = cpu_to_le64(
4b11111ab   Marcin Slusarz   udf: fix coding s...
1551
1552
  			(inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >>
  			(blocksize_bits - 9));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1553

56774805d   Marcin Slusarz   udf: convert udf_...
1554
1555
1556
  		udf_time_to_disk_stamp(&fe->accessTime, inode->i_atime);
  		udf_time_to_disk_stamp(&fe->modificationTime, inode->i_mtime);
  		udf_time_to_disk_stamp(&fe->attrTime, inode->i_ctime);
5ca4e4be8   Pekka Enberg   Remove struct typ...
1557
  		memset(&(fe->impIdent), 0, sizeof(struct regid));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1558
1559
1560
  		strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);
  		fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
  		fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1561
1562
1563
  		fe->uniqueID = cpu_to_le64(iinfo->i_unique);
  		fe->lengthExtendedAttr = cpu_to_le32(iinfo->i_lenEAttr);
  		fe->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1564
1565
  		fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE);
  		crclen = sizeof(struct fileEntry);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1566
  	} else {
4b11111ab   Marcin Slusarz   udf: fix coding s...
1567
  		memcpy(bh->b_data + sizeof(struct extendedFileEntry),
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1568
  		       iinfo->i_ext.i_data,
4b11111ab   Marcin Slusarz   udf: fix coding s...
1569
1570
  		       inode->i_sb->s_blocksize -
  					sizeof(struct extendedFileEntry));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1571
  		efe->objectSize = cpu_to_le64(inode->i_size);
28de7948a   Cyrill Gorcunov   UDF: coding style...
1572
  		efe->logicalBlocksRecorded = cpu_to_le64(
4b11111ab   Marcin Slusarz   udf: fix coding s...
1573
1574
  			(inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >>
  			(blocksize_bits - 9));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1575

48d6d8ff7   Marcin Slusarz   udf: cache struct...
1576
1577
1578
1579
  		if (iinfo->i_crtime.tv_sec > inode->i_atime.tv_sec ||
  		    (iinfo->i_crtime.tv_sec == inode->i_atime.tv_sec &&
  		     iinfo->i_crtime.tv_nsec > inode->i_atime.tv_nsec))
  			iinfo->i_crtime = inode->i_atime;
4b11111ab   Marcin Slusarz   udf: fix coding s...
1580

48d6d8ff7   Marcin Slusarz   udf: cache struct...
1581
1582
1583
1584
  		if (iinfo->i_crtime.tv_sec > inode->i_mtime.tv_sec ||
  		    (iinfo->i_crtime.tv_sec == inode->i_mtime.tv_sec &&
  		     iinfo->i_crtime.tv_nsec > inode->i_mtime.tv_nsec))
  			iinfo->i_crtime = inode->i_mtime;
4b11111ab   Marcin Slusarz   udf: fix coding s...
1585

48d6d8ff7   Marcin Slusarz   udf: cache struct...
1586
1587
1588
1589
  		if (iinfo->i_crtime.tv_sec > inode->i_ctime.tv_sec ||
  		    (iinfo->i_crtime.tv_sec == inode->i_ctime.tv_sec &&
  		     iinfo->i_crtime.tv_nsec > inode->i_ctime.tv_nsec))
  			iinfo->i_crtime = inode->i_ctime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1590

56774805d   Marcin Slusarz   udf: convert udf_...
1591
1592
1593
1594
  		udf_time_to_disk_stamp(&efe->accessTime, inode->i_atime);
  		udf_time_to_disk_stamp(&efe->modificationTime, inode->i_mtime);
  		udf_time_to_disk_stamp(&efe->createTime, iinfo->i_crtime);
  		udf_time_to_disk_stamp(&efe->attrTime, inode->i_ctime);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1595

5ca4e4be8   Pekka Enberg   Remove struct typ...
1596
  		memset(&(efe->impIdent), 0, sizeof(struct regid));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1597
1598
1599
  		strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER);
  		efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
  		efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1600
1601
1602
  		efe->uniqueID = cpu_to_le64(iinfo->i_unique);
  		efe->lengthExtendedAttr = cpu_to_le32(iinfo->i_lenEAttr);
  		efe->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1603
1604
1605
  		efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE);
  		crclen = sizeof(struct extendedFileEntry);
  	}
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1606
  	if (iinfo->i_strat4096) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1607
1608
1609
  		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...
1610
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
  		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;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1629
  	icbflags =	iinfo->i_alloc_type |
28de7948a   Cyrill Gorcunov   UDF: coding style...
1630
1631
1632
1633
1634
1635
  			((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
1636
1637
  
  	fe->icbTag.flags = cpu_to_le16(icbflags);
6c79e987d   Marcin Slusarz   udf: remove some ...
1638
  	if (sbi->s_udfrev >= 0x0200)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1639
1640
1641
  		fe->descTag.descVersion = cpu_to_le16(3);
  	else
  		fe->descTag.descVersion = cpu_to_le16(2);
6c79e987d   Marcin Slusarz   udf: remove some ...
1642
  	fe->descTag.tagSerialNum = cpu_to_le16(sbi->s_serial_number);
4b11111ab   Marcin Slusarz   udf: fix coding s...
1643
  	fe->descTag.tagLocation = cpu_to_le32(
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1644
  					iinfo->i_location.logicalBlockNum);
aae917cd1   Jan Kara   udf: Fix unalloc ...
1645
  	crclen += iinfo->i_lenEAttr + iinfo->i_lenAlloc - sizeof(struct tag);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1646
  	fe->descTag.descCRCLength = cpu_to_le16(crclen);
5ca4e4be8   Pekka Enberg   Remove struct typ...
1647
  	fe->descTag.descCRC = cpu_to_le16(crc_itu_t(0, (char *)fe + sizeof(struct tag),
f845fced9   Bob Copeland   udf: use crc_itu_...
1648
  						  crclen));
3f2587bb2   Marcin Slusarz   udf: create commo...
1649
  	fe->descTag.tagChecksum = udf_tag_checksum(&fe->descTag);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1650

aae917cd1   Jan Kara   udf: Fix unalloc ...
1651
  out:
5833ded9b   Jan Kara   udf: Do not read ...
1652
  	set_buffer_uptodate(bh);
aae917cd1   Jan Kara   udf: Fix unalloc ...
1653
  	unlock_buffer(bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1654
1655
  	/* write the data blocks */
  	mark_buffer_dirty(bh);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1656
  	if (do_sync) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1657
  		sync_dirty_buffer(bh);
aae917cd1   Jan Kara   udf: Fix unalloc ...
1658
  		if (buffer_write_io_error(bh)) {
78ace70c4   Joe Perches   udf: Convert prin...
1659
1660
1661
  			udf_warn(inode->i_sb, "IO error syncing udf inode [%08lx]
  ",
  				 inode->i_ino);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1662
1663
1664
  			err = -EIO;
  		}
  	}
3bf25cb40   Jan Kara   udf: use get_bh()
1665
  	brelse(bh);
28de7948a   Cyrill Gorcunov   UDF: coding style...
1666

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1667
1668
  	return err;
  }
97e961fdb   Pekka Enberg   Fix the udf code ...
1669
  struct inode *udf_iget(struct super_block *sb, struct kernel_lb_addr *ino)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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) {
97e961fdb   Pekka Enberg   Fix the udf code ...
1678
  		memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1679
1680
1681
1682
1683
1684
  		__udf_read_inode(inode);
  		unlock_new_inode(inode);
  	}
  
  	if (is_bad_inode(inode))
  		goto out_iput;
97e961fdb   Pekka Enberg   Fix the udf code ...
1685
1686
  	if (ino->logicalBlockNum >= UDF_SB(sb)->
  			s_partmaps[ino->partitionReferenceNum].s_partition_len) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1687
1688
  		udf_debug("block=%d, partition=%d out of range
  ",
97e961fdb   Pekka Enberg   Fix the udf code ...
1689
  			  ino->logicalBlockNum, ino->partitionReferenceNum);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1690
1691
1692
1693
1694
  		make_bad_inode(inode);
  		goto out_iput;
  	}
  
  	return inode;
28de7948a   Cyrill Gorcunov   UDF: coding style...
1695
   out_iput:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1696
1697
1698
  	iput(inode);
  	return NULL;
  }
7e49b6f24   Jan Kara   udf: Convert UDF ...
1699
1700
  int udf_add_aext(struct inode *inode, struct extent_position *epos,
  		 struct kernel_lb_addr *eloc, uint32_t elen, int inc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1701
1702
  {
  	int adsize;
5ca4e4be8   Pekka Enberg   Remove struct typ...
1703
1704
  	struct short_ad *sad = NULL;
  	struct long_ad *lad = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1705
  	struct allocExtDesc *aed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1706
  	uint8_t *ptr;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1707
  	struct udf_inode_info *iinfo = UDF_I(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1708

ff116fc8d   Jan Kara   UDF: introduce st...
1709
  	if (!epos->bh)
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1710
  		ptr = iinfo->i_ext.i_data + epos->offset -
4b11111ab   Marcin Slusarz   udf: fix coding s...
1711
  			udf_file_entry_alloc_offset(inode) +
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1712
  			iinfo->i_lenEAttr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1713
  	else
ff116fc8d   Jan Kara   UDF: introduce st...
1714
  		ptr = epos->bh->b_data + epos->offset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1715

48d6d8ff7   Marcin Slusarz   udf: cache struct...
1716
  	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
5ca4e4be8   Pekka Enberg   Remove struct typ...
1717
  		adsize = sizeof(struct short_ad);
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1718
  	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
5ca4e4be8   Pekka Enberg   Remove struct typ...
1719
  		adsize = sizeof(struct long_ad);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1720
  	else
7e49b6f24   Jan Kara   udf: Convert UDF ...
1721
  		return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1722

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1723
  	if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) {
391e8bbd3   Al Viro   sanitize const/si...
1724
  		unsigned char *sptr, *dptr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1725
1726
  		struct buffer_head *nbh;
  		int err, loffset;
5ca4e4be8   Pekka Enberg   Remove struct typ...
1727
  		struct kernel_lb_addr obloc = epos->block;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1728

4b11111ab   Marcin Slusarz   udf: fix coding s...
1729
1730
1731
1732
  		epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL,
  						obloc.partitionReferenceNum,
  						obloc.logicalBlockNum, &err);
  		if (!epos->block.logicalBlockNum)
7e49b6f24   Jan Kara   udf: Convert UDF ...
1733
  			return -ENOSPC;
4b11111ab   Marcin Slusarz   udf: fix coding s...
1734
  		nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
97e961fdb   Pekka Enberg   Fix the udf code ...
1735
  								 &epos->block,
4b11111ab   Marcin Slusarz   udf: fix coding s...
1736
1737
  								 0));
  		if (!nbh)
7e49b6f24   Jan Kara   udf: Convert UDF ...
1738
  			return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1739
1740
1741
1742
1743
1744
1745
1746
  		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))
4b11111ab   Marcin Slusarz   udf: fix coding s...
1747
1748
  			aed->previousAllocExtLocation =
  					cpu_to_le32(obloc.logicalBlockNum);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1749
  		if (epos->offset + adsize > inode->i_sb->s_blocksize) {
ff116fc8d   Jan Kara   UDF: introduce st...
1750
  			loffset = epos->offset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1751
1752
1753
1754
  			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...
1755
  			epos->offset = sizeof(struct allocExtDesc) + adsize;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1756
  		} else {
ff116fc8d   Jan Kara   UDF: introduce st...
1757
  			loffset = epos->offset + adsize;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1758
1759
  			aed->lengthAllocDescs = cpu_to_le32(0);
  			sptr = ptr;
ff116fc8d   Jan Kara   UDF: introduce st...
1760
  			epos->offset = sizeof(struct allocExtDesc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1761

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1762
  			if (epos->bh) {
ff116fc8d   Jan Kara   UDF: introduce st...
1763
  				aed = (struct allocExtDesc *)epos->bh->b_data;
c2104fda5   marcin.slusarz@gmail.com   udf: replace all ...
1764
  				le32_add_cpu(&aed->lengthAllocDescs, adsize);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1765
  			} else {
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1766
  				iinfo->i_lenAlloc += adsize;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1767
1768
1769
  				mark_inode_dirty(inode);
  			}
  		}
6c79e987d   Marcin Slusarz   udf: remove some ...
1770
  		if (UDF_SB(inode->i_sb)->s_udfrev >= 0x0200)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1771
  			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
5ca4e4be8   Pekka Enberg   Remove struct typ...
1772
  				    epos->block.logicalBlockNum, sizeof(struct tag));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1773
1774
  		else
  			udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
5ca4e4be8   Pekka Enberg   Remove struct typ...
1775
  				    epos->block.logicalBlockNum, sizeof(struct tag));
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1776
  		switch (iinfo->i_alloc_type) {
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1777
  		case ICBTAG_FLAG_AD_SHORT:
5ca4e4be8   Pekka Enberg   Remove struct typ...
1778
  			sad = (struct short_ad *)sptr;
28de7948a   Cyrill Gorcunov   UDF: coding style...
1779
1780
  			sad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
  						     inode->i_sb->s_blocksize);
4b11111ab   Marcin Slusarz   udf: fix coding s...
1781
1782
  			sad->extPosition =
  				cpu_to_le32(epos->block.logicalBlockNum);
28de7948a   Cyrill Gorcunov   UDF: coding style...
1783
  			break;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1784
  		case ICBTAG_FLAG_AD_LONG:
5ca4e4be8   Pekka Enberg   Remove struct typ...
1785
  			lad = (struct long_ad *)sptr;
28de7948a   Cyrill Gorcunov   UDF: coding style...
1786
1787
1788
1789
1790
  			lad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
  						     inode->i_sb->s_blocksize);
  			lad->extLocation = cpu_to_lelb(epos->block);
  			memset(lad->impUse, 0x00, sizeof(lad->impUse));
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1791
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1792
  		if (epos->bh) {
28de7948a   Cyrill Gorcunov   UDF: coding style...
1793
  			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
6c79e987d   Marcin Slusarz   udf: remove some ...
1794
  			    UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
ff116fc8d   Jan Kara   UDF: introduce st...
1795
  				udf_update_tag(epos->bh->b_data, loffset);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1796
  			else
4b11111ab   Marcin Slusarz   udf: fix coding s...
1797
1798
  				udf_update_tag(epos->bh->b_data,
  						sizeof(struct allocExtDesc));
ff116fc8d   Jan Kara   UDF: introduce st...
1799
  			mark_buffer_dirty_inode(epos->bh, inode);
3bf25cb40   Jan Kara   udf: use get_bh()
1800
  			brelse(epos->bh);
28de7948a   Cyrill Gorcunov   UDF: coding style...
1801
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1802
  			mark_inode_dirty(inode);
28de7948a   Cyrill Gorcunov   UDF: coding style...
1803
  		}
ff116fc8d   Jan Kara   UDF: introduce st...
1804
  		epos->bh = nbh;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1805
  	}
7e49b6f24   Jan Kara   udf: Convert UDF ...
1806
  	udf_write_aext(inode, epos, eloc, elen, inc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1807

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1808
  	if (!epos->bh) {
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1809
  		iinfo->i_lenAlloc += adsize;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1810
  		mark_inode_dirty(inode);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1811
  	} else {
ff116fc8d   Jan Kara   UDF: introduce st...
1812
  		aed = (struct allocExtDesc *)epos->bh->b_data;
c2104fda5   marcin.slusarz@gmail.com   udf: replace all ...
1813
  		le32_add_cpu(&aed->lengthAllocDescs, adsize);
4b11111ab   Marcin Slusarz   udf: fix coding s...
1814
1815
1816
1817
  		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
  				UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
  			udf_update_tag(epos->bh->b_data,
  					epos->offset + (inc ? 0 : adsize));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1818
  		else
4b11111ab   Marcin Slusarz   udf: fix coding s...
1819
1820
  			udf_update_tag(epos->bh->b_data,
  					sizeof(struct allocExtDesc));
ff116fc8d   Jan Kara   UDF: introduce st...
1821
  		mark_buffer_dirty_inode(epos->bh, inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1822
  	}
7e49b6f24   Jan Kara   udf: Convert UDF ...
1823
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1824
  }
7e49b6f24   Jan Kara   udf: Convert UDF ...
1825
1826
  void udf_write_aext(struct inode *inode, struct extent_position *epos,
  		    struct kernel_lb_addr *eloc, uint32_t elen, int inc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1827
1828
1829
  {
  	int adsize;
  	uint8_t *ptr;
5ca4e4be8   Pekka Enberg   Remove struct typ...
1830
1831
  	struct short_ad *sad;
  	struct long_ad *lad;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1832
  	struct udf_inode_info *iinfo = UDF_I(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1833

ff116fc8d   Jan Kara   UDF: introduce st...
1834
  	if (!epos->bh)
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1835
  		ptr = iinfo->i_ext.i_data + epos->offset -
4b11111ab   Marcin Slusarz   udf: fix coding s...
1836
  			udf_file_entry_alloc_offset(inode) +
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1837
  			iinfo->i_lenEAttr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1838
  	else
ff116fc8d   Jan Kara   UDF: introduce st...
1839
  		ptr = epos->bh->b_data + epos->offset;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1840

48d6d8ff7   Marcin Slusarz   udf: cache struct...
1841
  	switch (iinfo->i_alloc_type) {
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1842
  	case ICBTAG_FLAG_AD_SHORT:
5ca4e4be8   Pekka Enberg   Remove struct typ...
1843
  		sad = (struct short_ad *)ptr;
28de7948a   Cyrill Gorcunov   UDF: coding style...
1844
  		sad->extLength = cpu_to_le32(elen);
97e961fdb   Pekka Enberg   Fix the udf code ...
1845
  		sad->extPosition = cpu_to_le32(eloc->logicalBlockNum);
5ca4e4be8   Pekka Enberg   Remove struct typ...
1846
  		adsize = sizeof(struct short_ad);
28de7948a   Cyrill Gorcunov   UDF: coding style...
1847
  		break;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1848
  	case ICBTAG_FLAG_AD_LONG:
5ca4e4be8   Pekka Enberg   Remove struct typ...
1849
  		lad = (struct long_ad *)ptr;
28de7948a   Cyrill Gorcunov   UDF: coding style...
1850
  		lad->extLength = cpu_to_le32(elen);
97e961fdb   Pekka Enberg   Fix the udf code ...
1851
  		lad->extLocation = cpu_to_lelb(*eloc);
28de7948a   Cyrill Gorcunov   UDF: coding style...
1852
  		memset(lad->impUse, 0x00, sizeof(lad->impUse));
5ca4e4be8   Pekka Enberg   Remove struct typ...
1853
  		adsize = sizeof(struct long_ad);
28de7948a   Cyrill Gorcunov   UDF: coding style...
1854
  		break;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1855
  	default:
7e49b6f24   Jan Kara   udf: Convert UDF ...
1856
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1857
  	}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1858
  	if (epos->bh) {
28de7948a   Cyrill Gorcunov   UDF: coding style...
1859
  		if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
6c79e987d   Marcin Slusarz   udf: remove some ...
1860
  		    UDF_SB(inode->i_sb)->s_udfrev >= 0x0201) {
4b11111ab   Marcin Slusarz   udf: fix coding s...
1861
1862
  			struct allocExtDesc *aed =
  				(struct allocExtDesc *)epos->bh->b_data;
ff116fc8d   Jan Kara   UDF: introduce st...
1863
  			udf_update_tag(epos->bh->b_data,
4b11111ab   Marcin Slusarz   udf: fix coding s...
1864
1865
  				       le32_to_cpu(aed->lengthAllocDescs) +
  				       sizeof(struct allocExtDesc));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1866
  		}
ff116fc8d   Jan Kara   UDF: introduce st...
1867
  		mark_buffer_dirty_inode(epos->bh, inode);
28de7948a   Cyrill Gorcunov   UDF: coding style...
1868
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1869
  		mark_inode_dirty(inode);
28de7948a   Cyrill Gorcunov   UDF: coding style...
1870
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1871
1872
  
  	if (inc)
ff116fc8d   Jan Kara   UDF: introduce st...
1873
  		epos->offset += adsize;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1874
  }
4b11111ab   Marcin Slusarz   udf: fix coding s...
1875
  int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
5ca4e4be8   Pekka Enberg   Remove struct typ...
1876
  		     struct kernel_lb_addr *eloc, uint32_t *elen, int inc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1877
1878
  {
  	int8_t etype;
ff116fc8d   Jan Kara   UDF: introduce st...
1879
  	while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) ==
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1880
  	       (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) {
4b11111ab   Marcin Slusarz   udf: fix coding s...
1881
  		int block;
ff116fc8d   Jan Kara   UDF: introduce st...
1882
1883
  		epos->block = *eloc;
  		epos->offset = sizeof(struct allocExtDesc);
3bf25cb40   Jan Kara   udf: use get_bh()
1884
  		brelse(epos->bh);
97e961fdb   Pekka Enberg   Fix the udf code ...
1885
  		block = udf_get_lb_pblock(inode->i_sb, &epos->block, 0);
4b11111ab   Marcin Slusarz   udf: fix coding s...
1886
1887
1888
1889
  		epos->bh = udf_tread(inode->i_sb, block);
  		if (!epos->bh) {
  			udf_debug("reading block %d failed!
  ", block);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1890
1891
1892
1893
1894
1895
  			return -1;
  		}
  	}
  
  	return etype;
  }
4b11111ab   Marcin Slusarz   udf: fix coding s...
1896
  int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
5ca4e4be8   Pekka Enberg   Remove struct typ...
1897
  			struct kernel_lb_addr *eloc, uint32_t *elen, int inc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1898
1899
1900
1901
  {
  	int alen;
  	int8_t etype;
  	uint8_t *ptr;
5ca4e4be8   Pekka Enberg   Remove struct typ...
1902
1903
  	struct short_ad *sad;
  	struct long_ad *lad;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1904
  	struct udf_inode_info *iinfo = UDF_I(inode);
28de7948a   Cyrill Gorcunov   UDF: coding style...
1905

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1906
  	if (!epos->bh) {
ff116fc8d   Jan Kara   UDF: introduce st...
1907
1908
  		if (!epos->offset)
  			epos->offset = udf_file_entry_alloc_offset(inode);
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1909
  		ptr = iinfo->i_ext.i_data + epos->offset -
4b11111ab   Marcin Slusarz   udf: fix coding s...
1910
  			udf_file_entry_alloc_offset(inode) +
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1911
  			iinfo->i_lenEAttr;
4b11111ab   Marcin Slusarz   udf: fix coding s...
1912
  		alen = udf_file_entry_alloc_offset(inode) +
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1913
  							iinfo->i_lenAlloc;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1914
  	} else {
ff116fc8d   Jan Kara   UDF: introduce st...
1915
1916
1917
  		if (!epos->offset)
  			epos->offset = sizeof(struct allocExtDesc);
  		ptr = epos->bh->b_data + epos->offset;
28de7948a   Cyrill Gorcunov   UDF: coding style...
1918
  		alen = sizeof(struct allocExtDesc) +
4b11111ab   Marcin Slusarz   udf: fix coding s...
1919
1920
  			le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->
  							lengthAllocDescs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1921
  	}
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1922
  	switch (iinfo->i_alloc_type) {
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1923
  	case ICBTAG_FLAG_AD_SHORT:
4b11111ab   Marcin Slusarz   udf: fix coding s...
1924
1925
  		sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc);
  		if (!sad)
28de7948a   Cyrill Gorcunov   UDF: coding style...
1926
1927
1928
  			return -1;
  		etype = le32_to_cpu(sad->extLength) >> 30;
  		eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
4b11111ab   Marcin Slusarz   udf: fix coding s...
1929
  		eloc->partitionReferenceNum =
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1930
  				iinfo->i_location.partitionReferenceNum;
28de7948a   Cyrill Gorcunov   UDF: coding style...
1931
1932
  		*elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK;
  		break;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1933
  	case ICBTAG_FLAG_AD_LONG:
4b11111ab   Marcin Slusarz   udf: fix coding s...
1934
1935
  		lad = udf_get_filelongad(ptr, alen, &epos->offset, inc);
  		if (!lad)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1936
  			return -1;
28de7948a   Cyrill Gorcunov   UDF: coding style...
1937
1938
1939
1940
1941
  		etype = le32_to_cpu(lad->extLength) >> 30;
  		*eloc = lelb_to_cpu(lad->extLocation);
  		*elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK;
  		break;
  	default:
a983f368f   Joe Perches   udf: Neaten udf_d...
1942
1943
  		udf_debug("alloc_type = %d unsupported
  ", iinfo->i_alloc_type);
28de7948a   Cyrill Gorcunov   UDF: coding style...
1944
  		return -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1945
1946
1947
1948
  	}
  
  	return etype;
  }
28de7948a   Cyrill Gorcunov   UDF: coding style...
1949
  static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos,
5ca4e4be8   Pekka Enberg   Remove struct typ...
1950
  			      struct kernel_lb_addr neloc, uint32_t nelen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1951
  {
5ca4e4be8   Pekka Enberg   Remove struct typ...
1952
  	struct kernel_lb_addr oeloc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1953
1954
  	uint32_t oelen;
  	int8_t etype;
ff116fc8d   Jan Kara   UDF: introduce st...
1955
  	if (epos.bh)
3bf25cb40   Jan Kara   udf: use get_bh()
1956
  		get_bh(epos.bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1957

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1958
  	while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1) {
97e961fdb   Pekka Enberg   Fix the udf code ...
1959
  		udf_write_aext(inode, &epos, &neloc, nelen, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1960
1961
1962
  		neloc = oeloc;
  		nelen = (etype << 30) | oelen;
  	}
97e961fdb   Pekka Enberg   Fix the udf code ...
1963
  	udf_add_aext(inode, &epos, &neloc, nelen, 1);
3bf25cb40   Jan Kara   udf: use get_bh()
1964
  	brelse(epos.bh);
28de7948a   Cyrill Gorcunov   UDF: coding style...
1965

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1966
1967
  	return (nelen >> 30);
  }
4b11111ab   Marcin Slusarz   udf: fix coding s...
1968
  int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
5ca4e4be8   Pekka Enberg   Remove struct typ...
1969
  		       struct kernel_lb_addr eloc, uint32_t elen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1970
  {
ff116fc8d   Jan Kara   UDF: introduce st...
1971
1972
  	struct extent_position oepos;
  	int adsize;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1973
1974
  	int8_t etype;
  	struct allocExtDesc *aed;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1975
  	struct udf_inode_info *iinfo;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1976

cb00ea352   Cyrill Gorcunov   UDF: coding style...
1977
  	if (epos.bh) {
3bf25cb40   Jan Kara   udf: use get_bh()
1978
1979
  		get_bh(epos.bh);
  		get_bh(epos.bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1980
  	}
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1981
1982
  	iinfo = UDF_I(inode);
  	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
5ca4e4be8   Pekka Enberg   Remove struct typ...
1983
  		adsize = sizeof(struct short_ad);
48d6d8ff7   Marcin Slusarz   udf: cache struct...
1984
  	else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
5ca4e4be8   Pekka Enberg   Remove struct typ...
1985
  		adsize = sizeof(struct long_ad);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1986
1987
  	else
  		adsize = 0;
ff116fc8d   Jan Kara   UDF: introduce st...
1988
1989
  	oepos = epos;
  	if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1990
  		return -1;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1991
  	while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) {
97e961fdb   Pekka Enberg   Fix the udf code ...
1992
  		udf_write_aext(inode, &oepos, &eloc, (etype << 30) | elen, 1);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
1993
  		if (oepos.bh != epos.bh) {
ff116fc8d   Jan Kara   UDF: introduce st...
1994
  			oepos.block = epos.block;
3bf25cb40   Jan Kara   udf: use get_bh()
1995
1996
  			brelse(oepos.bh);
  			get_bh(epos.bh);
ff116fc8d   Jan Kara   UDF: introduce st...
1997
1998
  			oepos.bh = epos.bh;
  			oepos.offset = epos.offset - adsize;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1999
2000
  		}
  	}
5ca4e4be8   Pekka Enberg   Remove struct typ...
2001
  	memset(&eloc, 0x00, sizeof(struct kernel_lb_addr));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2002
  	elen = 0;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2003
  	if (epos.bh != oepos.bh) {
97e961fdb   Pekka Enberg   Fix the udf code ...
2004
2005
2006
  		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...
2007
  		if (!oepos.bh) {
48d6d8ff7   Marcin Slusarz   udf: cache struct...
2008
  			iinfo->i_lenAlloc -= (adsize * 2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2009
  			mark_inode_dirty(inode);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2010
  		} else {
ff116fc8d   Jan Kara   UDF: introduce st...
2011
  			aed = (struct allocExtDesc *)oepos.bh->b_data;
c2104fda5   marcin.slusarz@gmail.com   udf: replace all ...
2012
  			le32_add_cpu(&aed->lengthAllocDescs, -(2 * adsize));
28de7948a   Cyrill Gorcunov   UDF: coding style...
2013
  			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
6c79e987d   Marcin Slusarz   udf: remove some ...
2014
  			    UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
4b11111ab   Marcin Slusarz   udf: fix coding s...
2015
2016
  				udf_update_tag(oepos.bh->b_data,
  						oepos.offset - (2 * adsize));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2017
  			else
4b11111ab   Marcin Slusarz   udf: fix coding s...
2018
2019
  				udf_update_tag(oepos.bh->b_data,
  						sizeof(struct allocExtDesc));
ff116fc8d   Jan Kara   UDF: introduce st...
2020
  			mark_buffer_dirty_inode(oepos.bh, inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2021
  		}
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2022
  	} else {
97e961fdb   Pekka Enberg   Fix the udf code ...
2023
  		udf_write_aext(inode, &oepos, &eloc, elen, 1);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2024
  		if (!oepos.bh) {
48d6d8ff7   Marcin Slusarz   udf: cache struct...
2025
  			iinfo->i_lenAlloc -= adsize;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2026
  			mark_inode_dirty(inode);
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2027
  		} else {
ff116fc8d   Jan Kara   UDF: introduce st...
2028
  			aed = (struct allocExtDesc *)oepos.bh->b_data;
c2104fda5   marcin.slusarz@gmail.com   udf: replace all ...
2029
  			le32_add_cpu(&aed->lengthAllocDescs, -adsize);
28de7948a   Cyrill Gorcunov   UDF: coding style...
2030
  			if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
6c79e987d   Marcin Slusarz   udf: remove some ...
2031
  			    UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
4b11111ab   Marcin Slusarz   udf: fix coding s...
2032
2033
  				udf_update_tag(oepos.bh->b_data,
  						epos.offset - adsize);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2034
  			else
4b11111ab   Marcin Slusarz   udf: fix coding s...
2035
2036
  				udf_update_tag(oepos.bh->b_data,
  						sizeof(struct allocExtDesc));
ff116fc8d   Jan Kara   UDF: introduce st...
2037
  			mark_buffer_dirty_inode(oepos.bh, inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2038
2039
  		}
  	}
647bd61a5   Cyrill Gorcunov   UDF: check for al...
2040

3bf25cb40   Jan Kara   udf: use get_bh()
2041
2042
  	brelse(epos.bh);
  	brelse(oepos.bh);
28de7948a   Cyrill Gorcunov   UDF: coding style...
2043

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2044
2045
  	return (elen >> 30);
  }
4b11111ab   Marcin Slusarz   udf: fix coding s...
2046
  int8_t inode_bmap(struct inode *inode, sector_t block,
5ca4e4be8   Pekka Enberg   Remove struct typ...
2047
  		  struct extent_position *pos, struct kernel_lb_addr *eloc,
4b11111ab   Marcin Slusarz   udf: fix coding s...
2048
  		  uint32_t *elen, sector_t *offset)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2049
  {
4b11111ab   Marcin Slusarz   udf: fix coding s...
2050
  	unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
cb00ea352   Cyrill Gorcunov   UDF: coding style...
2051
  	loff_t lbcount = 0, bcount =
4b11111ab   Marcin Slusarz   udf: fix coding s...
2052
  	    (loff_t) block << blocksize_bits;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2053
  	int8_t etype;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
2054
  	struct udf_inode_info *iinfo;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2055

48d6d8ff7   Marcin Slusarz   udf: cache struct...
2056
  	iinfo = UDF_I(inode);
ff116fc8d   Jan Kara   UDF: introduce st...
2057
  	pos->offset = 0;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
2058
  	pos->block = iinfo->i_location;
ff116fc8d   Jan Kara   UDF: introduce st...
2059
  	pos->bh = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2060
  	*elen = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2061

cb00ea352   Cyrill Gorcunov   UDF: coding style...
2062
  	do {
4b11111ab   Marcin Slusarz   udf: fix coding s...
2063
2064
2065
  		etype = udf_next_aext(inode, pos, eloc, elen, 1);
  		if (etype == -1) {
  			*offset = (bcount - lbcount) >> blocksize_bits;
48d6d8ff7   Marcin Slusarz   udf: cache struct...
2066
  			iinfo->i_lenExtents = lbcount;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2067
2068
2069
2070
  			return -1;
  		}
  		lbcount += *elen;
  	} while (lbcount <= bcount);
4b11111ab   Marcin Slusarz   udf: fix coding s...
2071
  	*offset = (bcount + *elen - lbcount) >> blocksize_bits;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2072
2073
2074
  
  	return etype;
  }
60448b1d6   Jan Kara   udf: use sector_t...
2075
  long udf_block_map(struct inode *inode, sector_t block)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2076
  {
5ca4e4be8   Pekka Enberg   Remove struct typ...
2077
  	struct kernel_lb_addr eloc;
ff116fc8d   Jan Kara   UDF: introduce st...
2078
  	uint32_t elen;
60448b1d6   Jan Kara   udf: use sector_t...
2079
  	sector_t offset;
28de7948a   Cyrill Gorcunov   UDF: coding style...
2080
  	struct extent_position epos = {};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2081
  	int ret;
4d0fb621d   Alessio Igor Bogani   udf: Replace bkl ...
2082
  	down_read(&UDF_I(inode)->i_data_sem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2083

4b11111ab   Marcin Slusarz   udf: fix coding s...
2084
2085
  	if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) ==
  						(EXT_RECORDED_ALLOCATED >> 30))
97e961fdb   Pekka Enberg   Fix the udf code ...
2086
  		ret = udf_get_lb_pblock(inode->i_sb, &eloc, offset);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2087
2088
  	else
  		ret = 0;
4d0fb621d   Alessio Igor Bogani   udf: Replace bkl ...
2089
  	up_read(&UDF_I(inode)->i_data_sem);
3bf25cb40   Jan Kara   udf: use get_bh()
2090
  	brelse(epos.bh);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2091
2092
2093
2094
2095
2096
  
  	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV))
  		return udf_fixed_to_variable(ret);
  	else
  		return ret;
  }