From owner-svn-src-all@FreeBSD.ORG Wed Mar 18 18:20:21 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 472B810656C6; Wed, 18 Mar 2009 18:20:21 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 32BFE8FC1B; Wed, 18 Mar 2009 18:20:21 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n2IIKL1v033635; Wed, 18 Mar 2009 18:20:21 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n2IIKLFr033632; Wed, 18 Mar 2009 18:20:21 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <200903181820.n2IIKLFr033632@svn.freebsd.org> From: John Baldwin Date: Wed, 18 Mar 2009 18:20:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r189972 - in stable/7/sys: . contrib/pf dev/ath/ath_hal dev/cxgb fs/udf X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Mar 2009 18:20:23 -0000 Author: jhb Date: Wed Mar 18 18:20:20 2009 New Revision: 189972 URL: http://svn.freebsd.org/changeset/base/189972 Log: MFC: Add rudimentary support for symbolic links on UDF. Modified: stable/7/sys/ (props changed) stable/7/sys/contrib/pf/ (props changed) stable/7/sys/dev/ath/ath_hal/ (props changed) stable/7/sys/dev/cxgb/ (props changed) stable/7/sys/fs/udf/ecma167-udf.h stable/7/sys/fs/udf/udf_vnops.c Modified: stable/7/sys/fs/udf/ecma167-udf.h ============================================================================== --- stable/7/sys/fs/udf/ecma167-udf.h Wed Mar 18 18:18:38 2009 (r189971) +++ stable/7/sys/fs/udf/ecma167-udf.h Wed Mar 18 18:20:20 2009 (r189972) @@ -354,6 +354,18 @@ struct file_entry { #define UDF_FENTRY_PERM_GRP_MASK 0xE0 #define UDF_FENTRY_PERM_OWNER_MASK 0x1C00 +/* Path Component [4/14.16.1] */ +struct path_component { + uint8_t type; + uint8_t length; + uint16_t version; + uint8_t identifier[1]; +} __packed; +#define UDF_PATH_ROOT 2 +#define UDF_PATH_DOTDOT 3 +#define UDF_PATH_DOT 4 +#define UDF_PATH_PATH 5 + union dscrptr { struct desc_tag tag; struct anchor_vdp avdp; Modified: stable/7/sys/fs/udf/udf_vnops.c ============================================================================== --- stable/7/sys/fs/udf/udf_vnops.c Wed Mar 18 18:18:38 2009 (r189971) +++ stable/7/sys/fs/udf/udf_vnops.c Wed Mar 18 18:20:20 2009 (r189972) @@ -846,12 +846,121 @@ udf_readdir(struct vop_readdir_args *a) return (error); } -/* Are there any implementations out there that do soft-links? */ static int udf_readlink(struct vop_readlink_args *ap) { - printf("%s called\n", __func__); - return (EOPNOTSUPP); + struct path_component *pc, *end; + struct vnode *vp; + struct uio uio; + struct iovec iov[1]; + struct udf_node *node; + void *buf; + char *cp; + int error, len, root; + + /* + * A symbolic link in UDF is a list of variable-length path + * component structures. We build a pathname in the caller's + * uio by traversing this list. + */ + vp = ap->a_vp; + node = VTON(vp); + len = le64toh(node->fentry->inf_len); + buf = malloc(iov[0].iov_len, M_DEVBUF, M_WAITOK); + iov[0].iov_base = buf; + iov[0].iov_len = len; + uio.uio_iov = iov; + uio.uio_iovcnt = 1; + uio.uio_offset = 0; + uio.uio_resid = iov[0].iov_len; + uio.uio_segflg = UIO_SYSSPACE; + uio.uio_rw = UIO_READ; + uio.uio_td = curthread; + error = VOP_READ(vp, &uio, 0, ap->a_cred); + if (error) + goto error; + + pc = buf; + end = (void *)((char *)buf + len); + root = 0; + while (pc < end) { + switch (pc->type) { + case UDF_PATH_ROOT: + /* Only allow this at the beginning of a path. */ + if ((void *)pc != buf) { + error = EINVAL; + goto error; + } + cp = "/"; + len = 1; + root = 1; + break; + case UDF_PATH_DOT: + cp = "."; + len = 1; + break; + case UDF_PATH_DOTDOT: + cp = ".."; + len = 2; + break; + case UDF_PATH_PATH: + if (pc->length == 0) { + error = EINVAL; + goto error; + } + /* + * XXX: We only support CS8 which appears to map + * to ASCII directly. + */ + switch (pc->identifier[0]) { + case 8: + cp = pc->identifier + 1; + len = pc->length - 1; + break; + default: + error = EOPNOTSUPP; + goto error; + } + break; + default: + error = EINVAL; + goto error; + } + + /* + * If this is not the first component, insert a path + * separator. + */ + if (pc != buf) { + /* If we started with root we already have a "/". */ + if (root) + goto skipslash; + root = 0; + if (ap->a_uio->uio_resid < 1) { + error = ENAMETOOLONG; + goto error; + } + error = uiomove("/", 1, ap->a_uio); + if (error) + break; + } + skipslash: + + /* Append string at 'cp' of length 'len' to our path. */ + if (len > ap->a_uio->uio_resid) { + error = ENAMETOOLONG; + goto error; + } + error = uiomove(cp, len, ap->a_uio); + if (error) + break; + + /* Advance to next component. */ + pc = (void *)((char *)pc + 4 + pc->length); + } +error: + free(buf, M_DEVBUF); + return (error); } static int