From owner-p4-projects@FreeBSD.ORG Sun Jun 3 13:35:39 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0BF5616A46E; Sun, 3 Jun 2007 13:35:39 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id C9E3916A46C for ; Sun, 3 Jun 2007 13:35:38 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id B9ED713C468 for ; Sun, 3 Jun 2007 13:35:38 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l53DZccP082021 for ; Sun, 3 Jun 2007 13:35:38 GMT (envelope-from rdivacky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l53DZcGZ082006 for perforce@freebsd.org; Sun, 3 Jun 2007 13:35:38 GMT (envelope-from rdivacky@FreeBSD.org) Date: Sun, 3 Jun 2007 13:35:38 GMT Message-Id: <200706031335.l53DZcGZ082006@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to rdivacky@FreeBSD.org using -f From: Roman Divacky To: Perforce Change Reviews Cc: Subject: PERFORCE change 120839 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 03 Jun 2007 13:35:39 -0000 http://perforce.freebsd.org/chv.cgi?CH=120839 Change 120839 by rdivacky@rdivacky_witten on 2007/06/03 13:34:53 Implement linux_readlinkat(). Affected files ... .. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_dummy.c#6 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_proto.h#5 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_syscall.h#5 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_sysent.c#5 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/syscalls.master#5 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_file.c#7 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_dummy.c#5 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_proto.h#5 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_syscall.h#5 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_sysent.c#5 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/syscalls.master#5 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_syscalls.c#13 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/sys/syscallsubr.h#6 edit Differences ... ==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_dummy.c#6 (text+ko) ==== @@ -103,7 +103,6 @@ DUMMY(renameat); DUMMY(linkat); DUMMY(symlinkat); -DUMMY(readlinkat); DUMMY(pselect6); DUMMY(ppoll); DUMMY(unshare); ==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_proto.h#5 (text+ko) ==== @@ -914,7 +914,10 @@ register_t dummy; }; struct linux_readlinkat_args { - register_t dummy; + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; + char bufsiz_l_[PADL_(l_int)]; l_int bufsiz; char bufsiz_r_[PADR_(l_int)]; }; struct linux_fchmodat_args { char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; ==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_syscall.h#5 (text+ko) ==== ==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_sysent.c#5 (text+ko) ==== @@ -325,7 +325,7 @@ { 0, (sy_call_t *)linux_renameat, AUE_NULL, NULL, 0, 0 }, /* 302 = linux_renameat */ { 0, (sy_call_t *)linux_linkat, AUE_NULL, NULL, 0, 0 }, /* 303 = linux_linkat */ { 0, (sy_call_t *)linux_symlinkat, AUE_NULL, NULL, 0, 0 }, /* 304 = linux_symlinkat */ - { 0, (sy_call_t *)linux_readlinkat, AUE_NULL, NULL, 0, 0 }, /* 305 = linux_readlinkat */ + { AS(linux_readlinkat_args), (sy_call_t *)linux_readlinkat, AUE_NULL, NULL, 0, 0 }, /* 305 = linux_readlinkat */ { AS(linux_fchmodat_args), (sy_call_t *)linux_fchmodat, AUE_NULL, NULL, 0, 0 }, /* 306 = linux_fchmodat */ { AS(linux_faccessat_args), (sy_call_t *)linux_faccessat, AUE_NULL, NULL, 0, 0 }, /* 307 = linux_faccessat */ { 0, (sy_call_t *)linux_pselect6, AUE_NULL, NULL, 0, 0 }, /* 308 = linux_pselect6 */ ==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/syscalls.master#5 (text+ko) ==== @@ -476,7 +476,8 @@ 302 AUE_NULL STD { int linux_renameat(void); } 303 AUE_NULL STD { int linux_linkat(void); } 304 AUE_NULL STD { int linux_symlinkat(void); } -305 AUE_NULL STD { int linux_readlinkat(void); } +305 AUE_NULL STD { int linux_readlinkat(l_int dfd, char *path, \ + char *buf, l_int bufsiz); } 306 AUE_NULL STD { int linux_fchmodat(l_int dfd, char *filename, \ l_mode_t mode); } 307 AUE_NULL STD { int linux_faccessat(l_int dfd, char *filename, l_int mode); } ==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_file.c#7 (text+ko) ==== @@ -672,8 +672,8 @@ LCONVPATHEXIST(td, args->filename, &path); #ifdef DEBUG - if (ldebug(fchownat)) - printf(ARGS(fchownat, "%s, %d, %d"), path, args->uid, args->gid); + if (ldebug(fchmodat)) + printf(ARGS(fchmodat, "%s, %d, %d"), path, args->uid, args->gid); #endif if (args->dfd == LINUX_AT_FDCWD) @@ -787,6 +787,30 @@ } int +linux_readlinkat(struct thread *td, struct linux_readlinkat_args *args) +{ + char *name; + int error, dfd; + + LCONVPATHEXIST(td, args->path, &name); + +#ifdef DEBUG + if (ldebug(readlinkat)) + printf(ARGS(readlinkat, "%s, %p, %d"), name, (void *)args->buf, + args->bufsiz); +#endif + + if (args->dfd == LINUX_AT_FDCWD) + dfd = AT_FDCWD; + else + dfd = args->dfd; + + error = kern_readlinkat(td, name, UIO_SYSSPACE, args->buf, UIO_USERSPACE, + args->bufsiz, dfd); + LFREEPATH(name); + return (error); +} +int linux_truncate(struct thread *td, struct linux_truncate_args *args) { char *path; ==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_dummy.c#5 (text+ko) ==== @@ -94,7 +94,6 @@ DUMMY(renameat); DUMMY(linkat); DUMMY(symlinkat); -DUMMY(readlinkat); DUMMY(pselect6); DUMMY(ppoll); DUMMY(unshare); ==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_proto.h#5 (text+ko) ==== @@ -933,7 +933,10 @@ register_t dummy; }; struct linux_readlinkat_args { - register_t dummy; + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; + char bufsiz_l_[PADL_(l_int)]; l_int bufsiz; char bufsiz_r_[PADR_(l_int)]; }; struct linux_fchmodat_args { char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; ==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_syscall.h#5 (text+ko) ==== ==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_sysent.c#5 (text+ko) ==== @@ -324,7 +324,7 @@ { 0, (sy_call_t *)linux_renameat, AUE_NULL, NULL, 0, 0 }, /* 302 = linux_renameat */ { 0, (sy_call_t *)linux_linkat, AUE_NULL, NULL, 0, 0 }, /* 303 = linux_linkat */ { 0, (sy_call_t *)linux_symlinkat, AUE_NULL, NULL, 0, 0 }, /* 304 = linux_symlinkat */ - { 0, (sy_call_t *)linux_readlinkat, AUE_NULL, NULL, 0, 0 }, /* 305 = linux_readlinkat */ + { AS(linux_readlinkat_args), (sy_call_t *)linux_readlinkat, AUE_NULL, NULL, 0, 0 }, /* 305 = linux_readlinkat */ { AS(linux_fchmodat_args), (sy_call_t *)linux_fchmodat, AUE_NULL, NULL, 0, 0 }, /* 306 = linux_fchmodat */ { AS(linux_faccessat_args), (sy_call_t *)linux_faccessat, AUE_NULL, NULL, 0, 0 }, /* 307 = linux_faccessat */ { 0, (sy_call_t *)linux_pselect6, AUE_NULL, NULL, 0, 0 }, /* 308 = linux_pselect6 */ ==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/syscalls.master#5 (text+ko) ==== @@ -486,7 +486,8 @@ 302 AUE_NULL STD { int linux_renameat(void); } 303 AUE_NULL STD { int linux_linkat(void); } 304 AUE_NULL STD { int linux_symlinkat(void); } -305 AUE_NULL STD { int linux_readlinkat(void); } +305 AUE_NULL STD { int linux_readlinkat(l_int dfd, char *path, \ + char *buf, l_int bufsiz); } 306 AUE_NULL STD { int linux_fchmodat(l_int dfd, char *filename, \ l_mode_t mode); } 307 AUE_NULL STD { int linux_faccessat(l_int dfd, char *filename, l_int mode); } ==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_syscalls.c#13 (text+ko) ==== @@ -100,6 +100,8 @@ static int kern_common_lchown(struct thread *td, int uid, int gid, struct nameidata *nd); static int kern_common_chmod(struct thread *td, int mode, struct nameidata *nd); +static int kern_common_readlink(struct thread *td, char *buf, + enum uio_seg bufseg, int count, struct nameidata *nd); /* * The module initialization routine for POSIX asynchronous I/O will @@ -2437,20 +2439,57 @@ kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf, enum uio_seg bufseg, int count) { - register struct vnode *vp; + struct nameidata nd; + NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, + pathseg, path, td); + + return kern_common_readlink(td, buf, bufseg, count, &nd); +} + +int +kern_readlinkat(struct thread *td, char *path, enum uio_seg pathseg, char *buf, + enum uio_seg bufseg, int count, int dirfd) +{ + int error; + struct nameidata nd; + struct vnode *dir_vn; + + if (dirfd == AT_FDCWD) + dir_vn = NULL; + else { + error = fgetvp(td, dirfd, &dir_vn); + if (error) + return (error); + if (dir_vn->v_type != VDIR) { + vrele(dir_vn); + return (ENOTDIR); + } + } + + NDINIT_AT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, pathseg, + path, td, dir_vn); + + error = kern_common_readlink(td, buf, bufseg, count, &nd); + if (dirfd != AT_FDCWD) + vrele(dir_vn); + return (error); +} + +static int +kern_common_readlink(struct thread *td, char *buf, enum uio_seg bufseg, int count, + struct nameidata *nd) +{ + struct vnode *vp; struct iovec aiov; struct uio auio; int error; - struct nameidata nd; int vfslocked; - NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1, - pathseg, path, td); - if ((error = namei(&nd)) != 0) + if ((error = namei(nd)) != 0) return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); - vfslocked = NDHASGIANT(&nd); - vp = nd.ni_vp; + NDFREE(nd, NDF_ONLY_PNBUF); + vfslocked = NDHASGIANT(nd); + vp = nd->ni_vp; #ifdef MAC error = mac_check_vnode_readlink(td->td_ucred, vp); if (error) { ==== //depot/projects/soc2007/rdivacky/linux_at/sys/sys/syscallsubr.h#6 (text+ko) ==== @@ -140,6 +140,8 @@ int kern_pwritev(struct thread *td, int fd, struct uio *auio, off_t offset); int kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf, enum uio_seg bufseg, int count); +int kern_readlinkat(struct thread *td, char *path, enum uio_seg pathseg, + char *buf, enum uio_seg bufseg, int count, int dirfd); int kern_readv(struct thread *td, int fd, struct uio *auio); int kern_recvit(struct thread *td, int s, struct msghdr *mp, enum uio_seg fromseg, struct mbuf **controlp);