View | Details | Raw Unified | Return to bug 120989
Collapse All | Expand All

(-)b/sys/fs/udf/ecma167-udf.h (-2 / +52 lines)
Lines 42-48 enum { Link Here
42
	TAGID_LOGVOL_INTEGRITY = 9,
42
	TAGID_LOGVOL_INTEGRITY = 9,
43
	TAGID_FSD =		256,
43
	TAGID_FSD =		256,
44
	TAGID_FID =		257,
44
	TAGID_FID =		257,
45
	TAGID_FENTRY =		261
45
	TAGID_FENTRY =		261,
46
	TAGID_EXTFENTRY =	266
46
};
47
};
47
48
48
/* Descriptor tag [3/7.2] */
49
/* Descriptor tag [3/7.2] */
Lines 354-359 struct file_entry { Link Here
354
#define	UDF_FENTRY_PERM_GRP_MASK	0xE0
355
#define	UDF_FENTRY_PERM_GRP_MASK	0xE0
355
#define	UDF_FENTRY_PERM_OWNER_MASK	0x1C00
356
#define	UDF_FENTRY_PERM_OWNER_MASK	0x1C00
356
357
358
/* Extended File Entry [4/14.17] */
359
struct extfile_entry {
360
	struct desc_tag		tag;
361
	struct icb_tag		icbtag;
362
	uint32_t		uid;
363
	uint32_t		gid;
364
	uint32_t		perm;
365
	uint16_t		link_cnt;
366
	uint8_t			rec_format;
367
	uint8_t			rec_disp_attr;
368
	uint32_t		rec_len;
369
	uint64_t		inf_len;
370
	uint64_t		obj_size;
371
	uint64_t		logblks_rec;
372
	struct timestamp	atime;
373
	struct timestamp	mtime;
374
	struct timestamp	ctime;
375
	struct timestamp	attrtime;
376
	uint32_t		ckpoint;
377
	uint32_t		reserved1;
378
	struct long_ad		ex_attr_icb;
379
	struct long_ad		streamdir_icb;
380
	struct regid		imp_id;
381
	uint64_t		unique_id;
382
	uint32_t		l_ea;	/* Length of extended attribute area */
383
	uint32_t		l_ad;	/* Length of allocation descriptors */
384
	uint8_t			data[1];
385
} __packed;
386
#define	UDF_EXTFENTRY_SIZE	216
387
/* Given a pointer to file_entry or extfile_entry object and a field name
388
 * the following macro produces a field of a correctly typed structure
389
 * based on tag id of the entry.
390
 * This is not needed for fields up to and including inf_len, but is a must
391
 * for all following fields.
392
 * This macro, obviosly, can work only for fields that are present in both
393
 * structure types.
394
 */
395
#define GET_FENTRY_FIELD(entry, field)	\
396
	((entry)->tag.id == TAGID_FENTRY ? \
397
	    ((struct file_entry *)(entry))->field \
398
	    : \
399
	    ((struct extfile_entry *)(entry))->field)
400
#define GET_FENTRY_FIELD_PTR(entry, field)	\
401
	((entry)->tag.id == TAGID_FENTRY ? \
402
	    &((struct file_entry *)(entry))->field \
403
	    : \
404
	    &((struct extfile_entry *)(entry))->field)
405
357
union dscrptr {
406
union dscrptr {
358
	struct desc_tag		tag;
407
	struct desc_tag		tag;
359
	struct anchor_vdp	avdp;
408
	struct anchor_vdp	avdp;
Lines 364-374 union dscrptr { Link Here
364
	struct fileset_desc	fsd;
413
	struct fileset_desc	fsd;
365
	struct fileid_desc	fid;
414
	struct fileid_desc	fid;
366
	struct file_entry	fe;
415
	struct file_entry	fe;
416
	struct extfile_entry	efe;
367
};
417
};
368
418
369
/* Useful defines */
419
/* Useful defines */
370
420
371
#define	GETICB(ad_type, fentry, offset)	\
421
#define	GETICB(ad_type, fentry, offset)	\
372
	(struct ad_type *)&fentry->data[offset]
422
	((struct ad_type *)GET_FENTRY_FIELD_PTR(fentry, data[offset]))
373
423
374
#define	GETICBLEN(ad_type, icb)	le32toh(((struct ad_type *)(icb))->len)
424
#define	GETICBLEN(ad_type, icb)	le32toh(((struct ad_type *)(icb))->len)
(-)b/sys/fs/udf/udf_vfsops.c (-8 / +23 lines)
Lines 308-314 udf_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td) { Link Here
308
	struct part_desc *pd;
308
	struct part_desc *pd;
309
	struct logvol_desc *lvd;
309
	struct logvol_desc *lvd;
310
	struct fileset_desc *fsd;
310
	struct fileset_desc *fsd;
311
	struct file_entry *root_fentry;
311
	struct desc_tag *root_tag;
312
	uint32_t sector, size, mvds_start, mvds_end;
312
	uint32_t sector, size, mvds_start, mvds_end;
313
	uint32_t logical_secsize;
313
	uint32_t logical_secsize;
314
	uint32_t fsd_offset = 0;
314
	uint32_t fsd_offset = 0;
Lines 330-335 udf_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td) { Link Here
330
330
331
	bo = &devvp->v_bufobj;
331
	bo = &devvp->v_bufobj;
332
332
333
	if (devvp->v_rdev->si_iosize_max != 0)
334
		mp->mnt_iosize_max = devvp->v_rdev->si_iosize_max;
335
	if (mp->mnt_iosize_max > MAXPHYS)
336
		mp->mnt_iosize_max = MAXPHYS;
337
333
	/* XXX: should be M_WAITOK */
338
	/* XXX: should be M_WAITOK */
334
	MALLOC(udfmp, struct udf_mnt *, sizeof(struct udf_mnt), M_UDFMOUNT,
339
	MALLOC(udfmp, struct udf_mnt *, sizeof(struct udf_mnt), M_UDFMOUNT,
335
	    M_NOWAIT | M_ZERO);
340
	    M_NOWAIT | M_ZERO);
Lines 475-482 udf_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td) { Link Here
475
		goto bail;
480
		goto bail;
476
	}
481
	}
477
482
478
	root_fentry = (struct file_entry *)bp->b_data;
483
	root_tag = (struct desc_tag *)bp->b_data;
479
	if ((error = udf_checktag(&root_fentry->tag, TAGID_FENTRY))) {
484
	if ((error = udf_checktag(root_tag, TAGID_FENTRY))
485
	    && (error = udf_checktag(root_tag, TAGID_EXTFENTRY))) {
480
		printf("Invalid root file entry!\n");
486
		printf("Invalid root file entry!\n");
481
		goto bail;
487
		goto bail;
482
	}
488
	}
Lines 590-596 udf_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) Link Here
590
	struct thread *td;
596
	struct thread *td;
591
	struct vnode *vp;
597
	struct vnode *vp;
592
	struct udf_node *unode;
598
	struct udf_node *unode;
593
	struct file_entry *fe;
599
	struct desc_tag *tag;
594
	int error, sector, size;
600
	int error, sector, size;
595
601
596
	error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL);
602
	error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL);
Lines 637-654 udf_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) Link Here
637
		return (error);
643
		return (error);
638
	}
644
	}
639
645
640
	fe = (struct file_entry *)bp->b_data;
646
	tag = (struct desc_tag *)bp->b_data;
641
	if (udf_checktag(&fe->tag, TAGID_FENTRY)) {
647
	if (udf_checktag(tag, TAGID_FENTRY) == 0) {
648
		struct file_entry *fe = (struct file_entry *)bp->b_data;
649
		size = UDF_FENTRY_SIZE + le32toh(fe->l_ea) + le32toh(fe->l_ad);
650
	}
651
	else if (udf_checktag(tag, TAGID_EXTFENTRY) == 0) {
652
		struct extfile_entry *efe = (struct extfile_entry *)bp->b_data;
653
		size = UDF_EXTFENTRY_SIZE + le32toh(efe->l_ea) + le32toh(efe->l_ad);
654
	}
655
	else {
642
		printf("Invalid file entry!\n");
656
		printf("Invalid file entry!\n");
643
		vgone(vp);
657
		vgone(vp);
644
		vput(vp);
658
		vput(vp);
645
		brelse(bp);
659
		brelse(bp);
646
		*vpp = NULL;
660
		*vpp = NULL;
647
		return (ENOMEM);
661
		return (EINVAL);
648
	}
662
	}
649
	size = UDF_FENTRY_SIZE + le32toh(fe->l_ea) + le32toh(fe->l_ad);
663
650
	MALLOC(unode->fentry, struct file_entry *, size, M_UDFFENTRY,
664
	MALLOC(unode->fentry, struct file_entry *, size, M_UDFFENTRY,
651
	    M_NOWAIT | M_ZERO);
665
	    M_NOWAIT | M_ZERO);
666
652
	if (unode->fentry == NULL) {
667
	if (unode->fentry == NULL) {
653
		printf("Cannot allocate file entry block\n");
668
		printf("Cannot allocate file entry block\n");
654
		vgone(vp);
669
		vgone(vp);
(-)b/sys/fs/udf/udf_vnops.c (-49 / +134 lines)
Lines 168-173 udf_open(struct vop_open_args *ap) { Link Here
168
	struct udf_node *np = VTON(ap->a_vp);
168
	struct udf_node *np = VTON(ap->a_vp);
169
	off_t fsize;
169
	off_t fsize;
170
170
171
	/*
172
	 * We currently do not support any other strategy type, so
173
	 * udf_bmap_internal, udf_bmap, udf_strategy would fail.
174
	 * I.e. we can not access content of this file anyway.
175
	 */
176
	if (le16toh(np->fentry->icbtag.strat_type) != 4) {
177
		printf("Unsupported strategy type %d\n", le16toh(np->fentry->icbtag.strat_type));
178
		return EINVAL;
179
	}
180
181
	if (np->fentry->tag.id == TAGID_EXTFENTRY && 
182
	    np->fentry->inf_len != ((struct extfile_entry *)np->fentry)->obj_size) {
183
		printf("Files with multiple streams are not supported\n");
184
		return EINVAL;
185
	}
171
	fsize = le64toh(np->fentry->inf_len);
186
	fsize = le64toh(np->fentry->inf_len);
172
	vnode_create_vobject(ap->a_vp, fsize, ap->a_td);
187
	vnode_create_vobject(ap->a_vp, fsize, ap->a_td);
173
	return 0;
188
	return 0;
Lines 206-214 udf_timetotimespec(struct timestamp *time, struct timespec *t) Link Here
206
221
207
	t->tv_nsec = 0;
222
	t->tv_nsec = 0;
208
223
209
	/* DirectCD seems to like using bogus year values */
224
	/*
225
	 * DirectCD seems to like using bogus year values.
226
	 * Distrust time->month especially, since it will be used for an
227
	 * array index.
228
	 */
210
	year = le16toh(time->year);
229
	year = le16toh(time->year);
211
	if (year < 1970) {
230
	if (year < 1970 || time->month > 12) {
212
		t->tv_sec = 0;
231
		t->tv_sec = 0;
213
		return;
232
		return;
214
	}
233
	}
Lines 217-237 udf_timetotimespec(struct timestamp *time, struct timespec *t) Link Here
217
	t->tv_sec = time->second;
236
	t->tv_sec = time->second;
218
	t->tv_sec += time->minute * 60;
237
	t->tv_sec += time->minute * 60;
219
	t->tv_sec += time->hour * 3600;
238
	t->tv_sec += time->hour * 3600;
220
	t->tv_sec += time->day * 3600 * 24;
239
	t->tv_sec += (time->day - 1) * 3600 * 24;
221
240
222
	/* Calculate the month */
241
	/* Calculate the month */
223
	lpyear = udf_isaleapyear(year);
242
	lpyear = udf_isaleapyear(year);
224
	for (i = 1; i < time->month; i++)
243
	for (i = 1; i < time->month; i++)
225
		t->tv_sec += mon_lens[lpyear][i] * 3600 * 24;
244
		t->tv_sec += mon_lens[lpyear][i - 1] * 3600 * 24;
226
245
227
	/* Speed up the calculation */
246
	for (i = 1970; i < year; i++) {
228
	if (year > 1979)
229
		t->tv_sec += 315532800;
230
	if (year > 1989)
231
		t->tv_sec += 315619200;
232
	if (year > 1999)
233
		t->tv_sec += 315532800;
234
	for (i = 2000; i < year; i++) {
235
		daysinyear = udf_isaleapyear(i) + 365 ;
247
		daysinyear = udf_isaleapyear(i) + 365 ;
236
		t->tv_sec += daysinyear * 3600 * 24;
248
		t->tv_sec += daysinyear * 3600 * 24;
237
	}
249
	}
Lines 276-284 udf_getattr(struct vop_getattr_args *a) Link Here
276
	 */
288
	 */
277
	vap->va_uid = (le32toh(fentry->uid) == -1) ? 0 : le32toh(fentry->uid);
289
	vap->va_uid = (le32toh(fentry->uid) == -1) ? 0 : le32toh(fentry->uid);
278
	vap->va_gid = (le32toh(fentry->gid) == -1) ? 0 : le32toh(fentry->gid);
290
	vap->va_gid = (le32toh(fentry->gid) == -1) ? 0 : le32toh(fentry->gid);
279
	udf_timetotimespec(&fentry->atime, &vap->va_atime);
291
	if (fentry->tag.id == TAGID_FENTRY) {
280
	udf_timetotimespec(&fentry->mtime, &vap->va_mtime);
292
		udf_timetotimespec(&fentry->atime, &vap->va_atime);
281
	vap->va_ctime = vap->va_mtime; /* XXX Stored as an Extended Attribute */
293
		udf_timetotimespec(&fentry->mtime, &vap->va_mtime);
294
		vap->va_ctime = vap->va_mtime; /* XXX Stored as an Extended Attribute */
295
	}
296
	else { /*TAGID_EXTFENTRY*/
297
		udf_timetotimespec(&((struct extfile_entry *)fentry)->atime, &vap->va_atime);
298
		udf_timetotimespec(&((struct extfile_entry *)fentry)->mtime, &vap->va_atime);
299
		udf_timetotimespec(&((struct extfile_entry *)fentry)->ctime, &vap->va_ctime);
300
	}
282
	vap->va_rdev = 0; /* XXX */
301
	vap->va_rdev = 0; /* XXX */
283
	if (vp->v_type & VDIR) {
302
	if (vp->v_type & VDIR) {
284
		/*
303
		/*
Lines 287-295 udf_getattr(struct vop_getattr_args *a) Link Here
287
		 * that directories consume at least one logical block,
306
		 * that directories consume at least one logical block,
288
		 * make it appear so.
307
		 * make it appear so.
289
		 */
308
		 */
290
		if (fentry->logblks_rec != 0) {
309
		if (GET_FENTRY_FIELD(fentry, logblks_rec) != 0) {
291
			vap->va_size =
310
			vap->va_size =
292
			    le64toh(fentry->logblks_rec) * node->udfmp->bsize;
311
			    GET_FENTRY_FIELD(fentry, logblks_rec) * node->udfmp->bsize;
293
		} else {
312
		} else {
294
			vap->va_size = node->udfmp->bsize;
313
			vap->va_size = node->udfmp->bsize;
295
		}
314
		}
Lines 343-349 udf_pathconf(struct vop_pathconf_args *a) Link Here
343
362
344
#define lblkno(udfmp, loc)	((loc) >> (udfmp)->bshift)
363
#define lblkno(udfmp, loc)	((loc) >> (udfmp)->bshift)
345
#define blkoff(udfmp, loc)	((loc) & (udfmp)->bmask)
364
#define blkoff(udfmp, loc)	((loc) & (udfmp)->bmask)
346
#define lblktosize(imp, blk)	((blk) << (udfmp)->bshift)
365
#define lblktosize(udfmp, blk)	((blk) << (udfmp)->bshift)
366
367
#define HAS_EMBEDDED_DATA(node) ((le16toh((node)->fentry->icbtag.flags) & 0x7) == 3)
347
368
348
static int
369
static int
349
udf_read(struct vop_read_args *ap)
370
udf_read(struct vop_read_args *ap)
Lines 362-367 udf_read(struct vop_read_args *ap) Link Here
362
		return (0);
383
		return (0);
363
	if (uio->uio_offset < 0)
384
	if (uio->uio_offset < 0)
364
		return (EINVAL);
385
		return (EINVAL);
386
387
	if (HAS_EMBEDDED_DATA(node)) {
388
		uint8_t *data;
389
390
		if (node->fentry->tag.id == TAGID_FENTRY) {
391
			struct file_entry *fentry = node->fentry;
392
			data = &fentry->data[le32toh(fentry->l_ea)];
393
			fsize = le32toh(fentry->l_ad);
394
		}
395
		else {
396
			struct extfile_entry *fentry = (struct extfile_entry *)node->fentry;
397
			data = &fentry->data[le32toh(fentry->l_ea)];
398
			fsize = le32toh(fentry->l_ad);
399
		}
400
401
		n = uio->uio_resid;
402
		diff = fsize - uio->uio_offset;
403
		if (diff <= 0)
404
			return (0);
405
		if (diff < n)
406
			n = diff;
407
408
		error = uiomove(data + uio->uio_offset, (int)n, uio);
409
		return (error);
410
	}
411
365
	fsize = le64toh(node->fentry->inf_len);
412
	fsize = le64toh(node->fentry->inf_len);
366
	udfmp = node->udfmp;
413
	udfmp = node->udfmp;
367
	do {
414
	do {
Lines 758-764 udf_readdir(struct vop_readdir_args *a) Link Here
758
			    ds->this_off);
805
			    ds->this_off);
759
		}
806
		}
760
		if (error) {
807
		if (error) {
761
			printf("uiomove returned %d\n", error);
808
			if(error > 0)
809
				printf("uiomove returned %d\n", error);
762
			break;
810
			break;
763
		}
811
		}
764
812
Lines 768-773 udf_readdir(struct vop_readdir_args *a) Link Here
768
	*a->a_eofflag = uiodir.eofflag;
816
	*a->a_eofflag = uiodir.eofflag;
769
	uio->uio_offset = ds->offset + ds->off;
817
	uio->uio_offset = ds->offset + ds->off;
770
818
819
	if(error < 0)
820
		error = 0;
771
	if (!error)
821
	if (!error)
772
		error = ds->error;
822
		error = ds->error;
773
823
Lines 799-808 udf_strategy(struct vop_strategy_args *a) Link Here
799
	struct buf *bp;
849
	struct buf *bp;
800
	struct vnode *vp;
850
	struct vnode *vp;
801
	struct udf_node *node;
851
	struct udf_node *node;
852
	struct bufobj *bo;
802
	int maxsize;
853
	int maxsize;
803
	daddr_t sector;
854
	daddr_t sector;
804
	struct bufobj *bo;
855
	int error;
805
	int multiplier;
806
856
807
	bp = a->a_bp;
857
	bp = a->a_bp;
808
	vp = a->a_vp;
858
	vp = a->a_vp;
Lines 813-836 udf_strategy(struct vop_strategy_args *a) Link Here
813
		 * Files that are embedded in the fentry don't translate well
863
		 * Files that are embedded in the fentry don't translate well
814
		 * to a block number.  Reject.
864
		 * to a block number.  Reject.
815
		 */
865
		 */
816
		if (udf_bmap_internal(node, bp->b_lblkno * node->udfmp->bsize,
866
		error = udf_bmap_internal(node, lblktosize(node->udfmp, bp->b_lblkno), &sector, &maxsize);
817
		    &sector, &maxsize)) {
867
		if (error) {
868
			if (error == UDF_INVALID_BMAP)
869
				printf("udf_strategy called for file with data embedded in fentry\n");
818
			clrbuf(bp);
870
			clrbuf(bp);
819
			bp->b_blkno = -1;
871
			bp->b_blkno = -1;
872
			bufdone(bp);
873
			return (0);
820
		}
874
		}
821
875
		/* udf_bmap_internal gives sector numbers, bio works with device blocks */
822
		/* bmap gives sector numbers, bio works with device blocks */
876
		bp->b_blkno = sector << (node->udfmp->bshift - DEV_BSHIFT);
823
		multiplier = node->udfmp->bsize / DEV_BSIZE;
824
		bp->b_blkno = sector * multiplier;
825
826
	}
827
	if ((long)bp->b_blkno == -1) {
828
		bufdone(bp);
829
		return (0);
830
	}
877
	}
878
831
	bo = node->udfmp->im_bo;
879
	bo = node->udfmp->im_bo;
832
	bp->b_iooffset = dbtob(bp->b_blkno);
880
	bp->b_iooffset = dbtob(bp->b_blkno);
833
	BO_STRATEGY(bo, bp);
881
	BO_STRATEGY(bo, bp);
882
834
	return (0);
883
	return (0);
835
}
884
}
836
885
Lines 851-867 udf_bmap(struct vop_bmap_args *a) Link Here
851
	if (a->a_runb)
900
	if (a->a_runb)
852
		*a->a_runb = 0;
901
		*a->a_runb = 0;
853
902
854
	error = udf_bmap_internal(node, a->a_bn * node->udfmp->bsize, &lsector,
903
	/*
855
	    &max_size);
904
	 * UDF_INVALID_BMAP means data embedded into fentry, this is an internal
905
	 * error that should not be propagated to calling code.
906
	 * Most obvious mapping for this error is EOPNOTSUPP as we can not truly
907
	 * translate block numbers in this case.
908
	 * Incidentally, this return code will make vnode pager to use VOP_READ
909
	 * to get data for mmap-ed pages and udf_read knows how to do the right
910
	 * thing for this kind of files.
911
	 */
912
	error = udf_bmap_internal(node, a->a_bn << node->udfmp->bshift, &lsector, &max_size);
913
	if (error == UDF_INVALID_BMAP)
914
		return EOPNOTSUPP;
856
	if (error)
915
	if (error)
857
		return (error);
916
		return (error);
858
917
859
	/* Translate logical to physical sector number */
918
	/* Translate logical to physical sector number */
860
	*a->a_bnp = lsector << (node->udfmp->bshift - DEV_BSHIFT);
919
	*a->a_bnp = lsector << (node->udfmp->bshift - DEV_BSHIFT);
861
920
862
	/* Punt on read-ahead for now */
921
	/*
863
	if (a->a_runp)
922
	 * Determine maximum number of readahead blocks following the
864
		*a->a_runp = 0;
923
	 * requested block.
924
	 */
925
	if (a->a_runp) {
926
		int nblk;
927
928
		nblk = (max_size >> node->udfmp->bshift) - 1;
929
		if (nblk <= 0)
930
			*a->a_runp = 0;
931
		else if (nblk >= (MAXBSIZE >> node->udfmp->bshift))
932
			*a->a_runp = (MAXBSIZE >> node->udfmp->bshift) - 1;
933
		else
934
			*a->a_runp = nblk;
935
	}
936
937
	if (a->a_runb) {
938
		*a->a_runb = 0;
939
	}
865
940
866
	return (0);
941
	return (0);
867
}
942
}
Lines 1052-1058 udf_readatoffset(struct udf_node *node, int *size, off_t offset, Link Here
1052
    struct buf **bp, uint8_t **data)
1127
    struct buf **bp, uint8_t **data)
1053
{
1128
{
1054
	struct udf_mnt *udfmp;
1129
	struct udf_mnt *udfmp;
1055
	struct file_entry *fentry = NULL;
1056
	struct buf *bp1;
1130
	struct buf *bp1;
1057
	uint32_t max_size;
1131
	uint32_t max_size;
1058
	daddr_t sector;
1132
	daddr_t sector;
Lines 1060-1075 udf_readatoffset(struct udf_node *node, int *size, off_t offset, Link Here
1060
1134
1061
	udfmp = node->udfmp;
1135
	udfmp = node->udfmp;
1062
1136
1063
	*bp = NULL;
1137
	/*
1138
	 * This call is made not only to detect UDF_INVALID_BMAP case,
1139
	 * max_size is used as an ad-hoc read-ahead hint for "normal" case.
1140
	 */
1064
	error = udf_bmap_internal(node, offset, &sector, &max_size);
1141
	error = udf_bmap_internal(node, offset, &sector, &max_size);
1065
	if (error == UDF_INVALID_BMAP) {
1142
	if (error == UDF_INVALID_BMAP) {
1066
		/*
1143
		/*
1067
		 * This error means that the file *data* is stored in the
1144
		 * This error means that the file *data* is stored in the
1068
		 * allocation descriptor field of the file entry.
1145
		 * allocation descriptor field of the file entry.
1069
		 */
1146
		 */
1070
		fentry = node->fentry;
1147
		if (node->fentry->tag.id == TAGID_FENTRY) {
1071
		*data = &fentry->data[le32toh(fentry->l_ea)];
1148
			struct file_entry *fentry = node->fentry;
1072
		*size = le32toh(fentry->l_ad);
1149
			*data = &fentry->data[le32toh(fentry->l_ea)];
1150
			*size = le32toh(fentry->l_ad);
1151
		}
1152
		else {
1153
			struct extfile_entry *fentry = (struct extfile_entry *)node->fentry;
1154
			*data = &fentry->data[le32toh(fentry->l_ea)];
1155
			*size = le32toh(fentry->l_ad);
1156
		}
1073
		return (0);
1157
		return (0);
1074
	} else if (error != 0) {
1158
	} else if (error != 0) {
1075
		return (error);
1159
		return (error);
Lines 1078-1086 udf_readatoffset(struct udf_node *node, int *size, off_t offset, Link Here
1078
	/* Adjust the size so that it is within range */
1162
	/* Adjust the size so that it is within range */
1079
	if (*size == 0 || *size > max_size)
1163
	if (*size == 0 || *size > max_size)
1080
		*size = max_size;
1164
		*size = max_size;
1081
	*size = min(*size, MAXBSIZE);
1165
	*size = min(*size, MAXBSIZE - blkoff(udfmp, offset));
1082
1166
1083
	if ((error = udf_readlblks(udfmp, sector, *size + (offset & udfmp->bmask), bp))) {
1167
	*bp = NULL;
1168
	if ((error = bread(node->i_vnode, lblkno(udfmp, offset), (*size + blkoff(udfmp, offset) + udfmp->bmask) & ~udfmp->bmask, NOCRED, bp))) {
1084
		printf("warning: udf_readlblks returned error %d\n", error);
1169
		printf("warning: udf_readlblks returned error %d\n", error);
1085
		/* note: *bp may be non-NULL */
1170
		/* note: *bp may be non-NULL */
1086
		return (error);
1171
		return (error);
Lines 1137-1148 udf_bmap_internal(struct udf_node *node, off_t offset, daddr_t *sector, Link Here
1137
		do {
1222
		do {
1138
			offset -= icblen;
1223
			offset -= icblen;
1139
			ad_offset = sizeof(struct short_ad) * ad_num;
1224
			ad_offset = sizeof(struct short_ad) * ad_num;
1140
			if (ad_offset > le32toh(fentry->l_ad)) {
1225
			if (ad_offset > le32toh(GET_FENTRY_FIELD(fentry, l_ad))) {
1141
				printf("File offset out of bounds\n");
1226
				printf("File offset out of bounds\n");
1142
				return (EINVAL);
1227
				return (EINVAL);
1143
			}
1228
			}
1144
			icb = GETICB(short_ad, fentry,
1229
			icb = GETICB(short_ad, fentry,
1145
			    le32toh(fentry->l_ea) + ad_offset);
1230
			    le32toh(GET_FENTRY_FIELD(fentry, l_ea)) + ad_offset);
1146
			icblen = GETICBLEN(short_ad, icb);
1231
			icblen = GETICBLEN(short_ad, icb);
1147
			ad_num++;
1232
			ad_num++;
1148
		} while(offset >= icblen);
1233
		} while(offset >= icblen);
Lines 1162-1173 udf_bmap_internal(struct udf_node *node, off_t offset, daddr_t *sector, Link Here
1162
		do {
1247
		do {
1163
			offset -= icblen;
1248
			offset -= icblen;
1164
			ad_offset = sizeof(struct long_ad) * ad_num;
1249
			ad_offset = sizeof(struct long_ad) * ad_num;
1165
			if (ad_offset > le32toh(fentry->l_ad)) {
1250
			if (ad_offset > le32toh(GET_FENTRY_FIELD(fentry, l_ad))) {
1166
				printf("File offset out of bounds\n");
1251
				printf("File offset out of bounds\n");
1167
				return (EINVAL);
1252
				return (EINVAL);
1168
			}
1253
			}
1169
			icb = GETICB(long_ad, fentry,
1254
			icb = GETICB(long_ad, fentry,
1170
			    le32toh(fentry->l_ea) + ad_offset);
1255
			    le32toh(GET_FENTRY_FIELD(fentry, l_ea)) + ad_offset);
1171
			icblen = GETICBLEN(long_ad, icb);
1256
			icblen = GETICBLEN(long_ad, icb);
1172
			ad_num++;
1257
			ad_num++;
1173
		} while(offset >= icblen);
1258
		} while(offset >= icblen);

Return to bug 120989