Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 Aug 2002 18:44:07 -0700 (PDT)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 15991 for review
Message-ID:  <200208150144.g7F1i799095310@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://people.freebsd.org/~peter/p4db/chv.cgi?CH=15991

Change 15991 by peter@peter_daintree on 2002/08/14 18:43:44

	IFC @15988

Affected files ...

.. //depot/projects/ia64/include/stdio.h#5 integrate
.. //depot/projects/ia64/lib/libc/stdio/setbuf.3#2 integrate
.. //depot/projects/ia64/lib/libc/stdio/setbuf.c#3 integrate
.. //depot/projects/ia64/lib/libc/stdio/setvbuf.c#3 integrate
.. //depot/projects/ia64/sys/fs/udf/udf.h#2 integrate
.. //depot/projects/ia64/sys/fs/udf/udf_vfsops.c#5 integrate
.. //depot/projects/ia64/sys/fs/udf/udf_vnops.c#6 integrate

Differences ...

==== //depot/projects/ia64/include/stdio.h#5 (text+ko) ====

@@ -34,7 +34,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)stdio.h	8.5 (Berkeley) 4/29/95
- * $FreeBSD: src/include/stdio.h,v 1.41 2002/07/15 19:38:45 wollman Exp $
+ * $FreeBSD: src/include/stdio.h,v 1.42 2002/08/14 23:45:42 robert Exp $
  */
 
 #ifndef	_STDIO_H_
@@ -243,8 +243,8 @@
 int	 rename(const char *, const char *);
 void	 rewind(FILE *);
 int	 scanf(const char *, ...);
-void	 setbuf(FILE *, char *);
-int	 setvbuf(FILE *, char *, int, size_t);
+void	 setbuf(FILE *__restrict, char *__restrict);
+int	 setvbuf(FILE *__restrict, char *__restrict, int, size_t);
 int	 sprintf(char *, const char *, ...);
 int	 sscanf(const char *, const char *, ...);
 FILE	*tmpfile(void);

==== //depot/projects/ia64/lib/libc/stdio/setbuf.3#2 (text+ko) ====

@@ -34,7 +34,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     @(#)setbuf.3	8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/stdio/setbuf.3,v 1.10 2001/10/01 16:08:59 ru Exp $
+.\" $FreeBSD: src/lib/libc/stdio/setbuf.3,v 1.11 2002/08/14 23:45:42 robert Exp $
 .\"
 .Dd June 4, 1993
 .Dt SETBUF 3
@@ -50,13 +50,13 @@
 .Sh SYNOPSIS
 .In stdio.h
 .Ft void
-.Fn setbuf "FILE *stream" "char *buf"
+.Fn setbuf "FILE *restrict stream" "char *restrict buf"
 .Ft void
 .Fn setbuffer "FILE *stream" "char *buf" "int size"
 .Ft int
 .Fn setlinebuf "FILE *stream"
 .Ft int
-.Fn setvbuf "FILE *stream" "char *buf" "int mode" "size_t size"
+.Fn setvbuf "FILE *restrict stream" "char *restrict buf" "int mode" "size_t size"
 .Sh DESCRIPTION
 The three types of buffering available are unbuffered, block buffered,
 and line buffered.

==== //depot/projects/ia64/lib/libc/stdio/setbuf.c#3 (text+ko) ====

@@ -38,15 +38,13 @@
 static char sccsid[] = "@(#)setbuf.c	8.1 (Berkeley) 6/4/93";
 #endif /* LIBC_SCCS and not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/stdio/setbuf.c,v 1.2 2002/03/22 21:53:04 obrien Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/stdio/setbuf.c,v 1.3 2002/08/14 23:45:42 robert Exp $");
 
 #include <stdio.h>
 #include "local.h"
 
 void
-setbuf(fp, buf)
-	FILE *fp;
-	char *buf;
+setbuf(FILE *__restrict fp, char *__restrict buf)
 {
 	(void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
 }

==== //depot/projects/ia64/lib/libc/stdio/setvbuf.c#3 (text+ko) ====

@@ -38,7 +38,7 @@
 static char sccsid[] = "@(#)setvbuf.c	8.2 (Berkeley) 11/16/93";
 #endif /* LIBC_SCCS and not lint */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/stdio/setvbuf.c,v 1.11 2002/03/22 21:53:04 obrien Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/stdio/setvbuf.c,v 1.12 2002/08/14 23:45:42 robert Exp $");
 
 #include "namespace.h"
 #include <stdio.h>
@@ -52,11 +52,7 @@
  * a buffer.
  */
 int
-setvbuf(fp, buf, mode, size)
-	FILE *fp;
-	char *buf;
-	int mode;
-	size_t size;
+setvbuf(FILE *__restrict fp, char *__restrict buf, int mode, size_t size)
 {
 	int ret, flags;
 	size_t iosize;

==== //depot/projects/ia64/sys/fs/udf/udf.h#2 (text+ko) ====

@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/fs/udf/udf.h,v 1.2 2002/04/15 19:49:15 asmodai Exp $
+ * $FreeBSD: src/sys/fs/udf/udf.h,v 1.3 2002/08/15 00:43:43 scottl Exp $
  */
 
 struct udf_node {
@@ -57,6 +57,21 @@
 	struct udf_sparing_table *s_table;
 };
 
+struct udf_dirstream {
+	struct udf_node	*node;
+	struct udf_mnt	*udfmp;
+	struct buf	*bp;
+	uint8_t		*data;
+	uint8_t		*buf;
+	int		fsize;
+	int		off;
+	int		this_off;
+	int		offset;
+	int		size;
+	int		error;
+	int		fid_fragment;
+};
+
 #define	VFSTOUDFFS(mp)	((struct udf_mnt *)((mp)->mnt_data))
 #define	VTON(vp)	((struct udf_node *)((vp)->v_data))
 
@@ -113,3 +128,4 @@
 
 extern uma_zone_t udf_zone_trans;
 extern uma_zone_t udf_zone_node;
+extern uma_zone_t udf_zone_ds;

==== //depot/projects/ia64/sys/fs/udf/udf_vfsops.c#5 (text+ko) ====

@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/fs/udf/udf_vfsops.c,v 1.5 2002/08/04 10:29:31 jeff Exp $
+ * $FreeBSD: src/sys/fs/udf/udf_vfsops.c,v 1.6 2002/08/15 00:43:43 scottl Exp $
  */
 
 /* udf_vfsops.c */
@@ -100,6 +100,7 @@
 /* Zones */
 uma_zone_t udf_zone_trans = NULL;
 uma_zone_t udf_zone_node = NULL;
+uma_zone_t udf_zone_ds = NULL;
 
 static int udf_init(struct vfsconf *);
 static int udf_uninit(struct vfsconf *);
@@ -147,7 +148,11 @@
 	udf_zone_node = uma_zcreate("UDF Node zone", sizeof(struct udf_node),
 	    NULL, NULL, NULL, NULL, 0, 0);
 
-	if ((udf_zone_node == NULL) || (udf_zone_trans == NULL)) {
+	udf_zone_ds = uma_zcreate("UDF Dirstream zone",
+	    sizeof(struct udf_dirstream), NULL, NULL, NULL, NULL, 0, 0);
+
+	if ((udf_zone_node == NULL) || (udf_zone_trans == NULL) ||
+	    (udf_zone_ds == NULL)) {
 		printf("Cannot create allocation zones.\n");
 		return (ENOMEM);
 	}
@@ -169,6 +174,11 @@
 		udf_zone_node = NULL;
 	}
 
+	if (udf_zone_ds != NULL) {
+		uma_zdestroy(udf_zone_ds);
+		udf_zone_ds = NULL;
+	}
+
 	return (0);
 }
 

==== //depot/projects/ia64/sys/fs/udf/udf_vnops.c#6 (text+ko) ====

@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/fs/udf/udf_vnops.c,v 1.10 2002/08/04 16:42:20 scottl Exp $
+ * $FreeBSD: src/sys/fs/udf/udf_vnops.c,v 1.11 2002/08/15 00:43:43 scottl Exp $
  */
 
 /* udf_vnops.c */
@@ -91,6 +91,7 @@
 VNODEOP_SET(udf_vnodeop_opv_desc);
 
 MALLOC_DEFINE(M_UDFFID, "UDF FID", "UDF FileId structure");
+MALLOC_DEFINE(M_UDFDS, "UDF DS", "UDF Dirstream structure");
 
 #define INVALID_BMAP	-1
 
@@ -528,6 +529,146 @@
 	return (uiomove((caddr_t)uiodir->dirent, de_size, uio));
 }
 
+static struct udf_dirstream *
+udf_opendir(struct udf_node *node, int offset, int fsize, struct udf_mnt *udfmp)
+{
+	struct udf_dirstream *ds;
+
+	ds = uma_zalloc(udf_zone_ds, M_WAITOK | M_ZERO);
+
+	ds->node = node;
+	ds->offset = offset;
+	ds->udfmp = udfmp;
+	ds->fsize = fsize;
+
+	return (ds);
+}
+
+static struct fileid_desc *
+udf_getfid(struct udf_dirstream *ds)
+{
+	struct fileid_desc *fid;
+	int error, frag_size = 0, total_fid_size;
+
+	/* End of directory? */
+	if (ds->offset + ds->off >= ds->fsize) {
+		ds->error = 0;
+		return (NULL);
+	}
+
+	/* Grab the first extent of the directory */
+	if (ds->off == 0) {
+		ds->size = 0;
+		error = udf_readatoffset(ds->node, &ds->size, ds->offset,
+		    &ds->bp, &ds->data);
+		if (error) {
+			ds->error = error;
+			return (NULL);
+		}
+	}
+
+	/* XXX Is this the right place for this? */
+	if (ds->fid_fragment && ds->buf != NULL) {
+		ds->fid_fragment = 0;
+		FREE(ds->buf, M_UDFFID);
+	}
+
+	fid = (struct fileid_desc*)&ds->data[ds->off];
+
+	/*
+	 * Check to see if the fid is fragmented. The first test
+	 * ensures that we don't wander off the end of the buffer
+	 * looking for the l_iu and l_fi fields.
+	 */
+	if (ds->off + UDF_FID_SIZE > ds->size ||
+	    ds->off + fid->l_iu + fid->l_fi + UDF_FID_SIZE > ds->size) {
+
+		/* Copy what we have of the fid into a buffer */
+		frag_size = ds->size - ds->off;
+		if (frag_size >= ds->udfmp->bsize) {
+			printf("udf: invalid FID fragment\n");
+			ds->error = EINVAL;
+			return (NULL);
+		}
+
+		/*
+		 * File ID descriptors can only be at most one
+		 * logical sector in size.
+		 */
+		MALLOC(ds->buf, uint8_t*, ds->udfmp->bsize, M_UDFFID,
+		     M_WAITOK | M_ZERO);
+		bcopy(fid, ds->buf, frag_size);
+
+		/* Reduce all of the casting magic */
+		fid = (struct fileid_desc*)ds->buf;
+
+		if (ds->bp != NULL)
+			brelse(ds->bp);
+
+		/* Fetch the next allocation */
+		ds->offset += ds->size;
+		ds->size = 0;
+		error = udf_readatoffset(ds->node, &ds->size, ds->offset,
+		    &ds->bp, &ds->data);
+		if (error) {
+			ds->error = error;
+			return (NULL);
+		}
+
+		/*
+		 * If the fragment was so small that we didn't get
+		 * the l_iu and l_fi fields, copy those in.
+		 */
+		if (frag_size < UDF_FID_SIZE)
+			bcopy(ds->data, &ds->buf[frag_size],
+			    UDF_FID_SIZE - frag_size);
+
+		/*
+		 * Now that we have enough of the fid to work with,
+		 * copy in the rest of the fid from the new
+		 * allocation.
+		 */
+		total_fid_size = UDF_FID_SIZE + fid->l_iu + fid->l_fi;
+		if (total_fid_size > ds->udfmp->bsize) {
+			printf("udf: invalid FID\n");
+			ds->error = EIO;
+			return (NULL);
+		}
+		bcopy(ds->data, &ds->buf[frag_size],
+		    total_fid_size - frag_size);
+
+		ds->fid_fragment = 1;
+	} else {
+		total_fid_size = fid->l_iu + fid->l_fi + UDF_FID_SIZE;
+	}
+
+	/*
+	 * Update the offset. Align on a 4 byte boundary because the
+	 * UDF spec says so.  If it was a fragmented entry, clean up.
+	 */
+	ds->this_off = ds->off;
+	if (!ds->fid_fragment) {
+		ds->off += (total_fid_size + 3) & ~0x03;
+	} else {
+		ds->off = (total_fid_size - frag_size + 3) & ~0x03;
+	}
+
+	return (fid);
+}
+
+static void
+udf_closedir(struct udf_dirstream *ds)
+{
+
+	if (ds->bp != NULL)
+		brelse(ds->bp);
+
+	if (ds->fid_fragment && ds->buf != NULL)
+		FREE(ds->buf, M_UDFFID);
+
+	uma_zfree(udf_zone_ds, ds);
+}
+
 /* Prebuild the . and .. dirents.  d_fileno will need to be filled in */
 static struct dirent udf_de_dot =
 	{ 0, sizeof(struct dirent), DT_DIR, 1, "." };
@@ -538,26 +679,20 @@
 udf_readdir(struct vop_readdir_args *a)
 {
 	struct vnode *vp;
-	struct buf *bp;
 	struct uio *uio;
 	struct dirent dir;
 	struct udf_node *node;
-	struct udf_mnt *udfmp;
 	struct fileid_desc *fid;
 	struct udf_uiodir uiodir;
+	struct udf_dirstream *ds;
 	u_long *cookies = NULL;
-	uint8_t *data, *buf;
 	int ncookies;
-	int error = 0, offset, off, size, de_size, fid_size, fsize;
-	int total_fid_size = 0, frag_size = 0, fid_fragment = 0;
+	int error = 0, de_size;
 
 	vp = a->a_vp;
 	uio = a->a_uio;
 	node = VTON(vp);
-	udfmp = node->udfmp;
 	de_size = sizeof(struct dirent);
-	fid_size = UDF_FID_SIZE;
-	fsize = node->fentry->inf_len;
 	uiodir.eofflag = 1;
 
 	if (a->a_ncookies != NULL) {
@@ -579,109 +714,28 @@
 	}
 
 	/*
-	 * offset is the absolute offset into the file data. off is the offset
-	 * into the data, minus the blocks that weren't read because they fell
-	 * before offset.
-	 */
-	offset = uio->uio_offset;
-	off = 0;
-
-	/*
 	 * Iterate through the file id descriptors.  Give the parent dir
 	 * entry special attention.  size will be the size of the extent
 	 * returned in data.  If there is more than one extent, things get
 	 * ugly.
 	 */
-	size = 0;
-	error = udf_readatoffset(node, &size, offset, &bp, &data);
-	if (error) {
-		if (a->a_ncookies != NULL)
-			FREE(cookies, M_TEMP);
-		return (error);
-	}
+	ds = udf_opendir(node, uio->uio_offset, node->fentry->inf_len,
+	    node->udfmp);
 
-	while (offset + off < fsize) {
+	while ((fid = udf_getfid(ds)) != NULL) {
 
-		fid = (struct fileid_desc*)&data[off];
-
-		/*
-		 * Check to see if the fid is fragmented. The first test
-		 * ensures that we don't wander off the end of the buffer
-		 * looking for the l_iu and l_fi fields.
-		 */
-		if (off + fid_size > size ||
-		    off + fid->l_iu + fid->l_fi + fid_size > size) {
-
-			/* Copy what we have of the fid into a buffer */
-			frag_size = size - off;
-			if (frag_size >= udfmp->bsize) {
-				printf("udf: invalid FID fragment\n");
-				break;
-			}
-
-			/*
-			 * File ID descriptors can only be at most one
-			 * logical sector in size.
-			 */
-			MALLOC(buf, uint8_t*, udfmp->bsize, M_UDFFID,
-			     M_WAITOK | M_ZERO);
-			bcopy(fid, buf, frag_size);
-
-			/* Reduce all of the casting magic */
-			fid = (struct fileid_desc*)buf;
-
-			if (bp != NULL)
-				brelse(bp);
-
-			/* Fetch the next allocation */
-			offset += size;
-			size = 0;
-			error = udf_readatoffset(node, &size, offset, &bp,
-			    &data);
-			if (error)
-				break;
-
-			/*
-			 * If the fragment was so small that we didn't get
-			 * the l_iu and l_fi fields, copy those in.
-			 */
-			if (fid_size > frag_size)
-				bcopy(data, &buf[frag_size],
-				    fid_size - frag_size);
-
-			/*
-			 * Now that we have enough of the fid to work with,
-			 * copy in the rest of the fid from the new
-			 * allocation.
-			 */
-			total_fid_size = fid_size + fid->l_iu + fid->l_fi;
-			if (total_fid_size > udfmp->bsize) {
-				printf("udf: invalid FID\n");
-				break;
-			}
-			bcopy(data, &buf[frag_size],
-			    total_fid_size - frag_size);
-
-			fid_fragment = 1;
-		} else {
-			total_fid_size = fid->l_iu + fid->l_fi + fid_size;
-		}
-
 		/* XXX Should we return an error on a bad fid? */
 		if (udf_checktag(&fid->tag, TAGID_FID)) {
 			printf("Invalid FID tag\n");
+			udf_dumpblock(fid, UDF_FID_SIZE);
+			error = EIO;
 			break;
 		}
 
 		/* Is this a deleted file? */
 		if (fid->file_char & UDF_FILE_CHAR_DEL)
-			goto update_offset;
+			continue;
 
-		if (fid->l_iu != 0) {
-			printf("Possibly invalid fid found.\n");
-			goto update_offset;
-		}
-
 		if ((fid->l_fi == 0) && (fid->file_char & UDF_FILE_CHAR_PAR)) {
 			/* Do up the '.' and '..' entries.  Dummy values are
 			 * used for the cookies since the offset here is
@@ -705,36 +759,28 @@
 			    DT_DIR : DT_UNKNOWN;
 			dir.d_reclen = GENERIC_DIRSIZ(&dir);
 			uiodir.dirent = &dir;
-			error = udf_uiodir(&uiodir, dir.d_reclen, uio, off);
+			error = udf_uiodir(&uiodir, dir.d_reclen, uio,
+			    ds->this_off);
 		}
 		if (error) {
 			printf("uiomove returned %d\n", error);
 			break;
 		}
 
-update_offset:	/*
-		 * Update the offset. Align on a 4 byte boundary because the
-		 * UDF spec says so.  If it was a fragmented entry, clean up.
-		 */
-		if (fid_fragment) {
-			off = (total_fid_size - frag_size + 3) & ~0x03;
-			FREE(fid, M_UDFFID);
-			fid_fragment = 0;
-		} else {
-			off += (total_fid_size + 3) & ~0x03;
-		}
 	}
 
 	/* tell the calling layer whether we need to be called again */
 	*a->a_eofflag = uiodir.eofflag;
-	uio->uio_offset = offset + off;
+	uio->uio_offset = ds->offset + ds->off;
+
+	if (!error)
+		error = ds->error;
 
-	if (bp != NULL)
-		brelse(bp);
+	udf_closedir(ds);
 
 	if (a->a_ncookies != NULL) {
 		if (error)
-			free(cookies, M_TEMP);
+			FREE(cookies, M_TEMP);
 		else {
 			*a->a_ncookies = uiodir.acookies;
 			*a->a_cookies = cookies;
@@ -834,20 +880,18 @@
 	struct vnode *dvp;
 	struct vnode *tdp = NULL;
 	struct vnode **vpp = a->a_vpp;
-	struct buf *bp = NULL;
 	struct udf_node *node;
 	struct udf_mnt *udfmp;
 	struct fileid_desc *fid = NULL;
+	struct udf_dirstream *ds;
 	struct thread *td;
 	u_long nameiop;
 	u_long flags;
 	char *nameptr;
 	long namelen;
 	ino_t id = 0;
-	uint8_t *data, *buf;
-	int offset, off, error, size;
-	int numdirpasses, fid_size, fsize, icb_len;
-	int total_fid_size = 0, fid_fragment = 0, frag_size = 0;
+	int offset, error = 0;
+	int numdirpasses, fsize;
 
 	dvp = a->a_dvp;
 	node = VTON(dvp);
@@ -856,9 +900,7 @@
 	flags = a->a_cnp->cn_flags;
 	nameptr = a->a_cnp->cn_nameptr;
 	namelen = a->a_cnp->cn_namelen;
-	fid_size = UDF_FID_SIZE;
 	fsize = node->fentry->inf_len;
-	icb_len = sizeof(struct long_ad);
 	td = a->a_cnp->cn_thread;
 
 	/*
@@ -867,7 +909,7 @@
 	 * directory may need to be searched twice.  For a full description,
 	 * see /sys/isofs/cd9660/cd9660_lookup.c:cd9660_lookup()
 	 */
-	if (nameiop != LOOKUP || node->diroff == 0 || node->diroff > size) {
+	if (nameiop != LOOKUP || node->diroff == 0 || node->diroff > fsize) {
 		offset = 0;
 		numdirpasses = 1;
 	} else {
@@ -881,91 +923,20 @@
 	 * Can this be broken out and shared?
 	 */
 lookloop:
-	size = 0;
-	off = 0;
-	error = udf_readatoffset(node, &size, offset, &bp, &data);
-	if (error)
-		return (error);
+	ds = udf_opendir(node, offset, fsize, udfmp);
 
-	while (offset + off < fsize) {
-		fid = (struct fileid_desc*)&data[off];
+	while ((fid = udf_getfid(ds)) != NULL) {
 
-		/*
-		 * Check to see if the fid is fragmented. The first test
-		 * ensures that we don't wander off the end of the buffer
-		 * looking for the l_iu and l_fi fields.
-		 */
-		if (off + fid_size > size ||
-		    off + fid_size + fid->l_iu + fid->l_fi > size) {
-
-			frag_size = size - off;
-			if (frag_size >= udfmp->bsize) {
-				printf("udf: invalid FID fragment\n");
-				break;
-			}
-
-			/*
-			 * File ID descriptors can only be at most one
-			 * logical sector in size.
-			 * Copy what we have of the fid into a buffer
-			 */
-			MALLOC(buf, uint8_t*, udfmp->bsize, M_UDFFID,
-			     M_WAITOK | M_ZERO);
-			bcopy(fid, buf, frag_size);
-
-			/* Reduce all of the casting magic */
-			fid = (struct fileid_desc*)buf;
-
-			if (bp != NULL)
-				brelse(bp);
-
-			/* Fetch the next allocation */
-			offset += size;
-			size = 0;
-			error = udf_readatoffset(node, &size, offset, &bp,
-			    &data);
-			if (error)
-				return (error);
-
-			/*
-			 * If the fragment was so small that we didn't get
-			 * the l_iu and l_fi fields, copy those in.
-			 */
-			if (fid_size > frag_size)
-				bcopy(data, &buf[frag_size],
-				    fid_size - frag_size);
-
-			/*
-			 * Now that we have enough of the fid to work with,
-			 * copy the rest of the fid from the new
-			 * allocation.
-			 */
-			total_fid_size = fid_size + fid->l_iu + fid->l_fi;
-			if (total_fid_size > udfmp->bsize) {
-				printf("udf: invalid FID\n");
-				break;
-			}
-			bcopy(data, &buf[frag_size],
-			    total_fid_size - frag_size);
-
-			off = (total_fid_size - frag_size + 3) & ~0x03;
-			fid_fragment = 1;
-		} else {
-			/*
-			 * Update the offset here to avoid looking at this fid
-			 * again on a subsequent lookup.
-			 */	
-			total_fid_size = fid->l_iu + fid->l_fi + fid_size;
-			off += (total_fid_size + 3) & ~0x03;
+		/* XXX Should we return an error on a bad fid? */
+		if (udf_checktag(&fid->tag, TAGID_FID)) {
+			printf("udf_lookup: Invalid tag\n");
+			error = EIO;
+			break;
 		}
 
-		/* XXX Should we return an error on a bad fid? */
-		if (udf_checktag(&fid->tag, TAGID_FID))
-			goto continue_lookup;
-
 		/* Is this a deleted file? */
 		if (fid->file_char & UDF_FILE_CHAR_DEL)
-			goto continue_lookup;
+			continue;
 
 		if ((fid->l_fi == 0) && (fid->file_char & UDF_FILE_CHAR_PAR)) {
 			if (flags & ISDOTDOT) {
@@ -979,67 +950,63 @@
 				break;
 			}
 		}
+	}
 
-		/* 
-		 * If we got this far then this fid isn't what we were
-		 * looking for.  It's therefore safe to clean up from a
-		 * fragmented fid.
-		 */
-continue_lookup:
-		if (fid_fragment) {
-			FREE(fid, M_UDFFID);
-			fid_fragment = 0;
-		}
+	if (!error)
+		error = ds->error;
+
+	/* XXX Bail out here? */
+	if (error) {
+		udf_closedir(ds);
+		return (error);
 	}
 
 	/* Did we have a match? */
 	if (id) {
 		error = udf_vget(udfmp->im_mountp, id, LK_EXCLUSIVE, &tdp);
-		if (bp != NULL)
-			brelse(bp);
-		if (error)
-			return (error);
+		if (!error) {
+			/*
+			 * Remember where this entry was if it's the final
+			 * component.
+			 */
+			if ((flags & ISLASTCN) && nameiop == LOOKUP)
+				node->diroff = ds->offset + ds->off;
+			if (numdirpasses == 2)
+				nchstats.ncs_pass2++;
+			if (!(flags & LOCKPARENT) || !(flags & ISLASTCN)) {
+				a->a_cnp->cn_flags |= PDIRUNLOCK;
+				VOP_UNLOCK(dvp, 0, td);
+			}
+
+			*vpp = tdp;
 
-		/* Remember where this entry was if it's the final component */
-		if ((flags & ISLASTCN) && nameiop == LOOKUP)
-			node->diroff = offset + off;
-		if (numdirpasses == 2)
-			nchstats.ncs_pass2++;
-		if (!(flags & LOCKPARENT) || !(flags & ISLASTCN)) {
-			a->a_cnp->cn_flags |= PDIRUNLOCK;
-			VOP_UNLOCK(dvp, 0, td);
+			/* Put this entry in the cache */
+			if (flags & MAKEENTRY)
+				cache_enter(dvp, *vpp, a->a_cnp);
+		}
+	} else {
+		/* Name wasn't found on this pass.  Do another pass? */
+		if (numdirpasses == 2) {
+			numdirpasses--;
+			offset = 0;
+			udf_closedir(ds);
+			goto lookloop;
 		}
 
-		*vpp = tdp;
-
-		/* Put this entry in the cache */
+		/* Enter name into cache as non-existant */
 		if (flags & MAKEENTRY)
 			cache_enter(dvp, *vpp, a->a_cnp);
 
-		if (fid_fragment)
-			FREE(fid, M_UDFFID);
-
-		return (0);
+		if ((flags & ISLASTCN) &&
+		    (nameiop == CREATE || nameiop == RENAME)) {
+			error = EROFS;
+		} else {
+			error = ENOENT;
+		}
 	}
 
-	/* Name wasn't found on this pass.  Do another pass? */
-	if (numdirpasses == 2) {
-		numdirpasses--;
-		offset = 0;
-		goto lookloop;
-	}
-
-	if (bp != NULL)
-		brelse(bp);
-
-	/* Enter name into cache as non-existant */
-	if (flags & MAKEENTRY)
-		cache_enter(dvp, *vpp, a->a_cnp);
-
-	if ((flags & ISLASTCN) && (nameiop == CREATE || nameiop == RENAME))
-		return (EROFS);
-	return (ENOENT);
-
+	udf_closedir(ds);
+	return (error);
 }
 
 static int

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




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