[U-Boot] [PATCH v3] Enable journal replay for UBIFS

2015-01-20 Thread Anton Habegger
Hello Heiko

Thank you fro the review. I added atomic_long_read in ubifs.h as 
for other atomic operations.

I hope (but I can't garantee) by this time the mail is well
formed. If not please tell me again.

During mount_ubifs the ubifs_replay_journal was disabled. This patch
enables it again and fix some unrecoverable UBIFS volumes.

Signed-off-by: Anton Habegger anton.habeg...@delta-es.com
---
 fs/ubifs/Makefile |   2 +-
 fs/ubifs/gc.c | 987 ++
 fs/ubifs/replay.c |   4 -
 fs/ubifs/super.c  |   8 +-
 fs/ubifs/tnc.c|   2 -
 fs/ubifs/ubifs.h  |   1 +
 6 files changed, 990 insertions(+), 14 deletions(-)
 create mode 100644 fs/ubifs/gc.c

diff --git a/fs/ubifs/Makefile b/fs/ubifs/Makefile
index 8c8c6ac..5efb349 100644
--- a/fs/ubifs/Makefile
+++ b/fs/ubifs/Makefile
@@ -12,4 +12,4 @@
 obj-y := ubifs.o io.o super.o sb.o master.o lpt.o
 obj-y += lpt_commit.o scan.o lprops.o
 obj-y += tnc.o tnc_misc.o debug.o crc16.o budget.o
-obj-y += log.o orphan.o recovery.o replay.o
+obj-y += log.o orphan.o recovery.o replay.o gc.o
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c
new file mode 100644
index 000..159ee67
--- /dev/null
+++ b/fs/ubifs/gc.c
@@ -0,0 +1,987 @@
+/*
+ * This file is part of UBIFS.
+ *
+ * Copyright (C) 2006-2008 Nokia Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Adrian Hunter
+ *  Artem Bityutskiy (Битюцкий Артём)
+ */
+
+/*
+ * This file implements garbage collection. The procedure for garbage 
collection
+ * is different depending on whether a LEB as an index LEB (contains index
+ * nodes) or not. For non-index LEBs, garbage collection finds a LEB which
+ * contains a lot of dirty space (obsolete nodes), and copies the non-obsolete
+ * nodes to the journal, at which point the garbage-collected LEB is free to be
+ * reused. For index LEBs, garbage collection marks the non-obsolete index 
nodes
+ * dirty in the TNC, and after the next commit, the garbage-collected LEB is
+ * to be reused. Garbage collection will cause the number of dirty index nodes
+ * to grow, however sufficient space is reserved for the index to ensure the
+ * commit will never run out of space.
+ *
+ * Notes about dead watermark. At current UBIFS implementation we assume that
+ * LEBs which have less than @c-dead_wm bytes of free + dirty space are full
+ * and not worth garbage-collecting. The dead watermark is one min. I/O unit
+ * size, or min. UBIFS node size, depending on what is greater. Indeed, UBIFS
+ * Garbage Collector has to synchronize the GC head's write buffer before
+ * returning, so this is about wasting one min. I/O unit. However, UBIFS GC can
+ * actually reclaim even very small pieces of dirty space by garbage collecting
+ * enough dirty LEBs, but we do not bother doing this at this implementation.
+ *
+ * Notes about dark watermark. The results of GC work depends on how big are
+ * the UBIFS nodes GC deals with. Large nodes make GC waste more space. Indeed,
+ * if GC move data from LEB A to LEB B and nodes in LEB A are large, GC would
+ * have to waste large pieces of free space at the end of LEB B, because nodes
+ * from LEB A would not fit. And the worst situation is when all nodes are of
+ * maximum size. So dark watermark is the amount of free + dirty space in LEB
+ * which are guaranteed to be reclaimable. If LEB has less space, the GC might
+ * be unable to reclaim it. So, LEBs with free + dirty greater than dark
+ * watermark are good LEBs from GC's point of few. The other LEBs are not so
+ * good, and GC takes extra care when moving them.
+ */
+#ifndef __UBOOT__
+#include linux/slab.h
+#include linux/pagemap.h
+#include linux/list_sort.h
+#endif
+#include ubifs.h
+
+#ifndef __UBOOT__
+/*
+ * GC may need to move more than one LEB to make progress. The below constants
+ * define soft and hard limits on the number of LEBs the garbage collector
+ * may move.
+ */
+#define SOFT_LEBS_LIMIT 4
+#define HARD_LEBS_LIMIT 32
+
+/**
+ * switch_gc_head - switch the garbage collection journal head.
+ * @c: UBIFS file-system description object
+ * @buf: buffer to write
+ * @len: length of the buffer to write
+ * @lnum: LEB number written is returned here
+ * @offs: offset written is returned here
+ *
+ * This function switch the GC head to the next LEB which is reserved in
+ * @c-gc_lnum. Returns %0 in case of success, 

Re: [U-Boot] [PATCH v3] Enable journal replay for UBIFS

2015-01-20 Thread Heiko Schocher

Hello Anton,

Am 20.01.2015 15:22, schrieb Anton Habegger:

Hello Heiko

Thank you fro the review. I added atomic_long_read in ubifs.h as
for other atomic operations.


Hmm.. I see, there are other missing atomic defines for UBI also ...
Ok, I tend to accept your patch, but the correct way would
be to import include/asm-generic/atomic-long.h from linux
and drop this definitions in ubifs.h ... Could you prepare
such a second patch?


I hope (but I can't garantee) by this time the mail is well
formed. If not please tell me again.


It looks good now!


During mount_ubifs the ubifs_replay_journal was disabled. This patch
enables it again and fix some unrecoverable UBIFS volumes.


nitpick ... Sorry, this is not a valid commit message ... please look at

http://www.denx.de/wiki/view/U-Boot/Patches

how to write a commit message. Please add comments to your patch
under a --- line, and provide a patch history ... add also a
hint from which linux version you picked up the new file fs/ubifs/gc.c

Current version of the other MTD/UBI/UBIFS files is

1860e379875df: Linux 3.15

Could you use this as base for your patch?

Thanks!


Signed-off-by: Anton Habegger anton.habeg...@delta-es.com
---
  fs/ubifs/Makefile |   2 +-
  fs/ubifs/gc.c | 987 ++
  fs/ubifs/replay.c |   4 -
  fs/ubifs/super.c  |   8 +-
  fs/ubifs/tnc.c|   2 -
  fs/ubifs/ubifs.h  |   1 +
  6 files changed, 990 insertions(+), 14 deletions(-)
  create mode 100644 fs/ubifs/gc.c


Compiling current mainline with your patch drops the follwoing
warning:


  CC  fs/ubifs/tnc.o
fs/ubifs/tnc.c: In function 'ubifs_tnc_close':
fs/ubifs/tnc.c:2861:8: warning: variable 'n' set but not used 
[-Wunused-but-set-variable]

Could you please fix this too? Thanks!

Beside of this nitpicks, your patch looks good.

bye,
Heiko


diff --git a/fs/ubifs/Makefile b/fs/ubifs/Makefile
index 8c8c6ac..5efb349 100644
--- a/fs/ubifs/Makefile
+++ b/fs/ubifs/Makefile
@@ -12,4 +12,4 @@
  obj-y := ubifs.o io.o super.o sb.o master.o lpt.o
  obj-y += lpt_commit.o scan.o lprops.o
  obj-y += tnc.o tnc_misc.o debug.o crc16.o budget.o
-obj-y += log.o orphan.o recovery.o replay.o
+obj-y += log.o orphan.o recovery.o replay.o gc.o
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c
new file mode 100644
index 000..159ee67
--- /dev/null
+++ b/fs/ubifs/gc.c
@@ -0,0 +1,987 @@
+/*
+ * This file is part of UBIFS.
+ *
+ * Copyright (C) 2006-2008 Nokia Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Adrian Hunter
+ *  Artem Bityutskiy (Битюцкий Артём)
+ */
+
+/*
+ * This file implements garbage collection. The procedure for garbage 
collection
+ * is different depending on whether a LEB as an index LEB (contains index
+ * nodes) or not. For non-index LEBs, garbage collection finds a LEB which
+ * contains a lot of dirty space (obsolete nodes), and copies the non-obsolete
+ * nodes to the journal, at which point the garbage-collected LEB is free to be
+ * reused. For index LEBs, garbage collection marks the non-obsolete index 
nodes
+ * dirty in the TNC, and after the next commit, the garbage-collected LEB is
+ * to be reused. Garbage collection will cause the number of dirty index nodes
+ * to grow, however sufficient space is reserved for the index to ensure the
+ * commit will never run out of space.
+ *
+ * Notes about dead watermark. At current UBIFS implementation we assume that
+ * LEBs which have less than @c-dead_wm bytes of free + dirty space are full
+ * and not worth garbage-collecting. The dead watermark is one min. I/O unit
+ * size, or min. UBIFS node size, depending on what is greater. Indeed, UBIFS
+ * Garbage Collector has to synchronize the GC head's write buffer before
+ * returning, so this is about wasting one min. I/O unit. However, UBIFS GC can
+ * actually reclaim even very small pieces of dirty space by garbage collecting
+ * enough dirty LEBs, but we do not bother doing this at this implementation.
+ *
+ * Notes about dark watermark. The results of GC work depends on how big are
+ * the UBIFS nodes GC deals with. Large nodes make GC waste more space. Indeed,
+ * if GC move data from LEB A to LEB B and nodes in LEB A are large, GC would
+ * have to waste large pieces of free space at the end of LEB B, because nodes
+ * from LEB A would not fit. And the worst situation is when all