From 073b81c8ec025154ee98ff3147fbb3121200e157 Mon Sep 17 00:00:00 2001 From: Lucian Petrut Date: Fri, 7 Aug 2020 12:06:07 +0000 Subject: [PATCH] client: Port CephFS client to Windows This patch provides a few changes required in order to use the CephFS client on Windows. A subsequent patch will make use of it along with Dokan, an interface similar to Fuse. Signed-off-by: Lucian Petrut --- src/client/Client.cc | 39 +++++++++++++++++++++++++++-- src/client/Inode.h | 1 + src/common/compat.cc | 20 +++++++++++++++ src/include/cephfs/ceph_ll_client.h | 4 +++ src/include/compat.h | 20 +++++++++++---- src/include/win32/fs_compat.h | 35 ++++++++++++++++++++++++++ src/include/win32/sys/statvfs.h | 36 ++++++++++++++++++++++++++ src/mds/CInode.h | 1 + src/mds/mdstypes.h | 1 + 9 files changed, 150 insertions(+), 7 deletions(-) create mode 100644 src/include/win32/fs_compat.h diff --git a/src/client/Client.cc b/src/client/Client.cc index 3887a8675b1..96f6fd02b45 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -23,7 +23,9 @@ #include #include #include +#ifndef _WIN32 #include +#endif #include #include @@ -31,7 +33,7 @@ #include "common/async/waiter.h" -#if defined(__FreeBSD__) +#if defined(__FreeBSD__) || defined(_WIN32) #define XATTR_CREATE 0x1 #define XATTR_REPLACE 0x2 #else @@ -127,6 +129,20 @@ #define O_DIRECT 0x0 #endif +// Windows doesn't define those values. While the Posix compatibilty layer +// doesn't support those values, the Windows native functions do provide +// similar flags. Special care should be taken if we're going to use those +// flags in ceph-dokan. The current values are no-ops, while propagating +// them to the rest of the code might cause the Windows functions to reject +// them as invalid. +#ifndef O_NOFOLLOW +#define O_NOFOLLOW 0x0 +#endif + +#ifndef O_SYNC +#define O_SYNC 0x0 +#endif + #define DEBUG_GETATTR_CAPS (CEPH_CAP_XATTR_SHARED) using namespace TOPNSPC::common; @@ -2034,6 +2050,13 @@ MetaSession *Client::_get_or_open_mds_session(mds_rank_t mds) void Client::populate_metadata(const std::string &mount_root) { // Hostname +#ifdef _WIN32 + // TODO: move this to compat.h + char hostname[64]; + DWORD hostname_sz = 64; + GetComputerNameA(hostname, &hostname_sz); + metadata["hostname"] = hostname; +#else struct utsname u; int r = uname(&u); if (r >= 0) { @@ -2042,6 +2065,7 @@ void Client::populate_metadata(const std::string &mount_root) } else { ldout(cct, 1) << __func__ << " failed to read hostname (" << cpp_strerror(r) << ")" << dendl; } +#endif metadata["pid"] = stringify(getpid()); @@ -7439,6 +7463,9 @@ void Client::stat_to_statx(struct stat *st, struct ceph_statx *stx) #ifdef __APPLE__ stx->stx_mtime = st->st_mtimespec; stx->stx_atime = st->st_atimespec; +#elif __WIN32 + stx->stx_mtime.tv_sec = st->st_mtime; + stx->stx_atime.tv_sec = st->st_atime; #else stx->stx_mtime = st->st_mtim; stx->stx_atime = st->st_atim; @@ -7732,12 +7759,20 @@ int Client::fill_stat(Inode *in, struct stat *st, frag_info_t *dirstat, nest_inf st->st_size = in->rstat.rbytes; else st->st_size = in->dirstat.size(); +// The Windows "stat" structure provides just a subset of the fields that are +// available on Linux. +#ifndef _WIN32 st->st_blocks = 1; +#endif } else { st->st_size = in->size; +#ifndef _WIN32 st->st_blocks = (in->size + 511) >> 9; +#endif } +#ifndef _WIN32 st->st_blksize = std::max(in->layout.stripe_unit, 4096); +#endif if (dirstat) *dirstat = in->dirstat; @@ -8281,7 +8316,7 @@ void Client::fill_dirent(struct dirent *de, const char *name, int type, uint64_t { strncpy(de->d_name, name, 255); de->d_name[255] = '\0'; -#ifndef __CYGWIN__ +#if !defined(__CYGWIN__) && !(defined(_WIN32)) de->d_ino = ino; #if !defined(__APPLE__) && !defined(__FreeBSD__) de->d_off = next_off; diff --git a/src/client/Inode.h b/src/client/Inode.h index 797eb063eef..66fc0411a31 100644 --- a/src/client/Inode.h +++ b/src/client/Inode.h @@ -6,6 +6,7 @@ #include +#include "include/compat.h" #include "include/ceph_assert.h" #include "include/types.h" #include "include/xlist.h" diff --git a/src/common/compat.cc b/src/common/compat.cc index d4f30d54c24..3ec0ca2009c 100644 --- a/src/common/compat.cc +++ b/src/common/compat.cc @@ -529,6 +529,26 @@ ssize_t get_self_exe_path(char* path, int buff_length) { return GetModuleFileName(NULL, path, buff_length - 1); } +int geteuid() +{ + return 0; +} + +int getegid() +{ + return 0; +} + +int getuid() +{ + return 0; +} + +int getgid() +{ + return 0; +} + #else unsigned get_page_size() { diff --git a/src/include/cephfs/ceph_ll_client.h b/src/include/cephfs/ceph_ll_client.h index 4f3d4235eb5..78731db218d 100644 --- a/src/include/cephfs/ceph_ll_client.h +++ b/src/include/cephfs/ceph_ll_client.h @@ -15,6 +15,10 @@ #define CEPH_CEPH_LL_CLIENT_H #include +#ifdef _WIN32 +#include "include/win32/fs_compat.h" +#endif + #ifdef __cplusplus extern "C" { diff --git a/src/include/compat.h b/src/include/compat.h index 6147c5c0a19..0534c15e3bf 100644 --- a/src/include/compat.h +++ b/src/include/compat.h @@ -150,6 +150,9 @@ int sched_setaffinity(pid_t pid, size_t cpusetsize, #define LOG_AUTHPRIV (10<<3) #define LOG_FTP (11<<3) #define __STRING(x) "x" +#endif + +#if defined(__sun) || defined(_AIX) || defined(_WIN32) #define IFTODT(mode) (((mode) & 0170000) >> 12) #endif @@ -220,6 +223,7 @@ int ceph_memzero_s(void *dest, size_t destsz, size_t count); #include #include "include/win32/win32_errno.h" +#include "include/win32/fs_compat.h" // There are a few name collisions between Windows headers and Ceph. // Updating Ceph definitions would be the prefferable fix in order to avoid @@ -237,12 +241,12 @@ typedef unsigned int uint; typedef _sigset_t sigset_t; -typedef int uid_t; -typedef int gid_t; +typedef unsigned int uid_t; +typedef unsigned int gid_t; -typedef long blksize_t; -typedef long blkcnt_t; -typedef long nlink_t; +typedef unsigned int blksize_t; +typedef unsigned __int64 blkcnt_t; +typedef unsigned short nlink_t; typedef long long loff_t; @@ -297,6 +301,12 @@ int chown(const char *path, uid_t owner, gid_t group); int fchown(int fd, uid_t owner, gid_t group); int lchown(const char *path, uid_t owner, gid_t group); int setenv(const char *name, const char *value, int overwrite); + +int geteuid(); +int getegid(); +int getuid(); +int getgid(); + #define unsetenv(name) _putenv_s(name, "") int win_socketpair(int socks[2]); diff --git a/src/include/win32/fs_compat.h b/src/include/win32/fs_compat.h new file mode 100644 index 00000000000..ef699e0420b --- /dev/null +++ b/src/include/win32/fs_compat.h @@ -0,0 +1,35 @@ +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2021 SUSE LINUX GmbH + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +// Those definitions allow handling information coming from Ceph and should +// not be passed to Windows functions. + +#define S_IFLNK 0120000 + +#define S_ISTYPE(m, TYPE) ((m & S_IFMT) == TYPE) +#define S_ISLNK(m) S_ISTYPE(m, S_IFLNK) +#define S_ISUID 04000 +#define S_ISGID 02000 +#define S_ISVTX 01000 + +#define LOCK_SH 1 +#define LOCK_EX 2 +#define LOCK_NB 4 +#define LOCK_UN 8 +#define LOCK_MAND 32 +#define LOCK_READ 64 +#define LOCK_WRITE 128 +#define LOCK_RW 192 + +#define AT_SYMLINK_NOFOLLOW 0x100 + +#define MAXSYMLINKS 65000 diff --git a/src/include/win32/sys/statvfs.h b/src/include/win32/sys/statvfs.h index e69de29bb2d..73a892b88f2 100644 --- a/src/include/win32/sys/statvfs.h +++ b/src/include/win32/sys/statvfs.h @@ -0,0 +1,36 @@ +#ifndef _SYS_STATVFS_H +#define _SYS_STATVFS_H 1 + +typedef unsigned __int64 fsfilcnt64_t; +typedef unsigned __int64 fsblkcnt64_t; +typedef unsigned __int64 fsblkcnt_t; + +struct statvfs +{ + unsigned long int f_bsize; + unsigned long int f_frsize; + fsblkcnt64_t f_blocks; + fsblkcnt64_t f_bfree; + fsblkcnt64_t f_bavail; + fsfilcnt64_t f_files; + fsfilcnt64_t f_ffree; + fsfilcnt64_t f_favail; + unsigned long int f_fsid; + unsigned long int f_flag; + unsigned long int f_namemax; + int __f_spare[6]; +}; +struct flock { + short l_type; + short l_whence; + off_t l_start; + off_t l_len; + pid_t l_pid; +}; + +#define F_RDLCK 0 +#define F_WRLCK 1 +#define F_UNLCK 2 +#define F_SETLK 6 + +#endif /* _SYS_STATVFS_H */ diff --git a/src/mds/CInode.h b/src/mds/CInode.h index 513113ba146..177e02d0632 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -22,6 +22,7 @@ #include "common/config.h" #include "common/RefCountedObj.h" +#include "include/compat.h" #include "include/counter.h" #include "include/elist.h" #include "include/types.h" diff --git a/src/mds/mdstypes.h b/src/mds/mdstypes.h index 736cceaa813..796c935c7cf 100644 --- a/src/mds/mdstypes.h +++ b/src/mds/mdstypes.h @@ -17,6 +17,7 @@ #include "common/StackStringStream.h" #include "common/entity_name.h" +#include "include/compat.h" #include "include/Context.h" #include "include/frag.h" #include "include/xlist.h" -- 2.39.5