From a6a21255ee9d015e7edd847ae678673932b97a6e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 Apr 2013 16:21:39 -0700 Subject: [PATCH 1/4] Maintain a back-pointer to the fsp in struct smb_Dir when opening with FDOPENDIR. Signed-off-by: Jeremy Allison Reviewed-by: Andreas Schneider (cherry picked from commit e89ec641fc98ffd7f7193deb3728b0a284a093eb) --- source3/smbd/dir.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index a06fc5f..0dd75b1 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -50,6 +50,8 @@ struct smb_Dir { struct name_cache_entry *name_cache; unsigned int name_cache_index; unsigned int file_number; + files_struct *fsp; /* Back pointer to containing fsp, only + set from OpenDir_fsp(). */ }; struct dptr_struct { @@ -1537,7 +1539,9 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, if (fsp->is_directory && fsp->fh->fd != -1) { dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); - if (dirp->dir == NULL) { + if (dirp->dir != NULL) { + dirp->fsp = fsp; + } else { DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned " "NULL (%s)\n", dirp->dir_path, -- 1.8.2.1 From 1bcae12ae4ae4020e272b8f32427f98d6d58e163 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 Apr 2013 16:24:15 -0700 Subject: [PATCH 2/4] In the struct smb_Dir destructor, use the fsp back pointer to release resources. Removes one use of dirfd(). Signed-off-by: Jeremy Allison Reviewed-by: Andreas Schneider (cherry picked from commit ea14c9443178da9ae6ccbe71e573156396f6f699) --- source3/smbd/dir.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 0dd75b1..ad6826c 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1444,18 +1444,21 @@ bool is_visible_file(connection_struct *conn, const char *dir_path, static int smb_Dir_destructor(struct smb_Dir *dirp) { - if (dirp->dir) { -#ifdef HAVE_DIRFD - if (dirp->conn->sconn) { - files_struct *fsp = file_find_fd(dirp->conn->sconn, - dirfd(dirp->dir)); - if (fsp) { - /* The call below closes the underlying fd. */ - fsp->fh->fd = -1; + if (dirp->dir != NULL) { + SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir); + if (dirp->fsp != NULL) { + /* + * The SMB_VFS_CLOSEDIR above + * closes the underlying fd inside + * dirp->fsp. + */ + dirp->fsp->fh->fd = -1; + if (dirp->fsp->dptr != NULL) { + SMB_ASSERT(dirp->fsp->dptr->dir_hnd == dirp); + dirp->fsp->dptr->dir_hnd = NULL; } + dirp->fsp = NULL; } -#endif - SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir); } if (dirp->conn->sconn && !dirp->conn->sconn->using_smb2) { dirp->conn->sconn->searches.dirhandles_open--; -- 1.8.2.1 From e03af4aceb3144b095502a71acd4c03139114c89 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 Apr 2013 16:29:03 -0700 Subject: [PATCH 3/4] Remove the "Ugly hack" that was the second use of dirfd(). The destructor does all the resource deallocation needed. Signed-off-by: Jeremy Allison Reviewed-by: Andreas Schneider (cherry picked from commit 0fe894fb89f4867e266bb04670a58101311e0234) --- source3/smbd/dir.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index ad6826c..63f0227 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -677,20 +677,12 @@ done: void dptr_CloseDir(files_struct *fsp) { if (fsp->dptr) { -/* - * Ugly hack. We have defined fdopendir to return ENOSYS if dirfd also isn't - * present. I hate Solaris. JRA. - */ -#ifdef HAVE_DIRFD - if (fsp->fh->fd != -1 && - fsp->dptr->dir_hnd && - dirfd(fsp->dptr->dir_hnd->dir)) { - /* The call below closes the underlying fd. */ - fsp->fh->fd = -1; - } -#endif + /* + * The destructor for the struct smb_Dir + * (fsp->dptr->dir_hnd) now handles + * all resource deallocation. + */ dptr_close_internal(fsp->dptr); - fsp->dptr = NULL; } } -- 1.8.2.1 From bc3f6827ced4fcc827f919c2d7d4f7ab90917c7f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 Apr 2013 16:30:10 -0700 Subject: [PATCH 4/4] Remove dependency on detection of HAVE_DIRFD for use of fdopendir(). Signed-off-by: Jeremy Allison Reviewed-by: Andreas Schneider Autobuild-User(master): Andreas Schneider Autobuild-Date(master): Fri Apr 12 16:21:10 CEST 2013 on sn-devel-104 (cherry picked from commit 7a4dd845958f1411daa8031ca242987001ab2f26) --- source3/lib/system.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source3/lib/system.c b/source3/lib/system.c index d69f1c6..8dbf7dc 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -634,13 +634,11 @@ void kernel_flock(int fd, uint32 share_mode, uint32 access_mask) /******************************************************************* An fdopendir wrapper. - Ugly hack - we need dirfd for this to work correctly in the - calling code.. JRA. ********************************************************************/ DIR *sys_fdopendir(int fd) { -#if defined(HAVE_FDOPENDIR) && defined(HAVE_DIRFD) +#if defined(HAVE_FDOPENDIR) return fdopendir(fd); #else errno = ENOSYS; -- 1.8.2.1