PERFORCE change 120927 for review
Roman Divacky
rdivacky at FreeBSD.org
Mon Jun 4 20:17:51 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=120927
Change 120927 by rdivacky at 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 <machine/../linux/linux_proto.h>
#endif
+#include <compat/linux/linux_file.h>
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_signal.h>
#include <compat/linux/linux_util.h>
@@ -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);
More information about the p4-projects
mailing list