void file_free(struct smb_request *req, files_struct *fsp) { struct smbd_server_connection *sconn = fsp->conn->sconn; uint64_t fnum = fsp->fnum; if (fsp->notify) { struct notify_context *notify_ctx = fsp->conn->sconn->notify_ctx; notify_remove(notify_ctx, fsp); TALLOC_FREE(fsp->notify); } /* Ensure this event will never fire. */ TALLOC_FREE(fsp->update_write_time_event); if (fsp->op != NULL) { fsp->op->compat = NULL; } TALLOC_FREE(fsp->op); if ((req != NULL) && (fsp == req->chain_fsp)) { req->chain_fsp = NULL; } /* * Clear all possible chained fsp * pointers in the SMB2 request queue. */ if (req != NULL && req->smb2req) { remove_smb2_chained_fsp(fsp); } /* Closing a file can invalidate the positive cache. */ if (fsp == sconn->fsp_fi_cache.fsp) { ZERO_STRUCT(sconn->fsp_fi_cache); } /* Drop all remaining extensions. */ vfs_remove_all_fsp_extensions(fsp); fsp_free(fsp); DEBUG(5,("freed files structure %llu (%u used)\n", (unsigned long long)fnum, (unsigned int)sconn->num_files)); }
void file_free(struct smb_request *req, files_struct *fsp) { struct smbd_server_connection *sconn = fsp->conn->sconn; DLIST_REMOVE(sconn->files, fsp); SMB_ASSERT(sconn->num_files > 0); sconn->num_files--; TALLOC_FREE(fsp->fake_file_handle); if (fsp->fh->ref_count == 1) { TALLOC_FREE(fsp->fh); } else { fsp->fh->ref_count--; } if (fsp->notify) { struct notify_context *notify_ctx = fsp->conn->sconn->notify_ctx; notify_remove(notify_ctx, fsp); TALLOC_FREE(fsp->notify); } /* Ensure this event will never fire. */ TALLOC_FREE(fsp->oplock_timeout); /* Ensure this event will never fire. */ TALLOC_FREE(fsp->update_write_time_event); bitmap_clear(sconn->file_bmap, fsp->fnum - FILE_HANDLE_OFFSET); DEBUG(5,("freed files structure %d (%u used)\n", fsp->fnum, (unsigned int)sconn->num_files)); fsp->conn->num_files_open--; if ((req != NULL) && (fsp == req->chain_fsp)) { req->chain_fsp = NULL; } /* * Clear all possible chained fsp * pointers in the SMB2 request queue. */ if (req != NULL && req->smb2req) { remove_smb2_chained_fsp(fsp); } /* Closing a file can invalidate the positive cache. */ if (fsp == sconn->fsp_fi_cache.fsp) { ZERO_STRUCT(sconn->fsp_fi_cache); } /* Drop all remaining extensions. */ while (fsp->vfs_extension) { vfs_remove_fsp_extension(fsp->vfs_extension->owner, fsp); } /* this is paranoia, just in case someone tries to reuse the information */ ZERO_STRUCTP(fsp); /* fsp->fsp_name is a talloc child and is free'd automatically. */ TALLOC_FREE(fsp); }