vfs_xattr_tdb: implement SMB_VFS_OPENAT()
authorRalph Boehme <slow@samba.org>
Wed, 20 May 2020 20:32:57 +0000 (22:32 +0200)
committerJeremy Allison <jra@samba.org>
Thu, 21 May 2020 20:38:34 +0000 (20:38 +0000)
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/modules/vfs_xattr_tdb.c

index 9b772d4f5800712d797c7686ab343b6171aa1f79..c9c8e9ceb59e21f746bef686b15abd6bf4c22cb2 100644 (file)
@@ -542,6 +542,63 @@ static int xattr_tdb_open(vfs_handle_struct *handle,
        return fsp->fh->fd;
 }
 
+static int xattr_tdb_openat(struct vfs_handle_struct *handle,
+                           const struct files_struct *dirfsp,
+                           const struct smb_filename *smb_fname,
+                           struct files_struct *fsp,
+                           int flags,
+                           mode_t mode)
+{
+       struct db_context *db = NULL;
+       TALLOC_CTX *frame = NULL;
+       SMB_STRUCT_STAT sbuf;
+       int ret;
+
+       fsp->fh->fd = SMB_VFS_NEXT_OPENAT(handle,
+                                         dirfsp,
+                                         smb_fname,
+                                         fsp,
+                                         flags,
+                                         mode);
+
+       if (fsp->fh->fd < 0) {
+               return fsp->fh->fd;
+       }
+
+       if ((flags & (O_CREAT|O_EXCL)) != (O_CREAT|O_EXCL)) {
+               return fsp->fh->fd;
+       }
+
+       /*
+        * We know we used O_CREAT|O_EXCL and it worked.
+        * We must have created the file.
+        */
+
+       ret = SMB_VFS_FSTAT(fsp, &sbuf);
+       if (ret == -1) {
+               /* Can't happen... */
+               DBG_WARNING("SMB_VFS_FSTAT failed on file %s (%s)\n",
+                           smb_fname_str_dbg(smb_fname),
+                           strerror(errno));
+               return -1;
+       }
+
+       fsp->file_id = SMB_VFS_FILE_ID_CREATE(fsp->conn, &sbuf);
+
+       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;
+                               });
+
+       xattr_tdb_remove_all_attrs(db, &fsp->file_id);
+
+       TALLOC_FREE(frame);
+       return fsp->fh->fd;
+}
+
 static int xattr_tdb_mkdirat(vfs_handle_struct *handle,
                struct files_struct *dirfsp,
                const struct smb_filename *smb_fname,
@@ -720,6 +777,7 @@ static struct vfs_fn_pointers vfs_xattr_tdb_fns = {
        .removexattr_fn = xattr_tdb_removexattr,
        .fremovexattr_fn = xattr_tdb_fremovexattr,
        .open_fn = xattr_tdb_open,
+       .openat_fn = xattr_tdb_openat,
        .mkdirat_fn = xattr_tdb_mkdirat,
        .unlinkat_fn = xattr_tdb_unlinkat,
        .connect_fn = xattr_tdb_connect,