svn commit: r190048 - in stable/7/sys: . fs/udf

Andriy Gapon avg at FreeBSD.org
Thu Mar 19 07:05:01 PDT 2009


Author: avg
Date: Thu Mar 19 14:04:59 2009
New Revision: 190048
URL: http://svn.freebsd.org/changeset/base/190048

Log:
  MFC 189068: udf_read: correctly read data from files with data embedded into fentry
  
  Approved by:	jhb (mentor)

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/fs/udf/udf_vnops.c

Modified: stable/7/sys/fs/udf/udf_vnops.c
==============================================================================
--- stable/7/sys/fs/udf/udf_vnops.c	Thu Mar 19 14:00:23 2009	(r190047)
+++ stable/7/sys/fs/udf/udf_vnops.c	Thu Mar 19 14:04:59 2009	(r190048)
@@ -406,6 +406,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)
 {
@@ -413,7 +421,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;
@@ -423,6 +433,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-stable-7 mailing list