blob: 5b82e489af7851f476ad2ecf381c6466b77edf48 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * inode.c
3 *
4 * PURPOSE
5 * Inode handling routines for the OSTA-UDF(tm) filesystem.
6 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 * COPYRIGHT
8 * This file is distributed under the terms of the GNU General Public
9 * License (GPL). Copies of the GPL can be obtained from:
10 * ftp://prep.ai.mit.edu/pub/gnu/GPL
11 * Each contributing author retains all rights to their own work.
12 *
13 * (C) 1998 Dave Boynton
14 * (C) 1998-2004 Ben Fennema
15 * (C) 1999-2000 Stelias Computing Inc
16 *
17 * HISTORY
18 *
19 * 10/04/98 dgb Added rudimentary directory functions
20 * 10/07/98 Fully working udf_block_map! It works!
21 * 11/25/98 bmap altered to better support extents
22 * 12/06/98 blf partition support in udf_iget, udf_block_map and udf_read_inode
23 * 12/12/98 rewrote udf_block_map to handle next extents and descs across
24 * block boundaries (which is not actually allowed)
25 * 12/20/98 added support for strategy 4096
26 * 03/07/99 rewrote udf_block_map (again)
27 * New funcs, inode_bmap, udf_next_aext
28 * 04/19/99 Support for writing device EA's for major/minor #
29 */
30
31#include "udfdecl.h"
32#include <linux/mm.h>
33#include <linux/smp_lock.h>
34#include <linux/module.h>
35#include <linux/pagemap.h>
36#include <linux/buffer_head.h>
37#include <linux/writeback.h>
38#include <linux/slab.h>
39
40#include "udf_i.h"
41#include "udf_sb.h"
42
43MODULE_AUTHOR("Ben Fennema");
44MODULE_DESCRIPTION("Universal Disk Format Filesystem");
45MODULE_LICENSE("GPL");
46
47#define EXTENT_MERGE_SIZE 5
48
49static mode_t udf_convert_permissions(struct fileEntry *);
50static int udf_update_inode(struct inode *, int);
51static void udf_fill_inode(struct inode *, struct buffer_head *);
Cyrill Gorcunov647bd612007-07-15 23:39:47 -070052static int udf_alloc_i_data(struct inode *inode, size_t size);
Jan Kara60448b12007-05-08 00:35:13 -070053static struct buffer_head *inode_getblk(struct inode *, sector_t, int *,
Linus Torvalds1da177e2005-04-16 15:20:36 -070054 long *, int *);
Jan Karaff116fc2007-05-08 00:35:14 -070055static int8_t udf_insert_aext(struct inode *, struct extent_position,
56 kernel_lb_addr, uint32_t);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057static void udf_split_extents(struct inode *, int *, int, int,
58 kernel_long_ad [EXTENT_MERGE_SIZE], int *);
59static void udf_prealloc_extents(struct inode *, int, int,
60 kernel_long_ad [EXTENT_MERGE_SIZE], int *);
61static void udf_merge_extents(struct inode *,
62 kernel_long_ad [EXTENT_MERGE_SIZE], int *);
63static void udf_update_extents(struct inode *,
64 kernel_long_ad [EXTENT_MERGE_SIZE], int, int,
Jan Karaff116fc2007-05-08 00:35:14 -070065 struct extent_position *);
Linus Torvalds1da177e2005-04-16 15:20:36 -070066static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
67
68/*
69 * udf_delete_inode
70 *
71 * PURPOSE
72 * Clean-up before the specified inode is destroyed.
73 *
74 * DESCRIPTION
75 * This routine is called when the kernel destroys an inode structure
76 * ie. when iput() finds i_count == 0.
77 *
78 * HISTORY
79 * July 1, 1997 - Andrew E. Mileski
80 * Written, tested, and released.
81 *
82 * Called at the last iput() if i_nlink is zero.
83 */
84void udf_delete_inode(struct inode * inode)
85{
Mark Fashehfef26652005-09-09 13:01:31 -070086 truncate_inode_pages(&inode->i_data, 0);
87
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 if (is_bad_inode(inode))
89 goto no_delete;
90
91 inode->i_size = 0;
92 udf_truncate(inode);
93 lock_kernel();
94
95 udf_update_inode(inode, IS_SYNC(inode));
96 udf_free_inode(inode);
97
98 unlock_kernel();
99 return;
100no_delete:
101 clear_inode(inode);
102}
103
Jan Kara74584ae2007-06-16 10:16:14 -0700104/*
105 * If we are going to release inode from memory, we discard preallocation and
106 * truncate last inode extent to proper length. We could use drop_inode() but
107 * it's called under inode_lock and thus we cannot mark inode dirty there. We
108 * use clear_inode() but we have to make sure to write inode as it's not written
109 * automatically.
110 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111void udf_clear_inode(struct inode *inode)
112{
113 if (!(inode->i_sb->s_flags & MS_RDONLY)) {
114 lock_kernel();
Jan Kara74584ae2007-06-16 10:16:14 -0700115 /* Discard preallocation for directories, symlinks, etc. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 udf_discard_prealloc(inode);
Jan Kara74584ae2007-06-16 10:16:14 -0700117 udf_truncate_tail_extent(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 unlock_kernel();
Jan Kara74584ae2007-06-16 10:16:14 -0700119 write_inode_now(inode, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121 kfree(UDF_I_DATA(inode));
122 UDF_I_DATA(inode) = NULL;
123}
124
125static int udf_writepage(struct page *page, struct writeback_control *wbc)
126{
127 return block_write_full_page(page, udf_get_block, wbc);
128}
129
130static int udf_readpage(struct file *file, struct page *page)
131{
132 return block_read_full_page(page, udf_get_block);
133}
134
135static int udf_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
136{
137 return block_prepare_write(page, from, to, udf_get_block);
138}
139
140static sector_t udf_bmap(struct address_space *mapping, sector_t block)
141{
142 return generic_block_bmap(mapping,block,udf_get_block);
143}
144
Christoph Hellwigf5e54d62006-06-28 04:26:44 -0700145const struct address_space_operations udf_aops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 .readpage = udf_readpage,
147 .writepage = udf_writepage,
148 .sync_page = block_sync_page,
149 .prepare_write = udf_prepare_write,
150 .commit_write = generic_commit_write,
151 .bmap = udf_bmap,
152};
153
154void udf_expand_file_adinicb(struct inode * inode, int newsize, int * err)
155{
156 struct page *page;
157 char *kaddr;
158 struct writeback_control udf_wbc = {
159 .sync_mode = WB_SYNC_NONE,
160 .nr_to_write = 1,
161 };
162
163 /* from now on we have normal address_space methods */
164 inode->i_data.a_ops = &udf_aops;
165
166 if (!UDF_I_LENALLOC(inode))
167 {
168 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
169 UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
170 else
171 UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
172 mark_inode_dirty(inode);
173 return;
174 }
175
176 page = grab_cache_page(inode->i_mapping, 0);
Matt Mackallcd7619d2005-05-01 08:59:01 -0700177 BUG_ON(!PageLocked(page));
178
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 if (!PageUptodate(page))
180 {
181 kaddr = kmap(page);
182 memset(kaddr + UDF_I_LENALLOC(inode), 0x00,
183 PAGE_CACHE_SIZE - UDF_I_LENALLOC(inode));
184 memcpy(kaddr, UDF_I_DATA(inode) + UDF_I_LENEATTR(inode),
185 UDF_I_LENALLOC(inode));
186 flush_dcache_page(page);
187 SetPageUptodate(page);
188 kunmap(page);
189 }
190 memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0x00,
191 UDF_I_LENALLOC(inode));
192 UDF_I_LENALLOC(inode) = 0;
193 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
194 UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
195 else
196 UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
197
198 inode->i_data.a_ops->writepage(page, &udf_wbc);
199 page_cache_release(page);
200
201 mark_inode_dirty(inode);
202}
203
204struct buffer_head * udf_expand_dir_adinicb(struct inode *inode, int *block, int *err)
205{
206 int newblock;
Jan Karaff116fc2007-05-08 00:35:14 -0700207 struct buffer_head *dbh = NULL;
208 kernel_lb_addr eloc;
209 uint32_t elen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 uint8_t alloctype;
Jan Karaff116fc2007-05-08 00:35:14 -0700211 struct extent_position epos;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212
213 struct udf_fileident_bh sfibh, dfibh;
214 loff_t f_pos = udf_ext0_offset(inode) >> 2;
215 int size = (udf_ext0_offset(inode) + inode->i_size) >> 2;
216 struct fileIdentDesc cfi, *sfi, *dfi;
217
218 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
219 alloctype = ICBTAG_FLAG_AD_SHORT;
220 else
221 alloctype = ICBTAG_FLAG_AD_LONG;
222
223 if (!inode->i_size)
224 {
225 UDF_I_ALLOCTYPE(inode) = alloctype;
226 mark_inode_dirty(inode);
227 return NULL;
228 }
229
230 /* alloc block, and copy data to it */
231 *block = udf_new_block(inode->i_sb, inode,
232 UDF_I_LOCATION(inode).partitionReferenceNum,
233 UDF_I_LOCATION(inode).logicalBlockNum, err);
234
235 if (!(*block))
236 return NULL;
237 newblock = udf_get_pblock(inode->i_sb, *block,
238 UDF_I_LOCATION(inode).partitionReferenceNum, 0);
239 if (!newblock)
240 return NULL;
241 dbh = udf_tgetblk(inode->i_sb, newblock);
242 if (!dbh)
243 return NULL;
244 lock_buffer(dbh);
245 memset(dbh->b_data, 0x00, inode->i_sb->s_blocksize);
246 set_buffer_uptodate(dbh);
247 unlock_buffer(dbh);
248 mark_buffer_dirty_inode(dbh, inode);
249
250 sfibh.soffset = sfibh.eoffset = (f_pos & ((inode->i_sb->s_blocksize - 1) >> 2)) << 2;
Jan Karaff116fc2007-05-08 00:35:14 -0700251 sfibh.sbh = sfibh.ebh = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 dfibh.soffset = dfibh.eoffset = 0;
253 dfibh.sbh = dfibh.ebh = dbh;
254 while ( (f_pos < size) )
255 {
256 UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
Jan Karaff116fc2007-05-08 00:35:14 -0700257 sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL, NULL, NULL, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 if (!sfi)
259 {
Jan Kara3bf25cb2007-05-08 00:35:16 -0700260 brelse(dbh);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 return NULL;
262 }
263 UDF_I_ALLOCTYPE(inode) = alloctype;
264 sfi->descTag.tagLocation = cpu_to_le32(*block);
265 dfibh.soffset = dfibh.eoffset;
266 dfibh.eoffset += (sfibh.eoffset - sfibh.soffset);
267 dfi = (struct fileIdentDesc *)(dbh->b_data + dfibh.soffset);
268 if (udf_write_fi(inode, sfi, dfi, &dfibh, sfi->impUse,
269 sfi->fileIdent + le16_to_cpu(sfi->lengthOfImpUse)))
270 {
271 UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
Jan Kara3bf25cb2007-05-08 00:35:16 -0700272 brelse(dbh);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 return NULL;
274 }
275 }
276 mark_buffer_dirty_inode(dbh, inode);
277
278 memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode), 0, UDF_I_LENALLOC(inode));
279 UDF_I_LENALLOC(inode) = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 eloc.logicalBlockNum = *block;
281 eloc.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
282 elen = inode->i_size;
283 UDF_I_LENEXTENTS(inode) = elen;
Jan Karaff116fc2007-05-08 00:35:14 -0700284 epos.bh = NULL;
285 epos.block = UDF_I_LOCATION(inode);
286 epos.offset = udf_file_entry_alloc_offset(inode);
287 udf_add_aext(inode, &epos, eloc, elen, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 /* UniqueID stuff */
289
Jan Kara3bf25cb2007-05-08 00:35:16 -0700290 brelse(epos.bh);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 mark_inode_dirty(inode);
292 return dbh;
293}
294
295static int udf_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create)
296{
297 int err, new;
298 struct buffer_head *bh;
299 unsigned long phys;
300
301 if (!create)
302 {
303 phys = udf_block_map(inode, block);
304 if (phys)
305 map_bh(bh_result, inode->i_sb, phys);
306 return 0;
307 }
308
309 err = -EIO;
310 new = 0;
311 bh = NULL;
312
313 lock_kernel();
314
315 if (block < 0)
316 goto abort_negative;
317
318 if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1)
319 {
320 UDF_I_NEXT_ALLOC_BLOCK(inode) ++;
321 UDF_I_NEXT_ALLOC_GOAL(inode) ++;
322 }
323
324 err = 0;
325
326 bh = inode_getblk(inode, block, &err, &phys, &new);
Eric Sesterhenn2c2111c2006-04-02 13:40:13 +0200327 BUG_ON(bh);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328 if (err)
329 goto abort;
Eric Sesterhenn2c2111c2006-04-02 13:40:13 +0200330 BUG_ON(!phys);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331
332 if (new)
333 set_buffer_new(bh_result);
334 map_bh(bh_result, inode->i_sb, phys);
335abort:
336 unlock_kernel();
337 return err;
338
339abort_negative:
340 udf_warning(inode->i_sb, "udf_get_block", "block < 0");
341 goto abort;
342}
343
344static struct buffer_head *
345udf_getblk(struct inode *inode, long block, int create, int *err)
346{
347 struct buffer_head dummy;
348
349 dummy.b_state = 0;
350 dummy.b_blocknr = -1000;
351 *err = udf_get_block(inode, block, &dummy, create);
352 if (!*err && buffer_mapped(&dummy))
353 {
354 struct buffer_head *bh;
355 bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
356 if (buffer_new(&dummy))
357 {
358 lock_buffer(bh);
359 memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
360 set_buffer_uptodate(bh);
361 unlock_buffer(bh);
362 mark_buffer_dirty_inode(bh, inode);
363 }
364 return bh;
365 }
366 return NULL;
367}
368
Jan Kara31170b62007-05-08 00:35:21 -0700369/* Extend the file by 'blocks' blocks, return the number of extents added */
370int udf_extend_file(struct inode *inode, struct extent_position *last_pos,
371 kernel_long_ad *last_ext, sector_t blocks)
372{
373 sector_t add;
374 int count = 0, fake = !(last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
375 struct super_block *sb = inode->i_sb;
376 kernel_lb_addr prealloc_loc = {0, 0};
377 int prealloc_len = 0;
378
379 /* The previous extent is fake and we should not extend by anything
380 * - there's nothing to do... */
381 if (!blocks && fake)
382 return 0;
383 /* Round the last extent up to a multiple of block size */
384 if (last_ext->extLength & (sb->s_blocksize - 1)) {
385 last_ext->extLength =
386 (last_ext->extLength & UDF_EXTENT_FLAG_MASK) |
387 (((last_ext->extLength & UDF_EXTENT_LENGTH_MASK) +
388 sb->s_blocksize - 1) & ~(sb->s_blocksize - 1));
389 UDF_I_LENEXTENTS(inode) =
390 (UDF_I_LENEXTENTS(inode) + sb->s_blocksize - 1) &
391 ~(sb->s_blocksize - 1);
392 }
393 /* Last extent are just preallocated blocks? */
394 if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_ALLOCATED) {
395 /* Save the extent so that we can reattach it to the end */
396 prealloc_loc = last_ext->extLocation;
397 prealloc_len = last_ext->extLength;
398 /* Mark the extent as a hole */
399 last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
400 (last_ext->extLength & UDF_EXTENT_LENGTH_MASK);
401 last_ext->extLocation.logicalBlockNum = 0;
402 last_ext->extLocation.partitionReferenceNum = 0;
403 }
404 /* Can we merge with the previous extent? */
405 if ((last_ext->extLength & UDF_EXTENT_FLAG_MASK) == EXT_NOT_RECORDED_NOT_ALLOCATED) {
406 add = ((1<<30) - sb->s_blocksize - (last_ext->extLength &
407 UDF_EXTENT_LENGTH_MASK)) >> sb->s_blocksize_bits;
408 if (add > blocks)
409 add = blocks;
410 blocks -= add;
411 last_ext->extLength += add << sb->s_blocksize_bits;
412 }
413
414 if (fake) {
415 udf_add_aext(inode, last_pos, last_ext->extLocation,
416 last_ext->extLength, 1);
417 count++;
418 }
419 else
420 udf_write_aext(inode, last_pos, last_ext->extLocation, last_ext->extLength, 1);
421 /* Managed to do everything necessary? */
422 if (!blocks)
423 goto out;
424
425 /* All further extents will be NOT_RECORDED_NOT_ALLOCATED */
426 last_ext->extLocation.logicalBlockNum = 0;
427 last_ext->extLocation.partitionReferenceNum = 0;
428 add = (1 << (30-sb->s_blocksize_bits)) - 1;
429 last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED | (add << sb->s_blocksize_bits);
430 /* Create enough extents to cover the whole hole */
431 while (blocks > add) {
432 blocks -= add;
433 if (udf_add_aext(inode, last_pos, last_ext->extLocation,
434 last_ext->extLength, 1) == -1)
435 return -1;
436 count++;
437 }
438 if (blocks) {
439 last_ext->extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
440 (blocks << sb->s_blocksize_bits);
441 if (udf_add_aext(inode, last_pos, last_ext->extLocation,
442 last_ext->extLength, 1) == -1)
443 return -1;
444 count++;
445 }
446out:
447 /* Do we have some preallocated blocks saved? */
448 if (prealloc_len) {
449 if (udf_add_aext(inode, last_pos, prealloc_loc, prealloc_len, 1) == -1)
450 return -1;
451 last_ext->extLocation = prealloc_loc;
452 last_ext->extLength = prealloc_len;
453 count++;
454 }
455 /* last_pos should point to the last written extent... */
456 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
457 last_pos->offset -= sizeof(short_ad);
458 else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
459 last_pos->offset -= sizeof(long_ad);
460 else
461 return -1;
462 return count;
463}
464
Jan Kara60448b12007-05-08 00:35:13 -0700465static struct buffer_head * inode_getblk(struct inode * inode, sector_t block,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 int *err, long *phys, int *new)
467{
Jan Kara31170b62007-05-08 00:35:21 -0700468 static sector_t last_block;
Jan Karaff116fc2007-05-08 00:35:14 -0700469 struct buffer_head *result = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 kernel_long_ad laarr[EXTENT_MERGE_SIZE];
Jan Karaff116fc2007-05-08 00:35:14 -0700471 struct extent_position prev_epos, cur_epos, next_epos;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 int count = 0, startnum = 0, endnum = 0;
Jan Kara85d71242007-06-01 00:46:29 -0700473 uint32_t elen = 0, tmpelen;
474 kernel_lb_addr eloc, tmpeloc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 int c = 1;
Jan Kara60448b12007-05-08 00:35:13 -0700476 loff_t lbcount = 0, b_off = 0;
477 uint32_t newblocknum, newblock;
478 sector_t offset = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 int8_t etype;
480 int goal = 0, pgoal = UDF_I_LOCATION(inode).logicalBlockNum;
Jan Kara31170b62007-05-08 00:35:21 -0700481 int lastblock = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482
Jan Karaff116fc2007-05-08 00:35:14 -0700483 prev_epos.offset = udf_file_entry_alloc_offset(inode);
484 prev_epos.block = UDF_I_LOCATION(inode);
485 prev_epos.bh = NULL;
486 cur_epos = next_epos = prev_epos;
Jan Kara60448b12007-05-08 00:35:13 -0700487 b_off = (loff_t)block << inode->i_sb->s_blocksize_bits;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488
489 /* find the extent which contains the block we are looking for.
490 alternate between laarr[0] and laarr[1] for locations of the
491 current extent, and the previous extent */
492 do
493 {
Jan Karaff116fc2007-05-08 00:35:14 -0700494 if (prev_epos.bh != cur_epos.bh)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 {
Jan Kara3bf25cb2007-05-08 00:35:16 -0700496 brelse(prev_epos.bh);
497 get_bh(cur_epos.bh);
Jan Karaff116fc2007-05-08 00:35:14 -0700498 prev_epos.bh = cur_epos.bh;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 }
Jan Karaff116fc2007-05-08 00:35:14 -0700500 if (cur_epos.bh != next_epos.bh)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501 {
Jan Kara3bf25cb2007-05-08 00:35:16 -0700502 brelse(cur_epos.bh);
503 get_bh(next_epos.bh);
Jan Karaff116fc2007-05-08 00:35:14 -0700504 cur_epos.bh = next_epos.bh;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 }
506
507 lbcount += elen;
508
Jan Karaff116fc2007-05-08 00:35:14 -0700509 prev_epos.block = cur_epos.block;
510 cur_epos.block = next_epos.block;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511
Jan Karaff116fc2007-05-08 00:35:14 -0700512 prev_epos.offset = cur_epos.offset;
513 cur_epos.offset = next_epos.offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514
Jan Karaff116fc2007-05-08 00:35:14 -0700515 if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 1)) == -1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 break;
517
518 c = !c;
519
520 laarr[c].extLength = (etype << 30) | elen;
521 laarr[c].extLocation = eloc;
522
523 if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
524 pgoal = eloc.logicalBlockNum +
525 ((elen + inode->i_sb->s_blocksize - 1) >>
526 inode->i_sb->s_blocksize_bits);
527
528 count ++;
529 } while (lbcount + elen <= b_off);
530
531 b_off -= lbcount;
532 offset = b_off >> inode->i_sb->s_blocksize_bits;
Jan Kara85d71242007-06-01 00:46:29 -0700533 /*
534 * Move prev_epos and cur_epos into indirect extent if we are at
535 * the pointer to it
536 */
537 udf_next_aext(inode, &prev_epos, &tmpeloc, &tmpelen, 0);
538 udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539
540 /* if the extent is allocated and recorded, return the block
541 if the extent is not a multiple of the blocksize, round up */
542
543 if (etype == (EXT_RECORDED_ALLOCATED >> 30))
544 {
545 if (elen & (inode->i_sb->s_blocksize - 1))
546 {
547 elen = EXT_RECORDED_ALLOCATED |
548 ((elen + inode->i_sb->s_blocksize - 1) &
549 ~(inode->i_sb->s_blocksize - 1));
Jan Karaff116fc2007-05-08 00:35:14 -0700550 etype = udf_write_aext(inode, &cur_epos, eloc, elen, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 }
Jan Kara3bf25cb2007-05-08 00:35:16 -0700552 brelse(prev_epos.bh);
553 brelse(cur_epos.bh);
554 brelse(next_epos.bh);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 newblock = udf_get_lb_pblock(inode->i_sb, eloc, offset);
556 *phys = newblock;
557 return NULL;
558 }
559
Jan Kara31170b62007-05-08 00:35:21 -0700560 last_block = block;
561 /* Are we beyond EOF? */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 if (etype == -1)
563 {
Jan Kara31170b62007-05-08 00:35:21 -0700564 int ret;
565
566 if (count) {
567 if (c)
568 laarr[0] = laarr[1];
569 startnum = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 }
Jan Kara31170b62007-05-08 00:35:21 -0700571 else {
572 /* Create a fake extent when there's not one */
573 memset(&laarr[0].extLocation, 0x00, sizeof(kernel_lb_addr));
574 laarr[0].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED;
575 /* Will udf_extend_file() create real extent from a fake one? */
576 startnum = (offset > 0);
577 }
578 /* Create extents for the hole between EOF and offset */
579 ret = udf_extend_file(inode, &prev_epos, laarr, offset);
580 if (ret == -1) {
581 brelse(prev_epos.bh);
582 brelse(cur_epos.bh);
583 brelse(next_epos.bh);
584 /* We don't really know the error here so we just make
585 * something up */
586 *err = -ENOSPC;
587 return NULL;
588 }
589 c = 0;
590 offset = 0;
591 count += ret;
592 /* We are not covered by a preallocated extent? */
593 if ((laarr[0].extLength & UDF_EXTENT_FLAG_MASK) != EXT_NOT_RECORDED_ALLOCATED) {
594 /* Is there any real extent? - otherwise we overwrite
595 * the fake one... */
596 if (count)
597 c = !c;
598 laarr[c].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
599 inode->i_sb->s_blocksize;
600 memset(&laarr[c].extLocation, 0x00, sizeof(kernel_lb_addr));
601 count ++;
602 endnum ++;
603 }
604 endnum = c+1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 lastblock = 1;
606 }
Jan Kara31170b62007-05-08 00:35:21 -0700607 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 endnum = startnum = ((count > 2) ? 2 : count);
609
Jan Kara31170b62007-05-08 00:35:21 -0700610 /* if the current extent is in position 0, swap it with the previous */
611 if (!c && count != 1)
612 {
613 laarr[2] = laarr[0];
614 laarr[0] = laarr[1];
615 laarr[1] = laarr[2];
616 c = 1;
617 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618
Jan Kara31170b62007-05-08 00:35:21 -0700619 /* if the current block is located in an extent, read the next extent */
Jan Karaff116fc2007-05-08 00:35:14 -0700620 if ((etype = udf_next_aext(inode, &next_epos, &eloc, &elen, 0)) != -1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 {
622 laarr[c+1].extLength = (etype << 30) | elen;
623 laarr[c+1].extLocation = eloc;
624 count ++;
625 startnum ++;
626 endnum ++;
627 }
Jan Kara31170b62007-05-08 00:35:21 -0700628 else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629 lastblock = 1;
Jan Kara31170b62007-05-08 00:35:21 -0700630 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632
633 /* if the current extent is not recorded but allocated, get the
634 block in the extent corresponding to the requested block */
635 if ((laarr[c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
636 newblocknum = laarr[c].extLocation.logicalBlockNum + offset;
637 else /* otherwise, allocate a new block */
638 {
639 if (UDF_I_NEXT_ALLOC_BLOCK(inode) == block)
640 goal = UDF_I_NEXT_ALLOC_GOAL(inode);
641
642 if (!goal)
643 {
644 if (!(goal = pgoal))
645 goal = UDF_I_LOCATION(inode).logicalBlockNum + 1;
646 }
647
648 if (!(newblocknum = udf_new_block(inode->i_sb, inode,
649 UDF_I_LOCATION(inode).partitionReferenceNum, goal, err)))
650 {
Jan Kara3bf25cb2007-05-08 00:35:16 -0700651 brelse(prev_epos.bh);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 *err = -ENOSPC;
653 return NULL;
654 }
655 UDF_I_LENEXTENTS(inode) += inode->i_sb->s_blocksize;
656 }
657
658 /* if the extent the requsted block is located in contains multiple blocks,
659 split the extent into at most three extents. blocks prior to requested
660 block, requested block, and blocks after requested block */
661 udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum);
662
663#ifdef UDF_PREALLOCATE
664 /* preallocate blocks */
665 udf_prealloc_extents(inode, c, lastblock, laarr, &endnum);
666#endif
667
668 /* merge any continuous blocks in laarr */
669 udf_merge_extents(inode, laarr, &endnum);
670
671 /* write back the new extents, inserting new extents if the new number
Jan Kara31170b62007-05-08 00:35:21 -0700672 of extents is greater than the old number, and deleting extents if
673 the new number of extents is less than the old number */
Jan Karaff116fc2007-05-08 00:35:14 -0700674 udf_update_extents(inode, laarr, startnum, endnum, &prev_epos);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675
Jan Kara3bf25cb2007-05-08 00:35:16 -0700676 brelse(prev_epos.bh);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677
678 if (!(newblock = udf_get_pblock(inode->i_sb, newblocknum,
679 UDF_I_LOCATION(inode).partitionReferenceNum, 0)))
680 {
681 return NULL;
682 }
683 *phys = newblock;
684 *err = 0;
685 *new = 1;
686 UDF_I_NEXT_ALLOC_BLOCK(inode) = block;
687 UDF_I_NEXT_ALLOC_GOAL(inode) = newblocknum;
688 inode->i_ctime = current_fs_time(inode->i_sb);
689
690 if (IS_SYNC(inode))
691 udf_sync_inode(inode);
692 else
693 mark_inode_dirty(inode);
694 return result;
695}
696
697static void udf_split_extents(struct inode *inode, int *c, int offset, int newblocknum,
698 kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum)
699{
700 if ((laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30) ||
701 (laarr[*c].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
702 {
703 int curr = *c;
704 int blen = ((laarr[curr].extLength & UDF_EXTENT_LENGTH_MASK) +
705 inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
706 int8_t etype = (laarr[curr].extLength >> 30);
707
708 if (blen == 1)
709 ;
710 else if (!offset || blen == offset + 1)
711 {
712 laarr[curr+2] = laarr[curr+1];
713 laarr[curr+1] = laarr[curr];
714 }
715 else
716 {
717 laarr[curr+3] = laarr[curr+1];
718 laarr[curr+2] = laarr[curr+1] = laarr[curr];
719 }
720
721 if (offset)
722 {
723 if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
724 {
725 udf_free_blocks(inode->i_sb, inode, laarr[curr].extLocation, 0, offset);
726 laarr[curr].extLength = EXT_NOT_RECORDED_NOT_ALLOCATED |
727 (offset << inode->i_sb->s_blocksize_bits);
728 laarr[curr].extLocation.logicalBlockNum = 0;
729 laarr[curr].extLocation.partitionReferenceNum = 0;
730 }
731 else
732 laarr[curr].extLength = (etype << 30) |
733 (offset << inode->i_sb->s_blocksize_bits);
734 curr ++;
735 (*c) ++;
736 (*endnum) ++;
737 }
Cyrill Gorcunov647bd612007-07-15 23:39:47 -0700738
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 laarr[curr].extLocation.logicalBlockNum = newblocknum;
740 if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
741 laarr[curr].extLocation.partitionReferenceNum =
742 UDF_I_LOCATION(inode).partitionReferenceNum;
743 laarr[curr].extLength = EXT_RECORDED_ALLOCATED |
744 inode->i_sb->s_blocksize;
745 curr ++;
746
747 if (blen != offset + 1)
748 {
749 if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
750 laarr[curr].extLocation.logicalBlockNum += (offset + 1);
751 laarr[curr].extLength = (etype << 30) |
752 ((blen - (offset + 1)) << inode->i_sb->s_blocksize_bits);
753 curr ++;
754 (*endnum) ++;
755 }
756 }
757}
758
759static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
760 kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum)
761{
762 int start, length = 0, currlength = 0, i;
763
764 if (*endnum >= (c+1))
765 {
766 if (!lastblock)
767 return;
768 else
769 start = c;
770 }
771 else
772 {
773 if ((laarr[c+1].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
774 {
775 start = c+1;
776 length = currlength = (((laarr[c+1].extLength & UDF_EXTENT_LENGTH_MASK) +
777 inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
778 }
779 else
780 start = c;
781 }
782
783 for (i=start+1; i<=*endnum; i++)
784 {
785 if (i == *endnum)
786 {
787 if (lastblock)
788 length += UDF_DEFAULT_PREALLOC_BLOCKS;
789 }
790 else if ((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
791 length += (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
792 inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
793 else
794 break;
795 }
796
797 if (length)
798 {
799 int next = laarr[start].extLocation.logicalBlockNum +
800 (((laarr[start].extLength & UDF_EXTENT_LENGTH_MASK) +
801 inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
802 int numalloc = udf_prealloc_blocks(inode->i_sb, inode,
803 laarr[start].extLocation.partitionReferenceNum,
804 next, (UDF_DEFAULT_PREALLOC_BLOCKS > length ? length :
805 UDF_DEFAULT_PREALLOC_BLOCKS) - currlength);
806
807 if (numalloc)
808 {
809 if (start == (c+1))
810 laarr[start].extLength +=
811 (numalloc << inode->i_sb->s_blocksize_bits);
812 else
813 {
814 memmove(&laarr[c+2], &laarr[c+1],
815 sizeof(long_ad) * (*endnum - (c+1)));
816 (*endnum) ++;
817 laarr[c+1].extLocation.logicalBlockNum = next;
818 laarr[c+1].extLocation.partitionReferenceNum =
819 laarr[c].extLocation.partitionReferenceNum;
820 laarr[c+1].extLength = EXT_NOT_RECORDED_ALLOCATED |
821 (numalloc << inode->i_sb->s_blocksize_bits);
822 start = c+1;
823 }
824
825 for (i=start+1; numalloc && i<*endnum; i++)
826 {
827 int elen = ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
828 inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
829
830 if (elen > numalloc)
831 {
832 laarr[i].extLength -=
833 (numalloc << inode->i_sb->s_blocksize_bits);
834 numalloc = 0;
835 }
836 else
837 {
838 numalloc -= elen;
839 if (*endnum > (i+1))
Cyrill Gorcunov647bd612007-07-15 23:39:47 -0700840 memmove(&laarr[i], &laarr[i+1],
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 sizeof(long_ad) * (*endnum - (i+1)));
842 i --;
843 (*endnum) --;
844 }
845 }
846 UDF_I_LENEXTENTS(inode) += numalloc << inode->i_sb->s_blocksize_bits;
847 }
848 }
849}
850
851static void udf_merge_extents(struct inode *inode,
852 kernel_long_ad laarr[EXTENT_MERGE_SIZE], int *endnum)
853{
854 int i;
855
856 for (i=0; i<(*endnum-1); i++)
857 {
858 if ((laarr[i].extLength >> 30) == (laarr[i+1].extLength >> 30))
859 {
860 if (((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)) ||
861 ((laarr[i+1].extLocation.logicalBlockNum - laarr[i].extLocation.logicalBlockNum) ==
862 (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
863 inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits)))
864 {
865 if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
866 (laarr[i+1].extLength & UDF_EXTENT_LENGTH_MASK) +
867 inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK)
868 {
869 laarr[i+1].extLength = (laarr[i+1].extLength -
870 (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
871 UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize-1);
872 laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_FLAG_MASK) +
873 (UDF_EXTENT_LENGTH_MASK + 1) - inode->i_sb->s_blocksize;
874 laarr[i+1].extLocation.logicalBlockNum =
875 laarr[i].extLocation.logicalBlockNum +
876 ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) >>
877 inode->i_sb->s_blocksize_bits);
878 }
879 else
880 {
881 laarr[i].extLength = laarr[i+1].extLength +
882 (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
883 inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize-1));
884 if (*endnum > (i+2))
885 memmove(&laarr[i+1], &laarr[i+2],
886 sizeof(long_ad) * (*endnum - (i+2)));
887 i --;
888 (*endnum) --;
889 }
890 }
891 }
892 else if (((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30)) &&
893 ((laarr[i+1].extLength >> 30) == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30)))
894 {
895 udf_free_blocks(inode->i_sb, inode, laarr[i].extLocation, 0,
896 ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
897 inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
898 laarr[i].extLocation.logicalBlockNum = 0;
899 laarr[i].extLocation.partitionReferenceNum = 0;
900
901 if (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
902 (laarr[i+1].extLength & UDF_EXTENT_LENGTH_MASK) +
903 inode->i_sb->s_blocksize - 1) & ~UDF_EXTENT_LENGTH_MASK)
904 {
905 laarr[i+1].extLength = (laarr[i+1].extLength -
906 (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
907 UDF_EXTENT_LENGTH_MASK) & ~(inode->i_sb->s_blocksize-1);
908 laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_FLAG_MASK) +
909 (UDF_EXTENT_LENGTH_MASK + 1) - inode->i_sb->s_blocksize;
910 }
911 else
912 {
913 laarr[i].extLength = laarr[i+1].extLength +
914 (((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
915 inode->i_sb->s_blocksize - 1) & ~(inode->i_sb->s_blocksize-1));
916 if (*endnum > (i+2))
917 memmove(&laarr[i+1], &laarr[i+2],
918 sizeof(long_ad) * (*endnum - (i+2)));
919 i --;
920 (*endnum) --;
921 }
922 }
923 else if ((laarr[i].extLength >> 30) == (EXT_NOT_RECORDED_ALLOCATED >> 30))
924 {
925 udf_free_blocks(inode->i_sb, inode, laarr[i].extLocation, 0,
926 ((laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) +
927 inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits);
928 laarr[i].extLocation.logicalBlockNum = 0;
929 laarr[i].extLocation.partitionReferenceNum = 0;
930 laarr[i].extLength = (laarr[i].extLength & UDF_EXTENT_LENGTH_MASK) |
931 EXT_NOT_RECORDED_NOT_ALLOCATED;
932 }
933 }
934}
935
936static void udf_update_extents(struct inode *inode,
937 kernel_long_ad laarr[EXTENT_MERGE_SIZE], int startnum, int endnum,
Jan Karaff116fc2007-05-08 00:35:14 -0700938 struct extent_position *epos)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939{
940 int start = 0, i;
941 kernel_lb_addr tmploc;
942 uint32_t tmplen;
943
944 if (startnum > endnum)
945 {
946 for (i=0; i<(startnum-endnum); i++)
Jan Karaff116fc2007-05-08 00:35:14 -0700947 udf_delete_aext(inode, *epos, laarr[i].extLocation,
948 laarr[i].extLength);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 }
950 else if (startnum < endnum)
951 {
952 for (i=0; i<(endnum-startnum); i++)
953 {
Jan Karaff116fc2007-05-08 00:35:14 -0700954 udf_insert_aext(inode, *epos, laarr[i].extLocation,
955 laarr[i].extLength);
956 udf_next_aext(inode, epos, &laarr[i].extLocation,
957 &laarr[i].extLength, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958 start ++;
959 }
960 }
961
962 for (i=start; i<endnum; i++)
963 {
Jan Karaff116fc2007-05-08 00:35:14 -0700964 udf_next_aext(inode, epos, &tmploc, &tmplen, 0);
965 udf_write_aext(inode, epos, laarr[i].extLocation,
966 laarr[i].extLength, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967 }
968}
969
970struct buffer_head * udf_bread(struct inode * inode, int block,
971 int create, int * err)
972{
973 struct buffer_head * bh = NULL;
974
975 bh = udf_getblk(inode, block, create, err);
976 if (!bh)
977 return NULL;
978
979 if (buffer_uptodate(bh))
980 return bh;
981 ll_rw_block(READ, 1, &bh);
982 wait_on_buffer(bh);
983 if (buffer_uptodate(bh))
984 return bh;
985 brelse(bh);
986 *err = -EIO;
987 return NULL;
988}
989
990void udf_truncate(struct inode * inode)
991{
992 int offset;
993 int err;
994
995 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
996 S_ISLNK(inode->i_mode)))
997 return;
998 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
999 return;
1000
1001 lock_kernel();
1002 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
1003 {
1004 if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
1005 inode->i_size))
1006 {
1007 udf_expand_file_adinicb(inode, inode->i_size, &err);
1008 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
1009 {
1010 inode->i_size = UDF_I_LENALLOC(inode);
1011 unlock_kernel();
1012 return;
1013 }
1014 else
1015 udf_truncate_extents(inode);
1016 }
1017 else
1018 {
1019 offset = inode->i_size & (inode->i_sb->s_blocksize - 1);
1020 memset(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset, 0x00, inode->i_sb->s_blocksize - offset - udf_file_entry_alloc_offset(inode));
1021 UDF_I_LENALLOC(inode) = inode->i_size;
1022 }
1023 }
1024 else
1025 {
1026 block_truncate_page(inode->i_mapping, inode->i_size, udf_get_block);
1027 udf_truncate_extents(inode);
Cyrill Gorcunov647bd612007-07-15 23:39:47 -07001028 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029
1030 inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
1031 if (IS_SYNC(inode))
1032 udf_sync_inode (inode);
1033 else
1034 mark_inode_dirty(inode);
1035 unlock_kernel();
1036}
1037
1038static void
1039__udf_read_inode(struct inode *inode)
1040{
1041 struct buffer_head *bh = NULL;
1042 struct fileEntry *fe;
1043 uint16_t ident;
1044
1045 /*
1046 * Set defaults, but the inode is still incomplete!
1047 * Note: get_new_inode() sets the following on a new inode:
1048 * i_sb = sb
1049 * i_no = ino
1050 * i_flags = sb->s_flags
1051 * i_state = 0
1052 * clean_inode(): zero fills and sets
1053 * i_count = 1
1054 * i_nlink = 1
1055 * i_op = NULL;
1056 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident);
1058
1059 if (!bh)
1060 {
1061 printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed !bh\n",
1062 inode->i_ino);
1063 make_bad_inode(inode);
1064 return;
1065 }
1066
1067 if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE &&
1068 ident != TAG_IDENT_USE)
1069 {
1070 printk(KERN_ERR "udf: udf_read_inode(ino %ld) failed ident=%d\n",
1071 inode->i_ino, ident);
Jan Kara3bf25cb2007-05-08 00:35:16 -07001072 brelse(bh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 make_bad_inode(inode);
1074 return;
1075 }
1076
1077 fe = (struct fileEntry *)bh->b_data;
1078
1079 if (le16_to_cpu(fe->icbTag.strategyType) == 4096)
1080 {
1081 struct buffer_head *ibh = NULL, *nbh = NULL;
1082 struct indirectEntry *ie;
1083
1084 ibh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 1, &ident);
1085 if (ident == TAG_IDENT_IE)
1086 {
1087 if (ibh)
1088 {
1089 kernel_lb_addr loc;
1090 ie = (struct indirectEntry *)ibh->b_data;
Cyrill Gorcunov647bd612007-07-15 23:39:47 -07001091
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092 loc = lelb_to_cpu(ie->indirectICB.extLocation);
Cyrill Gorcunov647bd612007-07-15 23:39:47 -07001093
1094 if (ie->indirectICB.extLength &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 (nbh = udf_read_ptagged(inode->i_sb, loc, 0, &ident)))
1096 {
1097 if (ident == TAG_IDENT_FE ||
1098 ident == TAG_IDENT_EFE)
1099 {
1100 memcpy(&UDF_I_LOCATION(inode), &loc, sizeof(kernel_lb_addr));
Jan Kara3bf25cb2007-05-08 00:35:16 -07001101 brelse(bh);
1102 brelse(ibh);
1103 brelse(nbh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001104 __udf_read_inode(inode);
1105 return;
1106 }
1107 else
1108 {
Jan Kara3bf25cb2007-05-08 00:35:16 -07001109 brelse(nbh);
1110 brelse(ibh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 }
1112 }
1113 else
Jan Kara3bf25cb2007-05-08 00:35:16 -07001114 brelse(ibh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115 }
1116 }
1117 else
Jan Kara3bf25cb2007-05-08 00:35:16 -07001118 brelse(ibh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119 }
1120 else if (le16_to_cpu(fe->icbTag.strategyType) != 4)
1121 {
1122 printk(KERN_ERR "udf: unsupported strategy type: %d\n",
1123 le16_to_cpu(fe->icbTag.strategyType));
Jan Kara3bf25cb2007-05-08 00:35:16 -07001124 brelse(bh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125 make_bad_inode(inode);
1126 return;
1127 }
1128 udf_fill_inode(inode, bh);
Jan Kara31170b62007-05-08 00:35:21 -07001129
Jan Kara3bf25cb2007-05-08 00:35:16 -07001130 brelse(bh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131}
1132
1133static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
1134{
1135 struct fileEntry *fe;
1136 struct extendedFileEntry *efe;
1137 time_t convtime;
1138 long convtime_usec;
1139 int offset;
1140
1141 fe = (struct fileEntry *)bh->b_data;
1142 efe = (struct extendedFileEntry *)bh->b_data;
1143
1144 if (le16_to_cpu(fe->icbTag.strategyType) == 4)
1145 UDF_I_STRAT4096(inode) = 0;
1146 else /* if (le16_to_cpu(fe->icbTag.strategyType) == 4096) */
1147 UDF_I_STRAT4096(inode) = 1;
1148
1149 UDF_I_ALLOCTYPE(inode) = le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK;
1150 UDF_I_UNIQUE(inode) = 0;
1151 UDF_I_LENEATTR(inode) = 0;
1152 UDF_I_LENEXTENTS(inode) = 0;
1153 UDF_I_LENALLOC(inode) = 0;
1154 UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
1155 UDF_I_NEXT_ALLOC_GOAL(inode) = 0;
1156 if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_EFE)
1157 {
1158 UDF_I_EFE(inode) = 1;
1159 UDF_I_USE(inode) = 0;
Cyrill Gorcunov647bd612007-07-15 23:39:47 -07001160 if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry)))
1161 {
1162 make_bad_inode(inode);
1163 return;
1164 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165 memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct extendedFileEntry), inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry));
1166 }
1167 else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_FE)
1168 {
1169 UDF_I_EFE(inode) = 0;
1170 UDF_I_USE(inode) = 0;
Cyrill Gorcunov647bd612007-07-15 23:39:47 -07001171 if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize - sizeof(struct fileEntry)))
1172 {
1173 make_bad_inode(inode);
1174 return;
1175 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct fileEntry), inode->i_sb->s_blocksize - sizeof(struct fileEntry));
1177 }
1178 else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE)
1179 {
1180 UDF_I_EFE(inode) = 0;
1181 UDF_I_USE(inode) = 1;
1182 UDF_I_LENALLOC(inode) =
1183 le32_to_cpu(
1184 ((struct unallocSpaceEntry *)bh->b_data)->lengthAllocDescs);
Cyrill Gorcunov647bd612007-07-15 23:39:47 -07001185 if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry)))
1186 {
1187 make_bad_inode(inode);
1188 return;
1189 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 memcpy(UDF_I_DATA(inode), bh->b_data + sizeof(struct unallocSpaceEntry), inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry));
1191 return;
1192 }
1193
1194 inode->i_uid = le32_to_cpu(fe->uid);
Phillip Susi4d6660e2006-03-07 21:55:24 -08001195 if (inode->i_uid == -1 || UDF_QUERY_FLAG(inode->i_sb,
1196 UDF_FLAG_UID_IGNORE))
1197 inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198
1199 inode->i_gid = le32_to_cpu(fe->gid);
Phillip Susi4d6660e2006-03-07 21:55:24 -08001200 if (inode->i_gid == -1 || UDF_QUERY_FLAG(inode->i_sb,
1201 UDF_FLAG_GID_IGNORE))
1202 inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203
1204 inode->i_nlink = le16_to_cpu(fe->fileLinkCount);
1205 if (!inode->i_nlink)
1206 inode->i_nlink = 1;
Cyrill Gorcunov647bd612007-07-15 23:39:47 -07001207
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 inode->i_size = le64_to_cpu(fe->informationLength);
1209 UDF_I_LENEXTENTS(inode) = inode->i_size;
1210
1211 inode->i_mode = udf_convert_permissions(fe);
1212 inode->i_mode &= ~UDF_SB(inode->i_sb)->s_umask;
1213
1214 if (UDF_I_EFE(inode) == 0)
1215 {
1216 inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
1217 (inode->i_sb->s_blocksize_bits - 9);
1218
1219 if ( udf_stamp_to_time(&convtime, &convtime_usec,
1220 lets_to_cpu(fe->accessTime)) )
1221 {
1222 inode->i_atime.tv_sec = convtime;
1223 inode->i_atime.tv_nsec = convtime_usec * 1000;
1224 }
1225 else
1226 {
1227 inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
1228 }
1229
1230 if ( udf_stamp_to_time(&convtime, &convtime_usec,
1231 lets_to_cpu(fe->modificationTime)) )
1232 {
1233 inode->i_mtime.tv_sec = convtime;
1234 inode->i_mtime.tv_nsec = convtime_usec * 1000;
1235 }
1236 else
1237 {
1238 inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
1239 }
1240
1241 if ( udf_stamp_to_time(&convtime, &convtime_usec,
1242 lets_to_cpu(fe->attrTime)) )
1243 {
1244 inode->i_ctime.tv_sec = convtime;
1245 inode->i_ctime.tv_nsec = convtime_usec * 1000;
1246 }
1247 else
1248 {
1249 inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
1250 }
1251
1252 UDF_I_UNIQUE(inode) = le64_to_cpu(fe->uniqueID);
1253 UDF_I_LENEATTR(inode) = le32_to_cpu(fe->lengthExtendedAttr);
1254 UDF_I_LENALLOC(inode) = le32_to_cpu(fe->lengthAllocDescs);
1255 offset = sizeof(struct fileEntry) + UDF_I_LENEATTR(inode);
1256 }
1257 else
1258 {
Cyrill Gorcunov647bd612007-07-15 23:39:47 -07001259 inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260 (inode->i_sb->s_blocksize_bits - 9);
1261
1262 if ( udf_stamp_to_time(&convtime, &convtime_usec,
1263 lets_to_cpu(efe->accessTime)) )
1264 {
1265 inode->i_atime.tv_sec = convtime;
1266 inode->i_atime.tv_nsec = convtime_usec * 1000;
1267 }
1268 else
1269 {
1270 inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
1271 }
1272
1273 if ( udf_stamp_to_time(&convtime, &convtime_usec,
1274 lets_to_cpu(efe->modificationTime)) )
1275 {
1276 inode->i_mtime.tv_sec = convtime;
1277 inode->i_mtime.tv_nsec = convtime_usec * 1000;
1278 }
1279 else
1280 {
1281 inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
1282 }
1283
1284 if ( udf_stamp_to_time(&convtime, &convtime_usec,
1285 lets_to_cpu(efe->createTime)) )
1286 {
1287 UDF_I_CRTIME(inode).tv_sec = convtime;
1288 UDF_I_CRTIME(inode).tv_nsec = convtime_usec * 1000;
1289 }
1290 else
1291 {
1292 UDF_I_CRTIME(inode) = UDF_SB_RECORDTIME(inode->i_sb);
1293 }
1294
1295 if ( udf_stamp_to_time(&convtime, &convtime_usec,
1296 lets_to_cpu(efe->attrTime)) )
1297 {
1298 inode->i_ctime.tv_sec = convtime;
1299 inode->i_ctime.tv_nsec = convtime_usec * 1000;
1300 }
1301 else
1302 {
1303 inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
1304 }
1305
1306 UDF_I_UNIQUE(inode) = le64_to_cpu(efe->uniqueID);
1307 UDF_I_LENEATTR(inode) = le32_to_cpu(efe->lengthExtendedAttr);
1308 UDF_I_LENALLOC(inode) = le32_to_cpu(efe->lengthAllocDescs);
1309 offset = sizeof(struct extendedFileEntry) + UDF_I_LENEATTR(inode);
1310 }
1311
1312 switch (fe->icbTag.fileType)
1313 {
1314 case ICBTAG_FILE_TYPE_DIRECTORY:
1315 {
1316 inode->i_op = &udf_dir_inode_operations;
1317 inode->i_fop = &udf_dir_operations;
1318 inode->i_mode |= S_IFDIR;
Dave Hansend8c76e62006-09-30 23:29:04 -07001319 inc_nlink(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320 break;
1321 }
1322 case ICBTAG_FILE_TYPE_REALTIME:
1323 case ICBTAG_FILE_TYPE_REGULAR:
1324 case ICBTAG_FILE_TYPE_UNDEF:
1325 {
1326 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
1327 inode->i_data.a_ops = &udf_adinicb_aops;
1328 else
1329 inode->i_data.a_ops = &udf_aops;
1330 inode->i_op = &udf_file_inode_operations;
1331 inode->i_fop = &udf_file_operations;
1332 inode->i_mode |= S_IFREG;
1333 break;
1334 }
1335 case ICBTAG_FILE_TYPE_BLOCK:
1336 {
1337 inode->i_mode |= S_IFBLK;
1338 break;
1339 }
1340 case ICBTAG_FILE_TYPE_CHAR:
1341 {
1342 inode->i_mode |= S_IFCHR;
1343 break;
1344 }
1345 case ICBTAG_FILE_TYPE_FIFO:
1346 {
1347 init_special_inode(inode, inode->i_mode | S_IFIFO, 0);
1348 break;
1349 }
1350 case ICBTAG_FILE_TYPE_SOCKET:
1351 {
1352 init_special_inode(inode, inode->i_mode | S_IFSOCK, 0);
1353 break;
1354 }
1355 case ICBTAG_FILE_TYPE_SYMLINK:
1356 {
1357 inode->i_data.a_ops = &udf_symlink_aops;
1358 inode->i_op = &page_symlink_inode_operations;
1359 inode->i_mode = S_IFLNK|S_IRWXUGO;
1360 break;
1361 }
1362 default:
1363 {
1364 printk(KERN_ERR "udf: udf_fill_inode(ino %ld) failed unknown file type=%d\n",
1365 inode->i_ino, fe->icbTag.fileType);
1366 make_bad_inode(inode);
1367 return;
1368 }
1369 }
1370 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
1371 {
1372 struct deviceSpec *dsea =
1373 (struct deviceSpec *)
1374 udf_get_extendedattr(inode, 12, 1);
1375
1376 if (dsea)
1377 {
1378 init_special_inode(inode, inode->i_mode, MKDEV(
1379 le32_to_cpu(dsea->majorDeviceIdent),
1380 le32_to_cpu(dsea->minorDeviceIdent)));
1381 /* Developer ID ??? */
1382 }
1383 else
1384 {
1385 make_bad_inode(inode);
1386 }
1387 }
1388}
1389
Cyrill Gorcunov647bd612007-07-15 23:39:47 -07001390static int udf_alloc_i_data(struct inode *inode, size_t size)
1391{
1392 UDF_I_DATA(inode) = kmalloc(size, GFP_KERNEL);
1393
1394 if (!UDF_I_DATA(inode))
1395 {
1396 printk(KERN_ERR "udf:udf_alloc_i_data (ino %ld) no free memory\n",
1397 inode->i_ino);
1398 return -ENOMEM;
1399 }
1400
1401 return 0;
1402}
1403
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404static mode_t
1405udf_convert_permissions(struct fileEntry *fe)
1406{
1407 mode_t mode;
1408 uint32_t permissions;
1409 uint32_t flags;
1410
1411 permissions = le32_to_cpu(fe->permissions);
1412 flags = le16_to_cpu(fe->icbTag.flags);
1413
1414 mode = (( permissions ) & S_IRWXO) |
1415 (( permissions >> 2 ) & S_IRWXG) |
1416 (( permissions >> 4 ) & S_IRWXU) |
1417 (( flags & ICBTAG_FLAG_SETUID) ? S_ISUID : 0) |
1418 (( flags & ICBTAG_FLAG_SETGID) ? S_ISGID : 0) |
1419 (( flags & ICBTAG_FLAG_STICKY) ? S_ISVTX : 0);
1420
1421 return mode;
1422}
1423
1424/*
1425 * udf_write_inode
1426 *
1427 * PURPOSE
1428 * Write out the specified inode.
1429 *
1430 * DESCRIPTION
1431 * This routine is called whenever an inode is synced.
1432 * Currently this routine is just a placeholder.
1433 *
1434 * HISTORY
1435 * July 1, 1997 - Andrew E. Mileski
1436 * Written, tested, and released.
1437 */
1438
1439int udf_write_inode(struct inode * inode, int sync)
1440{
1441 int ret;
1442 lock_kernel();
1443 ret = udf_update_inode(inode, sync);
1444 unlock_kernel();
1445 return ret;
1446}
1447
1448int udf_sync_inode(struct inode * inode)
1449{
1450 return udf_update_inode(inode, 1);
1451}
1452
1453static int
1454udf_update_inode(struct inode *inode, int do_sync)
1455{
1456 struct buffer_head *bh = NULL;
1457 struct fileEntry *fe;
1458 struct extendedFileEntry *efe;
1459 uint32_t udfperms;
1460 uint16_t icbflags;
1461 uint16_t crclen;
1462 int i;
1463 kernel_timestamp cpu_time;
1464 int err = 0;
1465
1466 bh = udf_tread(inode->i_sb,
1467 udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0));
1468
1469 if (!bh)
1470 {
1471 udf_debug("bread failure\n");
1472 return -EIO;
1473 }
1474
1475 memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
1476
1477 fe = (struct fileEntry *)bh->b_data;
1478 efe = (struct extendedFileEntry *)bh->b_data;
1479
1480 if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_USE)
1481 {
1482 struct unallocSpaceEntry *use =
1483 (struct unallocSpaceEntry *)bh->b_data;
1484
1485 use->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
1486 memcpy(bh->b_data + sizeof(struct unallocSpaceEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct unallocSpaceEntry));
1487 crclen = sizeof(struct unallocSpaceEntry) + UDF_I_LENALLOC(inode) -
1488 sizeof(tag);
1489 use->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
1490 use->descTag.descCRCLength = cpu_to_le16(crclen);
1491 use->descTag.descCRC = cpu_to_le16(udf_crc((char *)use + sizeof(tag), crclen, 0));
1492
1493 use->descTag.tagChecksum = 0;
1494 for (i=0; i<16; i++)
1495 if (i != 4)
1496 use->descTag.tagChecksum += ((uint8_t *)&(use->descTag))[i];
1497
1498 mark_buffer_dirty(bh);
Jan Kara3bf25cb2007-05-08 00:35:16 -07001499 brelse(bh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500 return err;
1501 }
1502
Phillip Susi4d6660e2006-03-07 21:55:24 -08001503 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET))
1504 fe->uid = cpu_to_le32(-1);
Phillip Susi0e6b3e52006-03-25 03:08:14 -08001505 else fe->uid = cpu_to_le32(inode->i_uid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506
Phillip Susi4d6660e2006-03-07 21:55:24 -08001507 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET))
1508 fe->gid = cpu_to_le32(-1);
Phillip Susi0e6b3e52006-03-25 03:08:14 -08001509 else fe->gid = cpu_to_le32(inode->i_gid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510
1511 udfperms = ((inode->i_mode & S_IRWXO) ) |
1512 ((inode->i_mode & S_IRWXG) << 2) |
1513 ((inode->i_mode & S_IRWXU) << 4);
1514
1515 udfperms |= (le32_to_cpu(fe->permissions) &
1516 (FE_PERM_O_DELETE | FE_PERM_O_CHATTR |
1517 FE_PERM_G_DELETE | FE_PERM_G_CHATTR |
1518 FE_PERM_U_DELETE | FE_PERM_U_CHATTR));
1519 fe->permissions = cpu_to_le32(udfperms);
1520
1521 if (S_ISDIR(inode->i_mode))
1522 fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1);
1523 else
1524 fe->fileLinkCount = cpu_to_le16(inode->i_nlink);
1525
1526 fe->informationLength = cpu_to_le64(inode->i_size);
1527
1528 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
1529 {
1530 regid *eid;
1531 struct deviceSpec *dsea =
1532 (struct deviceSpec *)
1533 udf_get_extendedattr(inode, 12, 1);
1534
1535 if (!dsea)
1536 {
1537 dsea = (struct deviceSpec *)
1538 udf_add_extendedattr(inode,
1539 sizeof(struct deviceSpec) +
1540 sizeof(regid), 12, 0x3);
1541 dsea->attrType = cpu_to_le32(12);
1542 dsea->attrSubtype = 1;
1543 dsea->attrLength = cpu_to_le32(sizeof(struct deviceSpec) +
1544 sizeof(regid));
1545 dsea->impUseLength = cpu_to_le32(sizeof(regid));
1546 }
1547 eid = (regid *)dsea->impUse;
1548 memset(eid, 0, sizeof(regid));
1549 strcpy(eid->ident, UDF_ID_DEVELOPER);
1550 eid->identSuffix[0] = UDF_OS_CLASS_UNIX;
1551 eid->identSuffix[1] = UDF_OS_ID_LINUX;
1552 dsea->majorDeviceIdent = cpu_to_le32(imajor(inode));
1553 dsea->minorDeviceIdent = cpu_to_le32(iminor(inode));
1554 }
1555
1556 if (UDF_I_EFE(inode) == 0)
1557 {
1558 memcpy(bh->b_data + sizeof(struct fileEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct fileEntry));
1559 fe->logicalBlocksRecorded = cpu_to_le64(
1560 (inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >>
1561 (inode->i_sb->s_blocksize_bits - 9));
1562
1563 if (udf_time_to_stamp(&cpu_time, inode->i_atime))
1564 fe->accessTime = cpu_to_lets(cpu_time);
1565 if (udf_time_to_stamp(&cpu_time, inode->i_mtime))
1566 fe->modificationTime = cpu_to_lets(cpu_time);
1567 if (udf_time_to_stamp(&cpu_time, inode->i_ctime))
1568 fe->attrTime = cpu_to_lets(cpu_time);
1569 memset(&(fe->impIdent), 0, sizeof(regid));
1570 strcpy(fe->impIdent.ident, UDF_ID_DEVELOPER);
1571 fe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
1572 fe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
1573 fe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));
1574 fe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));
1575 fe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
1576 fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE);
1577 crclen = sizeof(struct fileEntry);
1578 }
1579 else
1580 {
1581 memcpy(bh->b_data + sizeof(struct extendedFileEntry), UDF_I_DATA(inode), inode->i_sb->s_blocksize - sizeof(struct extendedFileEntry));
1582 efe->objectSize = cpu_to_le64(inode->i_size);
1583 efe->logicalBlocksRecorded = cpu_to_le64(
1584 (inode->i_blocks + (1 << (inode->i_sb->s_blocksize_bits - 9)) - 1) >>
1585 (inode->i_sb->s_blocksize_bits - 9));
1586
1587 if (UDF_I_CRTIME(inode).tv_sec > inode->i_atime.tv_sec ||
1588 (UDF_I_CRTIME(inode).tv_sec == inode->i_atime.tv_sec &&
1589 UDF_I_CRTIME(inode).tv_nsec > inode->i_atime.tv_nsec))
1590 {
1591 UDF_I_CRTIME(inode) = inode->i_atime;
1592 }
1593 if (UDF_I_CRTIME(inode).tv_sec > inode->i_mtime.tv_sec ||
1594 (UDF_I_CRTIME(inode).tv_sec == inode->i_mtime.tv_sec &&
1595 UDF_I_CRTIME(inode).tv_nsec > inode->i_mtime.tv_nsec))
1596 {
1597 UDF_I_CRTIME(inode) = inode->i_mtime;
1598 }
1599 if (UDF_I_CRTIME(inode).tv_sec > inode->i_ctime.tv_sec ||
1600 (UDF_I_CRTIME(inode).tv_sec == inode->i_ctime.tv_sec &&
1601 UDF_I_CRTIME(inode).tv_nsec > inode->i_ctime.tv_nsec))
1602 {
1603 UDF_I_CRTIME(inode) = inode->i_ctime;
1604 }
1605
1606 if (udf_time_to_stamp(&cpu_time, inode->i_atime))
1607 efe->accessTime = cpu_to_lets(cpu_time);
1608 if (udf_time_to_stamp(&cpu_time, inode->i_mtime))
1609 efe->modificationTime = cpu_to_lets(cpu_time);
1610 if (udf_time_to_stamp(&cpu_time, UDF_I_CRTIME(inode)))
1611 efe->createTime = cpu_to_lets(cpu_time);
1612 if (udf_time_to_stamp(&cpu_time, inode->i_ctime))
1613 efe->attrTime = cpu_to_lets(cpu_time);
1614
1615 memset(&(efe->impIdent), 0, sizeof(regid));
1616 strcpy(efe->impIdent.ident, UDF_ID_DEVELOPER);
1617 efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
1618 efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
1619 efe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));
1620 efe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));
1621 efe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
1622 efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE);
1623 crclen = sizeof(struct extendedFileEntry);
1624 }
1625 if (UDF_I_STRAT4096(inode))
1626 {
1627 fe->icbTag.strategyType = cpu_to_le16(4096);
1628 fe->icbTag.strategyParameter = cpu_to_le16(1);
1629 fe->icbTag.numEntries = cpu_to_le16(2);
1630 }
1631 else
1632 {
1633 fe->icbTag.strategyType = cpu_to_le16(4);
1634 fe->icbTag.numEntries = cpu_to_le16(1);
1635 }
1636
1637 if (S_ISDIR(inode->i_mode))
1638 fe->icbTag.fileType = ICBTAG_FILE_TYPE_DIRECTORY;
1639 else if (S_ISREG(inode->i_mode))
1640 fe->icbTag.fileType = ICBTAG_FILE_TYPE_REGULAR;
1641 else if (S_ISLNK(inode->i_mode))
1642 fe->icbTag.fileType = ICBTAG_FILE_TYPE_SYMLINK;
1643 else if (S_ISBLK(inode->i_mode))
1644 fe->icbTag.fileType = ICBTAG_FILE_TYPE_BLOCK;
1645 else if (S_ISCHR(inode->i_mode))
1646 fe->icbTag.fileType = ICBTAG_FILE_TYPE_CHAR;
1647 else if (S_ISFIFO(inode->i_mode))
1648 fe->icbTag.fileType = ICBTAG_FILE_TYPE_FIFO;
1649 else if (S_ISSOCK(inode->i_mode))
1650 fe->icbTag.fileType = ICBTAG_FILE_TYPE_SOCKET;
1651
1652 icbflags = UDF_I_ALLOCTYPE(inode) |
1653 ((inode->i_mode & S_ISUID) ? ICBTAG_FLAG_SETUID : 0) |
1654 ((inode->i_mode & S_ISGID) ? ICBTAG_FLAG_SETGID : 0) |
1655 ((inode->i_mode & S_ISVTX) ? ICBTAG_FLAG_STICKY : 0) |
1656 (le16_to_cpu(fe->icbTag.flags) &
1657 ~(ICBTAG_FLAG_AD_MASK | ICBTAG_FLAG_SETUID |
1658 ICBTAG_FLAG_SETGID | ICBTAG_FLAG_STICKY));
1659
1660 fe->icbTag.flags = cpu_to_le16(icbflags);
1661 if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
1662 fe->descTag.descVersion = cpu_to_le16(3);
1663 else
1664 fe->descTag.descVersion = cpu_to_le16(2);
1665 fe->descTag.tagSerialNum = cpu_to_le16(UDF_SB_SERIALNUM(inode->i_sb));
1666 fe->descTag.tagLocation = cpu_to_le32(UDF_I_LOCATION(inode).logicalBlockNum);
1667 crclen += UDF_I_LENEATTR(inode) + UDF_I_LENALLOC(inode) - sizeof(tag);
1668 fe->descTag.descCRCLength = cpu_to_le16(crclen);
1669 fe->descTag.descCRC = cpu_to_le16(udf_crc((char *)fe + sizeof(tag), crclen, 0));
1670
1671 fe->descTag.tagChecksum = 0;
1672 for (i=0; i<16; i++)
1673 if (i != 4)
1674 fe->descTag.tagChecksum += ((uint8_t *)&(fe->descTag))[i];
1675
1676 /* write the data blocks */
1677 mark_buffer_dirty(bh);
1678 if (do_sync)
1679 {
1680 sync_dirty_buffer(bh);
1681 if (buffer_req(bh) && !buffer_uptodate(bh))
1682 {
1683 printk("IO error syncing udf inode [%s:%08lx]\n",
1684 inode->i_sb->s_id, inode->i_ino);
1685 err = -EIO;
1686 }
1687 }
Jan Kara3bf25cb2007-05-08 00:35:16 -07001688 brelse(bh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 return err;
1690}
1691
1692struct inode *
1693udf_iget(struct super_block *sb, kernel_lb_addr ino)
1694{
1695 unsigned long block = udf_get_lb_pblock(sb, ino, 0);
1696 struct inode *inode = iget_locked(sb, block);
1697
1698 if (!inode)
1699 return NULL;
1700
1701 if (inode->i_state & I_NEW) {
1702 memcpy(&UDF_I_LOCATION(inode), &ino, sizeof(kernel_lb_addr));
1703 __udf_read_inode(inode);
1704 unlock_new_inode(inode);
1705 }
1706
1707 if (is_bad_inode(inode))
1708 goto out_iput;
1709
1710 if (ino.logicalBlockNum >= UDF_SB_PARTLEN(sb, ino.partitionReferenceNum)) {
1711 udf_debug("block=%d, partition=%d out of range\n",
1712 ino.logicalBlockNum, ino.partitionReferenceNum);
1713 make_bad_inode(inode);
1714 goto out_iput;
1715 }
1716
1717 return inode;
1718
1719 out_iput:
1720 iput(inode);
1721 return NULL;
1722}
1723
Jan Karaff116fc2007-05-08 00:35:14 -07001724int8_t udf_add_aext(struct inode *inode, struct extent_position *epos,
1725 kernel_lb_addr eloc, uint32_t elen, int inc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726{
1727 int adsize;
1728 short_ad *sad = NULL;
1729 long_ad *lad = NULL;
1730 struct allocExtDesc *aed;
1731 int8_t etype;
1732 uint8_t *ptr;
1733
Jan Karaff116fc2007-05-08 00:35:14 -07001734 if (!epos->bh)
1735 ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 else
Jan Karaff116fc2007-05-08 00:35:14 -07001737 ptr = epos->bh->b_data + epos->offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738
1739 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
1740 adsize = sizeof(short_ad);
1741 else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
1742 adsize = sizeof(long_ad);
1743 else
1744 return -1;
1745
Jan Karaff116fc2007-05-08 00:35:14 -07001746 if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 {
1748 char *sptr, *dptr;
1749 struct buffer_head *nbh;
1750 int err, loffset;
Jan Karaff116fc2007-05-08 00:35:14 -07001751 kernel_lb_addr obloc = epos->block;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752
Jan Karaff116fc2007-05-08 00:35:14 -07001753 if (!(epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 obloc.partitionReferenceNum, obloc.logicalBlockNum, &err)))
1755 {
1756 return -1;
1757 }
1758 if (!(nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
Jan Karaff116fc2007-05-08 00:35:14 -07001759 epos->block, 0))))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 {
1761 return -1;
1762 }
1763 lock_buffer(nbh);
1764 memset(nbh->b_data, 0x00, inode->i_sb->s_blocksize);
1765 set_buffer_uptodate(nbh);
1766 unlock_buffer(nbh);
1767 mark_buffer_dirty_inode(nbh, inode);
1768
1769 aed = (struct allocExtDesc *)(nbh->b_data);
1770 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
1771 aed->previousAllocExtLocation = cpu_to_le32(obloc.logicalBlockNum);
Jan Karaff116fc2007-05-08 00:35:14 -07001772 if (epos->offset + adsize > inode->i_sb->s_blocksize)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 {
Jan Karaff116fc2007-05-08 00:35:14 -07001774 loffset = epos->offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 aed->lengthAllocDescs = cpu_to_le32(adsize);
1776 sptr = ptr - adsize;
1777 dptr = nbh->b_data + sizeof(struct allocExtDesc);
1778 memcpy(dptr, sptr, adsize);
Jan Karaff116fc2007-05-08 00:35:14 -07001779 epos->offset = sizeof(struct allocExtDesc) + adsize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 }
1781 else
1782 {
Jan Karaff116fc2007-05-08 00:35:14 -07001783 loffset = epos->offset + adsize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784 aed->lengthAllocDescs = cpu_to_le32(0);
1785 sptr = ptr;
Jan Karaff116fc2007-05-08 00:35:14 -07001786 epos->offset = sizeof(struct allocExtDesc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787
Jan Karaff116fc2007-05-08 00:35:14 -07001788 if (epos->bh)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789 {
Jan Karaff116fc2007-05-08 00:35:14 -07001790 aed = (struct allocExtDesc *)epos->bh->b_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 aed->lengthAllocDescs =
1792 cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
1793 }
1794 else
1795 {
1796 UDF_I_LENALLOC(inode) += adsize;
1797 mark_inode_dirty(inode);
1798 }
1799 }
1800 if (UDF_SB_UDFREV(inode->i_sb) >= 0x0200)
1801 udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
Jan Karaff116fc2007-05-08 00:35:14 -07001802 epos->block.logicalBlockNum, sizeof(tag));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 else
1804 udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
Jan Karaff116fc2007-05-08 00:35:14 -07001805 epos->block.logicalBlockNum, sizeof(tag));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 switch (UDF_I_ALLOCTYPE(inode))
1807 {
1808 case ICBTAG_FLAG_AD_SHORT:
1809 {
1810 sad = (short_ad *)sptr;
1811 sad->extLength = cpu_to_le32(
1812 EXT_NEXT_EXTENT_ALLOCDECS |
1813 inode->i_sb->s_blocksize);
Jan Karaff116fc2007-05-08 00:35:14 -07001814 sad->extPosition = cpu_to_le32(epos->block.logicalBlockNum);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 break;
1816 }
1817 case ICBTAG_FLAG_AD_LONG:
1818 {
1819 lad = (long_ad *)sptr;
1820 lad->extLength = cpu_to_le32(
1821 EXT_NEXT_EXTENT_ALLOCDECS |
1822 inode->i_sb->s_blocksize);
Jan Karaff116fc2007-05-08 00:35:14 -07001823 lad->extLocation = cpu_to_lelb(epos->block);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 memset(lad->impUse, 0x00, sizeof(lad->impUse));
1825 break;
1826 }
1827 }
Jan Karaff116fc2007-05-08 00:35:14 -07001828 if (epos->bh)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 {
1830 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
Jan Karaff116fc2007-05-08 00:35:14 -07001831 udf_update_tag(epos->bh->b_data, loffset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 else
Jan Karaff116fc2007-05-08 00:35:14 -07001833 udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc));
1834 mark_buffer_dirty_inode(epos->bh, inode);
Jan Kara3bf25cb2007-05-08 00:35:16 -07001835 brelse(epos->bh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 }
1837 else
1838 mark_inode_dirty(inode);
Jan Karaff116fc2007-05-08 00:35:14 -07001839 epos->bh = nbh;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 }
1841
Jan Karaff116fc2007-05-08 00:35:14 -07001842 etype = udf_write_aext(inode, epos, eloc, elen, inc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843
Jan Karaff116fc2007-05-08 00:35:14 -07001844 if (!epos->bh)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 {
1846 UDF_I_LENALLOC(inode) += adsize;
1847 mark_inode_dirty(inode);
1848 }
1849 else
1850 {
Jan Karaff116fc2007-05-08 00:35:14 -07001851 aed = (struct allocExtDesc *)epos->bh->b_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852 aed->lengthAllocDescs =
1853 cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize);
1854 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
Jan Karaff116fc2007-05-08 00:35:14 -07001855 udf_update_tag(epos->bh->b_data, epos->offset + (inc ? 0 : adsize));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856 else
Jan Karaff116fc2007-05-08 00:35:14 -07001857 udf_update_tag(epos->bh->b_data, sizeof(struct allocExtDesc));
1858 mark_buffer_dirty_inode(epos->bh, inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859 }
1860
1861 return etype;
1862}
1863
Jan Karaff116fc2007-05-08 00:35:14 -07001864int8_t udf_write_aext(struct inode *inode, struct extent_position *epos,
1865 kernel_lb_addr eloc, uint32_t elen, int inc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866{
1867 int adsize;
1868 uint8_t *ptr;
1869
Jan Karaff116fc2007-05-08 00:35:14 -07001870 if (!epos->bh)
1871 ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001872 else
Jan Karaff116fc2007-05-08 00:35:14 -07001873 ptr = epos->bh->b_data + epos->offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874
1875 switch (UDF_I_ALLOCTYPE(inode))
1876 {
1877 case ICBTAG_FLAG_AD_SHORT:
1878 {
1879 short_ad *sad = (short_ad *)ptr;
1880 sad->extLength = cpu_to_le32(elen);
1881 sad->extPosition = cpu_to_le32(eloc.logicalBlockNum);
1882 adsize = sizeof(short_ad);
1883 break;
1884 }
1885 case ICBTAG_FLAG_AD_LONG:
1886 {
1887 long_ad *lad = (long_ad *)ptr;
1888 lad->extLength = cpu_to_le32(elen);
1889 lad->extLocation = cpu_to_lelb(eloc);
1890 memset(lad->impUse, 0x00, sizeof(lad->impUse));
1891 adsize = sizeof(long_ad);
1892 break;
1893 }
1894 default:
1895 return -1;
1896 }
1897
Jan Karaff116fc2007-05-08 00:35:14 -07001898 if (epos->bh)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899 {
1900 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
1901 {
Jan Karaff116fc2007-05-08 00:35:14 -07001902 struct allocExtDesc *aed = (struct allocExtDesc *)epos->bh->b_data;
1903 udf_update_tag(epos->bh->b_data,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904 le32_to_cpu(aed->lengthAllocDescs) + sizeof(struct allocExtDesc));
1905 }
Jan Karaff116fc2007-05-08 00:35:14 -07001906 mark_buffer_dirty_inode(epos->bh, inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907 }
1908 else
1909 mark_inode_dirty(inode);
1910
1911 if (inc)
Jan Karaff116fc2007-05-08 00:35:14 -07001912 epos->offset += adsize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913 return (elen >> 30);
1914}
1915
Jan Karaff116fc2007-05-08 00:35:14 -07001916int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
1917 kernel_lb_addr *eloc, uint32_t *elen, int inc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918{
1919 int8_t etype;
1920
Jan Karaff116fc2007-05-08 00:35:14 -07001921 while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) ==
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 (EXT_NEXT_EXTENT_ALLOCDECS >> 30))
1923 {
Jan Karaff116fc2007-05-08 00:35:14 -07001924 epos->block = *eloc;
1925 epos->offset = sizeof(struct allocExtDesc);
Jan Kara3bf25cb2007-05-08 00:35:16 -07001926 brelse(epos->bh);
Jan Karaff116fc2007-05-08 00:35:14 -07001927 if (!(epos->bh = udf_tread(inode->i_sb, udf_get_lb_pblock(inode->i_sb, epos->block, 0))))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928 {
1929 udf_debug("reading block %d failed!\n",
Jan Karaff116fc2007-05-08 00:35:14 -07001930 udf_get_lb_pblock(inode->i_sb, epos->block, 0));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931 return -1;
1932 }
1933 }
1934
1935 return etype;
1936}
1937
Jan Karaff116fc2007-05-08 00:35:14 -07001938int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
1939 kernel_lb_addr *eloc, uint32_t *elen, int inc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940{
1941 int alen;
1942 int8_t etype;
1943 uint8_t *ptr;
1944
Jan Karaff116fc2007-05-08 00:35:14 -07001945 if (!epos->bh)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 {
Jan Karaff116fc2007-05-08 00:35:14 -07001947 if (!epos->offset)
1948 epos->offset = udf_file_entry_alloc_offset(inode);
1949 ptr = UDF_I_DATA(inode) + epos->offset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950 alen = udf_file_entry_alloc_offset(inode) + UDF_I_LENALLOC(inode);
1951 }
1952 else
1953 {
Jan Karaff116fc2007-05-08 00:35:14 -07001954 if (!epos->offset)
1955 epos->offset = sizeof(struct allocExtDesc);
1956 ptr = epos->bh->b_data + epos->offset;
1957 alen = sizeof(struct allocExtDesc) + le32_to_cpu(((struct allocExtDesc *)epos->bh->b_data)->lengthAllocDescs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958 }
1959
1960 switch (UDF_I_ALLOCTYPE(inode))
1961 {
1962 case ICBTAG_FLAG_AD_SHORT:
1963 {
1964 short_ad *sad;
1965
Jan Karaff116fc2007-05-08 00:35:14 -07001966 if (!(sad = udf_get_fileshortad(ptr, alen, &epos->offset, inc)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001967 return -1;
1968
1969 etype = le32_to_cpu(sad->extLength) >> 30;
1970 eloc->logicalBlockNum = le32_to_cpu(sad->extPosition);
1971 eloc->partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
1972 *elen = le32_to_cpu(sad->extLength) & UDF_EXTENT_LENGTH_MASK;
1973 break;
1974 }
1975 case ICBTAG_FLAG_AD_LONG:
1976 {
1977 long_ad *lad;
1978
Jan Karaff116fc2007-05-08 00:35:14 -07001979 if (!(lad = udf_get_filelongad(ptr, alen, &epos->offset, inc)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001980 return -1;
1981
1982 etype = le32_to_cpu(lad->extLength) >> 30;
1983 *eloc = lelb_to_cpu(lad->extLocation);
1984 *elen = le32_to_cpu(lad->extLength) & UDF_EXTENT_LENGTH_MASK;
1985 break;
1986 }
1987 default:
1988 {
1989 udf_debug("alloc_type = %d unsupported\n", UDF_I_ALLOCTYPE(inode));
1990 return -1;
1991 }
1992 }
1993
1994 return etype;
1995}
1996
1997static int8_t
Jan Karaff116fc2007-05-08 00:35:14 -07001998udf_insert_aext(struct inode *inode, struct extent_position epos,
1999 kernel_lb_addr neloc, uint32_t nelen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002000{
2001 kernel_lb_addr oeloc;
2002 uint32_t oelen;
2003 int8_t etype;
2004
Jan Karaff116fc2007-05-08 00:35:14 -07002005 if (epos.bh)
Jan Kara3bf25cb2007-05-08 00:35:16 -07002006 get_bh(epos.bh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007
Jan Karaff116fc2007-05-08 00:35:14 -07002008 while ((etype = udf_next_aext(inode, &epos, &oeloc, &oelen, 0)) != -1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002009 {
Jan Karaff116fc2007-05-08 00:35:14 -07002010 udf_write_aext(inode, &epos, neloc, nelen, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002011
2012 neloc = oeloc;
2013 nelen = (etype << 30) | oelen;
2014 }
Jan Karaff116fc2007-05-08 00:35:14 -07002015 udf_add_aext(inode, &epos, neloc, nelen, 1);
Jan Kara3bf25cb2007-05-08 00:35:16 -07002016 brelse(epos.bh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017 return (nelen >> 30);
2018}
2019
Jan Karaff116fc2007-05-08 00:35:14 -07002020int8_t udf_delete_aext(struct inode *inode, struct extent_position epos,
2021 kernel_lb_addr eloc, uint32_t elen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022{
Jan Karaff116fc2007-05-08 00:35:14 -07002023 struct extent_position oepos;
2024 int adsize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002025 int8_t etype;
2026 struct allocExtDesc *aed;
2027
Jan Karaff116fc2007-05-08 00:35:14 -07002028 if (epos.bh)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002029 {
Jan Kara3bf25cb2007-05-08 00:35:16 -07002030 get_bh(epos.bh);
2031 get_bh(epos.bh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002032 }
2033
2034 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
2035 adsize = sizeof(short_ad);
2036 else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
2037 adsize = sizeof(long_ad);
2038 else
2039 adsize = 0;
2040
Jan Karaff116fc2007-05-08 00:35:14 -07002041 oepos = epos;
2042 if (udf_next_aext(inode, &epos, &eloc, &elen, 1) == -1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043 return -1;
2044
Jan Karaff116fc2007-05-08 00:35:14 -07002045 while ((etype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046 {
Jan Karaff116fc2007-05-08 00:35:14 -07002047 udf_write_aext(inode, &oepos, eloc, (etype << 30) | elen, 1);
2048 if (oepos.bh != epos.bh)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049 {
Jan Karaff116fc2007-05-08 00:35:14 -07002050 oepos.block = epos.block;
Jan Kara3bf25cb2007-05-08 00:35:16 -07002051 brelse(oepos.bh);
2052 get_bh(epos.bh);
Jan Karaff116fc2007-05-08 00:35:14 -07002053 oepos.bh = epos.bh;
2054 oepos.offset = epos.offset - adsize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002055 }
2056 }
2057 memset(&eloc, 0x00, sizeof(kernel_lb_addr));
2058 elen = 0;
2059
Jan Karaff116fc2007-05-08 00:35:14 -07002060 if (epos.bh != oepos.bh)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061 {
Jan Karaff116fc2007-05-08 00:35:14 -07002062 udf_free_blocks(inode->i_sb, inode, epos.block, 0, 1);
2063 udf_write_aext(inode, &oepos, eloc, elen, 1);
2064 udf_write_aext(inode, &oepos, eloc, elen, 1);
2065 if (!oepos.bh)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002066 {
2067 UDF_I_LENALLOC(inode) -= (adsize * 2);
2068 mark_inode_dirty(inode);
2069 }
2070 else
2071 {
Jan Karaff116fc2007-05-08 00:35:14 -07002072 aed = (struct allocExtDesc *)oepos.bh->b_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073 aed->lengthAllocDescs =
2074 cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - (2*adsize));
2075 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
Jan Karaff116fc2007-05-08 00:35:14 -07002076 udf_update_tag(oepos.bh->b_data, oepos.offset - (2*adsize));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002077 else
Jan Karaff116fc2007-05-08 00:35:14 -07002078 udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc));
2079 mark_buffer_dirty_inode(oepos.bh, inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002080 }
2081 }
2082 else
2083 {
Jan Karaff116fc2007-05-08 00:35:14 -07002084 udf_write_aext(inode, &oepos, eloc, elen, 1);
2085 if (!oepos.bh)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 {
2087 UDF_I_LENALLOC(inode) -= adsize;
2088 mark_inode_dirty(inode);
2089 }
2090 else
2091 {
Jan Karaff116fc2007-05-08 00:35:14 -07002092 aed = (struct allocExtDesc *)oepos.bh->b_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002093 aed->lengthAllocDescs =
2094 cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) - adsize);
2095 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
Jan Karaff116fc2007-05-08 00:35:14 -07002096 udf_update_tag(oepos.bh->b_data, epos.offset - adsize);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097 else
Jan Karaff116fc2007-05-08 00:35:14 -07002098 udf_update_tag(oepos.bh->b_data, sizeof(struct allocExtDesc));
2099 mark_buffer_dirty_inode(oepos.bh, inode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002100 }
2101 }
Cyrill Gorcunov647bd612007-07-15 23:39:47 -07002102
Jan Kara3bf25cb2007-05-08 00:35:16 -07002103 brelse(epos.bh);
2104 brelse(oepos.bh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105 return (elen >> 30);
2106}
2107
Jan Karaff116fc2007-05-08 00:35:14 -07002108int8_t inode_bmap(struct inode *inode, sector_t block, struct extent_position *pos,
2109 kernel_lb_addr *eloc, uint32_t *elen, sector_t *offset)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002110{
Jan Kara60448b12007-05-08 00:35:13 -07002111 loff_t lbcount = 0, bcount = (loff_t)block << inode->i_sb->s_blocksize_bits;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002112 int8_t etype;
2113
2114 if (block < 0)
2115 {
2116 printk(KERN_ERR "udf: inode_bmap: block < 0\n");
2117 return -1;
2118 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002119
Jan Karaff116fc2007-05-08 00:35:14 -07002120 pos->offset = 0;
2121 pos->block = UDF_I_LOCATION(inode);
2122 pos->bh = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123 *elen = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124
2125 do
2126 {
Jan Karaff116fc2007-05-08 00:35:14 -07002127 if ((etype = udf_next_aext(inode, pos, eloc, elen, 1)) == -1)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128 {
Jan Kara60448b12007-05-08 00:35:13 -07002129 *offset = (bcount - lbcount) >> inode->i_sb->s_blocksize_bits;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002130 UDF_I_LENEXTENTS(inode) = lbcount;
2131 return -1;
2132 }
2133 lbcount += *elen;
2134 } while (lbcount <= bcount);
2135
Jan Kara60448b12007-05-08 00:35:13 -07002136 *offset = (bcount + *elen - lbcount) >> inode->i_sb->s_blocksize_bits;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137
2138 return etype;
2139}
2140
Jan Kara60448b12007-05-08 00:35:13 -07002141long udf_block_map(struct inode *inode, sector_t block)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002142{
Jan Karaff116fc2007-05-08 00:35:14 -07002143 kernel_lb_addr eloc;
2144 uint32_t elen;
Jan Kara60448b12007-05-08 00:35:13 -07002145 sector_t offset;
Jan Karaff116fc2007-05-08 00:35:14 -07002146 struct extent_position epos = { NULL, 0, { 0, 0}};
Linus Torvalds1da177e2005-04-16 15:20:36 -07002147 int ret;
2148
2149 lock_kernel();
2150
Jan Karaff116fc2007-05-08 00:35:14 -07002151 if (inode_bmap(inode, block, &epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
Jan Kara60448b12007-05-08 00:35:13 -07002152 ret = udf_get_lb_pblock(inode->i_sb, eloc, offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002153 else
2154 ret = 0;
2155
2156 unlock_kernel();
Jan Kara3bf25cb2007-05-08 00:35:16 -07002157 brelse(epos.bh);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158
2159 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_VARCONV))
2160 return udf_fixed_to_variable(ret);
2161 else
2162 return ret;
2163}