Changing smb_filename->base_name in VFS module.

Richard Sharpe realrichardsharpe at gmail.com
Wed Aug 29 13:46:15 UTC 2018


On Wed, Aug 29, 2018 at 4:35 AM, Vadim Lazovskiy via samba-technical
<samba-technical at lists.samba.org> wrote:
> Hello.
>
> I've encountered an issue after upgrading samba 3.6 to 4.5.
> My VFS module stopped working as expected.
>
> Briefly, module implements caching on SSD by searching file in several
> configured locations on file open:
>
> static int ssdcache_open(vfs_handle_struct *handle, struct smb_filename
> *smb_fname,
>     files_struct *fsp, int flags, mode_t mode)
> {
>         ...
>         ...
>
>         /* Calculate maximum basename length */
>         max_len = 0;
>         for (i = 0; cache_paths[i]; i++) {
>                 len = strlen(cache_paths[i]);
>
>                 if(len > max_len) {
>                         max_len = len;
>                 }
>         }
>
>         max_len += strlen(smb_fname->base_name) + 2; // for slash and \0
>         new_base_name = talloc_zero_size(talloc_tos(), max_len);
>
>         if (new_base_name == NULL) {
>                 errno = ENOMEM;
>                 return -1;
>         }
>
>         /* Allocate new smb_filename structure */
>         smb_fname_new = synthetic_smb_fname(talloc_tos(), new_base_name,
> NULL, NULL, smb_fname->flags);
>
>         if (smb_fname_new == NULL) {
>                 errno = ENOMEM;
>                 return -1;
>         }
>
>         for (i = 0; cache_paths[i]; i++) {
>                 strlcat(smb_fname_new->base_name, cache_paths[i], max_len);
>                 strlcat(smb_fname_new->base_name, "/", max_len);
>                 strlcat(smb_fname_new->base_name, smb_fname->base_name,
> max_len);
>
>                 if (SMB_VFS_STAT(handle->conn, smb_fname_new) == 0) {
>                         break;
>                 }
>
>                 *smb_fname_new->base_name = '\0';
>         }
>
>         if (*smb_fname_new->base_name == '\0') {
>                 strlcat(smb_fname_new->base_name, smb_fname->base_name,
> max_len);
>         }
>
>         return SMB_VFS_NEXT_OPEN(handle, smb_fname_new, fsp, flags, mode);
> }
>
> After some debugging I found out the point where I get ACCESS_DENIED:
> static NTSTATUS open_file_ntcreate
> in source3/smbd/open.c:
>
>         if (file_existed && !check_same_dev_ino(&saved_stat,
> &smb_fname->st)) {
>                 /*
>                  * The file did exist, but some other (local or NFS)
>                  * process either renamed/unlinked and re-created the
>                  * file with different dev/ino after we walked the path,
>                  * but before we did the open. We could retry the
>                  * open but it's a rare enough case it's easier to
>                  * just fail the open to prevent creating any problems
>                  * in the open file db having the wrong dev/ino key.
>                  */
>                 fd_close(fsp);
>
> This seems reasonable for sure because original file is not the same as
> cached file.
> Could you please explain how should I change my module implementation to
> mitigate this issue.
> Thank you!

You are going to have to implement more VFS functions. At least
realpath and stat, I would imagine.

-- 
Regards,
Richard Sharpe
(何以解憂?唯有杜康。--曹操)(传说杜康是酒的发明者)



More information about the samba-technical mailing list