aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2010-09-17 09:44:28 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2010-09-17 10:08:09 -0400
commit2680d722bf2c5f75225dd9acb3ec9e5a9e2652f4 (patch)
treeaf016ede5f300a33ddd3ad66a8c3c0e6bf05774e
parent8c893a5545ca772744376295690723dcb0b47d96 (diff)
UBIFS: introduce new flag for RO due to errors
The R/O state may have various reasons: 1. The UBI volume is R/O 2. The FS is mounted R/O 3. The FS switched to R/O mode because of an error However, in UBIFS we have only one variable which represents cases 1 and 3 - 'c->ro_media'. Indeed, we set this to 1 if we switch to R/O mode due to an error, and then we test it in many places to make sure that we stop writing as soon as the error happens. But this is very unclean. One consequence of this, for example, is that in 'ubifs_remount_fs()' we use 'c->ro_media' to check whether we are in R/O mode because on an error, and we print a message in this case. However, if we are in R/O mode because the media is R/O, our message is bogus. This patch introduces new flag - 'c->ro_error' which is set when we switch to R/O mode because of an error. It also changes all "if (c->ro_media)" checks to "if (c->ro_error)" checks, because this is what the checks actually mean. We do not need to check for 'c->ro_media' because if the UBI volume is in R/O mode, we do not allow R/W mounting, and now writes can happen. This is guaranteed by VFS. But it is good to double-check this, so this patch also adds many "ubifs_assert(!c->ro_media)" checks. In the 'ubifs_remount_fs()' function this patch makes a bit more changes - it fixes the error messages as well. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
-rw-r--r--fs/ubifs/commit.c4
-rw-r--r--fs/ubifs/file.c6
-rw-r--r--fs/ubifs/gc.c3
-rw-r--r--fs/ubifs/io.c16
-rw-r--r--fs/ubifs/journal.c3
-rw-r--r--fs/ubifs/log.c4
-rw-r--r--fs/ubifs/master.c3
-rw-r--r--fs/ubifs/misc.h9
-rw-r--r--fs/ubifs/shrinker.c2
-rw-r--r--fs/ubifs/super.c14
-rw-r--r--fs/ubifs/ubifs.h4
11 files changed, 44 insertions, 24 deletions
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c
index 37fa7ed062d8..712432789fb8 100644
--- a/fs/ubifs/commit.c
+++ b/fs/ubifs/commit.c
@@ -63,7 +63,9 @@ static int do_commit(struct ubifs_info *c)
63 struct ubifs_lp_stats lst; 63 struct ubifs_lp_stats lst;
64 64
65 dbg_cmt("start"); 65 dbg_cmt("start");
66 if (c->ro_media) { 66 ubifs_assert(!c->ro_media);
67
68 if (c->ro_error) {
67 err = -EROFS; 69 err = -EROFS;
68 goto out_up; 70 goto out_up;
69 } 71 }
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 03ae894c45de..c6bc51c9f07c 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -433,8 +433,9 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
433 struct page *page; 433 struct page *page;
434 434
435 ubifs_assert(ubifs_inode(inode)->ui_size == inode->i_size); 435 ubifs_assert(ubifs_inode(inode)->ui_size == inode->i_size);
436 ubifs_assert(!c->ro_media);
436 437
437 if (unlikely(c->ro_media)) 438 if (unlikely(c->ro_error))
438 return -EROFS; 439 return -EROFS;
439 440
440 /* Try out the fast-path part first */ 441 /* Try out the fast-path part first */
@@ -1440,8 +1441,9 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vm
1440 dbg_gen("ino %lu, pg %lu, i_size %lld", inode->i_ino, page->index, 1441 dbg_gen("ino %lu, pg %lu, i_size %lld", inode->i_ino, page->index,
1441 i_size_read(inode)); 1442 i_size_read(inode));
1442 ubifs_assert(!(inode->i_sb->s_flags & MS_RDONLY)); 1443 ubifs_assert(!(inode->i_sb->s_flags & MS_RDONLY));
1444 ubifs_assert(!c->ro_media);
1443 1445
1444 if (unlikely(c->ro_media)) 1446 if (unlikely(c->ro_error))
1445 return VM_FAULT_SIGBUS; /* -EROFS */ 1447 return VM_FAULT_SIGBUS; /* -EROFS */
1446 1448
1447 /* 1449 /*
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c
index 396f24a30af9..d927196d730b 100644
--- a/fs/ubifs/gc.c
+++ b/fs/ubifs/gc.c
@@ -616,13 +616,14 @@ int ubifs_garbage_collect(struct ubifs_info *c, int anyway)
616 struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf; 616 struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
617 617
618 ubifs_assert_cmt_locked(c); 618 ubifs_assert_cmt_locked(c);
619 ubifs_assert(!c->ro_media);
619 620
620 if (ubifs_gc_should_commit(c)) 621 if (ubifs_gc_should_commit(c))
621 return -EAGAIN; 622 return -EAGAIN;
622 623
623 mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); 624 mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead);
624 625
625 if (c->ro_media) { 626 if (c->ro_error) {
626 ret = -EROFS; 627 ret = -EROFS;
627 goto out_unlock; 628 goto out_unlock;
628 } 629 }
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index 9432431bf595..18a4b8d7c844 100644
--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -61,8 +61,8 @@
61 */ 61 */
62void ubifs_ro_mode(struct ubifs_info *c, int err) 62void ubifs_ro_mode(struct ubifs_info *c, int err)
63{ 63{
64 if (!c->ro_media) { 64 if (!c->ro_error) {
65 c->ro_media = 1; 65 c->ro_error = 1;
66 c->no_chk_data_crc = 0; 66 c->no_chk_data_crc = 0;
67 c->vfs_sb->s_flags |= MS_RDONLY; 67 c->vfs_sb->s_flags |= MS_RDONLY;
68 ubifs_warn("switched to read-only mode, error %d", err); 68 ubifs_warn("switched to read-only mode, error %d", err);
@@ -359,8 +359,9 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf)
359 ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY)); 359 ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY));
360 ubifs_assert(!(wbuf->avail & 7)); 360 ubifs_assert(!(wbuf->avail & 7));
361 ubifs_assert(wbuf->offs + c->min_io_size <= c->leb_size); 361 ubifs_assert(wbuf->offs + c->min_io_size <= c->leb_size);
362 ubifs_assert(!c->ro_media);
362 363
363 if (c->ro_media) 364 if (c->ro_error)
364 return -EROFS; 365 return -EROFS;
365 366
366 ubifs_pad(c, wbuf->buf + wbuf->used, wbuf->avail); 367 ubifs_pad(c, wbuf->buf + wbuf->used, wbuf->avail);
@@ -440,11 +441,12 @@ int ubifs_bg_wbufs_sync(struct ubifs_info *c)
440{ 441{
441 int err, i; 442 int err, i;
442 443
444 ubifs_assert(!c->ro_media);
443 if (!c->need_wbuf_sync) 445 if (!c->need_wbuf_sync)
444 return 0; 446 return 0;
445 c->need_wbuf_sync = 0; 447 c->need_wbuf_sync = 0;
446 448
447 if (c->ro_media) { 449 if (c->ro_error) {
448 err = -EROFS; 450 err = -EROFS;
449 goto out_timers; 451 goto out_timers;
450 } 452 }
@@ -519,6 +521,7 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
519 ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size); 521 ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size);
520 ubifs_assert(wbuf->avail > 0 && wbuf->avail <= c->min_io_size); 522 ubifs_assert(wbuf->avail > 0 && wbuf->avail <= c->min_io_size);
521 ubifs_assert(mutex_is_locked(&wbuf->io_mutex)); 523 ubifs_assert(mutex_is_locked(&wbuf->io_mutex));
524 ubifs_assert(!c->ro_media);
522 525
523 if (c->leb_size - wbuf->offs - wbuf->used < aligned_len) { 526 if (c->leb_size - wbuf->offs - wbuf->used < aligned_len) {
524 err = -ENOSPC; 527 err = -ENOSPC;
@@ -527,7 +530,7 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
527 530
528 cancel_wbuf_timer_nolock(wbuf); 531 cancel_wbuf_timer_nolock(wbuf);
529 532
530 if (c->ro_media) 533 if (c->ro_error)
531 return -EROFS; 534 return -EROFS;
532 535
533 if (aligned_len <= wbuf->avail) { 536 if (aligned_len <= wbuf->avail) {
@@ -663,8 +666,9 @@ int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum,
663 buf_len); 666 buf_len);
664 ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0); 667 ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
665 ubifs_assert(offs % c->min_io_size == 0 && offs < c->leb_size); 668 ubifs_assert(offs % c->min_io_size == 0 && offs < c->leb_size);
669 ubifs_assert(!c->ro_media);
666 670
667 if (c->ro_media) 671 if (c->ro_error)
668 return -EROFS; 672 return -EROFS;
669 673
670 ubifs_prepare_node(c, buf, len, 1); 674 ubifs_prepare_node(c, buf, len, 1);
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c
index d321baeca68d..a6da8aa68f37 100644
--- a/fs/ubifs/journal.c
+++ b/fs/ubifs/journal.c
@@ -122,11 +122,12 @@ static int reserve_space(struct ubifs_info *c, int jhead, int len)
122 * better to try to allocate space at the ends of eraseblocks. This is 122 * better to try to allocate space at the ends of eraseblocks. This is
123 * what the squeeze parameter does. 123 * what the squeeze parameter does.
124 */ 124 */
125 ubifs_assert(!c->ro_media);
125 squeeze = (jhead == BASEHD); 126 squeeze = (jhead == BASEHD);
126again: 127again:
127 mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead); 128 mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead);
128 129
129 if (c->ro_media) { 130 if (c->ro_error) {
130 err = -EROFS; 131 err = -EROFS;
131 goto out_unlock; 132 goto out_unlock;
132 } 133 }
diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c
index c345e125f42c..a41713e2fbb3 100644
--- a/fs/ubifs/log.c
+++ b/fs/ubifs/log.c
@@ -223,8 +223,8 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)
223 } 223 }
224 224
225 mutex_lock(&c->log_mutex); 225 mutex_lock(&c->log_mutex);
226 226 ubifs_assert(!c->ro_media);
227 if (c->ro_media) { 227 if (c->ro_error) {
228 err = -EROFS; 228 err = -EROFS;
229