… | |
… | |
584 | } |
584 | } |
585 | |
585 | |
586 | static void ecb_cold |
586 | static void ecb_cold |
587 | etp_end_thread (void) |
587 | etp_end_thread (void) |
588 | { |
588 | { |
589 | eio_req *req = calloc (1, sizeof (eio_req)); |
589 | eio_req *req = calloc (1, sizeof (eio_req)); /* will be freed by worker */ |
590 | |
590 | |
591 | req->type = -1; |
591 | req->type = -1; |
592 | req->pri = ETP_PRI_MAX - ETP_PRI_MIN; |
592 | req->pri = ETP_PRI_MAX - ETP_PRI_MIN; |
593 | |
593 | |
594 | X_LOCK (reqlock); |
594 | X_LOCK (reqlock); |
… | |
… | |
1963 | /*****************************************************************************/ |
1963 | /*****************************************************************************/ |
1964 | /* working directory stuff */ |
1964 | /* working directory stuff */ |
1965 | |
1965 | |
1966 | #if HAVE_AT |
1966 | #if HAVE_AT |
1967 | |
1967 | |
1968 | #define WD2FD(wd) (wd ? ((int)wd) - 1 : AT_FDCWD) |
1968 | #define WD2FD(wd) ((wd) ? ((int)(long)(wd)) - 1 : AT_FDCWD) |
|
|
1969 | |
|
|
1970 | #ifndef O_SEARCH |
|
|
1971 | # define O_SEARCH O_RDONLY |
|
|
1972 | #endif |
1969 | |
1973 | |
1970 | eio_wd |
1974 | eio_wd |
1971 | eio_wd_open_sync (eio_wd wd, const char *path) |
1975 | eio_wd_open_sync (eio_wd wd, const char *path) |
1972 | { |
1976 | { |
1973 | int fd = openat (WD2FD (wd), path, O_CLOEXEC | O_SEARCH | O_DIRECTORY); |
1977 | int fd = openat (WD2FD (wd), path, O_CLOEXEC | O_SEARCH | O_DIRECTORY); |
1974 | |
1978 | |
1975 | return fd >= 0 ? (eio_wd)(fd + 1) : EIO_INVALID_WD; |
1979 | return fd >= 0 ? (eio_wd)(long)(fd + 1) : EIO_INVALID_WD; |
|
|
1980 | } |
|
|
1981 | |
|
|
1982 | static eio_wd |
|
|
1983 | eio__wd_open_sync (struct tmpbuf *tmpbuf, eio_wd wd, const char *path) |
|
|
1984 | { |
|
|
1985 | return eio_wd_open_sync (wd, path); |
1976 | } |
1986 | } |
1977 | |
1987 | |
1978 | void |
1988 | void |
1979 | eio_wd_close_sync (eio_wd wd) |
1989 | eio_wd_close_sync (eio_wd wd) |
1980 | { |
1990 | { |
1981 | int fd = WD2FD (wd); |
1991 | int fd = WD2FD (wd); |
1982 | |
1992 | |
1983 | if (fd >= 0) |
1993 | if (fd >= 0) |
1984 | close (fd); |
1994 | close (fd); |
|
|
1995 | } |
|
|
1996 | |
|
|
1997 | static int |
|
|
1998 | eio__truncateat (int dirfd, const char *path, off_t length) |
|
|
1999 | { |
|
|
2000 | int fd = openat (dirfd, path, O_WRONLY | O_CLOEXEC); |
|
|
2001 | int res; |
|
|
2002 | |
|
|
2003 | if (fd < 0) |
|
|
2004 | return fd; |
|
|
2005 | |
|
|
2006 | res = ftruncate (fd, length); |
|
|
2007 | close (fd); |
|
|
2008 | return res; |
|
|
2009 | } |
|
|
2010 | |
|
|
2011 | static int |
|
|
2012 | eio__statvfsat (int dirfd, const char *path, struct statvfs *buf) |
|
|
2013 | { |
|
|
2014 | int fd = openat (dirfd, path, O_SEARCH | O_CLOEXEC); |
|
|
2015 | int res; |
|
|
2016 | |
|
|
2017 | if (fd < 0) |
|
|
2018 | return fd; |
|
|
2019 | |
|
|
2020 | res = fstatvfs (fd, buf); |
|
|
2021 | close (fd); |
|
|
2022 | return res; |
|
|
2023 | |
1985 | } |
2024 | } |
1986 | |
2025 | |
1987 | #else |
2026 | #else |
1988 | |
2027 | |
1989 | /* on legacy systems, we represent the working directories simply by their path strings */ |
2028 | /* on legacy systems, we represent the working directories simply by their path strings */ |
… | |
… | |
2006 | |
2045 | |
2007 | return res; |
2046 | return res; |
2008 | } |
2047 | } |
2009 | } |
2048 | } |
2010 | |
2049 | |
2011 | eio_wd |
2050 | static eio_wd |
2012 | eio__wd_open_sync (struct tmpbuf *tmpbuf, eio_wd wd, const char *path) |
2051 | eio__wd_open_sync (struct tmpbuf *tmpbuf, eio_wd wd, const char *path) |
2013 | { |
2052 | { |
2014 | if (*path == '/') /* absolute paths ignore wd */ |
2053 | if (*path == '/') /* absolute paths ignore wd */ |
2015 | path = strdup (path); |
2054 | path = strdup (path); |
2016 | else if (path [0] == '.' && !path [1]) /* special case '.', as it is common */ |
2055 | else if (path [0] == '.' && !path [1]) /* special case '.', as it is common */ |
… | |
… | |
2245 | |
2284 | |
2246 | case EIO_READAHEAD: req->result = readahead (req->int1, req->offs, req->size); break; |
2285 | case EIO_READAHEAD: req->result = readahead (req->int1, req->offs, req->size); break; |
2247 | case EIO_SENDFILE: req->result = eio__sendfile (req->int1, req->int2, req->offs, req->size); break; |
2286 | case EIO_SENDFILE: req->result = eio__sendfile (req->int1, req->int2, req->offs, req->size); break; |
2248 | |
2287 | |
2249 | #if HAVE_AT |
2288 | #if HAVE_AT |
2250 | case EIO_GETPATH: abort (); |
|
|
2251 | case EIO_STAT: ALLOC (sizeof (EIO_STRUCT_STAT)); |
2289 | case EIO_STAT: ALLOC (sizeof (EIO_STRUCT_STAT)); |
2252 | req->result = fstatat (dirfd, path, (EIO_STRUCT_STAT *)req->ptr2); break; |
2290 | req->result = fstatat (dirfd, req->ptr1, (EIO_STRUCT_STAT *)req->ptr2, 0); break; |
2253 | case EIO_LSTAT: ALLOC (sizeof (EIO_STRUCT_STAT)); |
2291 | case EIO_LSTAT: ALLOC (sizeof (EIO_STRUCT_STAT)); |
2254 | req->result = lstat (dirfd, path, (EIO_STRUCT_STAT *)req->ptr2); break; |
2292 | req->result = fstatat (dirfd, req->ptr1, (EIO_STRUCT_STAT *)req->ptr2, AT_SYMLINK_NOFOLLOW); break; |
2255 | #if 0/*D*/ |
2293 | case EIO_CHOWN: req->result = fchownat (dirfd, req->ptr1, req->int2, req->int3, 0); break; |
|
|
2294 | case EIO_CHMOD: req->result = fchmodat (dirfd, req->ptr1, (mode_t)req->int2, 0); break; |
|
|
2295 | case EIO_TRUNCATE: req->result = eio__truncateat (dirfd, req->ptr1, req->offs); break; |
|
|
2296 | case EIO_OPEN: req->result = openat (dirfd, req->ptr1, req->int1, (mode_t)req->int2); break; |
|
|
2297 | |
|
|
2298 | case EIO_UNLINK: req->result = unlinkat (dirfd, req->ptr1, 0); break; |
|
|
2299 | case EIO_RMDIR: req->result = unlinkat (dirfd, req->ptr1, AT_REMOVEDIR); break; |
|
|
2300 | case EIO_MKDIR: req->result = mkdirat (dirfd, req->ptr1, (mode_t)req->int2); break; |
|
|
2301 | case EIO_RENAME: req->result = renameat (dirfd, req->ptr1, WD2FD (req->int3), req->ptr2); break; |
|
|
2302 | case EIO_LINK: req->result = linkat (dirfd, req->ptr1, WD2FD (req->int3), req->ptr2, 0); break; |
|
|
2303 | case EIO_SYMLINK: req->result = symlinkat (req->ptr1, dirfd, req->ptr2); break; |
|
|
2304 | case EIO_MKNOD: req->result = mknodat (dirfd, req->ptr1, (mode_t)req->int2, (dev_t)req->offs); break; |
|
|
2305 | case EIO_READLINK: ALLOC (PATH_MAX); |
|
|
2306 | req->result = readlinkat (dirfd, req->ptr1, req->ptr2, PATH_MAX); break; |
2256 | case EIO_STATVFS: ALLOC (sizeof (EIO_STRUCT_STATVFS)); |
2307 | case EIO_STATVFS: ALLOC (sizeof (EIO_STRUCT_STATVFS)); |
2257 | req->result = statvfs (dirfd, path, (EIO_STRUCT_STATVFS *)req->ptr2); break; |
2308 | req->result = eio__statvfsat (dirfd, req->ptr1, (EIO_STRUCT_STATVFS *)req->ptr2); break; |
2258 | #endif |
|
|
2259 | case EIO_CHOWN: req->result = chown (dirfd, path, req->int2, req->int3); break; |
|
|
2260 | case EIO_CHMOD: req->result = chmod (dirfd, path, (mode_t)req->int2); break; |
|
|
2261 | case EIO_TRUNCATE: req->result = truncate (dirfd, path, req->offs); break; |
|
|
2262 | case EIO_OPEN: req->result = open (dirfd, path, req->int1, (mode_t)req->int2); break; |
|
|
2263 | |
|
|
2264 | case EIO_UNLINK: req->result = unlink (dirfd, path); break; |
|
|
2265 | case EIO_RMDIR: req->result = rmdir (dirfd, path); break; |
|
|
2266 | case EIO_MKDIR: req->result = mkdir (dirfd, path, (mode_t)req->int2); break; |
|
|
2267 | case EIO_RENAME: req->result = rename (dirfd, path, req->ptr2); break; |
|
|
2268 | case EIO_LINK: req->result = link (dirfd, path, req->ptr2); break; |
|
|
2269 | case EIO_SYMLINK: req->result = symlink (dirfd, path, req->ptr2); break; |
|
|
2270 | case EIO_MKNOD: req->result = mknod (dirfd, path, (mode_t)req->int2, (dev_t)req->offs); break; |
|
|
2271 | #else |
2309 | #else |
2272 | case EIO_STAT: ALLOC (sizeof (EIO_STRUCT_STAT)); |
2310 | case EIO_STAT: ALLOC (sizeof (EIO_STRUCT_STAT)); |
2273 | req->result = stat (path , (EIO_STRUCT_STAT *)req->ptr2); break; |
2311 | req->result = stat (path , (EIO_STRUCT_STAT *)req->ptr2); break; |
2274 | case EIO_LSTAT: ALLOC (sizeof (EIO_STRUCT_STAT)); |
2312 | case EIO_LSTAT: ALLOC (sizeof (EIO_STRUCT_STAT)); |
2275 | req->result = lstat (path , (EIO_STRUCT_STAT *)req->ptr2); break; |
2313 | req->result = lstat (path , (EIO_STRUCT_STAT *)req->ptr2); break; |
… | |
… | |
2283 | case EIO_MKDIR: req->result = mkdir (path , (mode_t)req->int2); break; |
2321 | case EIO_MKDIR: req->result = mkdir (path , (mode_t)req->int2); break; |
2284 | case EIO_RENAME: req->result = rename (path , req->ptr2); break; |
2322 | case EIO_RENAME: req->result = rename (path , req->ptr2); break; |
2285 | case EIO_LINK: req->result = link (path , req->ptr2); break; |
2323 | case EIO_LINK: req->result = link (path , req->ptr2); break; |
2286 | case EIO_SYMLINK: req->result = symlink (path , req->ptr2); break; |
2324 | case EIO_SYMLINK: req->result = symlink (path , req->ptr2); break; |
2287 | case EIO_MKNOD: req->result = mknod (path , (mode_t)req->int2, (dev_t)req->offs); break; |
2325 | case EIO_MKNOD: req->result = mknod (path , (mode_t)req->int2, (dev_t)req->offs); break; |
2288 | |
|
|
2289 | case EIO_READLINK: ALLOC (PATH_MAX); |
2326 | case EIO_READLINK: ALLOC (PATH_MAX); |
2290 | req->result = readlink (path, req->ptr2, PATH_MAX); break; |
2327 | req->result = readlink (path, req->ptr2, PATH_MAX); break; |
|
|
2328 | case EIO_STATVFS: ALLOC (sizeof (EIO_STRUCT_STATVFS)); |
|
|
2329 | req->result = statvfs (path , (EIO_STRUCT_STATVFS *)req->ptr2); break; |
2291 | #endif |
2330 | #endif |
2292 | |
2331 | |
2293 | case EIO_REALPATH: if (0 <= (req->result = eio__realpath (&self->tmpbuf, req->wd, req->ptr1))) |
2332 | case EIO_REALPATH: if (0 <= (req->result = eio__realpath (&self->tmpbuf, req->wd, req->ptr1))) |
2294 | { |
2333 | { |
2295 | ALLOC (req->result); |
2334 | ALLOC (req->result); |
2296 | memcpy (req->ptr2, self->tmpbuf.ptr, req->result); |
2335 | memcpy (req->ptr2, self->tmpbuf.ptr, req->result); |
2297 | } |
2336 | } |
2298 | break; |
2337 | break; |
2299 | |
|
|
2300 | case EIO_STATVFS: ALLOC (sizeof (EIO_STRUCT_STATVFS)); /*D*/ |
|
|
2301 | req->result = statvfs (path , (EIO_STRUCT_STATVFS *)req->ptr2); break; |
|
|
2302 | |
2338 | |
2303 | case EIO_FSTAT: ALLOC (sizeof (EIO_STRUCT_STAT)); |
2339 | case EIO_FSTAT: ALLOC (sizeof (EIO_STRUCT_STAT)); |
2304 | req->result = fstat (req->int1, (EIO_STRUCT_STAT *)req->ptr2); break; |
2340 | req->result = fstat (req->int1, (EIO_STRUCT_STAT *)req->ptr2); break; |
2305 | |
2341 | |
2306 | case EIO_FSTATVFS: ALLOC (sizeof (EIO_STRUCT_STATVFS)); |
2342 | case EIO_FSTATVFS: ALLOC (sizeof (EIO_STRUCT_STATVFS)); |