diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-05-27 23:36:21 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-05-27 23:36:21 +0200 |
commit | b58a4b938c4bc7e0499700859bd7abba9acc5b11 (patch) | |
tree | fab9f284d9abd5a183bfa79c271f467efa28960c /src/memfile.c | |
parent | 72fcf07b0639b49be3305de141d777baa9c965a0 (diff) | |
download | vim-git-b58a4b938c4bc7e0499700859bd7abba9acc5b11.tar.gz |
patch 8.1.1413: error when the drive of the swap file was disconnectedv8.1.1413
Problem: Error when the drive of the swap file was disconnected.
Solution: Try closing and re-opening the swap file. (closes #4378)
Diffstat (limited to 'src/memfile.c')
-rw-r--r-- | src/memfile.c | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/src/memfile.c b/src/memfile.c index 9a1b4cb1c..5bc587c1f 100644 --- a/src/memfile.c +++ b/src/memfile.c @@ -994,7 +994,8 @@ mf_write(memfile_T *mfp, bhdr_T *hp) unsigned page_count; /* number of pages written */ unsigned size; /* number of bytes written */ - if (mfp->mf_fd < 0) /* there is no file, can't write */ + if (mfp->mf_fd < 0 && !mfp->mf_reopen) + // there is no file and there was no file, can't write return FAIL; if (hp->bh_bnum < 0) /* must assign file block number */ @@ -1011,6 +1012,8 @@ mf_write(memfile_T *mfp, bhdr_T *hp) */ for (;;) { + int attempt; + nr = hp->bh_bnum; if (nr > mfp->mf_infile_count) /* beyond end of file */ { @@ -1021,29 +1024,49 @@ mf_write(memfile_T *mfp, bhdr_T *hp) hp2 = hp; offset = (off_T)page_size * nr; - if (vim_lseek(mfp->mf_fd, offset, SEEK_SET) != offset) - { - PERROR(_("E296: Seek error in swap file write")); - return FAIL; - } if (hp2 == NULL) /* freed block, fill with dummy data */ page_count = 1; else page_count = hp2->bh_page_count; size = page_size * page_count; - if (mf_write_block(mfp, hp2 == NULL ? hp : hp2, offset, size) == FAIL) + + for (attempt = 1; attempt <= 2; ++attempt) { - /* - * Avoid repeating the error message, this mostly happens when the - * disk is full. We give the message again only after a successful - * write or when hitting a key. We keep on trying, in case some - * space becomes available. - */ - if (!did_swapwrite_msg) - emsg(_("E297: Write error in swap file")); - did_swapwrite_msg = TRUE; - return FAIL; + if (mfp->mf_fd >= 0) + { + if (vim_lseek(mfp->mf_fd, offset, SEEK_SET) != offset) + { + PERROR(_("E296: Seek error in swap file write")); + return FAIL; + } + if (mf_write_block(mfp, + hp2 == NULL ? hp : hp2, offset, size) == OK) + break; + } + + if (attempt == 1) + { + // If the swap file is on a network drive, and the network + // gets disconnected and then re-connected, we can maybe fix it + // by closing and then re-opening the file. + if (mfp->mf_fd >= 0) + close(mfp->mf_fd); + mfp->mf_fd = mch_open_rw((char *)mfp->mf_fname, mfp->mf_flags); + mfp->mf_reopen = (mfp->mf_fd < 0); + } + if (attempt == 2 || mfp->mf_fd < 0) + { + // Avoid repeating the error message, this mostly happens when + // the disk is full. We give the message again only after a + // successful write or when hitting a key. We keep on trying, + // in case some space becomes available. + if (!did_swapwrite_msg) + emsg(_("E297: Write error in swap file")); + did_swapwrite_msg = TRUE; + return FAIL; + } } + did_swapwrite_msg = FALSE; if (hp2 != NULL) /* written a non-dummy block */ hp2->bh_flags &= ~BH_DIRTY; @@ -1271,6 +1294,7 @@ mf_do_open( * the file) */ flags |= O_NOINHERIT; #endif + mfp->mf_flags = flags; mfp->mf_fd = mch_open_rw((char *)mfp->mf_fname, flags); } |