mirror of
https://github.com/neovim/neovim.git
synced 2025-09-19 09:48:19 +00:00
IO: let 'fsync' option control more cases
Vim has the 'swapsync' option which we removed in 62d137ce09
.
Instead let 'fsync' control swapfile-fsync.
These cases ALWAYS force fsync (ignoring 'fsync' option):
- Idle (CursorHold).
- Exit caused by deadly signal.
- SIGPWR signal.
- Explicit :preserve command.
This commit is contained in:
@@ -6547,18 +6547,14 @@ void alist_slash_adjust(void)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/// ":preserve".
|
||||||
* ":preserve".
|
|
||||||
*/
|
|
||||||
static void ex_preserve(exarg_T *eap)
|
static void ex_preserve(exarg_T *eap)
|
||||||
{
|
{
|
||||||
curbuf->b_flags |= BF_PRESERVED;
|
curbuf->b_flags |= BF_PRESERVED;
|
||||||
ml_preserve(curbuf, TRUE);
|
ml_preserve(curbuf, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// ":recover".
|
||||||
* ":recover".
|
|
||||||
*/
|
|
||||||
static void ex_recover(exarg_T *eap)
|
static void ex_recover(exarg_T *eap)
|
||||||
{
|
{
|
||||||
/* Set recoverymode right away to avoid the ATTENTION prompt. */
|
/* Set recoverymode right away to avoid the ATTENTION prompt. */
|
||||||
|
@@ -3068,7 +3068,7 @@ nobackup:
|
|||||||
*/
|
*/
|
||||||
if (reset_changed && !newfile && overwriting
|
if (reset_changed && !newfile && overwriting
|
||||||
&& !(exiting && backup != NULL)) {
|
&& !(exiting && backup != NULL)) {
|
||||||
ml_preserve(buf, FALSE);
|
ml_preserve(buf, false, !!p_fs);
|
||||||
if (got_int) {
|
if (got_int) {
|
||||||
SET_ERRMSG(_(e_interr));
|
SET_ERRMSG(_(e_interr));
|
||||||
goto restore_backup;
|
goto restore_backup;
|
||||||
|
@@ -1347,14 +1347,17 @@ void before_blocking(void)
|
|||||||
* All the changed memfiles are synced if c == 0 or when the number of typed
|
* All the changed memfiles are synced if c == 0 or when the number of typed
|
||||||
* characters reaches 'updatecount' and 'updatecount' is non-zero.
|
* characters reaches 'updatecount' and 'updatecount' is non-zero.
|
||||||
*/
|
*/
|
||||||
void updatescript(int c)
|
static void updatescript(int c)
|
||||||
{
|
{
|
||||||
static int count = 0;
|
static int count = 0;
|
||||||
|
|
||||||
if (c && scriptout)
|
if (c && scriptout) {
|
||||||
putc(c, scriptout);
|
putc(c, scriptout);
|
||||||
if (c == 0 || (p_uc > 0 && ++count >= p_uc)) {
|
}
|
||||||
ml_sync_all(c == 0, TRUE);
|
bool idle = (c == 0);
|
||||||
|
if (idle || (p_uc > 0 && ++count >= p_uc)) {
|
||||||
|
ml_sync_all(idle, true,
|
||||||
|
(!!p_fs || idle)); // Always fsync at idle (CursorHold).
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1593,7 +1593,7 @@ static int recov_file_names(char_u **names, char_u *path, int prepend_dot)
|
|||||||
* If 'check_char' is TRUE, stop syncing when character becomes available, but
|
* If 'check_char' is TRUE, stop syncing when character becomes available, but
|
||||||
* always sync at least one block.
|
* always sync at least one block.
|
||||||
*/
|
*/
|
||||||
void ml_sync_all(int check_file, int check_char)
|
void ml_sync_all(int check_file, int check_char, bool do_fsync)
|
||||||
{
|
{
|
||||||
FOR_ALL_BUFFERS(buf) {
|
FOR_ALL_BUFFERS(buf) {
|
||||||
if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL)
|
if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL)
|
||||||
@@ -1612,14 +1612,14 @@ void ml_sync_all(int check_file, int check_char)
|
|||||||
if (!os_fileinfo((char *)buf->b_ffname, &file_info)
|
if (!os_fileinfo((char *)buf->b_ffname, &file_info)
|
||||||
|| file_info.stat.st_mtim.tv_sec != buf->b_mtime_read
|
|| file_info.stat.st_mtim.tv_sec != buf->b_mtime_read
|
||||||
|| os_fileinfo_size(&file_info) != buf->b_orig_size) {
|
|| os_fileinfo_size(&file_info) != buf->b_orig_size) {
|
||||||
ml_preserve(buf, FALSE);
|
ml_preserve(buf, false, do_fsync);
|
||||||
did_check_timestamps = FALSE;
|
did_check_timestamps = FALSE;
|
||||||
need_check_timestamps = TRUE; /* give message later */
|
need_check_timestamps = TRUE; /* give message later */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (buf->b_ml.ml_mfp->mf_dirty) {
|
if (buf->b_ml.ml_mfp->mf_dirty) {
|
||||||
(void)mf_sync(buf->b_ml.ml_mfp, (check_char ? MFS_STOP : 0)
|
(void)mf_sync(buf->b_ml.ml_mfp, (check_char ? MFS_STOP : 0)
|
||||||
| (bufIsChanged(buf) ? MFS_FLUSH : 0));
|
| (do_fsync && bufIsChanged(buf) ? MFS_FLUSH : 0));
|
||||||
if (check_char && os_char_avail()) /* character available now */
|
if (check_char && os_char_avail()) /* character available now */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1636,7 +1636,7 @@ void ml_sync_all(int check_file, int check_char)
|
|||||||
*
|
*
|
||||||
* when message is TRUE the success of preserving is reported
|
* when message is TRUE the success of preserving is reported
|
||||||
*/
|
*/
|
||||||
void ml_preserve(buf_T *buf, int message)
|
void ml_preserve(buf_T *buf, int message, bool do_fsync)
|
||||||
{
|
{
|
||||||
bhdr_T *hp;
|
bhdr_T *hp;
|
||||||
linenr_T lnum;
|
linenr_T lnum;
|
||||||
@@ -1656,7 +1656,7 @@ void ml_preserve(buf_T *buf, int message)
|
|||||||
|
|
||||||
ml_flush_line(buf); /* flush buffered line */
|
ml_flush_line(buf); /* flush buffered line */
|
||||||
(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush locked block */
|
(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush locked block */
|
||||||
status = mf_sync(mfp, MFS_ALL | MFS_FLUSH);
|
status = mf_sync(mfp, MFS_ALL | (do_fsync ? MFS_FLUSH : 0));
|
||||||
|
|
||||||
/* stack is invalid after mf_sync(.., MFS_ALL) */
|
/* stack is invalid after mf_sync(.., MFS_ALL) */
|
||||||
buf->b_ml.ml_stack_top = 0;
|
buf->b_ml.ml_stack_top = 0;
|
||||||
@@ -1686,7 +1686,7 @@ void ml_preserve(buf_T *buf, int message)
|
|||||||
}
|
}
|
||||||
(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush locked block */
|
(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush locked block */
|
||||||
/* sync the updated pointer blocks */
|
/* sync the updated pointer blocks */
|
||||||
if (mf_sync(mfp, MFS_ALL | MFS_FLUSH) == FAIL)
|
if (mf_sync(mfp, MFS_ALL | (do_fsync ? MFS_FLUSH : 0)) == FAIL)
|
||||||
status = FAIL;
|
status = FAIL;
|
||||||
buf->b_ml.ml_stack_top = 0; /* stack is invalid now */
|
buf->b_ml.ml_stack_top = 0; /* stack is invalid now */
|
||||||
}
|
}
|
||||||
|
@@ -2643,7 +2643,7 @@ void preserve_exit(void)
|
|||||||
if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL) {
|
if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL) {
|
||||||
mch_errmsg((uint8_t *)"Vim: preserving files...\n");
|
mch_errmsg((uint8_t *)"Vim: preserving files...\n");
|
||||||
ui_flush();
|
ui_flush();
|
||||||
ml_sync_all(false, false); // preserve all swap files
|
ml_sync_all(false, false, true); // preserve all swap files
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -145,7 +145,7 @@ static void on_signal(SignalWatcher *handle, int signum, void *data)
|
|||||||
case SIGPWR:
|
case SIGPWR:
|
||||||
// Signal of a power failure(eg batteries low), flush the swap files to
|
// Signal of a power failure(eg batteries low), flush the swap files to
|
||||||
// be safe
|
// be safe
|
||||||
ml_sync_all(false, false);
|
ml_sync_all(false, false, true);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGPIPE
|
#ifdef SIGPIPE
|
||||||
|
Reference in New Issue
Block a user