Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 3 Jun 2007 13:35:38 GMT
From:      Roman Divacky <rdivacky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 120839 for review
Message-ID:  <200706031335.l53DZcGZ082006@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);



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