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;
|
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
|
* 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,
|
.open_fn = xattr_tdb_open,
|
||||||
.mkdirat_fn = xattr_tdb_mkdirat,
|
.mkdirat_fn = xattr_tdb_mkdirat,
|
||||||
.unlink_fn = xattr_tdb_unlink,
|
.unlink_fn = xattr_tdb_unlink,
|
||||||
|
.unlinkat_fn = xattr_tdb_unlinkat,
|
||||||
.rmdir_fn = xattr_tdb_rmdir,
|
.rmdir_fn = xattr_tdb_rmdir,
|
||||||
.connect_fn = xattr_tdb_connect,
|
.connect_fn = xattr_tdb_connect,
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user