1 // SPDX-License-Identifier: GPL-2.0-only
6 * Directory related functions
14 #include <linux/string.h>
15 #include <linux/bio.h>
16 #include <linux/crc-itu-t.h>
17 #include <linux/iversion.h>
19 static int udf_verify_fi(struct udf_fileident_iter
*iter
)
23 if (iter
->fi
.descTag
.tagIdent
!= cpu_to_le16(TAG_IDENT_FID
)) {
24 udf_err(iter
->dir
->i_sb
,
25 "directory (ino %lu) has entry at pos %llu with incorrect tag %x\n",
26 iter
->dir
->i_ino
, (unsigned long long)iter
->pos
,
27 le16_to_cpu(iter
->fi
.descTag
.tagIdent
));
30 len
= udf_dir_entry_len(&iter
->fi
);
31 if (le16_to_cpu(iter
->fi
.lengthOfImpUse
) & 3) {
32 udf_err(iter
->dir
->i_sb
,
33 "directory (ino %lu) has entry at pos %llu with unaligned length of impUse field\n",
34 iter
->dir
->i_ino
, (unsigned long long)iter
->pos
);
38 * This is in fact allowed by the spec due to long impUse field but
39 * we don't support it. If there is real media with this large impUse
40 * field, support can be added.
42 if (len
> 1 << iter
->dir
->i_blkbits
) {
43 udf_err(iter
->dir
->i_sb
,
44 "directory (ino %lu) has too big (%u) entry at pos %llu\n",
45 iter
->dir
->i_ino
, len
, (unsigned long long)iter
->pos
);
48 if (iter
->pos
+ len
> iter
->dir
->i_size
) {
49 udf_err(iter
->dir
->i_sb
,
50 "directory (ino %lu) has entry past directory size at pos %llu\n",
51 iter
->dir
->i_ino
, (unsigned long long)iter
->pos
);
54 if (udf_dir_entry_len(&iter
->fi
) !=
55 sizeof(struct tag
) + le16_to_cpu(iter
->fi
.descTag
.descCRCLength
)) {
56 udf_err(iter
->dir
->i_sb
,
57 "directory (ino %lu) has entry where CRC length (%u) does not match entry length (%u)\n",
59 (unsigned)le16_to_cpu(iter
->fi
.descTag
.descCRCLength
),
60 (unsigned)(udf_dir_entry_len(&iter
->fi
) -
67 static int udf_copy_fi(struct udf_fileident_iter
*iter
)
69 struct udf_inode_info
*iinfo
= UDF_I(iter
->dir
);
70 u32 blksize
= 1 << iter
->dir
->i_blkbits
;
71 u32 off
, len
, nameoff
;
74 /* Skip copying when we are at EOF */
75 if (iter
->pos
>= iter
->dir
->i_size
) {
79 if (iter
->dir
->i_size
< iter
->pos
+ sizeof(struct fileIdentDesc
)) {
80 udf_err(iter
->dir
->i_sb
,
81 "directory (ino %lu) has entry straddling EOF\n",
85 if (iinfo
->i_alloc_type
== ICBTAG_FLAG_AD_IN_ICB
) {
86 memcpy(&iter
->fi
, iinfo
->i_data
+ iinfo
->i_lenEAttr
+ iter
->pos
,
87 sizeof(struct fileIdentDesc
));
88 err
= udf_verify_fi(iter
);
91 iter
->name
= iinfo
->i_data
+ iinfo
->i_lenEAttr
+ iter
->pos
+
92 sizeof(struct fileIdentDesc
) +
93 le16_to_cpu(iter
->fi
.lengthOfImpUse
);
97 off
= iter
->pos
& (blksize
- 1);
98 len
= min_t(u32
, sizeof(struct fileIdentDesc
), blksize
- off
);
99 memcpy(&iter
->fi
, iter
->bh
[0]->b_data
+ off
, len
);
100 if (len
< sizeof(struct fileIdentDesc
))
101 memcpy((char *)(&iter
->fi
) + len
, iter
->bh
[1]->b_data
,
102 sizeof(struct fileIdentDesc
) - len
);
103 err
= udf_verify_fi(iter
);
107 /* Handle directory entry name */
108 nameoff
= off
+ sizeof(struct fileIdentDesc
) +
109 le16_to_cpu(iter
->fi
.lengthOfImpUse
);
110 if (off
+ udf_dir_entry_len(&iter
->fi
) <= blksize
) {
111 iter
->name
= iter
->bh
[0]->b_data
+ nameoff
;
112 } else if (nameoff
>= blksize
) {
113 iter
->name
= iter
->bh
[1]->b_data
+ (nameoff
- blksize
);
115 iter
->name
= iter
->namebuf
;
116 len
= blksize
- nameoff
;
117 memcpy(iter
->name
, iter
->bh
[0]->b_data
+ nameoff
, len
);
118 memcpy(iter
->name
+ len
, iter
->bh
[1]->b_data
,
119 iter
->fi
.lengthFileIdent
- len
);
124 /* Readahead 8k once we are at 8k boundary */
125 static void udf_readahead_dir(struct udf_fileident_iter
*iter
)
127 unsigned int ralen
= 16 >> (iter
->dir
->i_blkbits
- 9);
128 struct buffer_head
*tmp
, *bha
[16];
132 if (iter
->loffset
& (ralen
- 1))
135 if (iter
->loffset
+ ralen
> (iter
->elen
>> iter
->dir
->i_blkbits
))
136 ralen
= (iter
->elen
>> iter
->dir
->i_blkbits
) - iter
->loffset
;
138 for (i
= 0; i
< ralen
; i
++) {
139 blk
= udf_get_lb_pblock(iter
->dir
->i_sb
, &iter
->eloc
,
141 tmp
= sb_getblk(iter
->dir
->i_sb
, blk
);
142 if (tmp
&& !buffer_uptodate(tmp
) && !buffer_locked(tmp
))
148 bh_readahead_batch(num
, bha
, REQ_RAHEAD
);
149 for (i
= 0; i
< num
; i
++)
154 static struct buffer_head
*udf_fiiter_bread_blk(struct udf_fileident_iter
*iter
)
158 udf_readahead_dir(iter
);
159 blk
= udf_get_lb_pblock(iter
->dir
->i_sb
, &iter
->eloc
, iter
->loffset
);
160 return sb_bread(iter
->dir
->i_sb
, blk
);
164 * Updates loffset to point to next directory block; eloc, elen & epos are
165 * updated if we need to traverse to the next extent as well.
167 static int udf_fiiter_advance_blk(struct udf_fileident_iter
*iter
)
173 if (iter
->loffset
< DIV_ROUND_UP(iter
->elen
, 1<<iter
->dir
->i_blkbits
))
177 err
= udf_next_aext(iter
->dir
, &iter
->epos
, &iter
->eloc
,
178 &iter
->elen
, &etype
, 1);
181 else if (err
== 0 || etype
!= (EXT_RECORDED_ALLOCATED
>> 30)) {
182 if (iter
->pos
== iter
->dir
->i_size
) {
186 udf_err(iter
->dir
->i_sb
,
187 "extent after position %llu not allocated in directory (ino %lu)\n",
188 (unsigned long long)iter
->pos
, iter
->dir
->i_ino
);
189 return -EFSCORRUPTED
;
194 static int udf_fiiter_load_bhs(struct udf_fileident_iter
*iter
)
196 int blksize
= 1 << iter
->dir
->i_blkbits
;
197 int off
= iter
->pos
& (blksize
- 1);
199 struct fileIdentDesc
*fi
;
201 /* Is there any further extent we can map from? */
202 if (!iter
->bh
[0] && iter
->elen
) {
203 iter
->bh
[0] = udf_fiiter_bread_blk(iter
);
208 if (!buffer_uptodate(iter
->bh
[0])) {
213 /* There's no next block so we are done */
214 if (iter
->pos
>= iter
->dir
->i_size
)
216 /* Need to fetch next block as well? */
217 if (off
+ sizeof(struct fileIdentDesc
) > blksize
)
219 fi
= (struct fileIdentDesc
*)(iter
->bh
[0]->b_data
+ off
);
220 /* Need to fetch next block to get name? */
221 if (off
+ udf_dir_entry_len(fi
) > blksize
) {
223 err
= udf_fiiter_advance_blk(iter
);
226 iter
->bh
[1] = udf_fiiter_bread_blk(iter
);
231 if (!buffer_uptodate(iter
->bh
[1])) {
240 iter
->bh
[0] = iter
->bh
[1] = NULL
;
244 int udf_fiiter_init(struct udf_fileident_iter
*iter
, struct inode
*dir
,
247 struct udf_inode_info
*iinfo
= UDF_I(dir
);
252 iter
->bh
[0] = iter
->bh
[1] = NULL
;
255 iter
->epos
.bh
= NULL
;
258 * When directory is verified, we don't expect directory iteration to
259 * fail and it can be difficult to undo without corrupting filesystem.
260 * So just do not allow memory allocation failures here.
262 iter
->namebuf
= kmalloc(UDF_NAME_LEN_CS0
, GFP_KERNEL
| __GFP_NOFAIL
);
264 if (iinfo
->i_alloc_type
== ICBTAG_FLAG_AD_IN_ICB
) {
265 err
= udf_copy_fi(iter
);
269 err
= inode_bmap(dir
, iter
->pos
>> dir
->i_blkbits
, &iter
->epos
,
270 &iter
->eloc
, &iter
->elen
, &iter
->loffset
, &etype
);
271 if (err
<= 0 || etype
!= (EXT_RECORDED_ALLOCATED
>> 30)) {
272 if (pos
== dir
->i_size
)
275 "position %llu not allocated in directory (ino %lu)\n",
276 (unsigned long long)pos
, dir
->i_ino
);
280 err
= udf_fiiter_load_bhs(iter
);
283 err
= udf_copy_fi(iter
);
286 udf_fiiter_release(iter
);
290 int udf_fiiter_advance(struct udf_fileident_iter
*iter
)
292 unsigned int oldoff
, len
;
293 int blksize
= 1 << iter
->dir
->i_blkbits
;
296 oldoff
= iter
->pos
& (blksize
- 1);
297 len
= udf_dir_entry_len(&iter
->fi
);
299 if (UDF_I(iter
->dir
)->i_alloc_type
!= ICBTAG_FLAG_AD_IN_ICB
) {
300 if (oldoff
+ len
>= blksize
) {
303 /* Next block already loaded? */
305 iter
->bh
[0] = iter
->bh
[1];
308 err
= udf_fiiter_advance_blk(iter
);
313 err
= udf_fiiter_load_bhs(iter
);
317 return udf_copy_fi(iter
);
320 void udf_fiiter_release(struct udf_fileident_iter
*iter
)
325 iter
->bh
[0] = iter
->bh
[1] = NULL
;
326 kfree(iter
->namebuf
);
327 iter
->namebuf
= NULL
;
330 static void udf_copy_to_bufs(void *buf1
, int len1
, void *buf2
, int len2
,
331 int off
, void *src
, int len
)
338 copy
= min(off
+ len
, len1
) - off
;
339 memcpy(buf1
+ off
, src
, copy
);
345 if (WARN_ON_ONCE(off
+ len
> len2
|| !buf2
))
347 memcpy(buf2
+ off
, src
, len
);
351 static uint16_t udf_crc_fi_bufs(void *buf1
, int len1
, void *buf2
, int len2
,
360 copy
= min(off
+ len
, len1
) - off
;
361 crc
= crc_itu_t(crc
, buf1
+ off
, copy
);
366 if (WARN_ON_ONCE(off
+ len
> len2
|| !buf2
))
368 crc
= crc_itu_t(crc
, buf2
+ off
, len
);
373 static void udf_copy_fi_to_bufs(char *buf1
, int len1
, char *buf2
, int len2
,
374 int off
, struct fileIdentDesc
*fi
,
375 uint8_t *impuse
, uint8_t *name
)
379 int crcoff
= off
+ sizeof(struct tag
);
380 unsigned int crclen
= udf_dir_entry_len(fi
) - sizeof(struct tag
);
381 char zeros
[UDF_NAME_PAD
] = {};
382 int endoff
= off
+ udf_dir_entry_len(fi
);
384 udf_copy_to_bufs(buf1
, len1
, buf2
, len2
, off
, fi
,
385 sizeof(struct fileIdentDesc
));
386 off
+= sizeof(struct fileIdentDesc
);
388 udf_copy_to_bufs(buf1
, len1
, buf2
, len2
, off
, impuse
,
389 le16_to_cpu(fi
->lengthOfImpUse
));
390 off
+= le16_to_cpu(fi
->lengthOfImpUse
);
392 udf_copy_to_bufs(buf1
, len1
, buf2
, len2
, off
, name
,
393 fi
->lengthFileIdent
);
394 off
+= fi
->lengthFileIdent
;
395 udf_copy_to_bufs(buf1
, len1
, buf2
, len2
, off
, zeros
,
399 crc
= udf_crc_fi_bufs(buf1
, len1
, buf2
, len2
, crcoff
, crclen
);
400 fi
->descTag
.descCRC
= cpu_to_le16(crc
);
401 fi
->descTag
.descCRCLength
= cpu_to_le16(crclen
);
402 fi
->descTag
.tagChecksum
= udf_tag_checksum(&fi
->descTag
);
404 udf_copy_to_bufs(buf1
, len1
, buf2
, len2
, fioff
, fi
, sizeof(struct tag
));
407 void udf_fiiter_write_fi(struct udf_fileident_iter
*iter
, uint8_t *impuse
)
409 struct udf_inode_info
*iinfo
= UDF_I(iter
->dir
);
410 void *buf1
, *buf2
= NULL
;
411 int len1
, len2
= 0, off
;
412 int blksize
= 1 << iter
->dir
->i_blkbits
;
414 off
= iter
->pos
& (blksize
- 1);
415 if (iinfo
->i_alloc_type
== ICBTAG_FLAG_AD_IN_ICB
) {
416 buf1
= iinfo
->i_data
+ iinfo
->i_lenEAttr
;
417 len1
= iter
->dir
->i_size
;
419 buf1
= iter
->bh
[0]->b_data
;
422 buf2
= iter
->bh
[1]->b_data
;
427 udf_copy_fi_to_bufs(buf1
, len1
, buf2
, len2
, off
, &iter
->fi
, impuse
,
428 iter
->name
== iter
->namebuf
? iter
->name
: NULL
);
430 if (iinfo
->i_alloc_type
== ICBTAG_FLAG_AD_IN_ICB
) {
431 mark_inode_dirty(iter
->dir
);
433 mark_buffer_dirty_inode(iter
->bh
[0], iter
->dir
);
435 mark_buffer_dirty_inode(iter
->bh
[1], iter
->dir
);
437 inode_inc_iversion(iter
->dir
);
440 void udf_fiiter_update_elen(struct udf_fileident_iter
*iter
, uint32_t new_elen
)
442 struct udf_inode_info
*iinfo
= UDF_I(iter
->dir
);
443 int diff
= new_elen
- iter
->elen
;
445 /* Skip update when we already went past the last extent */
448 iter
->elen
= new_elen
;
449 if (iinfo
->i_alloc_type
== ICBTAG_FLAG_AD_SHORT
)
450 iter
->epos
.offset
-= sizeof(struct short_ad
);
451 else if (iinfo
->i_alloc_type
== ICBTAG_FLAG_AD_LONG
)
452 iter
->epos
.offset
-= sizeof(struct long_ad
);
453 udf_write_aext(iter
->dir
, &iter
->epos
, &iter
->eloc
, iter
->elen
, 1);
454 iinfo
->i_lenExtents
+= diff
;
455 mark_inode_dirty(iter
->dir
);
458 /* Append new block to directory. @iter is expected to point at EOF */
459 int udf_fiiter_append_blk(struct udf_fileident_iter
*iter
)
461 struct udf_inode_info
*iinfo
= UDF_I(iter
->dir
);
462 int blksize
= 1 << iter
->dir
->i_blkbits
;
463 struct buffer_head
*bh
;
465 uint32_t old_elen
= iter
->elen
;
469 if (WARN_ON_ONCE(iinfo
->i_alloc_type
== ICBTAG_FLAG_AD_IN_ICB
))
472 /* Round up last extent in the file */
473 udf_fiiter_update_elen(iter
, ALIGN(iter
->elen
, blksize
));
475 /* Allocate new block and refresh mapping information */
476 block
= iinfo
->i_lenExtents
>> iter
->dir
->i_blkbits
;
477 bh
= udf_bread(iter
->dir
, block
, 1, &err
);
479 udf_fiiter_update_elen(iter
, old_elen
);
482 err
= inode_bmap(iter
->dir
, block
, &iter
->epos
, &iter
->eloc
, &iter
->elen
,
483 &iter
->loffset
, &etype
);
484 if (err
<= 0 || etype
!= (EXT_RECORDED_ALLOCATED
>> 30)) {
485 udf_err(iter
->dir
->i_sb
,
486 "block %llu not allocated in directory (ino %lu)\n",
487 (unsigned long long)block
, iter
->dir
->i_ino
);
488 return -EFSCORRUPTED
;
490 if (!(iter
->pos
& (blksize
- 1))) {
499 struct short_ad
*udf_get_fileshortad(uint8_t *ptr
, int maxoffset
, uint32_t *offset
,
504 if ((!ptr
) || (!offset
)) {
505 pr_err("%s: invalidparms\n", __func__
);
509 if ((*offset
+ sizeof(struct short_ad
)) > maxoffset
)
512 sa
= (struct short_ad
*)ptr
;
513 if (sa
->extLength
== 0)
518 *offset
+= sizeof(struct short_ad
);
522 struct long_ad
*udf_get_filelongad(uint8_t *ptr
, int maxoffset
, uint32_t *offset
, int inc
)
526 if ((!ptr
) || (!offset
)) {
527 pr_err("%s: invalidparms\n", __func__
);
531 if ((*offset
+ sizeof(struct long_ad
)) > maxoffset
)
534 la
= (struct long_ad
*)ptr
;
535 if (la
->extLength
== 0)
540 *offset
+= sizeof(struct long_ad
);