1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-26 21:57:41 +03:00

s3: VFS: vfs_xattr_tdb. Implement unlinkat().

Note this isn't identical to unlink() as
this must cope with (flags & AT_REMOVEDIR),
which is identical to rmdir(). It calls
either unlink or rmdir depending on the
flags parameter.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
This commit is contained in:
Jeremy Allison 2019-09-13 10:12:38 -07:00 committed by Ralph Boehme
parent 19c8cfa287
commit 95197108be

View File

@ -649,6 +649,75 @@ static int xattr_tdb_unlink(vfs_handle_struct *handle,
return ret;
}
/*
* On unlink we need to delete the tdb record
*/
static int xattr_tdb_unlinkat(vfs_handle_struct *handle,
struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
int flags)
{
struct smb_filename *smb_fname_tmp = NULL;
struct file_id id;
struct db_context *db;
int ret = -1;
bool remove_record = false;
TALLOC_CTX *frame = talloc_stackframe();
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
if (!xattr_tdb_init(-1, frame, &db))
{
TALLOC_FREE(frame); return -1;
});
smb_fname_tmp = cp_smb_filename(frame, smb_fname);
if (smb_fname_tmp == NULL) {
TALLOC_FREE(frame);
errno = ENOMEM;
return -1;
}
if (smb_fname_tmp->flags & SMB_FILENAME_POSIX_PATH) {
ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname_tmp);
} else {
ret = SMB_VFS_NEXT_STAT(handle, smb_fname_tmp);
}
if (ret == -1) {
goto out;
}
if (flags & AT_REMOVEDIR) {
/* Always remove record when removing a directory succeeds. */
remove_record = true;
} else {
if (smb_fname_tmp->st.st_ex_nlink == 1) {
/* Only remove record on last link to file. */
remove_record = true;
}
}
ret = SMB_VFS_NEXT_UNLINKAT(handle,
dirfsp,
smb_fname_tmp,
flags);
if (ret == -1) {
goto out;
}
if (!remove_record) {
goto out;
}
id = SMB_VFS_NEXT_FILE_ID_CREATE(handle, &smb_fname_tmp->st);
xattr_tdb_remove_all_attrs(db, &id);
out:
TALLOC_FREE(frame);
return ret;
}
/*
* On rmdir we need to delete the tdb record
*/
@ -747,6 +816,7 @@ static struct vfs_fn_pointers vfs_xattr_tdb_fns = {
.open_fn = xattr_tdb_open,
.mkdirat_fn = xattr_tdb_mkdirat,
.unlink_fn = xattr_tdb_unlink,
.unlinkat_fn = xattr_tdb_unlinkat,
.rmdir_fn = xattr_tdb_rmdir,
.connect_fn = xattr_tdb_connect,
};