Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 26 Feb 2009 12:33:12 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r189068 - head/sys/fs/udf
Message-ID:  <200902261233.n1QCXCc6027745@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200902261233.n1QCXCc6027745>