aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/ubi/eba.c
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2007-08-29 07:51:52 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2007-10-14 06:10:21 -0400
commite88d6e10e5c848fd5be8f89e09e3bce2570886b7 (patch)
tree27b5547a0e24add89deafedaed784328bc3c173e /drivers/mtd/ubi/eba.c
parent33818bbb84cd371b63ed8849cc5264d24c8b3aa2 (diff)
UBI: do not use vmalloc on I/O path
Similar reason as in case of the previous patch: it causes deadlocks if a filesystem with writeback support works on top of UBI. So pre-allocate needed buffers when attaching MTD device. We also need mutexes to protect the buffers, but they do not cause much contantion because they are used in recovery, torture, and WL copy routines, which are called seldom. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'drivers/mtd/ubi/eba.c')
-rw-r--r--drivers/mtd/ubi/eba.c70
1 files changed, 24 insertions, 46 deletions
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
index 89193104c6c8..81bb6a33b555 100644
--- a/drivers/mtd/ubi/eba.c
+++ b/drivers/mtd/ubi/eba.c
@@ -495,16 +495,18 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
495 int err, idx = vol_id2idx(ubi, vol_id), new_pnum, data_size, tries = 0; 495 int err, idx = vol_id2idx(ubi, vol_id), new_pnum, data_size, tries = 0;
496 struct ubi_volume *vol = ubi->volumes[idx]; 496 struct ubi_volume *vol = ubi->volumes[idx];
497 struct ubi_vid_hdr *vid_hdr; 497 struct ubi_vid_hdr *vid_hdr;
498 unsigned char *new_buf;
499 498
500 vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); 499 vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
501 if (!vid_hdr) { 500 if (!vid_hdr) {
502 return -ENOMEM; 501 return -ENOMEM;
503 } 502 }
504 503
504 mutex_lock(&ubi->buf_mutex);
505
505retry: 506retry:
506 new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN); 507 new_pnum = ubi_wl_get_peb(ubi, UBI_UNKNOWN);
507 if (new_pnum < 0) { 508 if (new_pnum < 0) {
509 mutex_unlock(&ubi->buf_mutex);
508 ubi_free_vid_hdr(ubi, vid_hdr); 510 ubi_free_vid_hdr(ubi, vid_hdr);
509 return new_pnum; 511 return new_pnum;
510 } 512 }
@@ -524,31 +526,22 @@ retry:
524 goto write_error; 526 goto write_error;
525 527
526 data_size = offset + len; 528 data_size = offset + len;
527 new_buf = vmalloc(data_size); 529 memset(ubi->peb_buf1 + offset, 0xFF, len);
528 if (!new_buf) {
529 err = -ENOMEM;
530 goto out_put;
531 }
532 memset(new_buf + offset, 0xFF, len);
533 530
534 /* Read everything before the area where the write failure happened */ 531 /* Read everything before the area where the write failure happened */
535 if (offset > 0) { 532 if (offset > 0) {
536 err = ubi_io_read_data(ubi, new_buf, pnum, 0, offset); 533 err = ubi_io_read_data(ubi, ubi->peb_buf1, pnum, 0, offset);
537 if (err && err != UBI_IO_BITFLIPS) { 534 if (err && err != UBI_IO_BITFLIPS)
538 vfree(new_buf);
539 goto out_put; 535 goto out_put;
540 }
541 } 536 }
542 537
543 memcpy(new_buf + offset, buf, len); 538 memcpy(ubi->peb_buf1 + offset, buf, len);
544 539
545 err = ubi_io_write_data(ubi, new_buf, new_pnum, 0, data_size); 540 err = ubi_io_write_data(ubi, ubi->peb_buf1, new_pnum, 0, data_size);
546 if (err) { 541 if (err)
547 vfree(new_buf);
548 goto write_error; 542 goto write_error;
549 }
550 543
551 vfree(new_buf); 544 mutex_unlock(&ubi->buf_mutex);
552 ubi_free_vid_hdr(ubi, vid_hdr); 545 ubi_free_vid_hdr(ubi, vid_hdr);
553 546
554 vol->eba_tbl[lnum] = new_pnum; 547 vol->eba_tbl[lnum] = new_pnum;
@@ -558,6 +551,7 @@ retry:
558 return 0; 551 return 0;
559 552
560out_put: 553out_put:
554 mutex_unlock(&ubi->buf_mutex);
561 ubi_wl_put_peb(ubi, new_pnum, 1); 555 ubi_wl_put_peb(ubi, new_pnum, 1);
562 ubi_free_vid_hdr(ubi, vid_hdr); 556 ubi_free_vid_hdr(ubi, vid_hdr);
563 return err; 557 return err;
@@ -570,6 +564,7 @@ write_error:
570 ubi_warn("failed to write to PEB %d", new_pnum); 564 ubi_warn("failed to write to PEB %d", new_pnum);
571 ubi_wl_put_peb(ubi, new_pnum, 1); 565 ubi_wl_put_peb(ubi, new_pnum, 1);
572 if (++tries > UBI_IO_RETRIES) { 566 if (++tries > UBI_IO_RETRIES) {
567 mutex_unlock(&ubi->buf_mutex);
573 ubi_free_vid_hdr(ubi, vid_hdr); 568 ubi_free_vid_hdr(ubi, vid_hdr);
574 return err; 569 return err;
575 } 570 }
@@ -965,7 +960,6 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
965 int err, vol_id, lnum, data_size, aldata_size, pnum, idx; 960 int err, vol_id, lnum, data_size, aldata_size, pnum, idx;
966 struct ubi_volume *vol; 961 struct ubi_volume *vol;
967 uint32_t crc; 962 uint32_t crc;
968 void *buf, *buf1 = NULL;
969 963
970 vol_id = be32_to_cpu(vid_hdr->vol_id); 964 vol_id = be32_to_cpu(vid_hdr->vol_id);
971 lnum = be32_to_cpu(vid_hdr->lnum); 965 lnum = be32_to_cpu(vid_hdr->lnum);
@@ -979,19 +973,15 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
979 data_size = aldata_size = 973 data_size = aldata_size =
980 ubi->leb_size - be32_to_cpu(vid_hdr->data_pad); 974 ubi->leb_size - be32_to_cpu(vid_hdr->data_pad);
981 975
982 buf = vmalloc(aldata_size);
983 if (!buf)
984 return -ENOMEM;
985
986 /* 976 /*
987 * We do not want anybody to write to this logical eraseblock while we 977 * We do not want anybody to write to this logical eraseblock while we
988 * are moving it, so we lock it. 978 * are moving it, so we lock it.
989 */ 979 */
990 err = leb_write_lock(ubi, vol_id, lnum); 980 err = leb_write_lock(ubi, vol_id, lnum);
991 if (err) { 981 if (err)
992 vfree(buf);
993 return err; 982 return err;
994 } 983
984 mutex_lock(&ubi->buf_mutex);
995 985
996 /* 986 /*
997 * But the logical eraseblock might have been put by this time. 987 * But the logical eraseblock might have been put by this time.
@@ -1023,7 +1013,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
1023 /* OK, now the LEB is locked and we can safely start moving it */ 1013 /* OK, now the LEB is locked and we can safely start moving it */
1024 1014
1025 dbg_eba("read %d bytes of data", aldata_size); 1015 dbg_eba("read %d bytes of data", aldata_size);
1026 err = ubi_io_read_data(ubi, buf, from, 0, aldata_size); 1016 err = ubi_io_read_data(ubi, ubi->peb_buf1, from, 0, aldata_size);
1027 if (err && err != UBI_IO_BITFLIPS) { 1017 if (err && err != UBI_IO_BITFLIPS) {
1028 ubi_warn("error %d while reading data from PEB %d", 1018 ubi_warn("error %d while reading data from PEB %d",
1029 err, from); 1019 err, from);
@@ -1042,10 +1032,10 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
1042 */ 1032 */
1043 if (vid_hdr->vol_type == UBI_VID_DYNAMIC) 1033 if (vid_hdr->vol_type == UBI_VID_DYNAMIC)
1044 aldata_size = data_size = 1034 aldata_size = data_size =
1045 ubi_calc_data_len(ubi, buf, data_size); 1035 ubi_calc_data_len(ubi, ubi->peb_buf1, data_size);
1046 1036
1047 cond_resched(); 1037 cond_resched();
1048 crc = crc32(UBI_CRC32_INIT, buf, data_size); 1038 crc = crc32(UBI_CRC32_INIT, ubi->peb_buf1, data_size);
1049 cond_resched(); 1039 cond_resched();
1050 1040
1051 /* 1041 /*
@@ -1076,23 +1066,18 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
1076 } 1066 }
1077 1067
1078 if (data_size > 0) { 1068 if (data_size > 0) {
1079 err = ubi_io_write_data(ubi, buf, to, 0, aldata_size); 1069 err = ubi_io_write_data(ubi, ubi->peb_buf1, to, 0, aldata_size);
1080 if (err) 1070 if (err)
1081 goto out_unlock; 1071 goto out_unlock;
1082 1072
1073 cond_resched();
1074
1083 /* 1075 /*
1084 * We've written the data and are going to read it back to make 1076 * We've written the data and are going to read it back to make
1085 * sure it was written correctly. 1077 * sure it was written correctly.
1086 */ 1078 */
1087 buf1 = vmalloc(aldata_size);
1088 if (!buf1) {
1089 err = -ENOMEM;
1090 goto out_unlock;
1091 }
1092 1079
1093 cond_resched(); 1080 err = ubi_io_read_data(ubi, ubi->peb_buf2, to, 0, aldata_size);
1094
1095 err = ubi_io_read_data(ubi, buf1, to, 0, aldata_size);
1096 if (err) { 1081 if (err) {
1097 if (err != UBI_IO_BITFLIPS) 1082 if (err != UBI_IO_BITFLIPS)
1098 ubi_warn("cannot read data back from PEB %d", 1083 ubi_warn("cannot read data back from PEB %d",
@@ -1102,7 +1087,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
1102 1087
1103 cond_resched(); 1088 cond_resched();
1104 1089
1105 if (memcmp(buf, buf1, aldata_size)) { 1090 if (memcmp(ubi->peb_buf1, ubi->peb_buf2, aldata_size)) {
1106 ubi_warn("read data back from PEB %d - it is different", 1091 ubi_warn("read data back from PEB %d - it is different",
1107 to); 1092 to);
1108 goto out_unlock; 1093 goto out_unlock;
@@ -1112,16 +1097,9 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
1112 ubi_assert(vol->eba_tbl[lnum] == from); 1097 ubi_assert(vol->eba_tbl[lnum] == from);
1113 vol->eba_tbl[lnum] = to; 1098 vol->eba_tbl[lnum] = to;
1114 1099
1115 leb_write_unlock(ubi, vol_id, lnum);
1116 vfree(buf);
1117 vfree(buf1);
1118
1119 return 0;
1120
1121out_unlock: 1100out_unlock:
1101 mutex_unlock(&ubi->buf_mutex);
1122 leb_write_unlock(ubi, vol_id, lnum); 1102 leb_write_unlock(ubi, vol_id, lnum);
1123 vfree(buf);
1124 vfree(buf1);
1125 return err; 1103 return err;
1126} 1104}
1127 1105