vfs_fruit: do ino calculation
authorRalph Boehme <slow@samba.org>
Wed, 22 Aug 2018 14:49:23 +0000 (16:49 +0200)
committerJeremy Allison <jra@samba.org>
Wed, 31 Oct 2018 20:27:22 +0000 (21:27 +0100)
As we'll start returning fake fds in open shortly, we can't rely on the
next module to calculat correct inode numbers for streams and must take
over that responsibility.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=13646

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/modules/vfs_fruit.c

index 7158fa5f21fd4ea097542f8c324b83262b8d7199..f6aac4100aa028a96555bb682b289ab47b27fe52 100644 (file)
@@ -4898,6 +4898,14 @@ static int fruit_stat_meta_stream(vfs_handle_struct *handle,
                                  bool follow_links)
 {
        int ret;
+       ino_t ino;
+
+       ret = fruit_stat_base(handle, smb_fname, false);
+       if (ret != 0) {
+               return -1;
+       }
+
+       ino = fruit_inode(&smb_fname->st, smb_fname->stream_name);
 
        if (follow_links) {
                ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
@@ -4905,6 +4913,8 @@ static int fruit_stat_meta_stream(vfs_handle_struct *handle,
                ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
        }
 
+       smb_fname->st.st_ex_ino = ino;
+
        return ret;
 }
 
@@ -5158,7 +5168,41 @@ static int fruit_fstat_meta_stream(vfs_handle_struct *handle,
                                   files_struct *fsp,
                                   SMB_STRUCT_STAT *sbuf)
 {
-       return SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
+       struct fio *fio = (struct fio *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
+       ino_t ino;
+       int ret;
+
+       if (fio == NULL) {
+               return -1;
+       }
+
+       if (fio->fake_fd) {
+               ret = fruit_stat_base(handle, fsp->base_fsp->fsp_name, false);
+               if (ret != 0) {
+                       return -1;
+               }
+
+               *sbuf = fsp->base_fsp->fsp_name->st;
+               sbuf->st_ex_size = AFP_INFO_SIZE;
+               sbuf->st_ex_ino = fruit_inode(sbuf, fsp->fsp_name->stream_name);
+               return 0;
+       }
+
+       ret = fruit_stat_base(handle, fsp->base_fsp->fsp_name, false);
+       if (ret != 0) {
+               return -1;
+       }
+       *sbuf = fsp->base_fsp->fsp_name->st;
+
+       ino = fruit_inode(sbuf, fsp->fsp_name->stream_name);
+
+       ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
+       if (ret != 0) {
+               return -1;
+       }
+
+       sbuf->st_ex_ino = ino;
+       return 0;
 }
 
 static int fruit_fstat_meta_netatalk(vfs_handle_struct *handle,
@@ -5393,12 +5437,14 @@ static NTSTATUS fruit_streaminfo_meta_stream(
                goto out;
        }
 
-       ret = SMB_VFS_NEXT_STAT(handle, sname);
+       ret = fruit_stat_base(handle, sname, false);
        if (ret != 0) {
                status = map_nt_error_from_unix(errno);
                goto out;
        }
 
+       sname->st.st_ex_ino = fruit_inode(&sname->st, AFPINFO_STREAM);
+
        id = SMB_VFS_NEXT_FILE_ID_CREATE(handle, &sname->st);
 
        lck = get_existing_share_mode_lock(talloc_tos(), id);