mirror of
https://github.com/samba-team/samba.git
synced 2025-02-25 17:57:42 +03:00
s3 onefs: update the onefs module to be compliant with stat_ex
This commit is contained in:
parent
0a455c1284
commit
5c623e6c2e
@ -170,4 +170,17 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd,
|
||||
ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset,
|
||||
size_t count);
|
||||
|
||||
void init_stat_ex_from_onefs_stat(struct stat_ex *dst, const struct stat *src);
|
||||
|
||||
int onefs_sys_stat(const char *fname, SMB_STRUCT_STAT *sbuf);
|
||||
|
||||
int onefs_sys_fstat(int fd, SMB_STRUCT_STAT *sbuf);
|
||||
|
||||
int onefs_sys_fstat_at(int base_fd, const char *fname, SMB_STRUCT_STAT *sbuf,
|
||||
int flags);
|
||||
|
||||
int onefs_sys_lstat(const char *fname, SMB_STRUCT_STAT *sbuf);
|
||||
|
||||
|
||||
|
||||
#endif /* _ONEFS_H */
|
||||
|
@ -393,7 +393,7 @@ onefs_canon_acl(files_struct *fsp, struct ifs_security_descriptor *sd)
|
||||
if (error)
|
||||
return false;
|
||||
|
||||
if ((sbuf.st_flags & SF_HASNTFSACL) != 0) {
|
||||
if ((sbuf.st_ex_flags & SF_HASNTFSACL) != 0) {
|
||||
DEBUG(10, ("Did not canonicalize ACLs because a "
|
||||
"Windows ACL set was found for file %s\n",
|
||||
fsp->fsp_name));
|
||||
@ -540,7 +540,8 @@ static bool add_sfs_aces(files_struct *fsp, struct ifs_security_descriptor *sd)
|
||||
}
|
||||
|
||||
/* Only continue if this is a synthetic ACL and a directory. */
|
||||
if (S_ISDIR(sbuf.st_mode) && (sbuf.st_flags & SF_HASNTFSACL) == 0) {
|
||||
if (S_ISDIR(sbuf.st_ex_mode) &&
|
||||
(sbuf.st_ex_flags & SF_HASNTFSACL) == 0) {
|
||||
struct ifs_ace new_aces[6];
|
||||
struct ifs_ace *old_aces;
|
||||
int i, num_aces_to_add = 0;
|
||||
|
@ -43,7 +43,7 @@
|
||||
#define RDP_DIRENTRIES_SIZE ((size_t)(RDP_BATCH_SIZE * sizeof(struct dirent)))
|
||||
|
||||
static char *rdp_direntries = NULL;
|
||||
static SMB_STRUCT_STAT *rdp_stats = NULL;
|
||||
static struct stat *rdp_stats = NULL;
|
||||
static uint64_t *rdp_cookies = NULL;
|
||||
|
||||
struct rdp_dir_state {
|
||||
@ -113,7 +113,7 @@ rdp_init(struct rdp_dir_state *dsp)
|
||||
|
||||
if (!rdp_stats) {
|
||||
rdp_stats =
|
||||
SMB_MALLOC(RDP_BATCH_SIZE * sizeof(SMB_STRUCT_STAT));
|
||||
SMB_MALLOC(RDP_BATCH_SIZE * sizeof(struct stat));
|
||||
if (!rdp_stats)
|
||||
return ENOMEM;
|
||||
}
|
||||
@ -367,11 +367,15 @@ onefs_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp,
|
||||
/* Return an entry from cache */
|
||||
ret_direntp = ((SMB_STRUCT_DIRENT *)dsp->direntries_cursor);
|
||||
if (sbuf) {
|
||||
*sbuf = rdp_stats[dsp->stat_cursor];
|
||||
struct stat onefs_sbuf;
|
||||
|
||||
onefs_sbuf = rdp_stats[dsp->stat_cursor];
|
||||
init_stat_ex_from_onefs_stat(sbuf, &onefs_sbuf);
|
||||
|
||||
/* readdirplus() sets st_ino field to 0, if it was
|
||||
* unable to retrieve stat information for that
|
||||
* particular directory entry. */
|
||||
if (sbuf->st_ino == 0)
|
||||
if (sbuf->st_ex_ino == 0)
|
||||
SET_STAT_INVALID(*sbuf);
|
||||
}
|
||||
|
||||
|
@ -630,21 +630,21 @@ onefs_notify_watch(vfs_handle_struct *vfs_handle,
|
||||
}
|
||||
|
||||
/* Get LIN for directory */
|
||||
if (sys_fstat(e->dir_fd, &sbuf)) {
|
||||
if (onefs_sys_fstat(e->dir_fd, &sbuf)) {
|
||||
DEBUG(0, ("stat on directory fd failed: %s\n",
|
||||
strerror(errno)));
|
||||
status = map_nt_error_from_unix(errno);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (sbuf.st_ino == 0) {
|
||||
if (sbuf.st_ex_ino == 0) {
|
||||
DEBUG(0, ("0 LIN found!\n"));
|
||||
goto err;
|
||||
}
|
||||
|
||||
wc->ctx = ctx;
|
||||
wc->watch_fd = e->dir_fd;
|
||||
wc->watch_lin = sbuf.st_ino;
|
||||
wc->watch_lin = sbuf.st_ex_ino;
|
||||
wc->ifs_event_fd = ifs_event_fd;
|
||||
wc->ifs_filter = ifs_filter;
|
||||
wc->smb_filter = smb_filter;
|
||||
@ -669,7 +669,7 @@ onefs_notify_watch(vfs_handle_struct *vfs_handle,
|
||||
"ifs_filter=0x%x, watch_tree=%d, ifs_event_fd=%d, "
|
||||
"dir_fd=%d, dir_lin=0x%llx\n",
|
||||
e->path, smb_filter, ifs_filter, watch_tree,
|
||||
ifs_event_fd, e->dir_fd, sbuf.st_ino));
|
||||
ifs_event_fd, e->dir_fd, sbuf.st_ex_ino));
|
||||
|
||||
return NT_STATUS_OK;
|
||||
|
||||
|
@ -148,7 +148,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
|
||||
* open flags. JRA.
|
||||
*/
|
||||
|
||||
if (file_existed && S_ISFIFO(psbuf->st_mode)) {
|
||||
if (file_existed && S_ISFIFO(psbuf->st_ex_mode)) {
|
||||
local_flags |= O_NONBLOCK;
|
||||
}
|
||||
#endif
|
||||
@ -289,13 +289,13 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
|
||||
* so catch a directory open and return an EISDIR. JRA.
|
||||
*/
|
||||
|
||||
if(S_ISDIR(psbuf->st_mode)) {
|
||||
if(S_ISDIR(psbuf->st_ex_mode)) {
|
||||
fd_close(fsp);
|
||||
errno = EISDIR;
|
||||
return NT_STATUS_FILE_IS_A_DIRECTORY;
|
||||
}
|
||||
|
||||
fsp->mode = psbuf->st_mode;
|
||||
fsp->mode = psbuf->st_ex_mode;
|
||||
fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
|
||||
fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
|
||||
fsp->file_pid = req ? req->smbpid : 0;
|
||||
@ -661,7 +661,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
|
||||
"FILE_CREATE requested for file %s "
|
||||
"and file already exists.\n",
|
||||
fname));
|
||||
if (S_ISDIR(psbuf->st_mode)) {
|
||||
if (S_ISDIR(psbuf->st_ex_mode)) {
|
||||
errno = EISDIR;
|
||||
} else {
|
||||
errno = EEXIST;
|
||||
@ -687,13 +687,13 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
|
||||
(create_disposition == FILE_OVERWRITE_IF))) {
|
||||
if (!open_match_attributes(conn, fname,
|
||||
existing_dos_attributes,
|
||||
new_dos_attributes, psbuf->st_mode,
|
||||
new_dos_attributes, psbuf->st_ex_mode,
|
||||
unx_mode, &new_unx_mode)) {
|
||||
DEBUG(5, ("onefs_open_file_ntcreate: attributes "
|
||||
"missmatch for file %s (%x %x) (0%o, 0%o)\n",
|
||||
fname, existing_dos_attributes,
|
||||
new_dos_attributes,
|
||||
(unsigned int)psbuf->st_mode,
|
||||
(unsigned int)psbuf->st_ex_mode,
|
||||
(unsigned int)unx_mode ));
|
||||
errno = EACCES;
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
@ -816,7 +816,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
|
||||
}
|
||||
|
||||
if (file_existed) {
|
||||
struct timespec old_write_time = get_mtimespec(psbuf);
|
||||
struct timespec old_write_time = psbuf->st_ex_mtime;
|
||||
id = vfs_file_id_from_sbuf(conn, psbuf);
|
||||
|
||||
lck = get_share_mode_lock(talloc_tos(), id,
|
||||
@ -900,7 +900,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
|
||||
struct deferred_open_record state;
|
||||
struct timespec old_write_time;
|
||||
|
||||
old_write_time = get_mtimespec(psbuf);
|
||||
old_write_time = psbuf->st_ex_mtime;
|
||||
|
||||
DEBUG(3, ("Someone created file %s with an "
|
||||
"oplock after we looked: Retrying\n",
|
||||
@ -1089,7 +1089,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
|
||||
}
|
||||
|
||||
if (!file_existed) {
|
||||
struct timespec old_write_time = get_mtimespec(psbuf);
|
||||
struct timespec old_write_time = psbuf->st_ex_mtime;
|
||||
/*
|
||||
* Deal with the race condition where two smbd's detect the
|
||||
* file doesn't exist and do the create at the same time. One
|
||||
@ -1267,7 +1267,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
|
||||
* May be necessary depending on acl policies.
|
||||
*/
|
||||
if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf)
|
||||
&& (psbuf->st_flags & SF_HASNTFSACL))) {
|
||||
&& (psbuf->st_ex_flags & SF_HASNTFSACL))) {
|
||||
|
||||
int saved_errno = errno; /* We might get ENOSYS in the next
|
||||
* call.. */
|
||||
@ -1495,7 +1495,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
|
||||
return map_nt_error_from_unix(errno);
|
||||
}
|
||||
|
||||
if (!S_ISDIR(psbuf->st_mode)) {
|
||||
if (!S_ISDIR(psbuf->st_ex_mode)) {
|
||||
DEBUG(0, ("Directory just '%s' created is not a "
|
||||
"directory\n", fname));
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
@ -1509,9 +1509,9 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
|
||||
* parent dir.
|
||||
*/
|
||||
if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
|
||||
(mode & ~psbuf->st_mode)) {
|
||||
SMB_VFS_CHMOD(conn, fname, (psbuf->st_mode |
|
||||
(mode & ~psbuf->st_mode)));
|
||||
(mode & ~psbuf->st_ex_mode)) {
|
||||
SMB_VFS_CHMOD(conn, fname, (psbuf->st_ex_mode |
|
||||
(mode & ~psbuf->st_ex_mode)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1533,7 +1533,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
|
||||
}
|
||||
|
||||
/* Setup the files_struct for it. */
|
||||
fsp->mode = psbuf->st_mode;
|
||||
fsp->mode = psbuf->st_ex_mode;
|
||||
fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
|
||||
fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
|
||||
fsp->file_pid = req ? req->smbpid : 0;
|
||||
@ -1556,7 +1556,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
|
||||
|
||||
string_set(&fsp->fsp_name,fname);
|
||||
|
||||
mtimespec = get_mtimespec(psbuf);
|
||||
mtimespec = psbuf->st_ex_mtime;
|
||||
|
||||
/*
|
||||
* Still set the samba share mode lock for correct delete-on-close
|
||||
@ -1904,7 +1904,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
|
||||
}
|
||||
}
|
||||
|
||||
if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
|
||||
if (!fsp->is_directory && S_ISDIR(sbuf.st_ex_mode)) {
|
||||
status = NT_STATUS_ACCESS_DENIED;
|
||||
goto fail;
|
||||
}
|
||||
@ -1912,7 +1912,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
|
||||
/* Save the requested allocation size. */
|
||||
if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
|
||||
if (allocation_size
|
||||
&& (allocation_size > sbuf.st_size)) {
|
||||
&& (allocation_size > sbuf.st_ex_size)) {
|
||||
fsp->initial_allocation_size = smb_roundup(
|
||||
fsp->conn, allocation_size);
|
||||
if (fsp->is_directory) {
|
||||
@ -1927,7 +1927,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
|
||||
}
|
||||
} else {
|
||||
fsp->initial_allocation_size = smb_roundup(
|
||||
fsp->conn, (uint64_t)sbuf.st_size);
|
||||
fsp->conn, (uint64_t)sbuf.st_ex_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,81 +222,84 @@ static void merge_stat(SMB_STRUCT_STAT *stream_sbuf,
|
||||
{
|
||||
int dos_flags = (UF_DOS_NOINDEX | UF_DOS_ARCHIVE |
|
||||
UF_DOS_HIDDEN | UF_DOS_RO | UF_DOS_SYSTEM);
|
||||
stream_sbuf->st_mtime = base_sbuf->st_mtime;
|
||||
stream_sbuf->st_ctime = base_sbuf->st_ctime;
|
||||
stream_sbuf->st_atime = base_sbuf->st_atime;
|
||||
stream_sbuf->st_flags &= ~dos_flags;
|
||||
stream_sbuf->st_flags |= base_sbuf->st_flags & dos_flags;
|
||||
stream_sbuf->st_ex_mtime = base_sbuf->st_ex_mtime;
|
||||
stream_sbuf->st_ex_ctime = base_sbuf->st_ex_ctime;
|
||||
stream_sbuf->st_ex_atime = base_sbuf->st_ex_atime;
|
||||
stream_sbuf->st_ex_flags &= ~dos_flags;
|
||||
stream_sbuf->st_ex_flags |= base_sbuf->st_ex_flags & dos_flags;
|
||||
}
|
||||
|
||||
/* fake timestamps */
|
||||
static void onefs_adjust_stat_time(vfs_handle_struct *handle, const char *fname,
|
||||
SMB_STRUCT_STAT *sbuf)
|
||||
static void onefs_adjust_stat_time(struct connection_struct *conn,
|
||||
const char *fname, SMB_STRUCT_STAT *sbuf)
|
||||
{
|
||||
struct onefs_vfs_share_config cfg;
|
||||
struct timeval tv_now = {0, 0};
|
||||
bool static_mtime = False;
|
||||
bool static_atime = False;
|
||||
|
||||
if (!onefs_get_config(SNUM(handle->conn),
|
||||
if (!onefs_get_config(SNUM(conn),
|
||||
ONEFS_VFS_CONFIG_FAKETIMESTAMPS, &cfg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_MTIME_STATIC_PATH(handle->conn, &cfg, fname)) {
|
||||
sbuf->st_mtime = sbuf->st_birthtime;
|
||||
if (IS_MTIME_STATIC_PATH(conn, &cfg, fname)) {
|
||||
sbuf->st_ex_mtime = sbuf->st_ex_btime;
|
||||
static_mtime = True;
|
||||
}
|
||||
if (IS_ATIME_STATIC_PATH(handle->conn, &cfg, fname)) {
|
||||
sbuf->st_atime = sbuf->st_birthtime;
|
||||
if (IS_ATIME_STATIC_PATH(conn, &cfg, fname)) {
|
||||
sbuf->st_ex_atime = sbuf->st_ex_btime;
|
||||
static_atime = True;
|
||||
}
|
||||
|
||||
if (IS_CTIME_NOW_PATH(handle->conn, &cfg, fname)) {
|
||||
if (IS_CTIME_NOW_PATH(conn, &cfg, fname)) {
|
||||
if (cfg.ctime_slop < 0) {
|
||||
sbuf->st_birthtime = INT_MAX - 1;
|
||||
sbuf->st_ex_btime.tv_sec = INT_MAX - 1;
|
||||
} else {
|
||||
GetTimeOfDay(&tv_now);
|
||||
sbuf->st_birthtime = tv_now.tv_sec + cfg.ctime_slop;
|
||||
sbuf->st_ex_btime.tv_sec = tv_now.tv_sec +
|
||||
cfg.ctime_slop;
|
||||
}
|
||||
}
|
||||
|
||||
if (!static_mtime && IS_MTIME_NOW_PATH(handle->conn,&cfg,fname)) {
|
||||
if (!static_mtime && IS_MTIME_NOW_PATH(conn,&cfg,fname)) {
|
||||
if (cfg.mtime_slop < 0) {
|
||||
sbuf->st_mtime = INT_MAX - 1;
|
||||
sbuf->st_ex_mtime.tv_sec = INT_MAX - 1;
|
||||
} else {
|
||||
if (tv_now.tv_sec == 0)
|
||||
GetTimeOfDay(&tv_now);
|
||||
sbuf->st_mtime = tv_now.tv_sec + cfg.mtime_slop;
|
||||
sbuf->st_ex_mtime.tv_sec = tv_now.tv_sec +
|
||||
cfg.mtime_slop;
|
||||
}
|
||||
}
|
||||
if (!static_atime && IS_ATIME_NOW_PATH(handle->conn,&cfg,fname)) {
|
||||
if (!static_atime && IS_ATIME_NOW_PATH(conn,&cfg,fname)) {
|
||||
if (cfg.atime_slop < 0) {
|
||||
sbuf->st_atime = INT_MAX - 1;
|
||||
sbuf->st_ex_atime.tv_sec = INT_MAX - 1;
|
||||
} else {
|
||||
if (tv_now.tv_sec == 0)
|
||||
GetTimeOfDay(&tv_now);
|
||||
sbuf->st_atime = tv_now.tv_sec + cfg.atime_slop;
|
||||
sbuf->st_ex_atime.tv_sec = tv_now.tv_sec +
|
||||
cfg.atime_slop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int stat_stream(vfs_handle_struct *handle, const char *base,
|
||||
static int stat_stream(struct connection_struct *conn, const char *base,
|
||||
const char *stream, SMB_STRUCT_STAT *sbuf, int flags)
|
||||
{
|
||||
SMB_STRUCT_STAT base_sbuf;
|
||||
int base_fd = -1, dir_fd, ret, saved_errno;
|
||||
|
||||
dir_fd = get_stream_dir_fd(handle->conn, base, &base_fd);
|
||||
dir_fd = get_stream_dir_fd(conn, base, &base_fd);
|
||||
if (dir_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Stat the stream. */
|
||||
ret = enc_fstatat(dir_fd, stream, ENC_DEFAULT, sbuf, flags);
|
||||
ret = onefs_sys_fstat_at(dir_fd, stream, sbuf, flags);
|
||||
if (ret != -1) {
|
||||
/* Now stat the base file and merge the results. */
|
||||
ret = sys_fstat(base_fd, &base_sbuf);
|
||||
ret = onefs_sys_fstat(base_fd, &base_sbuf);
|
||||
if (ret != -1) {
|
||||
merge_stat(sbuf, &base_sbuf);
|
||||
}
|
||||
@ -322,15 +325,15 @@ int onefs_stat(vfs_handle_struct *handle, const char *path,
|
||||
return ret;
|
||||
|
||||
if (!is_stream) {
|
||||
ret = SMB_VFS_NEXT_STAT(handle, path, sbuf);
|
||||
ret = onefs_sys_stat(path, sbuf);
|
||||
} else if (!stream) {
|
||||
/* If it's the ::$DATA stream just stat the base file name. */
|
||||
ret = SMB_VFS_NEXT_STAT(handle, base, sbuf);
|
||||
ret = onefs_sys_stat(base, sbuf);
|
||||
} else {
|
||||
ret = stat_stream(handle, base, stream, sbuf, 0);
|
||||
ret = stat_stream(handle->conn, base, stream, sbuf, 0);
|
||||
}
|
||||
|
||||
onefs_adjust_stat_time(handle, path, sbuf);
|
||||
onefs_adjust_stat_time(handle->conn, path, sbuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -341,20 +344,20 @@ int onefs_fstat(vfs_handle_struct *handle, struct files_struct *fsp,
|
||||
int ret;
|
||||
|
||||
/* Stat the stream, by calling next_fstat on the stream's fd. */
|
||||
ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
|
||||
ret = onefs_sys_fstat(fsp->fh->fd, sbuf);
|
||||
if (ret == -1) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Stat the base file and merge the results. */
|
||||
if (fsp != NULL && fsp->base_fsp != NULL) {
|
||||
ret = sys_fstat(fsp->base_fsp->fh->fd, &base_sbuf);
|
||||
ret = onefs_sys_fstat(fsp->base_fsp->fh->fd, &base_sbuf);
|
||||
if (ret != -1) {
|
||||
merge_stat(sbuf, &base_sbuf);
|
||||
}
|
||||
}
|
||||
|
||||
onefs_adjust_stat_time(handle, fsp->fsp_name, sbuf);
|
||||
onefs_adjust_stat_time(handle->conn, fsp->fsp_name, sbuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -371,16 +374,16 @@ int onefs_lstat(vfs_handle_struct *handle, const char *path,
|
||||
return ret;
|
||||
|
||||
if (!is_stream) {
|
||||
ret = SMB_VFS_NEXT_LSTAT(handle, path, sbuf);
|
||||
ret = onefs_sys_lstat(path, sbuf);
|
||||
} else if (!stream) {
|
||||
/* If it's the ::$DATA stream just stat the base file name. */
|
||||
ret = SMB_VFS_NEXT_LSTAT(handle, base, sbuf);
|
||||
ret = onefs_sys_lstat(base, sbuf);
|
||||
} else {
|
||||
ret = stat_stream(handle, base, stream, sbuf,
|
||||
ret = stat_stream(handle->conn, base, stream, sbuf,
|
||||
AT_SYMLINK_NOFOLLOW);
|
||||
}
|
||||
|
||||
onefs_adjust_stat_time(handle, path, sbuf);
|
||||
onefs_adjust_stat_time(handle->conn, path, sbuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -614,7 +617,7 @@ static NTSTATUS walk_onefs_streams(connection_struct *conn, files_struct *fsp,
|
||||
|
||||
if (!add_one_stream(state->mem_ctx,
|
||||
&state->num_streams, &state->streams,
|
||||
dp->d_name, stream_sbuf.st_size,
|
||||
dp->d_name, stream_sbuf.st_ex_size,
|
||||
SMB_VFS_GET_ALLOC_SIZE(conn, NULL,
|
||||
&stream_sbuf))) {
|
||||
state->status = NT_STATUS_NO_MEMORY;
|
||||
@ -677,10 +680,10 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle,
|
||||
}
|
||||
|
||||
/* Add the default stream. */
|
||||
if (S_ISREG(sbuf.st_mode)) {
|
||||
if (S_ISREG(sbuf.st_ex_mode)) {
|
||||
if (!add_one_stream(mem_ctx,
|
||||
&state.num_streams, &state.streams,
|
||||
"", sbuf.st_size,
|
||||
"", sbuf.st_ex_size,
|
||||
SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp,
|
||||
&sbuf))) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
@ -692,7 +695,7 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle,
|
||||
state.status = NT_STATUS_OK;
|
||||
|
||||
/* If there are more streams, add them too. */
|
||||
if (sbuf.st_flags & UF_HASADS) {
|
||||
if (sbuf.st_ex_flags & UF_HASADS) {
|
||||
|
||||
status = walk_onefs_streams(handle->conn, fsp, fname,
|
||||
&state, &sbuf);
|
||||
|
@ -666,3 +666,97 @@ out:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void init_stat_ex_from_onefs_stat(struct stat_ex *dst, const struct stat *src)
|
||||
{
|
||||
ZERO_STRUCT(*dst);
|
||||
|
||||
dst->st_ex_dev = src->st_dev;
|
||||
dst->st_ex_ino = src->st_ino;
|
||||
dst->st_ex_mode = src->st_mode;
|
||||
dst->st_ex_nlink = src->st_nlink;
|
||||
dst->st_ex_uid = src->st_uid;
|
||||
dst->st_ex_gid = src->st_gid;
|
||||
dst->st_ex_rdev = src->st_rdev;
|
||||
dst->st_ex_size = src->st_size;
|
||||
dst->st_ex_atime = src->st_atimespec;
|
||||
dst->st_ex_mtime = src->st_mtimespec;
|
||||
dst->st_ex_ctime = src->st_ctimespec;
|
||||
dst->st_ex_btime = src->st_birthtimespec;
|
||||
dst->st_ex_blksize = src->st_blksize;
|
||||
dst->st_ex_blocks = src->st_blocks;
|
||||
|
||||
dst->st_ex_flags = src->st_flags;
|
||||
|
||||
dst->vfs_private = src->st_snapid;
|
||||
}
|
||||
|
||||
int onefs_sys_stat(const char *fname, SMB_STRUCT_STAT *sbuf)
|
||||
{
|
||||
int ret;
|
||||
struct stat onefs_sbuf;
|
||||
|
||||
ret = stat(fname, &onefs_sbuf);
|
||||
|
||||
if (ret == 0) {
|
||||
/* we always want directories to appear zero size */
|
||||
if (S_ISDIR(onefs_sbuf.st_mode)) {
|
||||
onefs_sbuf.st_size = 0;
|
||||
}
|
||||
init_stat_ex_from_onefs_stat(sbuf, &onefs_sbuf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int onefs_sys_fstat(int fd, SMB_STRUCT_STAT *sbuf)
|
||||
{
|
||||
int ret;
|
||||
struct stat onefs_sbuf;
|
||||
|
||||
ret = fstat(fd, &onefs_sbuf);
|
||||
|
||||
if (ret == 0) {
|
||||
/* we always want directories to appear zero size */
|
||||
if (S_ISDIR(onefs_sbuf.st_mode)) {
|
||||
onefs_sbuf.st_size = 0;
|
||||
}
|
||||
init_stat_ex_from_onefs_stat(sbuf, &onefs_sbuf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int onefs_sys_fstat_at(int base_fd, const char *fname, SMB_STRUCT_STAT *sbuf,
|
||||
int flags)
|
||||
{
|
||||
int ret;
|
||||
struct stat onefs_sbuf;
|
||||
|
||||
ret = enc_fstatat(base_fd, fname, ENC_DEFAULT, &onefs_sbuf, flags);
|
||||
|
||||
if (ret == 0) {
|
||||
/* we always want directories to appear zero size */
|
||||
if (S_ISDIR(onefs_sbuf.st_mode)) {
|
||||
onefs_sbuf.st_size = 0;
|
||||
}
|
||||
init_stat_ex_from_onefs_stat(sbuf, &onefs_sbuf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int onefs_sys_lstat(const char *fname, SMB_STRUCT_STAT *sbuf)
|
||||
{
|
||||
int ret;
|
||||
struct stat onefs_sbuf;
|
||||
|
||||
ret = lstat(fname, &onefs_sbuf);
|
||||
|
||||
if (ret == 0) {
|
||||
/* we always want directories to appear zero size */
|
||||
if (S_ISDIR(onefs_sbuf.st_mode)) {
|
||||
onefs_sbuf.st_size = 0;
|
||||
}
|
||||
init_stat_ex_from_onefs_stat(sbuf, &onefs_sbuf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ static uint64_t onefs_get_alloc_size(struct vfs_handle_struct *handle,
|
||||
|
||||
START_PROFILE(syscall_get_alloc_size);
|
||||
|
||||
if(S_ISDIR(sbuf->st_mode)) {
|
||||
if(S_ISDIR(sbuf->st_ex_mode)) {
|
||||
result = 0;
|
||||
goto out;
|
||||
}
|
||||
@ -115,9 +115,9 @@ static struct file_id onefs_file_id_create(struct vfs_handle_struct *handle,
|
||||
* blob */
|
||||
ZERO_STRUCT(key);
|
||||
|
||||
key.devid = sbuf->st_dev;
|
||||
key.inode = sbuf->st_ino;
|
||||
key.extid = sbuf->st_snapid;
|
||||
key.devid = sbuf->st_ex_dev;
|
||||
key.inode = sbuf->st_ex_ino;
|
||||
key.extid = sbuf->vfs_private;
|
||||
|
||||
return key;
|
||||
}
|
||||
@ -152,7 +152,7 @@ static int onefs_get_real_filename(vfs_handle_struct *handle, const char *path,
|
||||
const char *name, TALLOC_CTX *mem_ctx,
|
||||
char **found_name)
|
||||
{
|
||||
SMB_STRUCT_STAT sb;
|
||||
struct stat sb;
|
||||
struct connection_struct *conn = handle->conn;
|
||||
struct stat_extra se;
|
||||
int result;
|
||||
@ -278,11 +278,11 @@ static vfs_op_tuple onefs_ops[] = {
|
||||
{SMB_VFS_OP(onefs_rename), SMB_VFS_OP_RENAME,
|
||||
SMB_VFS_LAYER_TRANSPARENT},
|
||||
{SMB_VFS_OP(onefs_stat), SMB_VFS_OP_STAT,
|
||||
SMB_VFS_LAYER_TRANSPARENT},
|
||||
SMB_VFS_LAYER_OPAQUE},
|
||||
{SMB_VFS_OP(onefs_fstat), SMB_VFS_OP_FSTAT,
|
||||
SMB_VFS_LAYER_TRANSPARENT},
|
||||
SMB_VFS_LAYER_OPAQUE},
|
||||
{SMB_VFS_OP(onefs_lstat), SMB_VFS_OP_LSTAT,
|
||||
SMB_VFS_LAYER_TRANSPARENT},
|
||||
SMB_VFS_LAYER_OPAQUE},
|
||||
{SMB_VFS_OP(onefs_get_alloc_size), SMB_VFS_OP_GET_ALLOC_SIZE,
|
||||
SMB_VFS_LAYER_OPAQUE},
|
||||
{SMB_VFS_OP(onefs_unlink), SMB_VFS_OP_UNLINK,
|
||||
|
Loading…
x
Reference in New Issue
Block a user