diff options
Diffstat (limited to 'fs/ubifs/super.c')
-rw-r--r-- | fs/ubifs/super.c | 80 |
1 files changed, 44 insertions, 36 deletions
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index cd5900b85d38..9a47c9f0ad07 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -1137,11 +1137,11 @@ static int check_free_space(struct ubifs_info *c) | |||
1137 | */ | 1137 | */ |
1138 | static int mount_ubifs(struct ubifs_info *c) | 1138 | static int mount_ubifs(struct ubifs_info *c) |
1139 | { | 1139 | { |
1140 | struct super_block *sb = c->vfs_sb; | 1140 | int err; |
1141 | int err, mounted_read_only = (sb->s_flags & MS_RDONLY); | ||
1142 | long long x; | 1141 | long long x; |
1143 | size_t sz; | 1142 | size_t sz; |
1144 | 1143 | ||
1144 | c->ro_mount = !!(c->vfs_sb->s_flags & MS_RDONLY); | ||
1145 | err = init_constants_early(c); | 1145 | err = init_constants_early(c); |
1146 | if (err) | 1146 | if (err) |
1147 | return err; | 1147 | return err; |
@@ -1154,7 +1154,7 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1154 | if (err) | 1154 | if (err) |
1155 | goto out_free; | 1155 | goto out_free; |
1156 | 1156 | ||
1157 | if (c->empty && (mounted_read_only || c->ro_media)) { | 1157 | if (c->empty && (c->ro_mount || c->ro_media)) { |
1158 | /* | 1158 | /* |
1159 | * This UBI volume is empty, and read-only, or the file system | 1159 | * This UBI volume is empty, and read-only, or the file system |
1160 | * is mounted read-only - we cannot format it. | 1160 | * is mounted read-only - we cannot format it. |
@@ -1165,7 +1165,7 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1165 | goto out_free; | 1165 | goto out_free; |
1166 | } | 1166 | } |
1167 | 1167 | ||
1168 | if (c->ro_media && !mounted_read_only) { | 1168 | if (c->ro_media && !c->ro_mount) { |
1169 | ubifs_err("cannot mount read-write - read-only media"); | 1169 | ubifs_err("cannot mount read-write - read-only media"); |
1170 | err = -EROFS; | 1170 | err = -EROFS; |
1171 | goto out_free; | 1171 | goto out_free; |
@@ -1185,7 +1185,7 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1185 | if (!c->sbuf) | 1185 | if (!c->sbuf) |
1186 | goto out_free; | 1186 | goto out_free; |
1187 | 1187 | ||
1188 | if (!mounted_read_only) { | 1188 | if (!c->ro_mount) { |
1189 | c->ileb_buf = vmalloc(c->leb_size); | 1189 | c->ileb_buf = vmalloc(c->leb_size); |
1190 | if (!c->ileb_buf) | 1190 | if (!c->ileb_buf) |
1191 | goto out_free; | 1191 | goto out_free; |
@@ -1228,7 +1228,7 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1228 | } | 1228 | } |
1229 | 1229 | ||
1230 | sprintf(c->bgt_name, BGT_NAME_PATTERN, c->vi.ubi_num, c->vi.vol_id); | 1230 | sprintf(c->bgt_name, BGT_NAME_PATTERN, c->vi.ubi_num, c->vi.vol_id); |
1231 | if (!mounted_read_only) { | 1231 | if (!c->ro_mount) { |
1232 | err = alloc_wbufs(c); | 1232 | err = alloc_wbufs(c); |
1233 | if (err) | 1233 | if (err) |
1234 | goto out_cbuf; | 1234 | goto out_cbuf; |
@@ -1254,12 +1254,12 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1254 | if ((c->mst_node->flags & cpu_to_le32(UBIFS_MST_DIRTY)) != 0) { | 1254 | if ((c->mst_node->flags & cpu_to_le32(UBIFS_MST_DIRTY)) != 0) { |
1255 | ubifs_msg("recovery needed"); | 1255 | ubifs_msg("recovery needed"); |
1256 | c->need_recovery = 1; | 1256 | c->need_recovery = 1; |
1257 | if (!mounted_read_only) { | 1257 | if (!c->ro_mount) { |
1258 | err = ubifs_recover_inl_heads(c, c->sbuf); | 1258 | err = ubifs_recover_inl_heads(c, c->sbuf); |
1259 | if (err) | 1259 | if (err) |
1260 | goto out_master; | 1260 | goto out_master; |
1261 | } | 1261 | } |
1262 | } else if (!mounted_read_only) { | 1262 | } else if (!c->ro_mount) { |
1263 | /* | 1263 | /* |
1264 | * Set the "dirty" flag so that if we reboot uncleanly we | 1264 | * Set the "dirty" flag so that if we reboot uncleanly we |
1265 | * will notice this immediately on the next mount. | 1265 | * will notice this immediately on the next mount. |
@@ -1270,7 +1270,7 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1270 | goto out_master; | 1270 | goto out_master; |
1271 | } | 1271 | } |
1272 | 1272 | ||
1273 | err = ubifs_lpt_init(c, 1, !mounted_read_only); | 1273 | err = ubifs_lpt_init(c, 1, !c->ro_mount); |
1274 | if (err) | 1274 | if (err) |
1275 | goto out_lpt; | 1275 | goto out_lpt; |
1276 | 1276 | ||
@@ -1285,11 +1285,11 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1285 | /* Calculate 'min_idx_lebs' after journal replay */ | 1285 | /* Calculate 'min_idx_lebs' after journal replay */ |
1286 | c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); | 1286 | c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); |
1287 | 1287 | ||
1288 | err = ubifs_mount_orphans(c, c->need_recovery, mounted_read_only); | 1288 | err = ubifs_mount_orphans(c, c->need_recovery, c->ro_mount); |
1289 | if (err) | 1289 | if (err) |
1290 | goto out_orphans; | 1290 | goto out_orphans; |
1291 | 1291 | ||
1292 | if (!mounted_read_only) { | 1292 | if (!c->ro_mount) { |
1293 | int lnum; | 1293 | int lnum; |
1294 | 1294 | ||
1295 | err = check_free_space(c); | 1295 | err = check_free_space(c); |
@@ -1351,7 +1351,7 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1351 | spin_unlock(&ubifs_infos_lock); | 1351 | spin_unlock(&ubifs_infos_lock); |
1352 | 1352 | ||
1353 | if (c->need_recovery) { | 1353 | if (c->need_recovery) { |
1354 | if (mounted_read_only) | 1354 | if (c->ro_mount) |
1355 | ubifs_msg("recovery deferred"); | 1355 | ubifs_msg("recovery deferred"); |
1356 | else { | 1356 | else { |
1357 | c->need_recovery = 0; | 1357 | c->need_recovery = 0; |
@@ -1378,7 +1378,7 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1378 | 1378 | ||
1379 | ubifs_msg("mounted UBI device %d, volume %d, name \"%s\"", | 1379 | ubifs_msg("mounted UBI device %d, volume %d, name \"%s\"", |
1380 | c->vi.ubi_num, c->vi.vol_id, c->vi.name); | 1380 | c->vi.ubi_num, c->vi.vol_id, c->vi.name); |
1381 | if (mounted_read_only) | 1381 | if (c->ro_mount) |
1382 | ubifs_msg("mounted read-only"); | 1382 | ubifs_msg("mounted read-only"); |
1383 | x = (long long)c->main_lebs * c->leb_size; | 1383 | x = (long long)c->main_lebs * c->leb_size; |
1384 | ubifs_msg("file system size: %lld bytes (%lld KiB, %lld MiB, %d " | 1384 | ubifs_msg("file system size: %lld bytes (%lld KiB, %lld MiB, %d " |
@@ -1640,7 +1640,7 @@ static int ubifs_remount_rw(struct ubifs_info *c) | |||
1640 | } | 1640 | } |
1641 | 1641 | ||
1642 | dbg_gen("re-mounted read-write"); | 1642 | dbg_gen("re-mounted read-write"); |
1643 | c->vfs_sb->s_flags &= ~MS_RDONLY; | 1643 | c->ro_mount = 0; |
1644 | c->remounting_rw = 0; | 1644 | c->remounting_rw = 0; |
1645 | c->always_chk_crc = 0; | 1645 | c->always_chk_crc = 0; |
1646 | err = dbg_check_space_info(c); | 1646 | err = dbg_check_space_info(c); |
@@ -1676,7 +1676,7 @@ static void ubifs_remount_ro(struct ubifs_info *c) | |||
1676 | int i, err; | 1676 | int i, err; |
1677 | 1677 | ||
1678 | ubifs_assert(!c->need_recovery); | 1678 | ubifs_assert(!c->need_recovery); |
1679 | ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY)); | 1679 | ubifs_assert(!c->ro_mount); |
1680 | 1680 | ||
1681 | mutex_lock(&c->umount_mutex); | 1681 | mutex_lock(&c->umount_mutex); |
1682 | if (c->bgt) { | 1682 | if (c->bgt) { |
@@ -1686,10 +1686,8 @@ static void ubifs_remount_ro(struct ubifs_info *c) | |||
1686 | 1686 | ||
1687 | dbg_save_space_info(c); | 1687 | dbg_save_space_info(c); |
1688 | 1688 | ||
1689 | for (i = 0; i < c->jhead_cnt; i++) { | 1689 | for (i = 0; i < c->jhead_cnt; i++) |
1690 | ubifs_wbuf_sync(&c->jheads[i].wbuf); | 1690 | ubifs_wbuf_sync(&c->jheads[i].wbuf); |
1691 | hrtimer_cancel(&c->jheads[i].wbuf.timer); | ||
1692 | } | ||
1693 | 1691 | ||
1694 | c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY); | 1692 | c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY); |
1695 | c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS); | 1693 | c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS); |
@@ -1704,6 +1702,7 @@ static void ubifs_remount_ro(struct ubifs_info *c) | |||
1704 | vfree(c->ileb_buf); | 1702 | vfree(c->ileb_buf); |
1705 | c->ileb_buf = NULL; | 1703 | c->ileb_buf = NULL; |
1706 | ubifs_lpt_free(c, 1); | 1704 | ubifs_lpt_free(c, 1); |
1705 | c->ro_mount = 1; | ||
1707 | err = dbg_check_space_info(c); | 1706 | err = dbg_check_space_info(c); |
1708 | if (err) | 1707 | if (err) |
1709 | ubifs_ro_mode(c, err); | 1708 | ubifs_ro_mode(c, err); |
@@ -1735,7 +1734,7 @@ static void ubifs_put_super(struct super_block *sb) | |||
1735 | * the mutex is locked. | 1734 | * the mutex is locked. |
1736 | */ | 1735 | */ |
1737 | mutex_lock(&c->umount_mutex); | 1736 | mutex_lock(&c->umount_mutex); |
1738 | if (!(c->vfs_sb->s_flags & MS_RDONLY)) { | 1737 | if (!c->ro_mount) { |
1739 | /* | 1738 | /* |
1740 | * First of all kill the background thread to make sure it does | 1739 | * First of all kill the background thread to make sure it does |
1741 | * not interfere with un-mounting and freeing resources. | 1740 | * not interfere with un-mounting and freeing resources. |
@@ -1745,23 +1744,22 @@ static void ubifs_put_super(struct super_block *sb) | |||
1745 | c->bgt = NULL; | 1744 | c->bgt = NULL; |
1746 | } | 1745 | } |
1747 | 1746 | ||
1748 | /* Synchronize write-buffers */ | ||
1749 | if (c->jheads) | ||
1750 | for (i = 0; i < c->jhead_cnt; i++) | ||
1751 | ubifs_wbuf_sync(&c->jheads[i].wbuf); | ||
1752 | |||
1753 | /* | 1747 | /* |
1754 | * On fatal errors c->ro_media is set to 1, in which case we do | 1748 | * On fatal errors c->ro_error is set to 1, in which case we do |
1755 | * not write the master node. | 1749 | * not write the master node. |
1756 | */ | 1750 | */ |
1757 | if (!c->ro_media) { | 1751 | if (!c->ro_error) { |
1752 | int err; | ||
1753 | |||
1754 | /* Synchronize write-buffers */ | ||
1755 | for (i = 0; i < c->jhead_cnt; i++) | ||
1756 | ubifs_wbuf_sync(&c->jheads[i].wbuf); | ||
1757 | |||
1758 | /* | 1758 | /* |
1759 | * We are being cleanly unmounted which means the | 1759 | * We are being cleanly unmounted which means the |
1760 | * orphans were killed - indicate this in the master | 1760 | * orphans were killed - indicate this in the master |
1761 | * node. Also save the reserved GC LEB number. | 1761 | * node. Also save the reserved GC LEB number. |
1762 | */ | 1762 | */ |
1763 | int err; | ||
1764 | |||
1765 | c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY); | 1763 | c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY); |
1766 | c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS); | 1764 | c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS); |
1767 | c->mst_node->gc_lnum = cpu_to_le32(c->gc_lnum); | 1765 | c->mst_node->gc_lnum = cpu_to_le32(c->gc_lnum); |
@@ -1774,6 +1772,10 @@ static void ubifs_put_super(struct super_block *sb) | |||
1774 | */ | 1772 | */ |
1775 | ubifs_err("failed to write master node, " | 1773 | ubifs_err("failed to write master node, " |
1776 | "error %d", err); | 1774 | "error %d", err); |
1775 | } else { | ||
1776 | for (i = 0; i < c->jhead_cnt; i++) | ||
1777 | /* Make sure write-buffer timers are canceled */ | ||
1778 | hrtimer_cancel(&c->jheads[i].wbuf.timer); | ||
1777 | } | 1779 | } |
1778 | } | 1780 | } |
1779 | 1781 | ||
@@ -1797,17 +1799,21 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) | |||
1797 | return err; | 1799 | return err; |
1798 | } | 1800 | } |
1799 | 1801 | ||
1800 | if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { | 1802 | if (c->ro_mount && !(*flags & MS_RDONLY)) { |
1803 | if (c->ro_error) { | ||
1804 | ubifs_msg("cannot re-mount R/W due to prior errors"); | ||
1805 | return -EROFS; | ||
1806 | } | ||
1801 | if (c->ro_media) { | 1807 | if (c->ro_media) { |
1802 | ubifs_msg("cannot re-mount due to prior errors"); | 1808 | ubifs_msg("cannot re-mount R/W - UBI volume is R/O"); |
1803 | return -EROFS; | 1809 | return -EROFS; |
1804 | } | 1810 | } |
1805 | err = ubifs_remount_rw(c); | 1811 | err = ubifs_remount_rw(c); |
1806 | if (err) | 1812 | if (err) |
1807 | return err; | 1813 | return err; |
1808 | } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) { | 1814 | } else if (!c->ro_mount && (*flags & MS_RDONLY)) { |
1809 | if (c->ro_media) { | 1815 | if (c->ro_error) { |
1810 | ubifs_msg("cannot re-mount due to prior errors"); | 1816 | ubifs_msg("cannot re-mount R/O due to prior errors"); |
1811 | return -EROFS; | 1817 | return -EROFS; |
1812 | } | 1818 | } |
1813 | ubifs_remount_ro(c); | 1819 | ubifs_remount_ro(c); |
@@ -2049,8 +2055,8 @@ static int ubifs_get_sb(struct file_system_type *fs_type, int flags, | |||
2049 | */ | 2055 | */ |
2050 | ubi = open_ubi(name, UBI_READONLY); | 2056 | ubi = open_ubi(name, UBI_READONLY); |
2051 | if (IS_ERR(ubi)) { | 2057 | if (IS_ERR(ubi)) { |
2052 | ubifs_err("cannot open \"%s\", error %d", | 2058 | dbg_err("cannot open \"%s\", error %d", |
2053 | name, (int)PTR_ERR(ubi)); | 2059 | name, (int)PTR_ERR(ubi)); |
2054 | return PTR_ERR(ubi); | 2060 | return PTR_ERR(ubi); |
2055 | } | 2061 | } |
2056 | ubi_get_volume_info(ubi, &vi); | 2062 | ubi_get_volume_info(ubi, &vi); |
@@ -2064,9 +2070,11 @@ static int ubifs_get_sb(struct file_system_type *fs_type, int flags, | |||
2064 | } | 2070 | } |
2065 | 2071 | ||
2066 | if (sb->s_root) { | 2072 | if (sb->s_root) { |
2073 | struct ubifs_info *c1 = sb->s_fs_info; | ||
2074 | |||
2067 | /* A new mount point for already mounted UBIFS */ | 2075 | /* A new mount point for already mounted UBIFS */ |
2068 | dbg_gen("this ubi volume is already mounted"); | 2076 | dbg_gen("this ubi volume is already mounted"); |
2069 | if ((flags ^ sb->s_flags) & MS_RDONLY) { | 2077 | if (!!(flags & MS_RDONLY) != c1->ro_mount) { |
2070 | err = -EBUSY; | 2078 | err = -EBUSY; |
2071 | goto out_deact; | 2079 | goto out_deact; |
2072 | } | 2080 | } |