svn commit: r189068 - head/sys/fs/udf

Andriy Gapon avg at FreeBSD.org
Thu Feb 26 04:33:13 PST 2009


Author: avg
Date: Thu Feb 26 12:33:12 2009
New Revision: 189068
URL: http://svn.freebsd.org/changeset/base/189068

Log:
  udf_read: correctly read data from files with data embedded into fentry,
  
  ... as opposed to files with data in extents.
  Some UDF authoring tools produce this type of file for sufficiently small
  data files.
  
  Approved by: jhb (mentor)

Modified:
  head/sys/fs/udf/udf_vnops.c

Modified: head/sys/fs/udf/udf_vnops.c
==============================================================================
--- head/sys/fs/udf/udf_vnops.c	Thu Feb 26 12:33:02 2009	(r189067)
+++ head/sys/fs/udf/udf_vnops.c	Thu Feb 26 12:33:12 2009	(r189068)
@@ -419,6 +419,14 @@ udf_print(struct vop_print_args *ap)
 #define blkoff(udfmp, loc)	((loc) & (udfmp)->bmask)
 #define lblktosize(udfmp, blk)	((blk) << (udfmp)->bshift)
 
+static inline int
+is_data_in_fentry(const struct udf_node *node)
+{
+	const struct file_entry *fentry = node->fentry;
+
+	return ((le16toh(fentry->icbtag.flags) & 0x7) == 3);
+}
+
 static int
 udf_read(struct vop_read_args *ap)
 {
@@ -426,7 +434,9 @@ udf_read(struct vop_read_args *ap)
 	struct uio *uio = ap->a_uio;
 	struct udf_node *node = VTON(vp);
 	struct udf_mnt *udfmp;
+	struct file_entry *fentry;
 	struct buf *bp;
+	uint8_t *data;
 	daddr_t lbn, rablock;
 	off_t diff, fsize;
 	int error = 0;
@@ -436,6 +446,22 @@ udf_read(struct vop_read_args *ap)
 		return (0);
 	if (uio->uio_offset < 0)
 		return (EINVAL);
+
+	if (is_data_in_fentry(node)) {
+		fentry = node->fentry;
+		data = &fentry->data[le32toh(fentry->l_ea)];
+		fsize = le32toh(fentry->l_ad);
+
+		n = uio->uio_resid;
+		diff = fsize - uio->uio_offset;
+		if (diff <= 0)
+			return (0);
+		if (diff < n)
+			n = diff;
+		error = uiomove(data + uio->uio_offset, (int)n, uio);
+		return (error);
+	}
+
 	fsize = le64toh(node->fentry->inf_len);
 	udfmp = node->udfmp;
 	do {


More information about the svn-src-all mailing list