Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
03bdaaf5
Commit
03bdaaf5
authored
Nov 16, 2006
by
marko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
branches/zip: Introduce a new preprocessor symbol, UNIV_BUF_DEBUG, and
enclose buf_validate() and friends in it.
parent
97b49ef9
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
65 additions
and
64 deletions
+65
-64
buf/buf0buf.c
buf/buf0buf.c
+32
-50
buf/buf0flu.c
buf/buf0flu.c
+10
-2
buf/buf0lru.c
buf/buf0lru.c
+6
-6
dict/dict0dict.c
dict/dict0dict.c
+3
-1
include/buf0buf.h
include/buf0buf.h
+4
-2
include/buf0flu.h
include/buf0flu.h
+2
-0
include/buf0lru.h
include/buf0lru.h
+4
-2
include/dict0dict.h
include/dict0dict.h
+3
-1
include/univ.i
include/univ.i
+1
-0
No files found.
buf/buf0buf.c
View file @
03bdaaf5
...
@@ -206,10 +206,12 @@ static const int WAIT_FOR_READ = 20000;
...
@@ -206,10 +206,12 @@ static const int WAIT_FOR_READ = 20000;
buf_pool_t
*
buf_pool
=
NULL
;
/* The buffer buf_pool of the database */
buf_pool_t
*
buf_pool
=
NULL
;
/* The buffer buf_pool of the database */
#if
def UNIV
_DEBUG
#if
defined UNIV_DEBUG || defined UNIV_BUF
_DEBUG
ulint
buf_dbg_counter
=
0
;
/* This is used to insert validation
static
ulint
buf_dbg_counter
=
0
;
/* This is used to insert validation
operations in excution in the
operations in excution in the
debug version */
debug version */
#endif
/* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG
ibool
buf_debug_prints
=
FALSE
;
/* If this is set TRUE,
ibool
buf_debug_prints
=
FALSE
;
/* If this is set TRUE,
the program prints info whenever
the program prints info whenever
read-ahead or flush occurs */
read-ahead or flush occurs */
...
@@ -1349,13 +1351,9 @@ buf_page_get_gen(
...
@@ -1349,13 +1351,9 @@ buf_page_get_gen(
buf_read_page
(
space
,
fil_space_get_zip_size
(
space
),
offset
);
buf_read_page
(
space
,
fil_space_get_zip_size
(
space
),
offset
);
#ifdef UNIV_DEBUG
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_dbg_counter
++
;
ut_a
(
++
buf_dbg_counter
%
37
||
buf_validate
());
#endif
/* UNIV_DEBUG || UNIV_BUF_DEBUG */
if
(
buf_dbg_counter
%
37
==
0
)
{
ut_ad
(
buf_validate
());
}
#endif
goto
loop
;
goto
loop
;
}
}
...
@@ -1399,15 +1397,11 @@ buf_page_get_gen(
...
@@ -1399,15 +1397,11 @@ buf_page_get_gen(
ut_a
(
block
->
file_page_was_freed
==
FALSE
);
ut_a
(
block
->
file_page_was_freed
==
FALSE
);
#endif
#endif
#ifdef UNIV_DEBUG
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_dbg_counter
++
;
ut_a
(
++
buf_dbg_counter
%
5771
||
buf_validate
());
ut_a
(
block
->
buf_fix_count
>
0
);
if
(
buf_dbg_counter
%
5771
==
0
)
{
ut_a
(
block
->
state
==
BUF_BLOCK_FILE_PAGE
);
ut_ad
(
buf_validate
());
#endif
/* UNIV_DEBUG || UNIV_BUF_DEBUG */
}
#endif
ut_ad
(
block
->
buf_fix_count
>
0
);
ut_ad
(
block
->
state
==
BUF_BLOCK_FILE_PAGE
);
if
(
mode
==
BUF_GET_NOWAIT
)
{
if
(
mode
==
BUF_GET_NOWAIT
)
{
if
(
rw_latch
==
RW_S_LATCH
)
{
if
(
rw_latch
==
RW_S_LATCH
)
{
...
@@ -1581,15 +1575,11 @@ buf_page_optimistic_get_func(
...
@@ -1581,15 +1575,11 @@ buf_page_optimistic_get_func(
mtr_memo_push
(
mtr
,
block
,
fix_type
);
mtr_memo_push
(
mtr
,
block
,
fix_type
);
#ifdef UNIV_DEBUG
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_dbg_counter
++
;
ut_a
(
++
buf_dbg_counter
%
5771
||
buf_validate
());
ut_a
(
block
->
buf_fix_count
>
0
);
if
(
buf_dbg_counter
%
5771
==
0
)
{
ut_a
(
block
->
state
==
BUF_BLOCK_FILE_PAGE
);
ut_ad
(
buf_validate
());
#endif
/* UNIV_DEBUG || UNIV_BUF_DEBUG */
}
#endif
ut_ad
(
block
->
buf_fix_count
>
0
);
ut_ad
(
block
->
state
==
BUF_BLOCK_FILE_PAGE
);
#ifdef UNIV_DEBUG_FILE_ACCESSES
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a
(
block
->
file_page_was_freed
==
FALSE
);
ut_a
(
block
->
file_page_was_freed
==
FALSE
);
...
@@ -1689,15 +1679,11 @@ buf_page_get_known_nowait(
...
@@ -1689,15 +1679,11 @@ buf_page_get_known_nowait(
mtr_memo_push
(
mtr
,
block
,
fix_type
);
mtr_memo_push
(
mtr
,
block
,
fix_type
);
#ifdef UNIV_DEBUG
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_dbg_counter
++
;
ut_a
(
++
buf_dbg_counter
%
5771
||
buf_validate
());
ut_a
(
block
->
buf_fix_count
>
0
);
if
(
buf_dbg_counter
%
5771
==
0
)
{
ut_a
(
block
->
state
==
BUF_BLOCK_FILE_PAGE
);
ut_ad
(
buf_validate
());
#endif
/* UNIV_DEBUG || UNIV_BUF_DEBUG */
}
#endif
ut_ad
(
block
->
buf_fix_count
>
0
);
ut_ad
(
block
->
state
==
BUF_BLOCK_FILE_PAGE
);
#ifdef UNIV_DEBUG_FILE_ACCESSES
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a
(
block
->
file_page_was_freed
==
FALSE
);
ut_a
(
block
->
file_page_was_freed
==
FALSE
);
#endif
#endif
...
@@ -1797,12 +1783,12 @@ buf_page_init(
...
@@ -1797,12 +1783,12 @@ buf_page_init(
" in the hash table
\n
"
,
" in the hash table
\n
"
,
(
ulong
)
space
,
(
ulong
)
space
,
(
ulong
)
offset
);
(
ulong
)
offset
);
#if
def UNIV
_DEBUG
#if
defined UNIV_DEBUG || defined UNIV_BUF
_DEBUG
buf_print
();
buf_print
();
buf_LRU_print
();
buf_LRU_print
();
buf_validate
();
buf_validate
();
buf_LRU_validate
();
buf_LRU_validate
();
#endif
/* UNIV_DEBUG */
#endif
/* UNIV_DEBUG
|| UNIV_BUF_DEBUG
*/
ut_error
;
ut_error
;
}
}
...
@@ -2043,13 +2029,9 @@ buf_page_create(
...
@@ -2043,13 +2029,9 @@ buf_page_create(
memset
(
frame
+
FIL_PAGE_FILE_FLUSH_LSN
,
0
,
8
);
memset
(
frame
+
FIL_PAGE_FILE_FLUSH_LSN
,
0
,
8
);
#ifdef UNIV_DEBUG
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_dbg_counter
++
;
ut_a
(
++
buf_dbg_counter
%
357
||
buf_validate
());
#endif
/* UNIV_DEBUG || UNIV_BUF_DEBUG */
if
(
buf_dbg_counter
%
357
==
0
)
{
ut_ad
(
buf_validate
());
}
#endif
#ifdef UNIV_IBUF_DEBUG
#ifdef UNIV_IBUF_DEBUG
ut_a
(
ibuf_count_get
(
block
->
space
,
block
->
offset
)
==
0
);
ut_a
(
ibuf_count_get
(
block
->
space
,
block
->
offset
)
==
0
);
#endif
#endif
...
@@ -2301,7 +2283,7 @@ buf_pool_invalidate(void)
...
@@ -2301,7 +2283,7 @@ buf_pool_invalidate(void)
mutex_exit
(
&
(
buf_pool
->
mutex
));
mutex_exit
(
&
(
buf_pool
->
mutex
));
}
}
#if
def UNIV
_DEBUG
#if
defined UNIV_DEBUG || defined UNIV_BUF
_DEBUG
/*************************************************************************
/*************************************************************************
Validates the buffer buf_pool data structure. */
Validates the buffer buf_pool data structure. */
...
@@ -2412,9 +2394,9 @@ buf_validate(void)
...
@@ -2412,9 +2394,9 @@ buf_validate(void)
return
(
TRUE
);
return
(
TRUE
);
}
}
#endif
/* UNIV_DEBUG */
#endif
/* UNIV_DEBUG
|| UNIV_BUF_DEBUG
*/
#if defined UNIV_DEBUG
|| defined UNIV_DEBUG_PRINT
#if defined UNIV_DEBUG
_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/*************************************************************************
/*************************************************************************
Prints info of the buffer buf_pool data structure. */
Prints info of the buffer buf_pool data structure. */
...
@@ -2521,9 +2503,9 @@ buf_print(void)
...
@@ -2521,9 +2503,9 @@ buf_print(void)
mem_free
(
index_ids
);
mem_free
(
index_ids
);
mem_free
(
counts
);
mem_free
(
counts
);
ut_a
d
(
buf_validate
());
ut_a
(
buf_validate
());
}
}
#endif
/* UNIV_DEBUG
|| UNIV_DEBUG_PRINT
*/
#endif
/* UNIV_DEBUG
_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG
*/
/*************************************************************************
/*************************************************************************
Returns the number of latched pages in the buffer pool. */
Returns the number of latched pages in the buffer pool. */
...
...
buf/buf0flu.c
View file @
03bdaaf5
...
@@ -33,6 +33,7 @@ flushed along with the original page. */
...
@@ -33,6 +33,7 @@ flushed along with the original page. */
#define BUF_FLUSH_AREA ut_min(BUF_READ_AHEAD_AREA,\
#define BUF_FLUSH_AREA ut_min(BUF_READ_AHEAD_AREA,\
buf_pool->curr_size / 16)
buf_pool->curr_size / 16)
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/**********************************************************************
/**********************************************************************
Validates the flush list. */
Validates the flush list. */
static
static
...
@@ -40,6 +41,7 @@ ibool
...
@@ -40,6 +41,7 @@ ibool
buf_flush_validate_low
(
void
);
buf_flush_validate_low
(
void
);
/*========================*/
/*========================*/
/* out: TRUE if ok */
/* out: TRUE if ok */
#endif
/* UNIV_DEBUG || UNIV_BUF_DEBUG */
/************************************************************************
/************************************************************************
Inserts a modified block into the flush list. */
Inserts a modified block into the flush list. */
...
@@ -62,7 +64,9 @@ buf_flush_insert_into_flush_list(
...
@@ -62,7 +64,9 @@ buf_flush_insert_into_flush_list(
UT_LIST_ADD_FIRST
(
flush_list
,
buf_pool
->
flush_list
,
block
);
UT_LIST_ADD_FIRST
(
flush_list
,
buf_pool
->
flush_list
,
block
);
ut_ad
(
buf_flush_validate_low
());
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a
(
buf_flush_validate_low
());
#endif
/* UNIV_DEBUG || UNIV_BUF_DEBUG */
}
}
/************************************************************************
/************************************************************************
...
@@ -98,7 +102,9 @@ buf_flush_insert_sorted_into_flush_list(
...
@@ -98,7 +102,9 @@ buf_flush_insert_sorted_into_flush_list(
block
);
block
);
}
}
ut_ad
(
buf_flush_validate_low
());
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a
(
buf_flush_validate_low
());
#endif
/* UNIV_DEBUG || UNIV_BUF_DEBUG */
}
}
/************************************************************************
/************************************************************************
...
@@ -1112,6 +1118,7 @@ buf_flush_free_margin(void)
...
@@ -1112,6 +1118,7 @@ buf_flush_free_margin(void)
}
}
}
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/**********************************************************************
/**********************************************************************
Validates the flush list. */
Validates the flush list. */
static
static
...
@@ -1161,3 +1168,4 @@ buf_flush_validate(void)
...
@@ -1161,3 +1168,4 @@ buf_flush_validate(void)
return
(
ret
);
return
(
ret
);
}
}
#endif
/* UNIV_DEBUG || UNIV_BUF_DEBUG */
buf/buf0lru.c
View file @
03bdaaf5
...
@@ -933,12 +933,12 @@ buf_LRU_block_remove_hashed_page(
...
@@ -933,12 +933,12 @@ buf_LRU_block_remove_hashed_page(
(
void
*
)
block
);
(
void
*
)
block
);
}
}
#if
def UNIV
_DEBUG
#if
defined UNIV_DEBUG || defined UNIV_BUF
_DEBUG
buf_print
();
buf_print
();
buf_LRU_print
();
buf_LRU_print
();
buf_validate
();
buf_validate
();
buf_LRU_validate
();
buf_LRU_validate
();
#endif
#endif
/* UNIV_DEBUG || UNIV_BUF_DEBUG */
ut_error
;
ut_error
;
}
}
...
@@ -971,7 +971,7 @@ buf_LRU_block_free_hashed_page(
...
@@ -971,7 +971,7 @@ buf_LRU_block_free_hashed_page(
buf_LRU_block_free_non_file_page
(
block
);
buf_LRU_block_free_non_file_page
(
block
);
}
}
#if
def UNIV
_DEBUG
#if
defined UNIV_DEBUG || defined UNIV_BUF
_DEBUG
/**************************************************************************
/**************************************************************************
Validates the LRU list. */
Validates the LRU list. */
...
@@ -1043,9 +1043,9 @@ buf_LRU_validate(void)
...
@@ -1043,9 +1043,9 @@ buf_LRU_validate(void)
mutex_exit
(
&
(
buf_pool
->
mutex
));
mutex_exit
(
&
(
buf_pool
->
mutex
));
return
(
TRUE
);
return
(
TRUE
);
}
}
#endif
/* UNIV_DEBUG */
#endif
/* UNIV_DEBUG
|| UNIV_BUF_DEBUG
*/
#if defined UNIV_DEBUG
|| defined UNIV_DEBUG_PRINT
#if defined UNIV_DEBUG
_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/**************************************************************************
/**************************************************************************
Prints the LRU list. */
Prints the LRU list. */
...
@@ -1098,4 +1098,4 @@ buf_LRU_print(void)
...
@@ -1098,4 +1098,4 @@ buf_LRU_print(void)
mutex_exit
(
&
(
buf_pool
->
mutex
));
mutex_exit
(
&
(
buf_pool
->
mutex
));
}
}
#endif
/* UNIV_DEBUG
|| UNIV_DEBUG_PRINT
*/
#endif
/* UNIV_DEBUG
_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG
*/
dict/dict0dict.c
View file @
03bdaaf5
...
@@ -3566,7 +3566,7 @@ dict_index_get_if_in_cache_low(
...
@@ -3566,7 +3566,7 @@ dict_index_get_if_in_cache_low(
return
(
dict_index_find_on_id_low
(
index_id
));
return
(
dict_index_find_on_id_low
(
index_id
));
}
}
#if
def UNIV
_DEBUG
#if
defined UNIV_DEBUG || defined UNIV_BUF
_DEBUG
/**************************************************************************
/**************************************************************************
Returns an index object if it is found in the dictionary cache. */
Returns an index object if it is found in the dictionary cache. */
...
@@ -3590,7 +3590,9 @@ dict_index_get_if_in_cache(
...
@@ -3590,7 +3590,9 @@ dict_index_get_if_in_cache(
return
(
index
);
return
(
index
);
}
}
#endif
/* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG
/**************************************************************************
/**************************************************************************
Checks that a tuple has n_fields_cmp value in a sensible range, so that
Checks that a tuple has n_fields_cmp value in a sensible range, so that
no comparison can occur with the page number field in a node pointer. */
no comparison can occur with the page number field in a node pointer. */
...
...
include/buf0buf.h
View file @
03bdaaf5
...
@@ -425,20 +425,22 @@ buf_block_get_lock_hash_val(
...
@@ -425,20 +425,22 @@ buf_block_get_lock_hash_val(
/* out: lock hash value */
/* out: lock hash value */
const
buf_block_t
*
block
)
/* in: block */
const
buf_block_t
*
block
)
/* in: block */
__attribute__
((
const
));
__attribute__
((
const
));
#if
def UNIV
_DEBUG
#if
defined UNIV_DEBUG || defined UNIV_BUF
_DEBUG
/*************************************************************************
/*************************************************************************
Validates the buffer pool data structure. */
Validates the buffer pool data structure. */
ibool
ibool
buf_validate
(
void
);
buf_validate
(
void
);
/*==============*/
/*==============*/
#endif
/* UNIV_DEBUG || UNIV_BUF_DEBUG */
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/*************************************************************************
/*************************************************************************
Prints info of the buffer pool data structure. */
Prints info of the buffer pool data structure. */
void
void
buf_print
(
void
);
buf_print
(
void
);
/*============*/
/*============*/
#endif
/* UNIV_DEBUG */
#endif
/* UNIV_DEBUG
_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG
*/
/************************************************************************
/************************************************************************
Prints a page to stderr. */
Prints a page to stderr. */
...
...
include/buf0flu.h
View file @
03bdaaf5
...
@@ -97,6 +97,7 @@ buf_flush_ready_for_replace(
...
@@ -97,6 +97,7 @@ buf_flush_ready_for_replace(
buf_block_t
*
block
);
/* in: buffer control block, must
buf_block_t
*
block
);
/* in: buffer control block, must
be in state BUF_BLOCK_FILE_PAGE
be in state BUF_BLOCK_FILE_PAGE
and in the LRU list */
and in the LRU list */
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/**********************************************************************
/**********************************************************************
Validates the flush list. */
Validates the flush list. */
...
@@ -104,6 +105,7 @@ ibool
...
@@ -104,6 +105,7 @@ ibool
buf_flush_validate
(
void
);
buf_flush_validate
(
void
);
/*====================*/
/*====================*/
/* out: TRUE if ok */
/* out: TRUE if ok */
#endif
/* UNIV_DEBUG || UNIV_BUF_DEBUG */
/* When buf_flush_free_margin is called, it tries to make this many blocks
/* When buf_flush_free_margin is called, it tries to make this many blocks
available to replacement in the free list and at the end of the LRU list (to
available to replacement in the free list and at the end of the LRU list (to
...
...
include/buf0lru.h
View file @
03bdaaf5
...
@@ -131,20 +131,22 @@ void
...
@@ -131,20 +131,22 @@ void
buf_LRU_make_block_old
(
buf_LRU_make_block_old
(
/*===================*/
/*===================*/
buf_block_t
*
block
);
/* in: control block */
buf_block_t
*
block
);
/* in: control block */
#if
def UNIV
_DEBUG
#if
defined UNIV_DEBUG || defined UNIV_BUF
_DEBUG
/**************************************************************************
/**************************************************************************
Validates the LRU list. */
Validates the LRU list. */
ibool
ibool
buf_LRU_validate
(
void
);
buf_LRU_validate
(
void
);
/*==================*/
/*==================*/
#endif
/* UNIV_DEBUG || UNIV_BUF_DEBUG */
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/**************************************************************************
/**************************************************************************
Prints the LRU list. */
Prints the LRU list. */
void
void
buf_LRU_print
(
void
);
buf_LRU_print
(
void
);
/*===============*/
/*===============*/
#endif
/* UNIV_DEBUG */
#endif
/* UNIV_DEBUG
_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG
*/
#ifndef UNIV_NONINL
#ifndef UNIV_NONINL
#include "buf0lru.ic"
#include "buf0lru.ic"
...
...
include/dict0dict.h
View file @
03bdaaf5
...
@@ -836,7 +836,7 @@ dict_index_get_if_in_cache_low(
...
@@ -836,7 +836,7 @@ dict_index_get_if_in_cache_low(
/*===========================*/
/*===========================*/
/* out: index, NULL if not found */
/* out: index, NULL if not found */
dulint
index_id
);
/* in: index id */
dulint
index_id
);
/* in: index id */
#if
def UNIV
_DEBUG
#if
defined UNIV_DEBUG || defined UNIV_BUF
_DEBUG
/**************************************************************************
/**************************************************************************
Returns an index object if it is found in the dictionary cache. */
Returns an index object if it is found in the dictionary cache. */
...
@@ -845,6 +845,8 @@ dict_index_get_if_in_cache(
...
@@ -845,6 +845,8 @@ dict_index_get_if_in_cache(
/*=======================*/
/*=======================*/
/* out: index, NULL if not found */
/* out: index, NULL if not found */
dulint
index_id
);
/* in: index id */
dulint
index_id
);
/* in: index id */
#endif
/* UNIV_DEBUG || UNIV_BUF_DEBUG */
#ifdef UNIV_DEBUG
/**************************************************************************
/**************************************************************************
Checks that a tuple has n_fields_cmp value in a sensible range, so that
Checks that a tuple has n_fields_cmp value in a sensible range, so that
no comparison can occur with the page number field in a node pointer. */
no comparison can occur with the page number field in a node pointer. */
...
...
include/univ.i
View file @
03bdaaf5
...
@@ -79,6 +79,7 @@ memory is read outside the allocated blocks. */
...
@@ -79,6 +79,7 @@ memory is read outside the allocated blocks. */
#
if
0
#
if
0
#
define
UNIV_DEBUG_VALGRIND
#
define
UNIV_DEBUG_VALGRIND
#
define
UNIV_DEBUG_PRINT
#
define
UNIV_DEBUG_PRINT
#
define
UNIV_BUF_DEBUG
#
define
UNIV_DEBUG
#
define
UNIV_DEBUG
#
define
UNIV_DEBUG_FILE_ACCESSES
#
define
UNIV_DEBUG_FILE_ACCESSES
#
define
UNIV_LIST_DEBUG
#
define
UNIV_LIST_DEBUG
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment