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:
parent
19c8cfa287
commit
95197108be
@ -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,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user