PERFORCE change 120839 for review
Roman Divacky
rdivacky at FreeBSD.org
Sun Jun 3 13:35:39 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=120839
Change 120839 by rdivacky at 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);
More information about the p4-projects
mailing list