From owner-p4-projects@FreeBSD.ORG Mon Jun 4 20:17:51 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 87F4816A478; Mon, 4 Jun 2007 20:17:51 +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 5AB7B16A476 for ; Mon, 4 Jun 2007 20:17:51 +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 49DAF13C4C1 for ; Mon, 4 Jun 2007 20:17:51 +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 l54KHpoZ054011 for ; Mon, 4 Jun 2007 20:17:51 GMT (envelope-from rdivacky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l54KHohh053993 for perforce@freebsd.org; Mon, 4 Jun 2007 20:17:50 GMT (envelope-from rdivacky@FreeBSD.org) Date: Mon, 4 Jun 2007 20:17:50 GMT Message-Id: <200706042017.l54KHohh053993@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 120927 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: Mon, 04 Jun 2007 20:17:51 -0000 http://perforce.freebsd.org/chv.cgi?CH=120927 Change 120927 by rdivacky@rdivacky_witten on 2007/06/04 20:16:51 Implement the rest of the *at syscalls. Affected files ... .. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_dummy.c#8 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_proto.h#7 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_syscall.h#7 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_sysent.c#7 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/syscalls.master#7 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_file.c#10 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_misc.c#3 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_util.h#3 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_dummy.c#7 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_proto.h#7 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_syscall.h#7 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_sysent.c#7 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/syscalls.master#7 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_syscalls.c#16 edit .. //depot/projects/soc2007/rdivacky/linux_at/sys/sys/syscallsubr.h#9 edit Differences ... ==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_dummy.c#8 (text+ko) ==== @@ -96,10 +96,6 @@ DUMMY(inotify_add_watch); DUMMY(inotify_rm_watch); DUMMY(migrate_pages); -DUMMY(mkdirat); -DUMMY(mknodat); -DUMMY(futimesat); -DUMMY(renameat); DUMMY(pselect6); DUMMY(ppoll); DUMMY(unshare); ==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_proto.h#7 (text+ko) ==== @@ -880,10 +880,15 @@ char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; }; struct linux_mkdirat_args { - register_t dummy; + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char pathname_l_[PADL_(char *)]; char * pathname; char pathname_r_[PADR_(char *)]; + char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; }; struct linux_mknodat_args { - register_t dummy; + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char filename_l_[PADL_(char *)]; char * filename; char filename_r_[PADR_(char *)]; + char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; + char dev_l_[PADL_(l_uint)]; l_uint dev; char dev_r_[PADR_(l_uint)]; }; struct linux_fchownat_args { char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; @@ -893,7 +898,9 @@ char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)]; }; struct linux_futimesat_args { - register_t dummy; + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char filename_l_[PADL_(char *)]; char * filename; char filename_r_[PADR_(char *)]; + char utimes_l_[PADL_(struct l_timeval *)]; struct l_timeval * utimes; char utimes_r_[PADR_(struct l_timeval *)]; }; struct linux_fstatat64_args { char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; @@ -907,7 +914,10 @@ char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)]; }; struct linux_renameat_args { - register_t dummy; + char olddfd_l_[PADL_(l_int)]; l_int olddfd; char olddfd_r_[PADR_(l_int)]; + char oldname_l_[PADL_(char *)]; char * oldname; char oldname_r_[PADR_(char *)]; + char newdfd_l_[PADL_(l_int)]; l_int newdfd; char newdfd_r_[PADR_(l_int)]; + char newname_l_[PADL_(char *)]; char * newname; char newname_r_[PADR_(char *)]; }; struct linux_linkat_args { char olddfd_l_[PADL_(l_int)]; l_int olddfd; char olddfd_r_[PADR_(l_int)]; ==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_syscall.h#7 (text+ko) ==== ==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_sysent.c#7 (text+ko) ==== @@ -316,13 +316,13 @@ { 0, (sy_call_t *)linux_inotify_rm_watch, AUE_NULL, NULL, 0, 0 }, /* 293 = linux_inotify_rm_watch */ { 0, (sy_call_t *)linux_migrate_pages, AUE_NULL, NULL, 0, 0 }, /* 294 = linux_migrate_pages */ { AS(linux_openat_args), (sy_call_t *)linux_openat, AUE_OPEN_RWTC, NULL, 0, 0 }, /* 295 = linux_openat */ - { 0, (sy_call_t *)linux_mkdirat, AUE_NULL, NULL, 0, 0 }, /* 296 = linux_mkdirat */ - { 0, (sy_call_t *)linux_mknodat, AUE_NULL, NULL, 0, 0 }, /* 297 = linux_mknodat */ + { AS(linux_mkdirat_args), (sy_call_t *)linux_mkdirat, AUE_NULL, NULL, 0, 0 }, /* 296 = linux_mkdirat */ + { AS(linux_mknodat_args), (sy_call_t *)linux_mknodat, AUE_NULL, NULL, 0, 0 }, /* 297 = linux_mknodat */ { AS(linux_fchownat_args), (sy_call_t *)linux_fchownat, AUE_NULL, NULL, 0, 0 }, /* 298 = linux_fchownat */ - { 0, (sy_call_t *)linux_futimesat, AUE_NULL, NULL, 0, 0 }, /* 299 = linux_futimesat */ + { AS(linux_futimesat_args), (sy_call_t *)linux_futimesat, AUE_NULL, NULL, 0, 0 }, /* 299 = linux_futimesat */ { AS(linux_fstatat64_args), (sy_call_t *)linux_fstatat64, AUE_NULL, NULL, 0, 0 }, /* 300 = linux_fstatat64 */ { AS(linux_unlinkat_args), (sy_call_t *)linux_unlinkat, AUE_NULL, NULL, 0, 0 }, /* 301 = linux_unlinkat */ - { 0, (sy_call_t *)linux_renameat, AUE_NULL, NULL, 0, 0 }, /* 302 = linux_renameat */ + { AS(linux_renameat_args), (sy_call_t *)linux_renameat, AUE_NULL, NULL, 0, 0 }, /* 302 = linux_renameat */ { AS(linux_linkat_args), (sy_call_t *)linux_linkat, AUE_NULL, NULL, 0, 0 }, /* 303 = linux_linkat */ { AS(linux_symlinkat_args), (sy_call_t *)linux_symlinkat, AUE_NULL, NULL, 0, 0 }, /* 304 = linux_symlinkat */ { AS(linux_readlinkat_args), (sy_call_t *)linux_readlinkat, AUE_NULL, NULL, 0, 0 }, /* 305 = linux_readlinkat */ ==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/syscalls.master#7 (text+ko) ==== @@ -465,15 +465,16 @@ 294 AUE_NULL STD { int linux_migrate_pages(void); } 295 AUE_OPEN_RWTC STD { int linux_openat(l_int dfd, char *filename, \ l_int flags, l_int mode); } -296 AUE_NULL STD { int linux_mkdirat(void); } -297 AUE_NULL STD { int linux_mknodat(void); } +296 AUE_NULL STD { int linux_mkdirat(l_int dfd, char *pathname, l_int mode); } +297 AUE_NULL STD { int linux_mknodat(l_int dfd, char *filename, l_int mode, l_uint dev); } 298 AUE_NULL STD { int linux_fchownat(l_int dfd, char *filename, \ l_uid16_t uid, l_gid16_t gid, l_int flag); } -299 AUE_NULL STD { int linux_futimesat(void); } +299 AUE_NULL STD { int linux_futimesat(l_int dfd, char *filename, struct l_timeval *utimes); } 300 AUE_NULL STD { int linux_fstatat64(l_int dfd, char *pathname, \ struct l_stat64 *statbuf, l_int flag); } 301 AUE_NULL STD { int linux_unlinkat(l_int dfd, char *pathname, l_int flag); } -302 AUE_NULL STD { int linux_renameat(void); } +302 AUE_NULL STD { int linux_renameat(l_int olddfd, char *oldname, l_int newdfd, \ + char *newname); } 303 AUE_NULL STD { int linux_linkat(l_int olddfd, char *oldname, \ l_int newdfd, char *newname, l_int flags); } 304 AUE_NULL STD { int linux_symlinkat(char *oldname, l_int newdfd, char *newname); } ==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_file.c#10 (text+ko) ==== @@ -712,6 +712,7 @@ LFREEPATH(path); return (error); } + int linux_mkdir(struct thread *td, struct linux_mkdir_args *args) { @@ -730,6 +731,28 @@ } int +linux_mkdirat(struct thread *td, struct linux_mkdirat_args *args) +{ + char *path; + int error, dfd; + + if (args->dfd == LINUX_AT_FDCWD) + dfd = AT_FDCWD; + else + dfd = args->dfd; + + LCONVPATHCREAT_AT(td, args->pathname, &path, dfd); + +#ifdef DEBUG + if (ldebug(mkdirat)) + printf(ARGS(mkdirat, "%s, %d"), path, args->mode); +#endif + error = kern_mkdirat(td, path, UIO_SYSSPACE, args->mode, dfd); + LFREEPATH(path); + return (error); +} + +int linux_rmdir(struct thread *td, struct linux_rmdir_args *args) { char *path; @@ -771,6 +794,40 @@ } int +linux_renameat(struct thread *td, struct linux_renameat_args *args) +{ + char *from, *to; + int error, olddfd, newdfd; + + if (args->olddfd == LINUX_AT_FDCWD) + olddfd = AT_FDCWD; + else + olddfd = args->olddfd; + + if (args->newdfd == LINUX_AT_FDCWD) + newdfd = AT_FDCWD; + else + newdfd = args->newdfd; + + LCONVPATHEXIST_AT(td, args->oldname, &from, olddfd); + /* Expand LCONVPATHCREATE so that `from' can be freed on errors */ + error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1, newdfd); + if (to == NULL) { + LFREEPATH(from); + return (error); + } + +#ifdef DEBUG + if (ldebug(renameat)) + printf(ARGS(renameat, "%s, %s"), from, to); +#endif + error = kern_renameat(td, from, to, UIO_SYSSPACE, olddfd, newdfd); + LFREEPATH(from); + LFREEPATH(to); + return (error); +} + +int linux_symlink(struct thread *td, struct linux_symlink_args *args) { char *path, *to; ==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_misc.c#3 (text+ko) ==== @@ -86,6 +86,7 @@ #include #endif +#include #include #include #include @@ -818,6 +819,43 @@ LFREEPATH(fname); return (error); } + +int +linux_futimesat(struct thread *td, struct linux_futimesat_args *args) +{ + l_timeval ltv[2]; + struct timeval tv[2], *tvp = NULL; + char *fname; + int error, dfd; + + if (args->dfd == LINUX_AT_FDCWD) + dfd = AT_FDCWD; + else + dfd = args->dfd; + + LCONVPATHEXIST_AT(td, args->filename, &fname, dfd); + +#ifdef DEBUG + if (ldebug(futimesat)) + printf(ARGS(futimesat, "%s, *"), fname); +#endif + + if (args->utimes!= NULL) { + if ((error = copyin(args->utimes, ltv, sizeof ltv))) { + LFREEPATH(fname); + return (error); + } + tv[0].tv_sec = ltv[0].tv_sec; + tv[0].tv_usec = ltv[0].tv_usec; + tv[1].tv_sec = ltv[1].tv_sec; + tv[1].tv_usec = ltv[1].tv_usec; + tvp = tv; + } + + error = kern_utimesat(td, fname, UIO_SYSSPACE, tvp, UIO_SYSSPACE, dfd); + LFREEPATH(fname); + return (error); +} #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ #define __WCLONE 0x80000000 @@ -955,6 +993,56 @@ return (error); } +int +linux_mknodat(struct thread *td, struct linux_mknodat_args *args) +{ + char *path; + int error, dfd; + + if (args->dfd == LINUX_AT_FDCWD) + dfd = AT_FDCWD; + else + dfd = args->dfd; + + LCONVPATHCREAT_AT(td, args->filename, &path, dfd); + +#ifdef DEBUG + if (ldebug(mknodat)) + printf(ARGS(mknodat, "%s, %d, %d"), path, args->mode, args->dev); +#endif + + switch (args->mode & S_IFMT) { + case S_IFIFO: + case S_IFSOCK: + error = kern_mkfifoat(td, path, UIO_SYSSPACE, args->mode, dfd); + break; + + case S_IFCHR: + case S_IFBLK: + error = kern_mknodat(td, path, UIO_SYSSPACE, args->mode, + args->dev, dfd); + break; + + case S_IFDIR: + error = EPERM; + break; + + case 0: + args->mode |= S_IFREG; + /* FALLTHROUGH */ + case S_IFREG: + error = kern_openat(td, path, UIO_SYSSPACE, + O_WRONLY | O_CREAT | O_TRUNC, args->mode, dfd); + break; + + default: + error = EINVAL; + break; + } + LFREEPATH(path); + return (error); +} + /* * UGH! This is just about the dumbest idea I've ever heard!! */ ==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_util.h#3 (text+ko) ==== @@ -69,6 +69,7 @@ #define LCONVPATHEXIST(td, upath, pathp) LCONVPATH(td, upath, pathp, 0) #define LCONVPATHEXIST_AT(td, upath, pathp, dfd) LCONVPATH_AT(td, upath, pathp, 0, dfd) #define LCONVPATHCREAT(td, upath, pathp) LCONVPATH(td, upath, pathp, 1) +#define LCONVPATHCREAT_AT(td, upath, pathp, dfd) LCONVPATH_AT(td, upath, pathp, 1, dfd) #define LFREEPATH(path) free(path, M_TEMP) #define DUMMY(s) \ ==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_dummy.c#7 (text+ko) ==== @@ -87,10 +87,6 @@ DUMMY(inotify_add_watch); DUMMY(inotify_rm_watch); DUMMY(migrate_pages); -DUMMY(mkdirat); -DUMMY(mknodat); -DUMMY(futimesat); -DUMMY(renameat); DUMMY(pselect6); DUMMY(ppoll); DUMMY(unshare); ==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_proto.h#7 (text+ko) ==== @@ -899,10 +899,15 @@ char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; }; struct linux_mkdirat_args { - register_t dummy; + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char pathname_l_[PADL_(char *)]; char * pathname; char pathname_r_[PADR_(char *)]; + char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; }; struct linux_mknodat_args { - register_t dummy; + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char filename_l_[PADL_(char *)]; char * filename; char filename_r_[PADR_(char *)]; + char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; + char dev_l_[PADL_(l_uint)]; l_uint dev; char dev_r_[PADR_(l_uint)]; }; struct linux_fchownat_args { char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; @@ -912,7 +917,9 @@ char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)]; }; struct linux_futimesat_args { - register_t dummy; + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char filename_l_[PADL_(char *)]; char * filename; char filename_r_[PADR_(char *)]; + char utimes_l_[PADL_(struct l_timeval *)]; struct l_timeval * utimes; char utimes_r_[PADR_(struct l_timeval *)]; }; struct linux_fstatat64_args { char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; @@ -926,7 +933,10 @@ char flag_l_[PADL_(l_int)]; l_int flag; char flag_r_[PADR_(l_int)]; }; struct linux_renameat_args { - register_t dummy; + char olddfd_l_[PADL_(l_int)]; l_int olddfd; char olddfd_r_[PADR_(l_int)]; + char oldname_l_[PADL_(char *)]; char * oldname; char oldname_r_[PADR_(char *)]; + char newdfd_l_[PADL_(l_int)]; l_int newdfd; char newdfd_r_[PADR_(l_int)]; + char newname_l_[PADL_(char *)]; char * newname; char newname_r_[PADR_(char *)]; }; struct linux_linkat_args { char olddfd_l_[PADL_(l_int)]; l_int olddfd; char olddfd_r_[PADR_(l_int)]; ==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_syscall.h#7 (text+ko) ==== ==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_sysent.c#7 (text+ko) ==== @@ -315,13 +315,13 @@ { 0, (sy_call_t *)linux_inotify_rm_watch, AUE_NULL, NULL, 0, 0 }, /* 293 = linux_inotify_rm_watch */ { 0, (sy_call_t *)linux_migrate_pages, AUE_NULL, NULL, 0, 0 }, /* 294 = linux_migrate_pages */ { AS(linux_openat_args), (sy_call_t *)linux_openat, AUE_OPEN_RWTC, NULL, 0, 0 }, /* 295 = linux_openat */ - { 0, (sy_call_t *)linux_mkdirat, AUE_NULL, NULL, 0, 0 }, /* 296 = linux_mkdirat */ - { 0, (sy_call_t *)linux_mknodat, AUE_NULL, NULL, 0, 0 }, /* 297 = linux_mknodat */ + { AS(linux_mkdirat_args), (sy_call_t *)linux_mkdirat, AUE_NULL, NULL, 0, 0 }, /* 296 = linux_mkdirat */ + { AS(linux_mknodat_args), (sy_call_t *)linux_mknodat, AUE_NULL, NULL, 0, 0 }, /* 297 = linux_mknodat */ { AS(linux_fchownat_args), (sy_call_t *)linux_fchownat, AUE_NULL, NULL, 0, 0 }, /* 298 = linux_fchownat */ - { 0, (sy_call_t *)linux_futimesat, AUE_NULL, NULL, 0, 0 }, /* 299 = linux_futimesat */ + { AS(linux_futimesat_args), (sy_call_t *)linux_futimesat, AUE_NULL, NULL, 0, 0 }, /* 299 = linux_futimesat */ { AS(linux_fstatat64_args), (sy_call_t *)linux_fstatat64, AUE_NULL, NULL, 0, 0 }, /* 300 = linux_fstatat64 */ { AS(linux_unlinkat_args), (sy_call_t *)linux_unlinkat, AUE_NULL, NULL, 0, 0 }, /* 301 = linux_unlinkat */ - { 0, (sy_call_t *)linux_renameat, AUE_NULL, NULL, 0, 0 }, /* 302 = linux_renameat */ + { AS(linux_renameat_args), (sy_call_t *)linux_renameat, AUE_NULL, NULL, 0, 0 }, /* 302 = linux_renameat */ { AS(linux_linkat_args), (sy_call_t *)linux_linkat, AUE_NULL, NULL, 0, 0 }, /* 303 = linux_linkat */ { AS(linux_symlinkat_args), (sy_call_t *)linux_symlinkat, AUE_NULL, NULL, 0, 0 }, /* 304 = linux_symlinkat */ { AS(linux_readlinkat_args), (sy_call_t *)linux_readlinkat, AUE_NULL, NULL, 0, 0 }, /* 305 = linux_readlinkat */ ==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/syscalls.master#7 (text+ko) ==== @@ -475,15 +475,16 @@ 294 AUE_NULL STD { int linux_migrate_pages(void); } 295 AUE_OPEN_RWTC STD { int linux_openat(l_int dfd, char *filename, \ l_int flags, l_int mode); } -296 AUE_NULL STD { int linux_mkdirat(void); } -297 AUE_NULL STD { int linux_mknodat(void); } +296 AUE_NULL STD { int linux_mkdirat(l_int dfd, char *pathname, l_int mode); } +297 AUE_NULL STD { int linux_mknodat(l_int dfd, char *filename, l_int mode, l_uint dev); } 298 AUE_NULL STD { int linux_fchownat(l_int dfd, char *filename, \ l_uid16_t uid, l_gid16_t gid, l_int flag); } -299 AUE_NULL STD { int linux_futimesat(void); } +299 AUE_NULL STD { int linux_futimesat(l_int dfd, char *filename, struct l_timeval *utimes); } 300 AUE_NULL STD { int linux_fstatat64(l_int dfd, char *pathname, \ struct l_stat64 *statbuf, l_int flag); } 301 AUE_NULL STD { int linux_unlinkat(l_int dfd, char *pathname, l_int flag); } -302 AUE_NULL STD { int linux_renameat(void); } +302 AUE_NULL STD { int linux_renameat(l_int olddfd, char *oldname, l_int newdfd, \ + char *newname); } 303 AUE_NULL STD { int linux_linkat(l_int olddfd, char *oldname, \ l_int newdfd, char *newname, l_int flags); } 304 AUE_NULL STD { int linux_symlinkat(char *oldname, l_int newdfd, char *newname); } ==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_syscalls.c#16 (text+ko) ==== @@ -105,6 +105,10 @@ enum uio_seg bufseg, int count, struct nameidata *nd); static int kern_common_link(struct thread *td, struct nameidata *ndp, struct nameidata *ndl); +static int kern_common_utimes(struct thread *td, char *path, enum uio_seg pathseg, + struct timeval *tptr, enum uio_seg tptrseg, struct nameidata *nd); +static int kern_common_rename(struct thread *td, char *from, char *to, + enum uio_seg pathseg, struct nameidata *fromnd, struct nameidata *tond); /* * The module initialization routine for POSIX asynchronous I/O will @@ -1208,7 +1212,14 @@ kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode, int dev) { - struct vnode *vp; + return kern_mknodat(td, path, pathseg, mode, dev, AT_FDCWD); +} + +int +kern_mknodat(struct thread *td, char *path, enum uio_seg pathseg, int mode, + int dev, int dirfd) +{ + struct vnode *vp, *dir_vn = NULL; struct mount *mp; struct vattr vattr; int error; @@ -1236,11 +1247,19 @@ if (error) return (error); restart: + if (dir_vn) + vrele(dir_vn); + error = kern_get_at(td, dirfd, &dir_vn); + if (error) + return (error); bwillwrite(); - NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, - pathseg, path, td); - if ((error = namei(&nd)) != 0) + NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, + pathseg, path, td, dir_vn); + if ((error = namei(&nd)) != 0) { + if (dir_vn) + vrele(dir_vn); return (error); + } vfslocked = NDHASGIANT(&nd); vp = nd.ni_vp; if (vp != NULL) { @@ -1251,6 +1270,8 @@ vput(nd.ni_dvp); vrele(vp); VFS_UNLOCK_GIANT(vfslocked); + if (dir_vn) + vrele(dir_vn); return (EEXIST); } else { VATTR_NULL(&vattr); @@ -1282,8 +1303,11 @@ NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); VFS_UNLOCK_GIANT(vfslocked); - if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) + if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) { + if (dir_vn) + vrele(dir_vn); return (error); + } goto restart; } #ifdef MAC @@ -1302,6 +1326,8 @@ vput(nd.ni_vp); } } + if (dir_vn) + vrele(dir_vn); NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); vn_finished_write(mp); @@ -1333,19 +1359,34 @@ int kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, int mode) { + return kern_mkfifoat(td, path, pathseg, mode, AT_FDCWD); +} + +int +kern_mkfifoat(struct thread *td, char *path, enum uio_seg pathseg, int mode, int dirfd) +{ struct mount *mp; struct vattr vattr; int error; struct nameidata nd; int vfslocked; + struct vnode *dir_vn = NULL; AUDIT_ARG(mode, mode); restart: + if (dir_vn) + vrele(dir_vn); + error = kern_get_at(td, dirfd, &dir_vn); + if (error) + return (error); bwillwrite(); - NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, - pathseg, path, td); - if ((error = namei(&nd)) != 0) + NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, + pathseg, path, td, dir_vn); + if ((error = namei(&nd)) != 0) { + if (dir_vn) + vrele(dir_vn); return (error); + } vfslocked = NDHASGIANT(&nd); if (nd.ni_vp != NULL) { NDFREE(&nd, NDF_ONLY_PNBUF); @@ -1355,14 +1396,19 @@ vput(nd.ni_dvp); vrele(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); + if (dir_vn) + vrele(dir_vn); return (EEXIST); } if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); VFS_UNLOCK_GIANT(vfslocked); - if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) + if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) { + if (dir_vn) + vrele(dir_vn); return (error); + } goto restart; } VATTR_NULL(&vattr); @@ -1383,6 +1429,8 @@ #ifdef MAC out: #endif + if (dir_vn) + vrele(dir_vn); vput(nd.ni_dvp); vn_finished_write(mp); VFS_UNLOCK_GIANT(vfslocked); @@ -3199,20 +3247,49 @@ kern_utimes(struct thread *td, char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg) { + struct nameidata nd; + + NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td); + + return kern_common_utimes(td, path, pathseg, tptr, tptrseg, &nd); +} + +int +kern_utimesat(struct thread *td, char *path, enum uio_seg pathseg, + struct timeval *tptr, enum uio_seg tptrseg, int dirfd) +{ + int error; + struct nameidata nd; + struct vnode *dir_vn; + + error = kern_get_at(td, dirfd, &dir_vn); + if (error) + return (error); + + NDINIT_AT(&nd, LOOKUP, FOLLOW | AUDITVNODE1 | MPSAFE, pathseg, path, td, dir_vn); + + error = kern_common_utimes(td, path, pathseg, tptr, tptrseg, &nd); + if (dir_vn) + vrele(dir_vn); + return (error); +} + +static int +kern_common_utimes(struct thread *td, char *path, enum uio_seg pathseg, + struct timeval *tptr, enum uio_seg tptrseg, struct nameidata *nd) +{ struct timespec ts[2]; int error; - struct nameidata nd; int vfslocked; if ((error = getutimes(tptr, tptrseg, ts)) != 0) return (error); - NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE | AUDITVNODE1, pathseg, path, td); - if ((error = namei(&nd)) != 0) + if ((error = namei(nd)) != 0) return (error); - vfslocked = NDHASGIANT(&nd); - NDFREE(&nd, NDF_ONLY_PNBUF); - error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); - vrele(nd.ni_vp); + vfslocked = NDHASGIANT(nd); + NDFREE(nd, NDF_ONLY_PNBUF); + error = setutimes(td, nd->ni_vp, ts, 2, tptr == NULL); + vrele(nd->ni_vp); VFS_UNLOCK_GIANT(vfslocked); return (error); } @@ -3564,14 +3641,8 @@ int kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) { - struct mount *mp = NULL; - struct vnode *tvp, *fvp, *tdvp; struct nameidata fromnd, tond; - int tvfslocked; - int fvfslocked; - int error; - bwillwrite(); #ifdef MAC NDINIT(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE | AUDITVNODE1, pathseg, from, td); @@ -3579,43 +3650,92 @@ NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART | MPSAFE | AUDITVNODE1, pathseg, from, td); #endif - if ((error = namei(&fromnd)) != 0) + NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | + MPSAFE | AUDITVNODE2, pathseg, to, td); + + return kern_common_rename(td, from, to, pathseg, &fromnd, &tond); +} + +int +kern_renameat(struct thread *td, char *from, char *to, enum uio_seg pathseg, int fdirfd, int tdirfd) +{ + struct nameidata fromnd, tond; + struct vnode *fdir_vn, *tdir_vn; + int error; + + error = kern_get_at(td, fdirfd, &fdir_vn); + if (error) + return (error); + error = kern_get_at(td, tdirfd, &tdir_vn); + if (error) + return (error); + +#ifdef MAC + NDINIT_AT(&fromnd, DELETE, LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE | + AUDITVNODE1, pathseg, from, td, fdir_vn); +#else + NDINIT_AT(&fromnd, DELETE, WANTPARENT | SAVESTART | MPSAFE | + AUDITVNODE1, pathseg, from, td, fdir_vn); +#endif + NDINIT_AT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | + MPSAFE | AUDITVNODE2, pathseg, to, td, tdir_vn); + + error = kern_common_rename(td, from, to, pathseg, &fromnd, &tond); + + if (fdir_vn) + vrele(fdir_vn); + if (tdir_vn) + vrele(tdir_vn); + + return (error); +} + +static int +kern_common_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg, + struct nameidata *fromnd, struct nameidata *tond) +{ + struct mount *mp = NULL; + struct vnode *tvp, *fvp, *tdvp; + int tvfslocked; + int fvfslocked; + int error; + + bwillwrite(); + if ((error = namei(fromnd)) != 0) return (error); - fvfslocked = NDHASGIANT(&fromnd); + fvfslocked = NDHASGIANT(fromnd); tvfslocked = 0; #ifdef MAC - error = mac_check_vnode_rename_from(td->td_ucred, fromnd.ni_dvp, - fromnd.ni_vp, &fromnd.ni_cnd); - VOP_UNLOCK(fromnd.ni_dvp, 0, td); - if (fromnd.ni_dvp != fromnd.ni_vp) - VOP_UNLOCK(fromnd.ni_vp, 0, td); + error = mac_check_vnode_rename_from(td->td_ucred, fromnd->ni_dvp, + fromnd->ni_vp, &(fromnd->ni_cnd)); + VOP_UNLOCK(fromnd->ni_dvp, 0, td); + if (fromnd->ni_dvp != fromnd->ni_vp) + VOP_UNLOCK(fromnd->ni_vp, 0, td); #endif - fvp = fromnd.ni_vp; + fvp = fromnd->ni_vp; if (error == 0) error = vn_start_write(fvp, &mp, V_WAIT | PCATCH); if (error != 0) { - NDFREE(&fromnd, NDF_ONLY_PNBUF); - vrele(fromnd.ni_dvp); + NDFREE(fromnd, NDF_ONLY_PNBUF); + vrele(fromnd->ni_dvp); vrele(fvp); goto out1; } - NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | - MPSAFE | AUDITVNODE2, pathseg, to, td); - if (fromnd.ni_vp->v_type == VDIR) - tond.ni_cnd.cn_flags |= WILLBEDIR; - if ((error = namei(&tond)) != 0) { + if (fromnd->ni_vp->v_type == VDIR) + tond->ni_cnd.cn_flags |= WILLBEDIR; + if ((error = namei(tond)) != 0) { /* Translate error code for rename("dir1", "dir2/."). */ if (error == EISDIR && fvp->v_type == VDIR) error = EINVAL; - NDFREE(&fromnd, NDF_ONLY_PNBUF); - vrele(fromnd.ni_dvp); + NDFREE(fromnd, NDF_ONLY_PNBUF); + vrele(fromnd->ni_dvp); vrele(fvp); vn_finished_write(mp); goto out1; } - tvfslocked = NDHASGIANT(&tond); - tdvp = tond.ni_dvp; - tvp = tond.ni_vp; + tvfslocked = NDHASGIANT(tond); + tdvp = tond->ni_dvp; + tvp = tond->ni_vp; if (tvp != NULL) { if (fvp->v_type == VDIR && tvp->v_type != VDIR) { error = ENOTDIR; @@ -3636,38 +3756,38 @@ #ifdef MAC else error = mac_check_vnode_rename_to(td->td_ucred, tdvp, - tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd); + tond->ni_vp, fromnd->ni_dvp == tdvp, &(tond->ni_cnd)); #endif out: if (!error) { VOP_LEASE(tdvp, td, td->td_ucred, LEASE_WRITE); - if (fromnd.ni_dvp != tdvp) { - VOP_LEASE(fromnd.ni_dvp, td, td->td_ucred, LEASE_WRITE); + if (fromnd->ni_dvp != tdvp) { + VOP_LEASE(fromnd->ni_dvp, td, td->td_ucred, LEASE_WRITE); } if (tvp) { VOP_LEASE(tvp, td, td->td_ucred, LEASE_WRITE); } - error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, - tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); - NDFREE(&fromnd, NDF_ONLY_PNBUF); - NDFREE(&tond, NDF_ONLY_PNBUF); + error = VOP_RENAME(fromnd->ni_dvp, fromnd->ni_vp, &(fromnd->ni_cnd), + tond->ni_dvp, tond->ni_vp, &(tond->ni_cnd)); + NDFREE(fromnd, NDF_ONLY_PNBUF); + NDFREE(tond, NDF_ONLY_PNBUF); } else { - NDFREE(&fromnd, NDF_ONLY_PNBUF); - NDFREE(&tond, NDF_ONLY_PNBUF); + NDFREE(fromnd, NDF_ONLY_PNBUF); + NDFREE(tond, NDF_ONLY_PNBUF); if (tvp) vput(tvp); if (tdvp == tvp) vrele(tdvp); else vput(tdvp); - vrele(fromnd.ni_dvp); + vrele(fromnd->ni_dvp); vrele(fvp); } - vrele(tond.ni_startdir); + vrele(tond->ni_startdir); vn_finished_write(mp); out1: - if (fromnd.ni_startdir) - vrele(fromnd.ni_startdir); + if (fromnd->ni_startdir) + vrele(fromnd->ni_startdir); VFS_UNLOCK_GIANT(fvfslocked); VFS_UNLOCK_GIANT(tvfslocked); if (error == -1) @@ -3699,8 +3819,14 @@ int kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode) { + return kern_mkdirat(td, path, segflg, mode, AT_FDCWD); +} + +int +kern_mkdirat(struct thread *td, char *path, enum uio_seg segflg, int mode, int dirfd) +{ struct mount *mp; - struct vnode *vp; + struct vnode *vp, *dir_vn = NULL; struct vattr vattr; int error; struct nameidata nd; @@ -3708,12 +3834,20 @@ AUDIT_ARG(mode, mode); restart: + if (dir_vn) + vrele(dir_vn); + error = kern_get_at(td, dirfd, &dir_vn); + if (error) + return (error); bwillwrite(); - NDINIT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, - segflg, path, td); + NDINIT_AT(&nd, CREATE, LOCKPARENT | SAVENAME | MPSAFE | AUDITVNODE1, + segflg, path, td, dir_vn); nd.ni_cnd.cn_flags |= WILLBEDIR; - if ((error = namei(&nd)) != 0) + if ((error = namei(&nd)) != 0) { + if (dir_vn) + vrele(dir_vn); return (error); + } vfslocked = NDHASGIANT(&nd); vp = nd.ni_vp; if (vp != NULL) { @@ -3729,14 +3863,19 @@ vput(nd.ni_dvp); vrele(vp); VFS_UNLOCK_GIANT(vfslocked); + if (dir_vn) + vrele(dir_vn); return (EEXIST); } if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); VFS_UNLOCK_GIANT(vfslocked); - if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) + if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) { + if (dir_vn) + vrele(dir_vn); return (error); + } goto restart; } VATTR_NULL(&vattr); @@ -3755,6 +3894,8 @@ #ifdef MAC out: #endif + if (dir_vn) + vrele(dir_vn); NDFREE(&nd, NDF_ONLY_PNBUF); vput(nd.ni_dvp); if (!error) @@ -3793,7 +3934,7 @@ kern_rmdirat(struct thread *td, char *path, enum uio_seg pathseg, int dirfd) { struct mount *mp; - struct vnode *vp, *dir_vn; + struct vnode *vp, *dir_vn = NULL; int error; struct nameidata nd; int vfslocked; ==== //depot/projects/soc2007/rdivacky/linux_at/sys/sys/syscallsubr.h#9 (text+ko) ==== @@ -121,10 +121,16 @@ struct timeval *tptr, enum uio_seg tptrseg); int kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode); +int kern_mkdirat(struct thread *td, char *path, enum uio_seg segflg, + int mode, int dirfd); int kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, int mode); +int kern_mkfifoat(struct thread *td, char *path, enum uio_seg pathseg, + int mode, int dirfd); int kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode, int dev); +int kern_mknodat(struct thread *td, char *path, enum uio_seg pathseg, + int mode, int dev, int dirfd); int kern_msgctl(struct thread *, int, int, struct msqid_ds *); int kern_msgsnd(struct thread *, int, const void *, size_t, int, long); int kern_msgrcv(struct thread *, int, void *, size_t, long, int, long *); @@ -149,6 +155,8 @@ enum uio_seg fromseg, struct mbuf **controlp); int kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg); +int kern_renameat(struct thread *td, char *from, char *to, + enum uio_seg pathseg, int fdirfd, int tdirfd); int kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg); int kern_rmdirat(struct thread *td, char *path, enum uio_seg pathseg, int dirfd); int kern_sched_rr_get_interval(struct thread *td, pid_t pid, @@ -195,6 +203,8 @@ int kern_unlinkat(struct thread *td, char *path, enum uio_seg pathseg, int dirfd); int kern_utimes(struct thread *td, char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg); +int kern_utimesat(struct thread *td, char *path, enum uio_seg pathseg, + struct timeval *tptr, enum uio_seg tptrseg, int dirfd); int kern_wait(struct thread *td, pid_t pid, int *status, int options, struct rusage *rup); int kern_writev(struct thread *td, int fd, struct uio *auio);