From 5c623e6c2e787cad6efde036161e8a2f816d5203 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Thu, 28 May 2009 14:11:43 -0700 Subject: s3 onefs: update the onefs module to be compliant with stat_ex --- source3/modules/onefs.h | 13 ++++++ source3/modules/onefs_acl.c | 5 ++- source3/modules/onefs_dir.c | 12 ++++-- source3/modules/onefs_notify.c | 8 ++-- source3/modules/onefs_open.c | 38 ++++++++--------- source3/modules/onefs_streams.c | 83 ++++++++++++++++++------------------ source3/modules/onefs_system.c | 94 +++++++++++++++++++++++++++++++++++++++++ source3/modules/vfs_onefs.c | 16 +++---- 8 files changed, 192 insertions(+), 77 deletions(-) (limited to 'source3/modules') diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h index 9d63021f42..70f90b5cd5 100644 --- a/source3/modules/onefs.h +++ b/source3/modules/onefs.h @@ -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 */ diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index d66e5d65fa..81bdfd26cc 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -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; diff --git a/source3/modules/onefs_dir.c b/source3/modules/onefs_dir.c index 47da33fff1..2ab8b86771 100644 --- a/source3/modules/onefs_dir.c +++ b/source3/modules/onefs_dir.c @@ -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); } diff --git a/source3/modules/onefs_notify.c b/source3/modules/onefs_notify.c index 3455afd4ab..0447d0c03e 100644 --- a/source3/modules/onefs_notify.c +++ b/source3/modules/onefs_notify.c @@ -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; diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c index 6cfa24f9f6..21c5d51f90 100644 --- a/source3/modules/onefs_open.c +++ b/source3/modules/onefs_open.c @@ -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); } } diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c index 05b36d7d3c..284e199fc5 100644 --- a/source3/modules/onefs_streams.c +++ b/source3/modules/onefs_streams.c @@ -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); diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c index 3e51c6cd85..d2f853f9ee 100644 --- a/source3/modules/onefs_system.c +++ b/source3/modules/onefs_system.c @@ -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; +} + diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c index e4a0febbec..7414f16cf9 100644 --- a/source3/modules/vfs_onefs.c +++ b/source3/modules/vfs_onefs.c @@ -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, -- cgit