1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-02 09:47:23 +03:00

s3: VFS: Change SMB_VFS_LINK to use const struct smb_filename * instead of const char *.

We need to migrate all pathname based VFS calls to use a struct
to finish modernising the VFS with extra timestamp and flags parameters.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Richard Sharpe <realrichardsharpe@gmail.com>
This commit is contained in:
Jeremy Allison 2017-06-02 14:21:54 -07:00
parent 0da76414fd
commit fc92d451cf
17 changed files with 190 additions and 89 deletions

View File

@ -489,8 +489,9 @@ static int skel_vfs_readlink(vfs_handle_struct *handle, const char *path,
return -1;
}
static int skel_link(vfs_handle_struct *handle, const char *oldpath,
const char *newpath)
static int skel_link(vfs_handle_struct *handle,
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname)
{
errno = ENOSYS;
return -1;

View File

@ -581,10 +581,11 @@ static int skel_vfs_readlink(vfs_handle_struct *handle, const char *path,
return SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz);
}
static int skel_link(vfs_handle_struct *handle, const char *oldpath,
const char *newpath)
static int skel_link(vfs_handle_struct *handle,
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname)
{
return SMB_VFS_NEXT_LINK(handle, oldpath, newpath);
return SMB_VFS_NEXT_LINK(handle, old_smb_fname, new_smb_fname);
}
static int skel_mknod(vfs_handle_struct *handle,

View File

@ -220,6 +220,8 @@
to const struct smb_filename * */
/* Version 37 - Change get_quota from const char *
to const struct smb_filename * */
/* Version 37 - Change link from const char *
to const struct smb_filename * */
#define SMB_VFS_INTERFACE_VERSION 37
@ -739,7 +741,9 @@ struct vfs_fn_pointers {
bool (*getlock_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid);
int (*symlink_fn)(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath);
int (*readlink_fn)(struct vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz);
int (*link_fn)(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath);
int (*link_fn)(struct vfs_handle_struct *handle,
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname);
int (*mknod_fn)(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
mode_t mode,
@ -1241,8 +1245,9 @@ int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
const char *newpath);
int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
const char *path, char *buf, size_t bufsiz);
int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
const char *newpath);
int smb_vfs_call_link(struct vfs_handle_struct *handle,
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname);
int smb_vfs_call_mknod(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
mode_t mode,

View File

@ -504,16 +504,56 @@ static int cap_readlink(vfs_handle_struct *handle, const char *path,
return SMB_VFS_NEXT_READLINK(handle, cappath, buf, bufsiz);
}
static int cap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
static int cap_link(vfs_handle_struct *handle,
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname)
{
char *capold = capencode(talloc_tos(), oldpath);
char *capnew = capencode(talloc_tos(), newpath);
char *capold = capencode(talloc_tos(), old_smb_fname->base_name);
char *capnew = capencode(talloc_tos(), new_smb_fname->base_name);
struct smb_filename *old_cap_smb_fname = NULL;
struct smb_filename *new_cap_smb_fname = NULL;
int saved_errno = 0;
int ret;
if (!capold || !capnew) {
errno = ENOMEM;
return -1;
}
return SMB_VFS_NEXT_LINK(handle, capold, capnew);
old_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
capold,
NULL,
NULL,
old_smb_fname->flags);
if (old_cap_smb_fname == NULL) {
TALLOC_FREE(capold);
TALLOC_FREE(capnew);
errno = ENOMEM;
return -1;
}
new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
capnew,
NULL,
NULL,
new_smb_fname->flags);
if (new_cap_smb_fname == NULL) {
TALLOC_FREE(capold);
TALLOC_FREE(capnew);
TALLOC_FREE(old_cap_smb_fname);
errno = ENOMEM;
return -1;
}
ret = SMB_VFS_NEXT_LINK(handle, old_cap_smb_fname, new_cap_smb_fname);
if (ret == -1) {
saved_errno = errno;
}
TALLOC_FREE(capold);
TALLOC_FREE(capnew);
TALLOC_FREE(old_cap_smb_fname);
TALLOC_FREE(new_cap_smb_fname);
if (saved_errno != 0) {
errno = saved_errno;
}
return ret;
}
static int cap_mknod(vfs_handle_struct *handle,

View File

@ -1141,11 +1141,17 @@ static int cephwrap_readlink(struct vfs_handle_struct *handle, const char *path
WRAP_RETURN(result);
}
static int cephwrap_link(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath)
static int cephwrap_link(struct vfs_handle_struct *handle,
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname)
{
int result = -1;
DBG_DEBUG("[CEPH] link(%p, %s, %s)\n", handle, oldpath, newpath);
result = ceph_link(handle->data, oldpath, newpath);
DBG_DEBUG("[CEPH] link(%p, %s, %s)\n", handle,
old_smb_fname->base_name,
new_smb_fname->base_name);
result = ceph_link(handle->data,
old_smb_fname->base_name,
new_smb_fname->base_name);
DBG_DEBUG("[CEPH] link(...) = %d\n", result);
WRAP_RETURN(result);
}

View File

@ -2436,12 +2436,14 @@ static int vfswrap_readlink(vfs_handle_struct *handle, const char *path, char *b
return result;
}
static int vfswrap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
static int vfswrap_link(vfs_handle_struct *handle,
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname)
{
int result;
START_PROFILE(syscall_link);
result = link(oldpath, newpath);
result = link(old_smb_fname->base_name, new_smb_fname->base_name);
END_PROFILE(syscall_link);
return result;
}

View File

@ -1651,14 +1651,15 @@ static int smb_full_audit_readlink(vfs_handle_struct *handle,
}
static int smb_full_audit_link(vfs_handle_struct *handle,
const char *oldpath, const char *newpath)
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname)
{
int result;
result = SMB_VFS_NEXT_LINK(handle, oldpath, newpath);
result = SMB_VFS_NEXT_LINK(handle, old_smb_fname, new_smb_fname);
do_log(SMB_VFS_OP_LINK, (result >= 0), handle,
"%s|%s", oldpath, newpath);
"%s|%s", old_smb_fname->base_name, new_smb_fname->base_name);
return result;
}

View File

@ -1246,9 +1246,12 @@ static int vfs_gluster_readlink(struct vfs_handle_struct *handle,
}
static int vfs_gluster_link(struct vfs_handle_struct *handle,
const char *oldpath, const char *newpath)
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname)
{
return glfs_link(handle->data, oldpath, newpath);
return glfs_link(handle->data,
old_smb_fname->base_name,
new_smb_fname->base_name);
}
static int vfs_gluster_mknod(struct vfs_handle_struct *handle,

View File

@ -1807,43 +1807,37 @@ out:
* Failure: set errno, return -1
*/
static int mh_link(vfs_handle_struct *handle,
const char *oldpath,
const char *newpath)
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname)
{
int status;
char *oldClientPath;
char *newClientPath;
TALLOC_CTX *ctx;
struct smb_filename *oldclientFname = NULL;
struct smb_filename *newclientFname = NULL;
DEBUG(MH_INFO_DEBUG, ("Entering mh_link\n"));
if (!is_in_media_files(oldpath) && !is_in_media_files(newpath))
{
status = SMB_VFS_NEXT_LINK(handle, oldpath, newpath);
if (!is_in_media_files(old_smb_fname->base_name) &&
!is_in_media_files(new_smb_fname->base_name)) {
status = SMB_VFS_NEXT_LINK(handle,
old_smb_fname,
new_smb_fname);
goto out;
}
oldClientPath = NULL;
newClientPath = NULL;
ctx = talloc_tos();
if ((status = alloc_get_client_path(handle, ctx,
oldpath,
&oldClientPath)))
{
if ((status = alloc_get_client_smb_fname(handle, talloc_tos(),
old_smb_fname,
&oldclientFname))) {
goto err;
}
if ((status = alloc_get_client_smb_fname(handle, talloc_tos(),
new_smb_fname,
&newclientFname))) {
goto err;
}
if ((status = alloc_get_client_path(handle, ctx,
newpath,
&newClientPath)))
{
goto err;
}
status = SMB_VFS_NEXT_LINK(handle, oldClientPath, newClientPath);
status = SMB_VFS_NEXT_LINK(handle, oldclientFname, newclientFname);
err:
TALLOC_FREE(newClientPath);
TALLOC_FREE(oldClientPath);
TALLOC_FREE(newclientFname);
TALLOC_FREE(oldclientFname);
out:
return status;
}

View File

@ -1180,19 +1180,28 @@ static int shadow_copy2_symlink(vfs_handle_struct *handle,
}
static int shadow_copy2_link(vfs_handle_struct *handle,
const char *oldname, const char *newname)
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname)
{
time_t timestamp_old = 0;
time_t timestamp_new = 0;
char *snappath_old = NULL;
char *snappath_new = NULL;
if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, oldname,
&timestamp_old, NULL, &snappath_old)) {
if (!shadow_copy2_strip_snapshot_internal(talloc_tos(),
handle,
old_smb_fname->base_name,
&timestamp_old,
NULL,
&snappath_old)) {
return -1;
}
if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, newname,
&timestamp_new, NULL, &snappath_new)) {
if (!shadow_copy2_strip_snapshot_internal(talloc_tos(),
handle,
new_smb_fname->base_name,
&timestamp_new,
NULL,
&snappath_new)) {
return -1;
}
if ((timestamp_old != 0) || (timestamp_new != 0)) {
@ -1206,7 +1215,7 @@ static int shadow_copy2_link(vfs_handle_struct *handle,
errno = EROFS;
return -1;
}
return SMB_VFS_NEXT_LINK(handle, oldname, newname);
return SMB_VFS_NEXT_LINK(handle, old_smb_fname, new_smb_fname);
}
static int shadow_copy2_stat(vfs_handle_struct *handle,

View File

@ -2057,23 +2057,31 @@ static int snapper_gmt_symlink(vfs_handle_struct *handle,
}
static int snapper_gmt_link(vfs_handle_struct *handle,
const char *oldname, const char *newname)
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname)
{
time_t timestamp_old, timestamp_new;
time_t timestamp_old = 0;
time_t timestamp_new = 0;
if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, oldname,
&timestamp_old, NULL)) {
if (!snapper_gmt_strip_snapshot(talloc_tos(),
handle,
old_smb_fname->base_name,
&timestamp_old,
NULL)) {
return -1;
}
if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, newname,
&timestamp_new, NULL)) {
if (!snapper_gmt_strip_snapshot(talloc_tos(),
handle,
new_smb_fname->base_name,
&timestamp_new,
NULL)) {
return -1;
}
if ((timestamp_old != 0) || (timestamp_new != 0)) {
errno = EROFS;
return -1;
}
return SMB_VFS_NEXT_LINK(handle, oldname, newname);
return SMB_VFS_NEXT_LINK(handle, old_smb_fname, new_smb_fname);
}
static int snapper_gmt_stat(vfs_handle_struct *handle,

View File

@ -192,9 +192,22 @@ static int syncops_symlink(vfs_handle_struct *handle,
}
static int syncops_link(vfs_handle_struct *handle,
const char *oldname, const char *newname)
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname)
{
SYNCOPS_NEXT(LINK, newname, (handle, oldname, newname));
int ret;
struct syncops_config_data *config;
SMB_VFS_HANDLE_GET_DATA(handle, config,
struct syncops_config_data,
return -1);
ret = SMB_VFS_NEXT_LINK(handle, old_smb_fname, new_smb_fname);
if (ret == 0 && config->onmeta && !config->disable) {
syncops_two_names(old_smb_fname->base_name,
new_smb_fname->base_name);
}
return ret;
}
static int syncops_open(vfs_handle_struct *handle,

View File

@ -1461,19 +1461,21 @@ static int smb_time_audit_readlink(vfs_handle_struct *handle,
}
static int smb_time_audit_link(vfs_handle_struct *handle,
const char *oldpath, const char *newpath)
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname)
{
int result;
struct timespec ts1,ts2;
double timediff;
clock_gettime_mono(&ts1);
result = SMB_VFS_NEXT_LINK(handle, oldpath, newpath);
result = SMB_VFS_NEXT_LINK(handle, old_smb_fname, new_smb_fname);
clock_gettime_mono(&ts2);
timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
if (timediff > audit_timeout) {
smb_time_audit_log_fname("link", timediff, newpath);
smb_time_audit_log_fname("link", timediff,
new_smb_fname->base_name);
}
return result;

View File

@ -1379,35 +1379,35 @@ err:
}
static int um_link(vfs_handle_struct *handle,
const char *oldpath,
const char *newpath)
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname)
{
int status;
char *old_client_path = NULL;
char *new_client_path = NULL;
struct smb_filename *old_client_fname = NULL;
struct smb_filename *new_client_fname = NULL;
DEBUG(10, ("Entering um_link\n"));
if (!is_in_media_files(oldpath) && !is_in_media_files(newpath)) {
return SMB_VFS_NEXT_LINK(handle, oldpath, newpath);
if (!is_in_media_files(old_smb_fname->base_name) &&
!is_in_media_files(new_smb_fname->base_name)) {
return SMB_VFS_NEXT_LINK(handle, old_smb_fname, new_smb_fname);
}
status = alloc_get_client_path(handle, talloc_tos(),
oldpath, &old_client_path);
status = alloc_get_client_smb_fname(handle, talloc_tos(),
old_smb_fname, &old_client_fname);
if (status != 0) {
goto err;
}
status = alloc_get_client_smb_fname(handle, talloc_tos(),
new_smb_fname, &new_client_fname);
if (status != 0) {
goto err;
}
status = alloc_get_client_path(handle, talloc_tos(),
newpath, &new_client_path);
if (status != 0) {
goto err;
}
status = SMB_VFS_NEXT_LINK(handle, old_client_path, new_client_path);
status = SMB_VFS_NEXT_LINK(handle, old_client_fname, new_client_fname);
err:
TALLOC_FREE(new_client_path);
TALLOC_FREE(old_client_path);
TALLOC_FREE(old_client_fname);
TALLOC_FREE(new_client_fname);
return status;
}

View File

@ -6149,8 +6149,7 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
smb_fname_old->base_name, smb_fname_new->base_name));
if (SMB_VFS_LINK(conn, smb_fname_old->base_name,
smb_fname_new->base_name) != 0) {
if (SMB_VFS_LINK(conn, smb_fname_old, smb_fname_new) != 0) {
status = map_nt_error_from_unix(errno);
DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
nt_errstr(status), smb_fname_old->base_name,

View File

@ -2165,11 +2165,12 @@ int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
return handle->fns->readlink_fn(handle, path, buf, bufsiz);
}
int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
const char *newpath)
int smb_vfs_call_link(struct vfs_handle_struct *handle,
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname)
{
VFS_FIND(link);
return handle->fns->link_fn(handle, oldpath, newpath);
return handle->fns->link_fn(handle, old_smb_fname, new_smb_fname);
}
int smb_vfs_call_mknod(struct vfs_handle_struct *handle,

View File

@ -1251,12 +1251,28 @@ static NTSTATUS cmd_readlink(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
static NTSTATUS cmd_link(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
struct smb_filename *old_smb_fname = NULL;
struct smb_filename *new_smb_fname = NULL;
if (argc != 3) {
printf("Usage: link <path> <link>\n");
return NT_STATUS_OK;
}
if (SMB_VFS_LINK(vfs->conn, argv[1], argv[2]) == -1) {
old_smb_fname = synthetic_smb_fname_split(mem_ctx,
argv[1],
lp_posix_pathnames());
if (old_smb_fname == NULL) {
return NT_STATUS_NO_MEMORY;
}
new_smb_fname = synthetic_smb_fname_split(mem_ctx,
argv[2],
lp_posix_pathnames());
if (new_smb_fname == NULL) {
return NT_STATUS_NO_MEMORY;
}
if (SMB_VFS_LINK(vfs->conn, old_smb_fname, new_smb_fname) == -1) {
printf("link: error=%d (%s)\n", errno, strerror(errno));
return NT_STATUS_UNSUCCESSFUL;
}