summaryrefslogtreecommitdiffstats
path: root/sys/fs/udf
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs/udf')
-rw-r--r--sys/fs/udf/udf_vnops.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/sys/fs/udf/udf_vnops.c b/sys/fs/udf/udf_vnops.c
index 5570808..bde9215 100644
--- a/sys/fs/udf/udf_vnops.c
+++ b/sys/fs/udf/udf_vnops.c
@@ -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 {
OpenPOWER on IntegriCloud