1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

s3:streams_xattr: add support for renaming streams

metze
This commit is contained in:
Stefan Metzmacher 2008-12-01 13:54:53 -08:00 committed by Jeremy Allison
parent 787b0536b7
commit 9ae1a17c95

View File

@ -94,7 +94,7 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp,
DEBUG(10, ("streams_xattr_fstat called for %d\n", fsp->fh->fd));
if (io == NULL) {
if (io == NULL || fsp->base_fsp == NULL) {
return SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
}
@ -136,6 +136,10 @@ static int streams_xattr_stat(vfs_handle_struct *handle, const char *fname,
return -1;
}
if (sname == NULL){
return SMB_VFS_NEXT_STAT(handle, base, sbuf);
}
if (SMB_VFS_STAT(handle->conn, base, sbuf) == -1) {
goto fail;
}
@ -183,6 +187,10 @@ static int streams_xattr_lstat(vfs_handle_struct *handle, const char *fname,
goto fail;
}
if (sname == NULL){
return SMB_VFS_NEXT_LSTAT(handle, base, sbuf);
}
if (SMB_VFS_LSTAT(handle->conn, base, sbuf) == -1) {
goto fail;
}
@ -239,6 +247,12 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname,
goto fail;
}
if (sname == NULL) {
hostfd = SMB_VFS_NEXT_OPEN(handle, base, fsp, flags, mode);
talloc_free(frame);
return hostfd;
}
xattr_name = talloc_asprintf(talloc_tos(), "%s%s",
SAMBA_XATTR_DOSSTREAM_PREFIX, sname);
if (xattr_name == NULL) {
@ -391,6 +405,10 @@ static int streams_xattr_unlink(vfs_handle_struct *handle, const char *fname)
goto fail;
}
if (sname == NULL){
return SMB_VFS_NEXT_UNLINK(handle, base);
}
xattr_name = talloc_asprintf(talloc_tos(), "%s%s",
SAMBA_XATTR_DOSSTREAM_PREFIX, sname);
if (xattr_name == NULL) {
@ -413,6 +431,127 @@ static int streams_xattr_unlink(vfs_handle_struct *handle, const char *fname)
return ret;
}
static int streams_xattr_rename(vfs_handle_struct *handle,
const char *oldname,
const char *newname)
{
NTSTATUS status;
TALLOC_CTX *frame = NULL;
char *obase;
char *ostream;
char *nbase;
char *nstream;
const char *base;
int ret = -1;
char *oxattr_name;
char *nxattr_name;
bool o_is_stream;
bool n_is_stream;
ssize_t oret;
ssize_t nret;
struct ea_struct ea;
o_is_stream = is_ntfs_stream_name(oldname);
n_is_stream = is_ntfs_stream_name(newname);
if (!o_is_stream && !n_is_stream) {
return SMB_VFS_NEXT_RENAME(handle, oldname, newname);
}
if (!(o_is_stream && n_is_stream)) {
errno = ENOSYS;
goto fail;
}
frame = talloc_stackframe();
if (!frame) {
goto fail;
}
status = split_ntfs_stream_name(talloc_tos(), oldname, &obase, &ostream);
if (!NT_STATUS_IS_OK(status)) {
errno = EINVAL;
goto fail;
}
status = split_ntfs_stream_name(talloc_tos(), newname, &nbase, &nstream);
if (!NT_STATUS_IS_OK(status)) {
errno = EINVAL;
goto fail;
}
/*TODO: maybe call SMB_VFS_NEXT_RENAME() both streams are NULL (::$DATA) */
if (ostream == NULL) {
errno = ENOSYS;
goto fail;
}
if (nstream == NULL) {
errno = ENOSYS;
goto fail;
}
/* the new base should be empty */
if (StrCaseCmp(obase, nbase) != 0) {
errno = ENOSYS;
goto fail;
}
if (StrCaseCmp(ostream, nstream) == 0) {
goto done;
}
base = obase;
oxattr_name = talloc_asprintf(talloc_tos(), "%s%s",
SAMBA_XATTR_DOSSTREAM_PREFIX, ostream);
if (oxattr_name == NULL) {
errno = ENOMEM;
goto fail;
}
nxattr_name = talloc_asprintf(talloc_tos(), "%s%s",
SAMBA_XATTR_DOSSTREAM_PREFIX, nstream);
if (nxattr_name == NULL) {
errno = ENOMEM;
goto fail;
}
/* read the old stream */
status = get_ea_value(talloc_tos(), handle->conn, NULL,
base, oxattr_name, &ea);
if (!NT_STATUS_IS_OK(status)) {
errno = ENOENT;
goto fail;
}
/* (over)write the new stream */
nret = SMB_VFS_SETXATTR(handle->conn, base, nxattr_name,
ea.value.data, ea.value.length, 0);
if (nret < 0) {
if (errno == ENOATTR) {
errno = ENOENT;
}
goto fail;
}
/* remove the old stream */
oret = SMB_VFS_REMOVEXATTR(handle->conn, base, oxattr_name);
if (oret < 0) {
if (errno == ENOATTR) {
errno = ENOENT;
}
goto fail;
}
done:
errno = 0;
ret = 0;
fail:
TALLOC_FREE(frame);
return ret;
}
static NTSTATUS walk_xattr_streams(connection_struct *conn, files_struct *fsp,
const char *fname,
bool (*fn)(struct ea_struct *ea,
@ -761,6 +900,8 @@ static vfs_op_tuple streams_xattr_ops[] = {
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(streams_xattr_unlink), SMB_VFS_OP_UNLINK,
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(streams_xattr_rename), SMB_VFS_OP_RENAME,
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(streams_xattr_ftruncate), SMB_VFS_OP_FTRUNCATE,
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(streams_xattr_streaminfo), SMB_VFS_OP_STREAMINFO,