Skip to contentSkip to conversation

reiserfsprogs patch queue

PATCH In review [email protected] 3 participants 23 messages Jan 24, 2008 – Jan 9, 2009 Library code

lore
Share & tools
lore
#0 lore raw

cover reiserfsprogs patch queue

This patch queue consists of 9 patches and brings the official reiserfsprogs mostly in line with the SUSE version.

Please apply.

-Jeff

--
Jeff Mahoney
SUSE Labs

#1 lore raw

PATCH 1/9 reiserfsprogs: QUIET_MODE should silence credits too

This patch allows -q to silence the output of the credits information.

---
 mkreiserfs/mkreiserfs.c |   13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)
mkreiserfs/mkreiserfs.c +5 -8
@@ -656,8 +656,10 @@ int main (int argc, char **argv)
 
     print_banner (program_name);
 
-    misc_print_credit(stdout);
-    printf("\n");
+    if (!(mode & QUIET_MODE)) {
+	misc_print_credit(stdout);
+	printf("\n");
+    }
     
     if (mode & QUIET_MODE)
 	fclose(stdout);
@@ -740,7 +742,6 @@ int main (int argc, char **argv)
 
 
     invalidate_other_formats (fs->fs_dev);
-
     zero_journal (fs);
 
     reiserfs_close (fs);
@@ -751,11 +752,7 @@ int main (int argc, char **argv)
  
     if (mode & DEBUG_MODE)
 	return 0;
-    
-    printf("\nTell your friends to use a kernel based on 2.4.18 or "
-	"later, and especially not a\nkernel based on 2.4.9, "
-	"when you use reiserFS. Have fun.\n\n");
-        
+
     printf("ReiserFS is successfully created on %s.\n", device_name);
 
     return 0;
#2 lore raw

PATCH 2/9 reiserfsprogs: Warn on block sizes > 4k

In reply to [email protected]

Filesystems created with block size > page size will not work until that support is added to the kernel. Filesystems with block size > 4k (lowest page size supported in Linux) will not work on all systems. This patch adds a check and a warning in those conditions, informing the user of the caveats of using a larger block size. It can be overridden with -f.

---
 mkreiserfs/mkreiserfs.c    |    3 +++
 reiserfscore/reiserfslib.c |   18 ++++++++++++++++++
 2 files changed, 21 insertions(+)
mkreiserfs/mkreiserfs.c +3 -0
@@ -686,6 +686,9 @@ int main (int argc, char **argv)
     
     if (!(mode & QUIET_MODE) && !can_we_format_it (device_name, force))
         return 1;
+
+    if (!(mode & QUIET_MODE) && !block_size_ok (Block_size, force))
+        return 1;
 	
     if (jdevice_name)
         if (!(mode & QUIET_MODE) && !can_we_format_it (jdevice_name, force))
reiserfscore/reiserfslib.c +18 -0
@@ -1175,6 +1175,24 @@ void make_sure_root_dir_exists (reiserfs
     		&parent_root_dir_key, ih_flags);
 }
 
+int block_size_ok (int blocksize, int force)
+{
+    int pagesize = getpagesize();
+    if (blocksize > 4096) {
+        reiserfs_warning (stderr, "Block sizes larger than 4k are not "
+                          "supported on all architectures.\n");
+        if (blocksize > pagesize)
+            reiserfs_warning (stderr, "The newly created filesystem will not "
+                              "be mountable on this system.\n");
+        else
+            reiserfs_warning (stderr, "The newly created filesystem may not "
+                              "be mountable on other systems.\n");
+        check_forcing_ask_confirmation (force);
+    }
+
+    return 1;
+}
+
 
 /* we only can use a file for filesystem or journal if it is either not
    mounted block device or regular file and we are forced to use it */
#3 lore raw

PATCH 3/9 reiserfsprogs: id_map_init off-by-one

In reply to [email protected]

The following patch fixes a bug where reiserfsck will crash if OIDs up around the maximum are in use. The problem is that INDEX_COUNT ends up rounding down and the last chunk isn't allocated, causing a segfault.

---
 fsck/uobjectid.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fsck/uobjectid.c +1 -1
@@ -15,7 +15,7 @@
 /* 2 bytes for the counter */
 #define BM_SIZE				(ALLOC_SIZE - sizeof(__u16))
 #define BM_INTERVAL			(BM_SIZE * 8)
-#define INDEX_COUNT			(MAX_ID / BM_INTERVAL)
+#define INDEX_COUNT			((MAX_ID / BM_INTERVAL) + 1)
 
 #define id_map_interval(map, id)	(map->index + (id / BM_INTERVAL))
 
#4 lore raw

PATCH 4/9 reiserfsprogs: changes for better external journal defaults

In reply to [email protected]

Currently, when presented with an external journal device, reiserfsprogs will use the entire device. This is fine when the external device is, say, a 128 MB NVRAM "disk", but when it is another external partition it can cause problems on 32-bit machines and 64-bit machines with limited memory capacity.

This patch does a few things, all related:
* It changes the default external journal size to be journal_default_size, just like the internal size.
* If an external journal device is larger than the used space, it warns the user that they are wasting space.
* Changes the warning re: journal sizes > default size to be more descriptive.
* Checks to see if the journal size is larger than the max size. If it is an error is issued with a description why and instructions to use -f if the action is truly desired.
* Adds a "force" mode to reiserfs_create_journal()

This may all sound theoretical, but it actually causes machines to crash. We recenly saw a bug report where the user chose an external journal device of ~ 8 GB. When journal_init() tried to allocate cnodes, it failed silently and then panicked the node when it needed to actually use a cnode. A patch to address that issue follows.

---
 include/reiserfs_lib.h  |    2 +-
 mkreiserfs/mkreiserfs.c |    2 +-
 reiserfscore/journal.c  |   42 ++++++++++++++++++++++++++++++++++--------
 tune/tune.c             |    2 +-
 4 files changed, 37 insertions(+), 11 deletions(-)
include/reiserfs_lib.h +1 -1
@@ -346,7 +346,7 @@ int reiserfs_open_journal (reiserfs_fils
 int reiserfs_journal_params_check(reiserfs_filsys_t *fs);
 int reiserfs_create_journal (reiserfs_filsys_t * fs, char * j_filename,
 			     unsigned long offset, unsigned long len, 
-			     int transaction_max_size);
+			     int transaction_max_size, int force);
 int reiserfs_journal_opened (reiserfs_filsys_t *);
 void reiserfs_flush_journal (reiserfs_filsys_t * fs);
 void reiserfs_free_journal (reiserfs_filsys_t * fs);
mkreiserfs/mkreiserfs.c +1 -1
@@ -702,7 +702,7 @@ int main (int argc, char **argv)
     }
 		
     if (!reiserfs_create_journal (fs, jdevice_name, Offset, Journal_size, 
-	Max_trans_size)) 
+	Max_trans_size, force))
     {
         return 1;
     }
reiserfscore/journal.c +34 -8

62 lines not on this page · raw message

tune/tune.c +1 -1
@@ -710,7 +710,7 @@ int main (int argc, char **argv)
     reiserfs_close_journal (fs);
 
     if (!reiserfs_create_journal (fs, j_new_device_name, Offset,
-				  Journal_size, Max_trans_size)) {
+				  Journal_size, Max_trans_size, Force)) {
 	message ("Could not create new journal");
 	reiserfs_close (fs);
         return 1;
#5 lore raw

PATCH 5/9 reiserfsprogs: remove fsck_sleep

In reply to [email protected]

fsck_sleep causes the file descriptors to be kept open during mount. Multipath/kpartx doesn't like that.

---
 fsck/main.c |   17 -----------------
 1 file changed, 17 deletions(-)
fsck/main.c +0 -17
@@ -924,21 +924,6 @@ static void clean_attributes (reiserfs_f
 
 }
 
-/* Do not allow buffers to be flushed after finishing to avoid another bitmap 
- * reading on mounting. */
-static void fsck_sleep() {
-    int res;
-    
-    res = fork();
-    
-    if (res == -1) {
-	reiserfs_panic ("reiserfsck: Fork failed: %s", strerror(errno));
-    } else if (res == 0) {
-	/* Make the child process to sleep for 5 secs. */
-	sleep(5);
-    }
-}
-
 static int auto_check (reiserfs_filsys_t *fs) {
     __u16 state;
     int retval = 0;
@@ -1005,8 +990,6 @@ static int auto_check (reiserfs_filsys_t
     
     clean_after_dma_check(fs->fs_dev, &dma_info);
     
-    fsck_sleep();
-    
     reiserfs_close (fs);
     /* do not do anything else. */    
     exit (EXIT_OK);
#6 lore raw

PATCH 6/9 reiserfsprogs: mkfs should use O_EXCL

In reply to [email protected]

This patch forces reiserfs_create to open the device exclusively.

---
 reiserfscore/reiserfslib.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
reiserfscore/reiserfslib.c +1 -1
@@ -206,7 +206,7 @@ reiserfs_filsys_t * reiserfs_create (cha
 	return 0;
     }
 
-    fs->fs_dev = open (filename, O_RDWR 
+    fs->fs_dev = open (filename, O_RDWR | O_EXCL
 #if defined(O_LARGEFILE)
 		       | O_LARGEFILE
 #endif
#7 lore raw

PATCH 7/9 reiserfsprogs: enforce 2^32-1 block limit

In reply to [email protected]

Currently, mkreiserfs on a block device >= 16 TiB will fail with this error:
reiserfs_create_journal: cannot create a journal of 8193 blocks with 18 offset on 0 blocks

The message doesn't adequately describe that the problem is that reiserfs supports file system sizes up to 2^32-1 blocks, and it silently overflows.

This patch treats the block device size, as well as the <blocks> command line parameter as __u64's, so that they can be safely compared to UINT_MAX.

If the block device is too large, we warn the user, offer to truncate the file system to 2^32-1 blocks, and confirm. This is overridable by the -f option, which will elect to truncate automatically.

If the user has specified a block count that is too large, we fail always since the user has provided invalid input.

---
 mkreiserfs/mkreiserfs.c |   41 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 39 insertions(+), 2 deletions(-)
mkreiserfs/mkreiserfs.c +39 -2
@@ -27,6 +27,7 @@
 #include <stdarg.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <sys/utsname.h>
 
 #if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H)
@@ -434,6 +435,21 @@ static int str2int (char * str)
     return val;
 }
 
+static __u64 str2u64 (char *str)
+{
+    __u64 val;
+    char *tmp;
+
+    val = (__u64)strtoll(str, &tmp, 0);
+
+    if (*tmp) {
+	reiserfs_exit (1, "%s: strtoll is unable to make an integer of %s\n",
+		       program_name, str);
+    }
+
+    return val;
+}
+
 
 static void set_block_size (char * str, int *b_size)
 {
@@ -537,7 +553,7 @@ int main (int argc, char **argv)
     int force = 0;
     char * device_name = NULL;
     char * jdevice_name = NULL;
-    unsigned long fs_size = 0;
+    __u64 fs_size = 0;
     int c;
     static int flag;
 
@@ -672,7 +688,7 @@ int main (int argc, char **argv)
     
     if (optind == argc - 2) {
         /* number of blocks for filesystem is specified */
-        fs_size = str2int (argv[optind + 1]);
+        fs_size = str2u64 (argv[optind + 1]);
     } else if (optind == argc - 1) {
         /* number of blocks is not specified */
         if (!(fs_size = count_blocks (device_name, Block_size)))
@@ -681,6 +697,27 @@ int main (int argc, char **argv)
         print_usage_and_exit ();
     }
 
+    if (fs_size >= UINT_MAX) {
+	fprintf(stderr, ">>> ReiserFS supports file systems of up to %u "
+	        "blocks.\n>>> The maximum size with a block size of %u bytes "
+		"is about %Lu MiB.\n>>> This file system would occupy %Lu "
+		"blocks. ", UINT_MAX, Block_size,
+		((__u64)UINT_MAX * Block_size) / (1024 * 1024), fs_size);
+
+	if (optind == argc - 1) {
+	    if (!force &&
+		!user_confirmed (stderr, "Truncate? (y/N): ", "y\n")) {
+		fprintf(stderr, "\nExiting.\n\n");
+		exit(1);
+	    }
+	    fprintf(stderr, "Truncating.\n\n");
+	    fs_size = UINT_MAX;
+	} else {
+	    fprintf(stderr, "Exiting.\n\n");
+	    exit(1);
+	}
+    }
+
     if (is_journal_default (device_name, jdevice_name, Block_size))
         Create_default_journal = 1;
     
#8 lore raw

PATCH 8/9 reiserfsprogs: Support for file systems > 8 TB

In reply to [email protected]

The reiserfs disk format tries to support large file systems, but falls short in the superblock format where it contains the number of bitmaps in the file system as a 16 bit value. This limits the file system size to 65536 bitmap blocks, which can describe 8TiB - 128MiB.

The following patch is somewhat of a backport of the bitmap tracking behavior in reiserfsprogs 3.6.20. It calculates the bmap count on the fly rather than depending on the superblock value.

It also teaches fsck to detect and adjust s_bmap_nr when it's not zero but describes a file system larger than 8 TB. In order to do this, many places which use get_sb_bmap_nr() directly need to use the calculated value instead.

---
 debugreiserfs/corruption.c        |    4 ++--
 debugreiserfs/pack.c              |    5 ++---
 fsck/check_tree.c                 |    5 +++--
 fsck/pass0.c                      |    2 +-
 fsck/pass1.c                      |    2 +-
 fsck/super.c                      |   18 +++++++++++-------
 include/reiserfs_lib.h            |    4 ++++
 mkreiserfs/mkreiserfs.c           |    9 ++++++---
 reiserfscore/bitmap.c             |   29 +++++++++++++++++++----------
 reiserfscore/node_formats.c       |    2 +-
 reiserfscore/prints.c             |    8 +++++---
 reiserfscore/reiserfslib.c        |    6 +++++-
 resize_reiserfs/do_shrink.c       |   10 ++++++----
 resize_reiserfs/resize_reiserfs.c |    6 ++++--
 14 files changed, 70 insertions(+), 40 deletions(-)
debugreiserfs/corruption.c +2 -2
@@ -157,7 +157,7 @@ static void edit_super_block (reiserfs_f
 		strncpy (fs->fs_ondisk_sb->s_v1.s_magic, str, n > 10 ? 10 : n);
     
     /* __u16 sb_fsck_state; */
-    printf ("\tFielsystem state: current: %u: new:", get_sb_fs_state (fs->fs_ondisk_sb));
+    printf ("\tFilesystem state: current: %u: new:", get_sb_fs_state (fs->fs_ondisk_sb));
     getline (&str, &n, stdin);
     if (str2int (str, &num))
 		set_sb_fs_state (fs->fs_ondisk_sb, num);
@@ -809,7 +809,7 @@ void do_bitmap_corruption (reiserfs_fils
 	struct buffer_head * bh;
 	unsigned int i;
 
-	nr_bitmap_to_corrupt = (unsigned long)get_rand (1, get_sb_bmap_nr (fs->fs_ondisk_sb) - 1);
+	nr_bitmap_to_corrupt = (unsigned long)get_rand (1, reiserfs_fs_bmap_nr(fs) - 1);
 
 	if ((data(fs)->log_file_name) && (data(fs)->log)) {
 		fprintf (data(fs)->log, "%lu bitmaps will be corrupted\n", nr_bitmap_to_corrupt);
debugreiserfs/pack.c +2 -3
@@ -581,13 +581,12 @@ static void pack_frozen_data (reiserfs_f
     /* super block */
     reiserfs_warning (stderr, "super block..");fflush (stderr);
     send_block (fs, fs->fs_super_bh, 1/*send block even if its format is not determined */);
-    reiserfs_warning (stderr, "ok\nbitmaps..(%d).. ", 
-		      get_sb_bmap_nr (fs->fs_ondisk_sb));
+    reiserfs_warning (stderr, "ok\nbitmaps..(%d).. ", reiserfs_fs_bmap_nr(fs));
     fflush (stderr);
 
     /* bitmaps */
     block = fs->fs_super_bh->b_blocknr + 1;
-    for (i = 0; i < get_sb_bmap_nr (fs->fs_ondisk_sb); i ++) {
+    for (i = 0; i < reiserfs_fs_bmap_nr(fs); i ++) {
 	bh = bread (fs->fs_dev, block, fs->fs_blocksize);
 	if (!bh) {
 	    fprintf (stderr, "pack_frozen_data: bread failed: %lu\n", block);
fsck/check_tree.c +3 -2
@@ -142,9 +142,10 @@ static void init_control_bitmap (reiserf
     unsigned int i;
     unsigned long block;
     unsigned long reserved;
+    unsigned int blocks = get_sb_block_count(fs->fs_ondisk_sb);
     
 
-    control_bitmap = reiserfs_create_bitmap(get_sb_block_count(fs->fs_ondisk_sb));
+    control_bitmap = reiserfs_create_bitmap(blocks);
     if (!control_bitmap)
 	die ("init_control_bitmap: Failed to allocate a control bitmap.");
 
@@ -161,7 +162,7 @@ static void init_control_bitmap (reiserf
 
     /* bitmaps */
     block = fs->fs_super_bh->b_blocknr + 1;
-    for (i = 0; i < get_sb_bmap_nr (fs->fs_ondisk_sb); i ++) {
+    for (i = 0; i < reiserfs_fs_bmap_nr(fs); i ++) {
         we_met_it (block);
 
 	if (spread_bitmaps (fs))
fsck/pass0.c +1 -1
@@ -1802,7 +1802,7 @@ static void init_source_bitmap (reiserfs
     block = fs->fs_super_bh->b_blocknr + 1;
 
     reserved = fsck_source_bitmap(fs)->bm_bit_size;
-    for (i = 0; i < get_sb_bmap_nr (fs->fs_ondisk_sb); i ++) {
+    for (i = 0; i < reiserfs_fs_bmap_nr(fs); i ++) {
 	if (!reiserfs_bitmap_test_bit (fsck_source_bitmap (fs), block)) {
 	    /* bitmap is definitely broken, mark all blocks of this bitmap block as used */
 	
fsck/pass1.c +1 -1
@@ -483,7 +483,7 @@ static void init_new_bitmap (reiserfs_fi
 
     /* mark bitmap blocks as used */
     block = fs->fs_super_bh->b_blocknr + 1;
-    for (i = 0; i < get_sb_bmap_nr (fs->fs_ondisk_sb); i ++) {
+    for (i = 0; i < reiserfs_fs_bmap_nr(fs); i ++) {
 	mark_block_used (block, 1);
 	if (spread_bitmaps (fs))
 	    block = (block / (fs->fs_blocksize * 8) + 1) * (fs->fs_blocksize * 8);
fsck/super.c +11 -7
@@ -178,7 +178,7 @@ void rebuild_sb (reiserfs_filsys_t * fs,
     int magic_was_found = 0;
     unsigned long block_count = 0;
     __u16 p_oid_maxsize;
-    __u16 p_bmap_nr;
+    unsigned int bmap_nr;
     __u32 p_jp_journal_1st_block = 0;
     __u32 p_jp_dev_size = 0;
     int standard_journal = -1;
@@ -446,12 +446,16 @@ void rebuild_sb (reiserfs_filsys_t * fs,
 	set_sb_oid_maxsize (sb, p_oid_maxsize);
     }
 
-    p_bmap_nr = (block_count + (fs->fs_blocksize * 8 - 1)) / (fs->fs_blocksize * 8);
-    if (get_sb_bmap_nr (sb) != p_bmap_nr) {
-	fsck_log("rebuild-sb: wrong bitmap number occured (%lu), fixed (%lu)\n", 
-		get_sb_bmap_nr (sb), p_bmap_nr);
-	set_sb_bmap_nr (sb, 
-		(block_count + (fs->fs_blocksize * 8 - 1)) / (fs->fs_blocksize * 8));
+    bmap_nr = reiserfs_fs_bmap_nr(fs);
+
+    if (reiserfs_bmap_over(bmap_nr) && get_sb_bmap_nr(sb) != 0) {
+	fsck_log("rebuild-sb: wrong bitmap number occured (%u), fixed (0) "
+	         "(really %u)\n", get_sb_bmap_nr (sb), bmap_nr);
+	set_sb_bmap_nr (sb, 0);
+    } else if (get_sb_bmap_nr(sb) != bmap_nr) {
+	fsck_log("rebuild-sb: wrong bitmap number occured (%u), "
+		 "fixed (%u)\n", get_sb_bmap_nr (sb), bmap_nr);
+	set_sb_bmap_nr (sb, bmap_nr);
     }
 
     if (get_sb_root_block (sb) > block_count) {
include/reiserfs_lib.h +4 -0
@@ -152,6 +152,9 @@ void mark_badblock(reiserfs_filsys_t *fs
 int create_badblock_bitmap (reiserfs_filsys_t * fs, char * badblocks_file);
 void add_badblock_list (reiserfs_filsys_t * fs, int no_badblock_in_tree_yet);
 void badblock_list(reiserfs_filsys_t * fs, badblock_func_t action, void *data);
+#define reiserfs_fs_bmap_nr(fs) reiserfs_bmap_nr(get_sb_block_count(fs->fs_ondisk_sb), fs->fs_blocksize)
+#define reiserfs_bmap_nr(count, blk_size) ((count - 1) / (blk_size * 8) + 1)
+#define reiserfs_bmap_over(nr) (nr > ((1LL << 16) - 1))
 
 extern struct key root_dir_key;
 extern struct key parent_root_dir_key;
@@ -166,6 +169,7 @@ int reiserfs_create_ondisk_bitmap (reise
 void reiserfs_free_ondisk_bitmap (reiserfs_filsys_t *);
 void reiserfs_close_ondisk_bitmap (reiserfs_filsys_t *);
 int reiserfs_flush_to_ondisk_bitmap (reiserfs_bitmap_t * bm, reiserfs_filsys_t * fs);
+unsigned int reiserfs_calc_bmap_nr(reiserfs_filsys_t *fs, unsigned int blocks);
 
 reiserfs_bitmap_t * reiserfs_create_bitmap (unsigned int bit_count);
 int reiserfs_expand_bitmap (reiserfs_bitmap_t * bm, unsigned int bit_count);
mkreiserfs/mkreiserfs.c +6 -3
@@ -223,7 +223,7 @@ static void make_bitmap (reiserfs_filsys
     /* mark bitmaps as used */
     block = fs->fs_super_bh->b_blocknr + 1;
 
-    for (i = 0; i < get_sb_bmap_nr (sb); i ++) {
+    for (i = 0; i < reiserfs_fs_bmap_nr(fs); i ++) {
 	reiserfs_bitmap_set_bit (fs->fs_bitmap2, block);
 	marked ++;
 	if (spread_bitmaps (fs))
@@ -350,8 +350,11 @@ static void report (reiserfs_filsys_t * 
     reiserfs_warning (stdout, "Hash function used to sort names: %s\n",
 		      code2name (get_sb_hash_code (sb)));
     if (mode & DEBUG_MODE) {
-        reiserfs_warning (stdout, "Number of bitmaps: %u\n", get_sb_bmap_nr (sb));
-        reiserfs_warning (stdout, "Root block: %u\n", get_sb_root_block (sb));
+        reiserfs_warning (stdout, "Number of bitmaps: %u", get_sb_bmap_nr (sb));
+	if (get_sb_bmap_nr(sb) != reiserfs_fs_bmap_nr(fs))
+		reiserfs_warning(stdout, " (really uses %u)",
+		                 reiserfs_fs_bmap_nr(fs));
+        reiserfs_warning (stdout, "\nRoot block: %u\n", get_sb_root_block (sb));
         reiserfs_warning (stdout, "Tree height: %d\n", get_sb_tree_height (sb));
         reiserfs_warning (stdout, "Objectid map size %d, max %d\n", 
 			  get_sb_oid_cursize (sb), get_sb_oid_maxsize (sb));
reiserfscore/bitmap.c +19 -10
@@ -685,25 +685,35 @@ void reiserfs_free_ondisk_bitmap (reiser
     }
 }
 
-
 /* read bitmap blocks */
 int reiserfs_open_ondisk_bitmap (reiserfs_filsys_t * fs)
 {
+    unsigned int blocks = get_sb_block_count(fs->fs_ondisk_sb) ;
+    unsigned int bmap_nr = reiserfs_bmap_nr(blocks, fs->fs_blocksize);
+
     if (fs->fs_bitmap2)
 	reiserfs_panic ("bitmap is initiaized already");
 
-    fs->fs_bitmap2 = reiserfs_create_bitmap (get_sb_block_count (fs->fs_ondisk_sb));
+    fs->fs_bitmap2 = reiserfs_create_bitmap (blocks);
     if (!fs->fs_bitmap2)
 	return -1;
 
-    if ((get_sb_block_count (fs->fs_ondisk_sb) + fs->fs_blocksize * 8 - 1) / 
-	(fs->fs_blocksize * 8) != get_sb_bmap_nr (fs->fs_ondisk_sb)) 
-    {
-	reiserfs_warning (stderr, "%s: wrong either bitmaps number,\n", __FUNCTION__);
-	reiserfs_warning (stderr, "count of blocks or blocksize, run with --rebuild-sb "
-	    "to fix it\n");
+    if (reiserfs_bmap_over(bmap_nr)) {
+	     if (get_sb_bmap_nr(fs->fs_ondisk_sb) != 0) {
+		reiserfs_warning (stderr, "%s: large file system has "
+		                  "incorrect bitmap count %u. Should be 0 "
+				  "to indicate overflow.\nPlease re-run with "
+				  "--rebuild-sb to fix it.\n", __FUNCTION__,
+				  get_sb_bmap_nr(fs->fs_ondisk_sb));
+		return -1;
+	     }
+    } else if (bmap_nr != get_sb_bmap_nr (fs->fs_ondisk_sb)) {
+	reiserfs_warning (stderr, "%s: wrong either bitmaps number,\n",
+	                  __FUNCTION__);
+	reiserfs_warning (stderr, "count of blocks or blocksize, run with "
+	                  "--rebuild-sb to fix it\n");
 	return -1;
-    }    	
+    }
 
     return reiserfs_fetch_ondisk_bitmap (fs->fs_bitmap2, fs);
 }
@@ -720,7 +730,6 @@ int reiserfs_create_ondisk_bitmap (reise
     return 1;
 }
 
-
 void reiserfs_close_ondisk_bitmap (reiserfs_filsys_t * fs)
 {
     if (!fs->fs_bitmap2)
reiserfscore/node_formats.c +1 -1
@@ -372,7 +372,7 @@ int block_of_bitmap (reiserfs_filsys_t *
 	return (block == (REISERFS_DISK_OFFSET_IN_BYTES / fs->fs_blocksize + 1)) ;
     } else {
 	/* bitmap in */
-	return (block > 2ul && block < 3ul + get_sb_bmap_nr(fs->fs_ondisk_sb)) ? 1 : 0;
+	return (block > 2ul && block < 3ul + reiserfs_fs_bmap_nr(fs)) ? 1 : 0;
     }
     return 0;
 }
reiserfscore/prints.c +5 -3
@@ -641,8 +641,10 @@ int print_super_block (FILE * fp, reiser
 		get_sb_block_count (sb), get_sb_free_blocks (sb), get_sb_block_size (sb));
     } else {
 	reiserfs_warning (fp, "Count of blocks on the device: %u\n", get_sb_block_count (sb));
-	reiserfs_warning (fp, "Number of bitmaps: %u\n", get_sb_bmap_nr (sb));
-	reiserfs_warning (fp, "Blocksize: %d\n", get_sb_block_size (sb));
+	reiserfs_warning (fp, "Number of bitmaps: %u", get_sb_bmap_nr (sb));
+	if (get_sb_bmap_nr (sb) != reiserfs_fs_bmap_nr(fs))
+		reiserfs_warning (fp, " (really uses %u)", reiserfs_fs_bmap_nr(fs));
+	reiserfs_warning (fp, "\nBlocksize: %d\n", get_sb_block_size (sb));
 	reiserfs_warning (fp, "Free blocks (count of blocks - used [journal, "
 		      "bitmaps, data, reserved] blocks): %u\n", get_sb_free_blocks (sb));
 	reiserfs_warning (fp, "Root block: %u\n", get_sb_root_block (sb));
@@ -916,7 +918,7 @@ void print_bmap (FILE * fp, reiserfs_fil
 
 
     sb = fs->fs_ondisk_sb;
-    bmap_nr = get_sb_bmap_nr (sb);
+    bmap_nr = reiserfs_fs_bmap_nr(fs);
     bits_per_block = fs->fs_blocksize * 8;
     blocks = bits_per_block;
 
reiserfscore/reiserfslib.c +5 -1
@@ -160,6 +160,7 @@ reiserfs_filsys_t * reiserfs_open (char 
     fs->fs_flags = flags; /* O_RDONLY or O_RDWR */
 
     fs->fs_format = get_reiserfs_format (sb);
+
     
     /*reiserfs_read_bitmap_blocks(fs);*/
     if (flags & O_RDWR)
@@ -181,6 +182,7 @@ reiserfs_filsys_t * reiserfs_create (cha
 				     int new_format)
 {
     reiserfs_filsys_t * fs;
+    unsigned int bmap_nr = reiserfs_bmap_nr(block_count, block_size);;
 
 
     /* convert root dir key and parent root dir key to little endian format */
@@ -278,8 +280,10 @@ reiserfs_filsys_t * reiserfs_create (cha
     /* sb_fsck_state */
     /* sb_hash_function_code */
     /* sb_tree_height */
+
     set_sb_bmap_nr (fs->fs_ondisk_sb,
-		    (block_count + (block_size * 8 - 1)) / (block_size * 8));
+                    reiserfs_bmap_over(bmap_nr) ? 0 : bmap_nr);
+
     set_sb_version (fs->fs_ondisk_sb, version);
     /* sb_not_used1 */
 
resize_reiserfs/do_shrink.c +6 -4
@@ -187,8 +187,7 @@ int shrink_fs(reiserfs_filsys_t * fs, lo
 
 	/* is shrinking possible ? */
 	if (get_sb_block_count(ondisk_sb) - blocks > 
-	    get_sb_free_blocks(ondisk_sb) + get_sb_bmap_nr(ondisk_sb) - 
-	    bmap_nr_new) 
+	    get_sb_free_blocks(ondisk_sb) + reiserfs_fs_bmap_nr(fs) - bmap_nr_new)
 	{
 	    fprintf(stderr, "resize_reiserfs: can\'t shrink fs; too many "
 		"blocks already allocated\n");
@@ -226,7 +225,7 @@ int shrink_fs(reiserfs_filsys_t * fs, lo
 	blocks_used = 
 	    get_sb_block_count(fs->fs_ondisk_sb)
 	    - get_sb_free_blocks(fs->fs_ondisk_sb)
-	    - get_sb_bmap_nr(fs->fs_ondisk_sb)
+	    - reiserfs_fs_bmap_nr(fs)
 	    - get_jp_journal_size(sb_jp (fs->fs_ondisk_sb))
 	    - REISERFS_DISK_OFFSET_IN_BYTES / fs->fs_blocksize
 	    - 2; /* superblock itself and 1 descriptor after the journal */
@@ -289,10 +288,13 @@ int shrink_fs(reiserfs_filsys_t * fs, lo
 
 	set_sb_free_blocks (ondisk_sb, get_sb_free_blocks(ondisk_sb)
 			    - (get_sb_block_count(ondisk_sb) - blocks)
-			    + (get_sb_bmap_nr(ondisk_sb) - bmap_nr_new)
+			    + (reiserfs_fs_bmap_nr(fs) - bmap_nr_new)
 			    + bad_count);
 	set_sb_block_count (ondisk_sb, blocks);
 	set_sb_bmap_nr (ondisk_sb, bmap_nr_new);
 
+	set_sb_bmap_nr (fs->fs_ondisk_sb,
+	                reiserfs_bmap_over(bmap_nr_new) ? 0 : bmap_nr_new);
+
 	return 0;
 }
resize_reiserfs/resize_reiserfs.c +4 -2
@@ -114,14 +114,16 @@ static int expand_fs (reiserfs_filsys_t 
 
     /* count bitmap blocks in new fs */
     bmap_nr_new = (block_count_new - 1) / (fs->fs_blocksize * 8) + 1;
-    bmap_nr_old = get_sb_bmap_nr(sb);
+    bmap_nr_old = reiserfs_fs_bmap_nr(fs);
 	
     /* update super block buffer*/
     set_sb_free_blocks (sb, get_sb_free_blocks(sb) + 
 			(block_count_new - get_sb_block_count(sb)) - 
 			(bmap_nr_new - bmap_nr_old));
     set_sb_block_count (sb, block_count_new);
-    set_sb_bmap_nr (sb, bmap_nr_new);
+
+    set_sb_bmap_nr (fs->fs_ondisk_sb,
+                    reiserfs_bmap_over(bmap_nr_new) ? 0 : bmap_nr_new);
 
     /* mark new bitmap blocks as used */
     for (i = bmap_nr_old; i < bmap_nr_new; i++)
#9 lore raw

PATCH 1/2 reiserfsprogs: add ext3-style mount count and last check expiry for better fsck -a behavior

In reply to [email protected]

Currently, fsck.reiserfs -a <dev> performs a full --check scan on every reiserfs file system during every boot. This is obviously suboptimal, since it kills one of the major features of a journaled file system.

This patch adds mount counting and last check expiration to fsck, mkfs, and debugfs so that we can perform fscks on a user defined schedule.

The defaults are 180 days or 30 mounts before fsck -a results in a full scan.

On file systems where this feature hasn't yet been enabled, the fsck -a will perform a full scan and then mark the superblock with the defaults.

While the mount count won't work with kernels that don't support it, the timeout obviously will. I'll be following this patch up with a kernel patch that reserves the fields and updates the mount counts.

This support is super important with multi-terabyte file systems, since the check is causing huge delays during mount.

Whether or not this patch is immediately accepted into the reiserfsprogs repository, I'd at least like confirmation that I can reserve these fields in the superblock for this purpose.

Thanks.

---

 configure.in               |    2 
 fsck/fsck.h                |    3 -
 fsck/main.c                |   78 ++++++++++++++++++++++++++++-
 fsck/reiserfsck.8          |   10 ++-
 include/Makefile.am        |    2 
 include/parse_time.h       |   15 +++++
 include/reiserfs_fs.h      |   25 +++++++++
 lib/Makefile.am            |    2 
 lib/parse_time.c           |   36 +++++++++++++
 reiserfscore/prints.c      |   29 ++++++++++
 reiserfscore/reiserfslib.c |    7 ++
 tune/reiserfstune.8        |   77 ++++++++++++++++++++++++++++
 tune/tune.c                |  120 +++++++++++++++++++++++++++++++++++++++++++--
 13 files changed, 392 insertions(+), 14 deletions(-)
configure.in +1 -1
@@ -105,7 +105,7 @@ AC_FUNC_MEMCMP
 AC_FUNC_STRFTIME
 AC_FUNC_VPRINTF
 AC_CHECK_FUNCS(strerror strstr strtol register_printf_function statfs getmntent\
-	       hasmntopt memset time uname)
+	       hasmntopt memset time uname strptime ctime_r)
 
 
 dnl Never enable this. It is for debugging only
fsck/fsck.h +2 -1
@@ -62,7 +62,8 @@ int main (int argc, char * argv []);
 #define OPT_SAVE_PASSES_DUMP            1 << 7
 #define OPT_SAVE_ROLLBACK               1 << 8
 #define OPT_YES				1 << 9
-#define BADBLOCKS_FILE               	1 << 10
+#define BADBLOCKS_FILE			1 << 10
+#define OPT_FORCE			1 << 11
 
 
 /* pass0.c */
fsck/main.c +76 -2

138 lines not on this page · raw message

fsck/reiserfsck.8 +7 -3
@@ -6,7 +6,7 @@
 reiserfsck \- The checking tool for the ReiserFS filesystem.
 .SH SYNOPSIS
 .B reiserfsck 
-[ \fB-afprVy\fR ]
+[ \fB-aprVy\fR ]
 [ \fB--rebuild-sb\fR | \fB--check\fR | \fB--fix-fixable\fR
 | \fB--rebuild-tree\fR | \fB--clean-attributes\fR ]
 .\" [ \fB-i\fR | \fB--interactive\fR ]
@@ -17,6 +17,7 @@ reiserfsck \- The checking tool for the 
 [ \fB-l\fR | \fB--logfile \fIfile\fR ]
 [ \fB-q\fR | \fB--quiet\fR ]
 [ \fB-y\fR | \fB--yes\fR ]
+[ \fB-f\fR | \fB--force\fR ]
 .\" [ \fB-b\fR | \fB--scan-marked-in-bitmap \fIbitmap-filename\fR ]
 .\" [ \fB-h\fR | \fB--hash \fIhash-name\fR ]
 .\" [ \fB-g\fR | \fB--background\fR ]
@@ -122,11 +123,14 @@ corruption is found set in the superbloc
 to the fix-fixable mode. If the flag indicating a fatal corruption is found 
 set in the superblock, then \fBreiserfsck\fR finishes with an error.
 .TP
+.B --force, -f
+Force checking even if the file system seems clean.
+.TP
 .B -V
 This option prints the reiserfsprogs version and then exit.
 .TP
-\fB-r\fR, \fB-f\fR
-These options are not yet operational and therefore are ignored.
+\fB-r\fR This option does nothing at all; it is provided only for
+backwards compatibility.
 .SH EXPERT OPTIONS
 DO NOT USE THESE OPTIONS UNLESS YOU KNOW WHAT YOU ARE DOING. 
 WE ARE NOT RESPONSIBLE IF YOU LOSE DATA AS A RESULT OF THESE
include/Makefile.am +1 -1
@@ -1 +1 @@
-noinst_HEADERS = io.h  misc.h  reiserfs_fs.h  reiserfs_lib.h swab.h
+noinst_HEADERS = io.h  misc.h  reiserfs_fs.h  reiserfs_lib.h swab.h parse_time.h
include/parse_time.h new file +15 -0
@@ -0,0 +1,15 @@
+/*
+ * Copyright 1996-2004 by Hans Reiser, licensing governed by
+ * reiserfsprogs/README
+ */
+
+/* nothing abount reiserfs here */
+
+#ifndef TIME_H
+#define TIME_H
+
+#include <time.h>
+
+time_t parse_time(char *str);
+
+#endif /* TIME_H */
include/reiserfs_fs.h +24 -1
@@ -194,7 +194,11 @@ struct reiserfs_super_block
 /* 80 */     __u32 s_flags;                /* Right now used only by inode-attributes, if enabled */
 /* 84 */    unsigned char s_uuid[16];      /* filesystem unique identifier */
 /*100 */    unsigned char s_label[16];     /* filesystem volume label */
-/*116 */    char s_unused[88] ;            /* zero filled by mkreiserfs and reiserfs_convert_objectid_map_v1()
+/*116 */    __u16 s_mnt_count;
+/*118 */    __u16 s_max_mnt_count;
+/*120 */    __u32 s_lastcheck;
+/*124 */    __u32 s_check_interval;
+/*128 */    char s_unused[76] ;            /* zero filled by mkreiserfs and reiserfs_convert_objectid_map_v1()
                                             * so any additions must be updated there as well. */ 
 /*204*/
 } __attribute__ ((__packed__));;
@@ -258,6 +262,22 @@ typedef enum {
 #define get_sb_v2_inode_generation(sb)		get_le32 (sb, sb_inode_generation)
 #define set_sb_v2_inode_generation(sb,val)	set_le32 (sb, sb_inode_generation, val)
 
+#define get_sb_v2_mnt_count(sb)		get_le16 (sb, s_mnt_count)
+#define set_sb_v2_mnt_count(sb,val)	set_le16 (sb, s_mnt_count, val)
+
+#define get_sb_v2_max_mnt_count(sb)				\
+	get_le16 (sb, s_max_mnt_count)
+#define set_sb_v2_max_mnt_count(sb,val)			\
+	set_le16 (sb, s_max_mnt_count, val)
+
+#define get_sb_v2_lastcheck(sb)		get_le32 (sb, s_lastcheck)
+#define set_sb_v2_lastcheck(sb,val)		set_le32 (sb, s_lastcheck, val)
+
+#define get_sb_v2_check_interval(sb)				\
+	get_le32 (sb, s_check_interval)
+#define set_sb_v2_check_interval(sb,val)			\
+	set_le32 (sb, s_check_interval, val)
+
 #define get_sb_v2_flags(sb)		get_le32 (sb, s_flags)
 #define set_sb_v2_flags(sb, val)	set_le32 (sb, s_flags, val)
 
@@ -269,6 +289,9 @@ typedef enum {
 #define journal_is_relocated(sb)        get_jp_journal_dev(sb_jp (sb))
 */
 
+#define DEFAULT_MAX_MNT_COUNT	30			/* 30 mounts */
+#define DEFAULT_CHECK_INTERVAL	(180 * 60 * 60 * 24)	/* 180 days */
+
 /* these are possible values for sb_fs_state */
 #define FS_CONSISTENT   0x0	    /* this is set by mkreiserfs and by reiserfsck */
 #define FS_ERROR	0x1	    /* this is set by the kernel when fsck is wanted. */
lib/Makefile.am +1 -1
@@ -1,5 +1,5 @@
 noinst_LIBRARIES = libmisc.a
 
-libmisc_a_SOURCES = io.c misc.c 
+libmisc_a_SOURCES = io.c misc.c parse_time.c
 ##reiserfs.c
 
lib/parse_time.c new file +36 -0
@@ -0,0 +1,36 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "misc.h"
+#include "reiserfs_lib.h"
+
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+
+time_t parse_time(char *str)
+{
+	struct tm ts;
+
+	if (strcmp(str, "now") == 0) {
+		return (time(0));
+	}
+	memset(&ts, 0, sizeof (ts));
+#ifdef HAVE_STRPTIME
+	strptime(str, "%Y%m%d%H%M%S", &ts);
+#else
+	sscanf(str, "%4d%2d%2d%2d%2d%2d", &ts.tm_year, &ts.tm_mon,
+	       &ts.tm_mday, &ts.tm_hour, &ts.tm_min, &ts.tm_sec);
+	ts.tm_year -= 1900;
+	ts.tm_mon -= 1;
+	if (ts.tm_year < 0 || ts.tm_mon < 0 || ts.tm_mon > 11 ||
+	    ts.tm_mday < 0 || ts.tm_mday > 31 || ts.tm_hour > 23 ||
+	    ts.tm_min > 59 || ts.tm_sec > 61)
+		ts.tm_mday = 0;
+#endif
+	if (ts.tm_mday == 0)
+		reiserfs_warning(stderr, "Couldn't parse date/time "
+		                 "specifier: %s", str);
+	return (mktime(&ts));
+}
reiserfscore/prints.c +29 -0
@@ -9,6 +9,8 @@
 #include <stdarg.h>
 #include <limits.h>
 #include <printf.h>
+#include <limits.h>
+#include <time.h>
 
 #if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H)
 #  include <uuid/uuid.h>
@@ -612,6 +614,8 @@ int print_super_block (FILE * fp, reiser
     dev_t rdev;
     int format = 0;
     __u16 state;
+    time_t last_check = get_sb_v2_lastcheck(sb);
+    char last_check_buf[26];
 
     if (!does_look_like_super_block (sb))
 	return 1;
@@ -680,6 +684,31 @@ int print_super_block (FILE * fp, reiser
         reiserfs_warning (fp, "Set flags in SB:\n");
 	if ((get_sb_v2_flag (sb, reiserfs_attrs_cleared)))
 	    reiserfs_warning (fp, "\tATTRIBUTES CLEAN\n");
+	reiserfs_warning(fp, "Mount count: %u\n",
+			 get_sb_v2_mnt_count(sb));
+	reiserfs_warning(fp, "Maximum mount count: ");
+	if (get_sb_v2_max_mnt_count(sb) &&
+	    get_sb_v2_max_mnt_count(sb) != USHRT_MAX)
+		reiserfs_warning(fp, "%u\n", get_sb_v2_max_mnt_count(sb));
+	else if (get_sb_v2_max_mnt_count(sb) == USHRT_MAX)
+		reiserfs_warning(fp, "Administratively disabled.\n");
+	else
+		reiserfs_warning(fp, "Disabled. Run fsck.reiserfs(8) or use tunefs.reiserfs(8) to enable.\n");
+	if (last_check) {
+		ctime_r(&last_check, last_check_buf);
+		reiserfs_warning(fp, "Last fsck run: %s", last_check_buf);
+	} else
+		reiserfs_warning(fp, "Last fsck run: Never with a version "
+				 "that supports this feature.\n");
+	reiserfs_warning(fp, "Check interval in days: ");
+	if (get_sb_v2_check_interval(sb) &&
+	    get_sb_v2_check_interval(sb) != UINT_MAX)
+		reiserfs_warning(fp, "%u\n",
+			 get_sb_v2_check_interval(sb) / (24*60*60));
+	else if (get_sb_v2_check_interval(sb) == UINT_MAX)
+		reiserfs_warning(fp, "Administratively disabled.\n");
+	else
+		reiserfs_warning(fp, "Disabled. Run fsck.reiserfs(8) or use tunefs.reiserfs(8) to enable.\n");
     }
 
     return 0;
reiserfscore/reiserfslib.c +7 -0
@@ -7,6 +7,7 @@
 
 #include "includes.h"
 #include <linux/kdev_t.h>
+#include <time.h>
 
 struct key root_dir_key = {0, 0, {{0, 0},}};
 struct key parent_root_dir_key = {0, 0, {{0, 0},}};
@@ -183,6 +184,7 @@ reiserfs_filsys_t * reiserfs_create (cha
 {
     reiserfs_filsys_t * fs;
     unsigned int bmap_nr = reiserfs_bmap_nr(block_count, block_size);;
+    time_t now;
 
 
     /* convert root dir key and parent root dir key to little endian format */
@@ -285,6 +287,11 @@ reiserfs_filsys_t * reiserfs_create (cha
                     reiserfs_bmap_over(bmap_nr) ? 0 : bmap_nr);
 
     set_sb_version (fs->fs_ondisk_sb, version);
+    set_sb_v2_lastcheck(fs->fs_ondisk_sb, time(&now));
+    set_sb_v2_check_interval(fs->fs_ondisk_sb, DEFAULT_CHECK_INTERVAL);
+    set_sb_v2_mnt_count(fs->fs_ondisk_sb, 1);
+    set_sb_v2_max_mnt_count(fs->fs_ondisk_sb, DEFAULT_MAX_MNT_COUNT);
+
     /* sb_not_used1 */
 
     mark_buffer_dirty (fs->fs_super_bh);
tune/reiserfstune.8 +77 -0

101 lines not on this page · raw message

tune/tune.c +116 -4

188 lines not on this page · raw message

-
To unsubscribe from this list: send the line "unsubscribe reiserfs-devel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#11 lore raw

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 2 lines · Edward Shishkin

Thanks, queued.
Btw I got compilation errors. Have you missed something?

Yeah, I guess I did. It builds fine on my SLES boxes, but not on my openSUSE machines. I'll them up for that (I need to anyway) and resend.

Thanks for the feedback.

- -Jeff

- --
Jeff Mahoney
SUSE Labs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.4-svn0 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD8DBQFHmgP/LPWxlyuTD7IRAnNoAJ0TpoB6aXFvubLJ8X5blcIB/F9ZTQCgnxVD Kwkv8OGOUy34yTsmdnnMqCQ=
=Q8Br
-----END PGP SIGNATURE-----

#12 lore raw

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 8 lines · Jeff Mahoney
Quoted 2 lines · Edward Shishkin

Thanks, queued.
Btw I got compilation errors. Have you missed something?

Yeah, I guess I did. It builds fine on my SLES boxes, but not on my openSUSE machines. I'll them up for that (I need to anyway) and resend.

Thanks for the feedback.

But then again, 3.6.19 without any patches doesn't build for me either. I'll add a patch to the queue to fix that as well.

- -Jeff

- --
Jeff Mahoney
SUSE Labs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.4-svn0 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD8DBQFHmgVHLPWxlyuTD7IRAn2xAKCeyQTPqgzpIyiyP4u7Q3P7X8+MGwCgnffs W9xBadtoerKE8D5OPrHnHhM=
=rGaL
-----END PGP SIGNATURE-----

#13 lore raw
In reply to Jeff Mahoney
Quoted 9 lines · Jeff Mahoney
Quoted 2 lines · Edward Shishkin

Thanks, queued.
Btw I got compilation errors. Have you missed something?

Yeah, I guess I did. It builds fine on my SLES boxes, but not on my openSUSE machines. I'll them up for that (I need to anyway) and resend.

The following makes me think that something is
missed (the patch series was applied to 3.6.19):

main.c: In function `reiserfs_check_auto_state':
main.c:971: warning: unsigned int format, long int arg (arg 3)
mkreiserfs.c: In function `main':
mkreiserfs.c:730: warning: implicit declaration of function block_size_ok' tune.o(.text+0xa86): In function main':
/home/edward/work/reiserfsprogs-3.6.19/tune/tune.c:268: undefined reference to `parse_time'
collect2: ld returned 1 exit status
make[1]: *** [reiserfstune] Error 1

#14 lore raw

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 12 lines · Edward Shishkin
Quoted 9 lines · Jeff Mahoney
Quoted 2 lines · Edward Shishkin

Thanks, queued.
Btw I got compilation errors. Have you missed something?

Yeah, I guess I did. It builds fine on my SLES boxes, but not on my openSUSE machines. I'll them up for that (I need to anyway) and resend.

Quoted 7 lines

The following makes me think that something is
missed (the patch series was applied to 3.6.19):

main.c: In function `reiserfs_check_auto_state':
main.c:971: warning: unsigned int format, long int arg (arg 3) mkreiserfs.c: In function `main':
mkreiserfs.c:730: warning: implicit declaration of function `block_size_ok'

This was a missing entry in reiserfs_lib.h. I've attached an updated patch that adds it. I've also attached an updated reiserfsprogs-better-fsck-a-behavior. The only difference is the addition of "#define _XOPEN_SOURCE" for the strptime prototype. There was a warning for that too.

Quoted 5 lines

tune.o(.text+0xa86): In function `main':
/home/edward/work/reiserfsprogs-3.6.19/tune/tune.c:268: undefined reference to `parse_time'
collect2: ld returned 1 exit status
make[1]: *** [reiserfstune] Error 1

This one looks like you didn't run autoreconf before running ./configure. Since I've added files and changed Makefile.am, it needs to regenerate the Makefile.in's.

- -Jeff

- --
Jeff Mahoney
SUSE Labs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.8 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iEYEARECAAYFAkfnES4ACgkQLPWxlyuTD7KtQQCgmjsZlThZ9I+RqGYjrrHS2ssA 0KcAmwc4Lah1F8RsOtPvPD0St04Pya1Q
=MjSs
-----END PGP SIGNATURE-----

From: Jeff Mahoney <[email protected]>
Subject: [PATCH 1/2] reiserfsprogs: add ext3-style mount count and last check expiry for better fsck -a behavior

Currently, fsck.reiserfs -a <dev> performs a full --check scan on every reiserfs file system during every boot. This is obviously suboptimal, since it kills one of the major features of a journaled file system.

This patch adds mount counting and last check expiration to fsck, mkfs, and debugfs so that we can perform fscks on a user defined schedule.

The defaults are 180 days or 30 mounts before fsck -a results in a full scan.

On file systems where this feature hasn't yet been enabled, the fsck -a will perform a full scan and then mark the superblock with the defaults.

While the mount count won't work with kernels that don't support it, the timeout obviously will. I'll be following this patch up with a kernel patch that reserves the fields and updates the mount counts.

This support is super important with multi-terabyte file systems, since the check is causing huge delays during mount.

Whether or not this patch is immediately accepted into the reiserfsprogs repository, I'd at least like confirmation that I can reserve these fields in the superblock for this purpose.

Thanks.

---

 configure.in               |    2 
 fsck/fsck.h                |    3 -
 fsck/main.c                |   78 ++++++++++++++++++++++++++++-
 fsck/reiserfsck.8          |   10 ++-
 include/Makefile.am        |    2 
 include/parse_time.h       |   15 +++++
 include/reiserfs_fs.h      |   25 +++++++++
 lib/Makefile.am            |    2 
 lib/parse_time.c           |   37 +++++++++++++
 reiserfscore/prints.c      |   29 ++++++++++
 reiserfscore/reiserfslib.c |    7 ++
 tune/reiserfstune.8        |   77 ++++++++++++++++++++++++++++
 tune/tune.c                |  120 +++++++++++++++++++++++++++++++++++++++++++--
 13 files changed, 393 insertions(+), 14 deletions(-)
configure.in +1 -1
@@ -105,7 +105,7 @@ AC_FUNC_MEMCMP
 AC_FUNC_STRFTIME
 AC_FUNC_VPRINTF
 AC_CHECK_FUNCS(strerror strstr strtol register_printf_function statfs getmntent\
-	       hasmntopt memset time uname)
+	       hasmntopt memset time uname strptime ctime_r)
 
 
 dnl Never enable this. It is for debugging only
fsck/fsck.h +2 -1
@@ -62,7 +62,8 @@ int main (int argc, char * argv []);
 #define OPT_SAVE_PASSES_DUMP            1 << 7
 #define OPT_SAVE_ROLLBACK               1 << 8
 #define OPT_YES				1 << 9
-#define BADBLOCKS_FILE               	1 << 10
+#define BADBLOCKS_FILE			1 << 10
+#define OPT_FORCE			1 << 11
 
 
 /* pass0.c */
fsck/main.c +76 -2

138 lines not on this page · raw message

fsck/reiserfsck.8 +7 -3
@@ -6,7 +6,7 @@
 reiserfsck \- The checking tool for the ReiserFS filesystem.
 .SH SYNOPSIS
 .B reiserfsck 
-[ \fB-afprVy\fR ]
+[ \fB-aprVy\fR ]
 [ \fB--rebuild-sb\fR | \fB--check\fR | \fB--fix-fixable\fR
 | \fB--rebuild-tree\fR | \fB--clean-attributes\fR ]
 .\" [ \fB-i\fR | \fB--interactive\fR ]
@@ -17,6 +17,7 @@ reiserfsck \- The checking tool for the
 [ \fB-l\fR | \fB--logfile \fIfile\fR ]
 [ \fB-q\fR | \fB--quiet\fR ]
 [ \fB-y\fR | \fB--yes\fR ]
+[ \fB-f\fR | \fB--force\fR ]
 .\" [ \fB-b\fR | \fB--scan-marked-in-bitmap \fIbitmap-filename\fR ]
 .\" [ \fB-h\fR | \fB--hash \fIhash-name\fR ]
 .\" [ \fB-g\fR | \fB--background\fR ]
@@ -122,11 +123,14 @@ corruption is found set in the superbloc
 to the fix-fixable mode. If the flag indicating a fatal corruption is found 
 set in the superblock, then \fBreiserfsck\fR finishes with an error.
 .TP
+.B --force, -f
+Force checking even if the file system seems clean.
+.TP
 .B -V
 This option prints the reiserfsprogs version and then exit.
 .TP
-\fB-r\fR, \fB-f\fR
-These options are not yet operational and therefore are ignored.
+\fB-r\fR This option does nothing at all; it is provided only for
+backwards compatibility.
 .SH EXPERT OPTIONS
 DO NOT USE THESE OPTIONS UNLESS YOU KNOW WHAT YOU ARE DOING. 
 WE ARE NOT RESPONSIBLE IF YOU LOSE DATA AS A RESULT OF THESE
include/Makefile.am +1 -1
@@ -1 +1 @@
-noinst_HEADERS = io.h  misc.h  reiserfs_fs.h  reiserfs_lib.h swab.h
+noinst_HEADERS = io.h  misc.h  reiserfs_fs.h  reiserfs_lib.h swab.h parse_time.h
include/parse_time.h new file +15 -0
@@ -0,0 +1,15 @@
+/*
+ * Copyright 1996-2004 by Hans Reiser, licensing governed by
+ * reiserfsprogs/README
+ */
+
+/* nothing abount reiserfs here */
+
+#ifndef TIME_H
+#define TIME_H
+
+#include <time.h>
+
+time_t parse_time(char *str);
+
+#endif /* TIME_H */
include/reiserfs_fs.h +24 -1
@@ -202,7 +202,11 @@ struct reiserfs_super_block
 /* 80 */     __u32 s_flags;                /* Right now used only by inode-attributes, if enabled */
 /* 84 */    unsigned char s_uuid[16];      /* filesystem unique identifier */
 /*100 */    unsigned char s_label[16];     /* filesystem volume label */
-/*116 */    char s_unused[88] ;            /* zero filled by mkreiserfs and reiserfs_convert_objectid_map_v1()
+/*116 */    __u16 s_mnt_count;
+/*118 */    __u16 s_max_mnt_count;
+/*120 */    __u32 s_lastcheck;
+/*124 */    __u32 s_check_interval;
+/*128 */    char s_unused[76] ;            /* zero filled by mkreiserfs and reiserfs_convert_objectid_map_v1()
                                             * so any additions must be updated there as well. */ 
 /*204*/
 } __attribute__ ((__packed__));;
@@ -266,6 +270,22 @@ typedef enum {
 #define get_sb_v2_inode_generation(sb)		get_le32 (sb, sb_inode_generation)
 #define set_sb_v2_inode_generation(sb,val)	set_le32 (sb, sb_inode_generation, val)
 
+#define get_sb_v2_mnt_count(sb)		get_le16 (sb, s_mnt_count)
+#define set_sb_v2_mnt_count(sb,val)	set_le16 (sb, s_mnt_count, val)
+
+#define get_sb_v2_max_mnt_count(sb)				\
+	get_le16 (sb, s_max_mnt_count)
+#define set_sb_v2_max_mnt_count(sb,val)			\
+	set_le16 (sb, s_max_mnt_count, val)
+
+#define get_sb_v2_lastcheck(sb)		get_le32 (sb, s_lastcheck)
+#define set_sb_v2_lastcheck(sb,val)		set_le32 (sb, s_lastcheck, val)
+
+#define get_sb_v2_check_interval(sb)				\
+	get_le32 (sb, s_check_interval)
+#define set_sb_v2_check_interval(sb,val)			\
+	set_le32 (sb, s_check_interval, val)
+
 #define get_sb_v2_flags(sb)		get_le32 (sb, s_flags)
 #define set_sb_v2_flags(sb, val)	set_le32 (sb, s_flags, val)
 
@@ -277,6 +297,9 @@ typedef enum {
 #define journal_is_relocated(sb)        get_jp_journal_dev(sb_jp (sb))
 */
 
+#define DEFAULT_MAX_MNT_COUNT	30			/* 30 mounts */
+#define DEFAULT_CHECK_INTERVAL	(180 * 60 * 60 * 24)	/* 180 days */
+
 /* these are possible values for sb_fs_state */
 #define FS_CONSISTENT   0x0	    /* this is set by mkreiserfs and by reiserfsck */
 #define FS_ERROR	0x1	    /* this is set by the kernel when fsck is wanted. */
lib/Makefile.am +1 -1
@@ -1,5 +1,5 @@
 noinst_LIBRARIES = libmisc.a
 
-libmisc_a_SOURCES = io.c misc.c 
+libmisc_a_SOURCES = io.c misc.c parse_time.c
 ##reiserfs.c
 
lib/parse_time.c new file +37 -0
@@ -0,0 +1,37 @@
+#define _XOPEN_SOURCE
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "misc.h"
+#include "reiserfs_lib.h"
+
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+
+time_t parse_time(char *str)
+{
+	struct tm ts;
+
+	if (strcmp(str, "now") == 0) {
+		return (time(0));
+	}
+	memset(&ts, 0, sizeof (ts));
+#ifdef HAVE_STRPTIME
+	strptime(str, "%Y%m%d%H%M%S", &ts);
+#else
+	sscanf(str, "%4d%2d%2d%2d%2d%2d", &ts.tm_year, &ts.tm_mon,
+	       &ts.tm_mday, &ts.tm_hour, &ts.tm_min, &ts.tm_sec);
+	ts.tm_year -= 1900;
+	ts.tm_mon -= 1;
+	if (ts.tm_year < 0 || ts.tm_mon < 0 || ts.tm_mon > 11 ||
+	    ts.tm_mday < 0 || ts.tm_mday > 31 || ts.tm_hour > 23 ||
+	    ts.tm_min > 59 || ts.tm_sec > 61)
+		ts.tm_mday = 0;
+#endif
+	if (ts.tm_mday == 0)
+		reiserfs_warning(stderr, "Couldn't parse date/time "
+		                 "specifier: %s", str);
+	return (mktime(&ts));
+}
reiserfscore/prints.c +29 -0
@@ -9,6 +9,8 @@
 #include <stdarg.h>
 #include <limits.h>
 #include <printf.h>
+#include <limits.h>
+#include <time.h>
 
 #if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H)
 #  include <uuid/uuid.h>
@@ -612,6 +614,8 @@ int print_super_block (FILE * fp, reiser
     dev_t rdev;
     int format = 0;
     __u16 state;
+    time_t last_check = get_sb_v2_lastcheck(sb);
+    char last_check_buf[26];
 
     if (!does_look_like_super_block (sb))
 	return 1;
@@ -680,6 +684,31 @@ int print_super_block (FILE * fp, reiser
         reiserfs_warning (fp, "Set flags in SB:\n");
 	if ((get_sb_v2_flag (sb, reiserfs_attrs_cleared)))
 	    reiserfs_warning (fp, "\tATTRIBUTES CLEAN\n");
+	reiserfs_warning(fp, "Mount count: %u\n",
+			 get_sb_v2_mnt_count(sb));
+	reiserfs_warning(fp, "Maximum mount count: ");
+	if (get_sb_v2_max_mnt_count(sb) &&
+	    get_sb_v2_max_mnt_count(sb) != USHRT_MAX)
+		reiserfs_warning(fp, "%u\n", get_sb_v2_max_mnt_count(sb));
+	else if (get_sb_v2_max_mnt_count(sb) == USHRT_MAX)
+		reiserfs_warning(fp, "Administratively disabled.\n");
+	else
+		reiserfs_warning(fp, "Disabled. Run fsck.reiserfs(8) or use tunefs.reiserfs(8) to enable.\n");
+	if (last_check) {
+		ctime_r(&last_check, last_check_buf);
+		reiserfs_warning(fp, "Last fsck run: %s", last_check_buf);
+	} else
+		reiserfs_warning(fp, "Last fsck run: Never with a version "
+				 "that supports this feature.\n");
+	reiserfs_warning(fp, "Check interval in days: ");
+	if (get_sb_v2_check_interval(sb) &&
+	    get_sb_v2_check_interval(sb) != UINT_MAX)
+		reiserfs_warning(fp, "%u\n",
+			 get_sb_v2_check_interval(sb) / (24*60*60));
+	else if (get_sb_v2_check_interval(sb) == UINT_MAX)
+		reiserfs_warning(fp, "Administratively disabled.\n");
+	else
+		reiserfs_warning(fp, "Disabled. Run fsck.reiserfs(8) or use tunefs.reiserfs(8) to enable.\n");
     }
 
     return 0;
reiserfscore/reiserfslib.c +7 -0
@@ -7,6 +7,7 @@
 
 #include "includes.h"
 #include <linux/kdev_t.h>
+#include <time.h>
 
 struct key root_dir_key = {0, 0, {{0, 0},}};
 struct key parent_root_dir_key = {0, 0, {{0, 0},}};
@@ -183,6 +184,7 @@ reiserfs_filsys_t * reiserfs_create (cha
 {
     reiserfs_filsys_t * fs;
     unsigned int bmap_nr = reiserfs_bmap_nr(block_count, block_size);;
+    time_t now;
 
 
     /* convert root dir key and parent root dir key to little endian format */
@@ -285,6 +287,11 @@ reiserfs_filsys_t * reiserfs_create (cha
                     reiserfs_bmap_over(bmap_nr) ? 0 : bmap_nr);
 
     set_sb_version (fs->fs_ondisk_sb, version);
+    set_sb_v2_lastcheck(fs->fs_ondisk_sb, time(&now));
+    set_sb_v2_check_interval(fs->fs_ondisk_sb, DEFAULT_CHECK_INTERVAL);
+    set_sb_v2_mnt_count(fs->fs_ondisk_sb, 1);
+    set_sb_v2_max_mnt_count(fs->fs_ondisk_sb, DEFAULT_MAX_MNT_COUNT);
+
     /* sb_not_used1 */
 
     mark_buffer_dirty (fs->fs_super_bh);
tune/reiserfstune.8 +77 -0

101 lines not on this page · raw message

tune/tune.c +116 -4

188 lines not on this page · raw message

Subject: [PATCH] reiserfsprogs: Warn on block sizes > 4k
From: Jeff Mahoney <[email protected]>

Filesystems created with block size > page size will not work until that support is added to the kernel. Filesystems with block size > 4k (lowest page size supported in Linux) will not work on all systems. This patch adds a check and a warning in those conditions, informing the user of the caveats of using a larger block size. It can be overridden with -f.

---
 include/reiserfs_lib.h     |    1 +
 mkreiserfs/mkreiserfs.c    |    3 +++
 reiserfscore/reiserfslib.c |   18 ++++++++++++++++++
 3 files changed, 22 insertions(+)
include/reiserfs_lib.h +1 -0
@@ -92,6 +92,7 @@ void reiserfs_read_bitmap_blocks (reiser
 void reiserfs_free_bitmap_blocks (reiserfs_filsys_t *);
 */
 int no_reiserfs_found (reiserfs_filsys_t *);
+int block_size_ok(int blocksize, int force);
 int is_block_count_correct (unsigned long block_of_super_block, unsigned int block_size,
 	unsigned long block_count, unsigned long journal_size);
 //unsigned long min_block_amount (int block_size, unsigned long journal_size);
mkreiserfs/mkreiserfs.c +3 -0
@@ -686,6 +686,9 @@ int main (int argc, char **argv)
     
     if (!(mode & QUIET_MODE) && !can_we_format_it (device_name, force))
         return 1;
+
+    if (!(mode & QUIET_MODE) && !block_size_ok (Block_size, force))
+        return 1;
 	
     if (jdevice_name)
         if (!(mode & QUIET_MODE) && !can_we_format_it (jdevice_name, force))
reiserfscore/reiserfslib.c +18 -0
@@ -1175,6 +1175,24 @@ void make_sure_root_dir_exists (reiserfs
     		&parent_root_dir_key, ih_flags);
 }
 
+int block_size_ok (int blocksize, int force)
+{
+    int pagesize = getpagesize();
+    if (blocksize > 4096) {
+        reiserfs_warning (stderr, "Block sizes larger than 4k are not "
+                          "supported on all architectures.\n");
+        if (blocksize > pagesize)
+            reiserfs_warning (stderr, "The newly created filesystem will not "
+                              "be mountable on this system.\n");
+        else
+            reiserfs_warning (stderr, "The newly created filesystem may not "
+                              "be mountable on other systems.\n");
+        check_forcing_ask_confirmation (force);
+    }
+
+    return 1;
+}
+
 
 /* we only can use a file for filesystem or journal if it is either not
    mounted block device or regular file and we are forced to use it */
#15 lore raw

Well, I am about to release reiserfsprogs-3.6.21, which includes the following changes since 3.6.19:

Jeff Mahoney:
- mkreiserfs-quiet.diff
- reiserfsprogs-large-block-warning.diff
- reiserfsprogs-fsck-mapid.diff
- reiserfsprogs-external-journal-changes.diff
- reiserfsprogs-remove-stupid-fsck_sleep.diff
- reiserfsprogs-mkfs-use-o_excl.diff
- reiserfsprogs-enforce-block-limit.diff
- reiserfsprogs-large-fs.diff
- reiserfsprogs-better-fsck-a-behavior.diff
- reiserfsprogs-remove-dependency-on-asm_unaligned.h.diff

Ludwig Nussel:
- mkreiserfs-set-the-owner-of-the-root-directory-to-the-calling-user.diff

Edward Shishkin:
- mkreiserfs-disable-small-block-sizes.diff

Jeff, do you have something to add here?
Sorry for delay.

Edward.

Quoted 40 lines
Quoted 11 lines · Edward Shishkin
Quoted 9 lines · Jeff Mahoney
Quoted 2 lines · Edward Shishkin

Thanks, queued.
Btw I got compilation errors. Have you missed something?

Yeah, I guess I did. It builds fine on my SLES boxes, but not on my openSUSE machines. I'll them up for that (I need to anyway) and resend.

Quoted 7 lines

The following makes me think that something is
missed (the patch series was applied to 3.6.19):

main.c: In function `reiserfs_check_auto_state':
main.c:971: warning: unsigned int format, long int arg (arg 3) mkreiserfs.c: In function `main':
mkreiserfs.c:730: warning: implicit declaration of function

`block_size_ok'

This was a missing entry in reiserfs_lib.h. I've attached an updated patch that adds it. I've also attached an updated reiserfsprogs-better-fsck-a-behavior. The only difference is the addition of "#define _XOPEN_SOURCE" for the strptime prototype. There was a warning for that too.

Quoted 5 lines

tune.o(.text+0xa86): In function `main':
/home/edward/work/reiserfsprogs-3.6.19/tune/tune.c:268: undefined reference to `parse_time'
collect2: ld returned 1 exit status
make[1]: *** [reiserfstune] Error 1

This one looks like you didn't run autoreconf before running ./configure. Since I've added files and changed Makefile.am, it needs to regenerate the Makefile.in's.

Quoted 5 lines

-Jeff

--
Jeff Mahoney
SUSE Labs

-------------------------

From: Jeff Mahoney <[email protected]>
Subject: [PATCH 1/2] reiserfsprogs: add ext3-style mount count and last check expiry for better fsck -a behavior

Currently, fsck.reiserfs -a <dev> performs a full --check scan on every reiserfs file system during every boot. This is obviously suboptimal, since it kills one of the major features of a journaled file system.

This patch adds mount counting and last check expiration to fsck, mkfs, and debugfs so that we can perform fscks on a user defined schedule.

The defaults are 180 days or 30 mounts before fsck -a results in a full scan.

On file systems where this feature hasn't yet been enabled, the fsck -a will perform a full scan and then mark the superblock with the defaults.

While the mount count won't work with kernels that don't support it, the timeout obviously will. I'll be following this patch up with a kernel patch that reserves the fields and updates the mount counts.

This support is super important with multi-terabyte file systems, since the check is causing huge delays during mount.

Whether or not this patch is immediately accepted into the reiserfsprogs repository, I'd at least like confirmation that I can reserve these fields in the superblock for this purpose.

Thanks.

---

configure.in | 2
fsck/fsck.h | 3 -
fsck/main.c | 78 ++++++++++++++++++++++++++++- fsck/reiserfsck.8 | 10 ++-
include/Makefile.am | 2
include/parse_time.h | 15 +++++
include/reiserfs_fs.h | 25 +++++++++
lib/Makefile.am | 2
lib/parse_time.c | 37 +++++++++++++ reiserfscore/prints.c | 29 ++++++++++ reiserfscore/reiserfslib.c | 7 ++
tune/reiserfstune.8 | 77 ++++++++++++++++++++++++++++ tune/tune.c | 120 +++++++++++++++++++++++++++++++++++++++++++--

13 files changed, 393 insertions(+), 14 deletions(-)
configure.in 2008-03-23 22:09:44.000000000 -0400 renamed from configure.in 2008-03-23 22:09:31.000000000 -0400 +0 -0
@@ -105,7 +105,7 @@ AC_FUNC_MEMCMP

AC_FUNC_STRFTIME
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(strerror strstr strtol register_printf_function statfs getmntent\
- hasmntopt memset time uname)
+ hasmntopt memset time uname strptime ctime_r)

dnl Never enable this. It is for debugging only

fsck/fsck.h 2008-03-23 22:09:44.000000000 -0400 renamed from fsck/fsck.h 2008-03-23 22:09:31.000000000 -0400 +0 -0
@@ -62,7 +62,8 @@ int main (int argc, char * argv []);

#define OPT_SAVE_PASSES_DUMP 1 << 7
#define OPT_SAVE_ROLLBACK 1 << 8
#define OPT_YES 1 << 9
-#define BADBLOCKS_FILE 1 << 10
+#define BADBLOCKS_FILE 1 << 10
+#define OPT_FORCE 1 << 11

/* pass0.c */

fsck/main.c 2008-03-23 22:09:44.000000000 -0400 renamed from fsck/main.c 2008-03-23 22:09:31.000000000 -0400 +0 -0
@@ -8,6 +8,7 @@

#include <sys/resource.h>
#include <sys/mman.h>
#include <signal.h>
+#include <limits.h>

extern int screen_width;
extern int screen_savebuffer_len;
@@ -37,9 +38,10 @@ fsck_progress ("Usage: %s [mode] [option

" -z | --adjust-size\t\tfix file sizes to real size\n" \
" -q | --quiet\t\t\tno speed info\n" \
" -y | --yes\t\t\tno confirmations\n" \

+" -f | --force\t\tforce checking even if the file system is marked clean\n"\
" -V\t\t\t\tprints version and exits\n" \
" -a and -p\t\t\tsome light-weight auto checks for bootup\n" \
-" -f and -r\t\t\tignored\n" \
+" -r\t\t\tignored\n" \
"Expert options:\n" \
" --no-journal-available\tdo not open nor replay journal\n" \
" -S | --scan-whole-partition\tbuild tree of all blocks of the device\n\n", \
@@ -103,6 +105,7 @@ static char * parse_options (struct fsck {"adjust-size", no_argument, 0, 'z'},
{"quiet", no_argument, 0, 'q'},
{"yes", no_argument, 0, 'y'},
+ {"force", no_argument, 0, 'f'},
{"nolog", no_argument, 0, 'n'},

/* if file exists ad reiserfs can be load of it - only @@ -233,6 +236,8 @@ static char * parse_options (struct fsck break;

case 'f':
+ data->options |= OPT_FORCE;
+ break;
case 'r': /* ignored */
break;

@@ -665,6 +670,22 @@ static int where_to_start_from (reiserfs return START_FROM_THE_BEGINNING;
}

+static void reiserfs_update_interval_fields(reiserfs_filsys_t *fs) +{
+ /* Not supported on v3.5 */
+ if (get_sb_version (fs->fs_ondisk_sb) == REISERFS_FORMAT_3_5)
+ return;
+
+ set_sb_v2_lastcheck(fs->fs_ondisk_sb, time(NULL));
+ set_sb_v2_mnt_count(fs->fs_ondisk_sb, 1);
+
+ if (get_sb_v2_max_mnt_count(fs->fs_ondisk_sb) == 0)
+ set_sb_v2_max_mnt_count(fs->fs_ondisk_sb,
+ DEFAULT_MAX_MNT_COUNT);
+ if (get_sb_v2_check_interval(fs->fs_ondisk_sb) == 0)
+ set_sb_v2_check_interval(fs->fs_ondisk_sb,
+ DEFAULT_CHECK_INTERVAL);
+}

static void mark_filesystem_consistent (reiserfs_filsys_t * fs) {
@@ -687,6 +708,7 @@ static void mark_filesystem_consistent (

set_sb_umount_state (fs->fs_ondisk_sb, FS_CLEANLY_UMOUNTED); set_sb_fs_state (fs->fs_ondisk_sb, FS_CONSISTENT);
+ reiserfs_update_interval_fields(fs);

mark_buffer_dirty (fs->fs_super_bh);
}
@@ -924,9 +946,51 @@ static void clean_attributes (reiserfs_f

}

+static int reiserfs_check_auto_state(reiserfs_filsys_t *fs) +{
+ time_t now = time(NULL);
+ time_t lastcheck = get_sb_v2_lastcheck(fs->fs_ondisk_sb);
+ unsigned int mnt_count = get_sb_v2_mnt_count(fs->fs_ondisk_sb);
+ unsigned int max_mnt_count = get_sb_v2_max_mnt_count(fs->fs_ondisk_sb);
+ unsigned int interval = get_sb_v2_check_interval(fs->fs_ondisk_sb); +
+ /* v3.5 file systems don't have the superblock fields for this */
+ if (get_sb_version (fs->fs_ondisk_sb) == REISERFS_FORMAT_3_5)
+ return 1;
+
+ if (lastcheck == 0 || mnt_count == 0 || max_mnt_count == 0 ||
+ interval == 0) {
+ fprintf(stderr, "File system hasn't been enabled for faster "
+ "boot-time checking. It will be enabled after a "
+ "successful run.\n");
+ return 1;
+ }
+
+ if (interval != UINT_MAX && now > lastcheck + interval) {
+ fprintf(stderr, "File system hasn't been checked in %u days. "
+ "Checking now.\n", (now - lastcheck) / (60*60*24));
+ return 1;
+ }
+
+ if (interval != UINT_MAX && lastcheck > now) {
+ fprintf(stderr, "File system check timestamp is in the future. "
+ "Checking now.\n");
+ return 1;
+ }
+
+ if (mnt_count > max_mnt_count && max_mnt_count != USHRT_MAX) {
+ fprintf(stderr, "File system has been mounted %u times "
+ "without being checked. Checking now.\n", mnt_count);
+ return 1;
+ }
+
+ return 0;
+}
+
static int auto_check (reiserfs_filsys_t *fs) {
__u16 state;
int retval = 0;
+ int force = fsck_data(fs)->options & OPT_FORCE;

print_super_block (stdout, fs, fs->fs_file_name, fs->fs_super_bh, 1);

@@ -948,7 +1012,12 @@ static int auto_check (reiserfs_filsys_t fprintf(stderr, "Some strange state was specified in the super block. " "Do usual check.\n");

+ if (get_sb_umount_state (fs->fs_ondisk_sb) == FS_CLEANLY_UMOUNTED &&
+ !force && !reiserfs_check_auto_state(fs))
+ exit(EXIT_OK);
prepare_fs_for_check(fs);
+ if (!force && !reiserfs_check_auto_state(fs))
+ exit(EXIT_OK);

/* Check bitmaps. */
retval = reiserfs_open_ondisk_bitmap (fs);
@@ -987,7 +1056,12 @@ static int auto_check (reiserfs_filsys_t /* run fixable pass. */
return 0;
}
-
+
+ reiserfs_update_interval_fields(fs);
+ mark_buffer_dirty(fs->fs_super_bh);
+ bwrite(fs->fs_super_bh);
+ fs->fs_dirt = 1;
+
clean_after_dma_check(fs->fs_dev, &dma_info);

reiserfs_close (fs);

fsck/reiserfsck.8 2008-03-23 22:09:44.000000000 -0400 renamed from fsck/reiserfsck.8 2008-03-23 22:09:31.000000000 -0400 +0 -0
@@ -6,7 +6,7 @@

reiserfsck \- The checking tool for the ReiserFS filesystem. .SH SYNOPSIS
.B reiserfsck
-[ \fB-afprVy\fR ]
+[ \fB-aprVy\fR ]
[ \fB--rebuild-sb\fR | \fB--check\fR | \fB--fix-fixable\fR

| \fB--rebuild-tree\fR | \fB--clean-attributes\fR ]
.\" [ \fB-i\fR | \fB--interactive\fR ]
@@ -17,6 +17,7 @@ reiserfsck \- The checking tool for the
[ \fB-l\fR | \fB--logfile \fIfile\fR ]
[ \fB-q\fR | \fB--quiet\fR ]
[ \fB-y\fR | \fB--yes\fR ]
+[ \fB-f\fR | \fB--force\fR ]
.\" [ \fB-b\fR | \fB--scan-marked-in-bitmap \fIbitmap-filename\fR ]
.\" [ \fB-h\fR | \fB--hash \fIhash-name\fR ]
.\" [ \fB-g\fR | \fB--background\fR ]

@@ -122,11 +123,14 @@ corruption is found set in the superbloc to the fix-fixable mode. If the flag indicating a fatal corruption is found set in the superblock, then \fBreiserfsck\fR finishes with an error. .TP
+.B --force, -f
+Force checking even if the file system seems clean.
+.TP
.B -V
This option prints the reiserfsprogs version and then exit.
.TP
-\fB-r\fR, \fB-f\fR
-These options are not yet operational and therefore are ignored. +\fB-r\fR This option does nothing at all; it is provided only for +backwards compatibility.
.SH EXPERT OPTIONS
DO NOT USE THESE OPTIONS UNLESS YOU KNOW WHAT YOU ARE DOING.
WE ARE NOT RESPONSIBLE IF YOU LOSE DATA AS A RESULT OF THESE

include/Makefile.am 2008-03-23 22:09:44.000000000 -0400 renamed from include/Makefile.am 2008-03-23 22:09:31.000000000 -0400 +1 -1
@@ -1 +1 @@
-noinst_HEADERS = io.h misc.h reiserfs_fs.h reiserfs_lib.h swab.h
+noinst_HEADERS = io.h misc.h reiserfs_fs.h reiserfs_lib.h swab.h parse_time.h
include/parse_time.h 2008-03-23 22:09:44.000000000 -0400 renamed from dev/null 1970-01-01 00:00:00.000000000 +0000 +15 -0
@@ -0,0 +1,15 @@
+/*
+ * Copyright 1996-2004 by Hans Reiser, licensing governed by
+ * reiserfsprogs/README
+ */
+
+/* nothing abount reiserfs here */
+
+#ifndef TIME_H
+#define TIME_H
+
+#include <time.h>
+
+time_t parse_time(char *str);
+
+#endif /* TIME_H */
include/reiserfs_fs.h 2008-03-23 22:09:44.000000000 -0400 renamed from include/reiserfs_fs.h 2008-03-23 22:09:31.000000000 -0400 +0 -0
@@ -202,7 +202,11 @@ struct reiserfs_super_block

/* 80 */ __u32 s_flags; /* Right now used only by inode-attributes, if enabled */ /* 84 */ unsigned char s_uuid[16]; /* filesystem unique identifier */
/*100 */ unsigned char s_label[16]; /* filesystem volume label */
-/*116 */ char s_unused[88] ; /* zero filled by mkreiserfs and reiserfs_convert_objectid_map_v1() +/*116 */ __u16 s_mnt_count;
+/*118 */ __u16 s_max_mnt_count;
+/*120 */ __u32 s_lastcheck;
+/*124 */ __u32 s_check_interval;
+/*128 */ char s_unused[76] ; /* zero filled by mkreiserfs and reiserfs_convert_objectid_map_v1()
* so any additions must be updated there as well. */
/*204*/
} __attribute__ ((__packed__));;
@@ -266,6 +270,22 @@ typedef enum {
#define get_sb_v2_inode_generation(sb) get_le32 (sb, sb_inode_generation)
#define set_sb_v2_inode_generation(sb,val) set_le32 (sb, sb_inode_generation, val)

+#define get_sb_v2_mnt_count(sb) get_le16 (sb, s_mnt_count) +#define set_sb_v2_mnt_count(sb,val) set_le16 (sb, s_mnt_count, val) +
+#define get_sb_v2_max_mnt_count(sb) \
+ get_le16 (sb, s_max_mnt_count)
+#define set_sb_v2_max_mnt_count(sb,val) \
+ set_le16 (sb, s_max_mnt_count, val)
+
+#define get_sb_v2_lastcheck(sb) get_le32 (sb, s_lastcheck) +#define set_sb_v2_lastcheck(sb,val) set_le32 (sb, s_lastcheck, val) +
+#define get_sb_v2_check_interval(sb) \
+ get_le32 (sb, s_check_interval)
+#define set_sb_v2_check_interval(sb,val) \
+ set_le32 (sb, s_check_interval, val)
+
#define get_sb_v2_flags(sb) get_le32 (sb, s_flags) #define set_sb_v2_flags(sb, val) set_le32 (sb, s_flags, val)

@@ -277,6 +297,9 @@ typedef enum {
#define journal_is_relocated(sb) get_jp_journal_dev(sb_jp (sb)) */

+#define DEFAULT_MAX_MNT_COUNT 30 /* 30 mounts */
+#define DEFAULT_CHECK_INTERVAL (180 * 60 * 60 * 24) /* 180 days */ +
/* these are possible values for sb_fs_state */
#define FS_CONSISTENT 0x0 /* this is set by mkreiserfs and by reiserfsck */ #define FS_ERROR 0x1 /* this is set by the kernel when fsck is wanted. */

lib/Makefile.am 2008-03-23 22:09:44.000000000 -0400 renamed from lib/Makefile.am 2008-03-23 22:09:31.000000000 -0400 +0 -0
@@ -1,5 +1,5 @@

noinst_LIBRARIES = libmisc.a

-libmisc_a_SOURCES = io.c misc.c
+libmisc_a_SOURCES = io.c misc.c parse_time.c
##reiserfs.c

lib/parse_time.c 2008-03-23 22:12:26.000000000 -0400 renamed from dev/null 1970-01-01 00:00:00.000000000 +0000 +37 -0
@@ -0,0 +1,37 @@
+#define _XOPEN_SOURCE
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "misc.h"
+#include "reiserfs_lib.h"
+
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+
+time_t parse_time(char *str)
+{
+ struct tm ts;
+
+ if (strcmp(str, "now") == 0) {
+ return (time(0));
+ }
+ memset(&ts, 0, sizeof (ts));
+#ifdef HAVE_STRPTIME
+ strptime(str, "%Y%m%d%H%M%S", &ts);
+#else
+ sscanf(str, "%4d%2d%2d%2d%2d%2d", &ts.tm_year, &ts.tm_mon,
+ &ts.tm_mday, &ts.tm_hour, &ts.tm_min, &ts.tm_sec);
+ ts.tm_year -= 1900;
+ ts.tm_mon -= 1;
+ if (ts.tm_year < 0 || ts.tm_mon < 0 || ts.tm_mon > 11 ||
+ ts.tm_mday < 0 || ts.tm_mday > 31 || ts.tm_hour > 23 ||
+ ts.tm_min > 59 || ts.tm_sec > 61)
+ ts.tm_mday = 0;
+#endif
+ if (ts.tm_mday == 0)
+ reiserfs_warning(stderr, "Couldn't parse date/time "
+ "specifier: %s", str);
+ return (mktime(&ts));
+}
reiserfscore/prints.c 2008-03-23 22:09:44.000000000 -0400 renamed from reiserfscore/prints.c 2008-03-23 22:09:31.000000000 -0400 +0 -0
@@ -9,6 +9,8 @@

#include <stdarg.h>
#include <limits.h>
#include <printf.h>
+#include <limits.h>
+#include <time.h>

#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H)

# include <uuid/uuid.h>
@@ -612,6 +614,8 @@ int print_super_block (FILE * fp, reiser
dev_t rdev;
int format = 0;
__u16 state;
+ time_t last_check = get_sb_v2_lastcheck(sb);
+ char last_check_buf[26];

if (!does_look_like_super_block (sb))
return 1;
@@ -680,6 +684,31 @@ int print_super_block (FILE * fp, reiser
reiserfs_warning (fp, "Set flags in SB:\n");
if ((get_sb_v2_flag (sb, reiserfs_attrs_cleared)))
reiserfs_warning (fp, "\tATTRIBUTES CLEAN\n");
+ reiserfs_warning(fp, "Mount count: %u\n",
+ get_sb_v2_mnt_count(sb));
+ reiserfs_warning(fp, "Maximum mount count: ");
+ if (get_sb_v2_max_mnt_count(sb) &&
+ get_sb_v2_max_mnt_count(sb) != USHRT_MAX)
+ reiserfs_warning(fp, "%u\n", get_sb_v2_max_mnt_count(sb));
+ else if (get_sb_v2_max_mnt_count(sb) == USHRT_MAX)
+ reiserfs_warning(fp, "Administratively disabled.\n");
+ else
+ reiserfs_warning(fp, "Disabled. Run fsck.reiserfs(8) or use tunefs.reiserfs(8) to enable.\n");
+ if (last_check) {
+ ctime_r(&last_check, last_check_buf);
+ reiserfs_warning(fp, "Last fsck run: %s", last_check_buf);
+ } else
+ reiserfs_warning(fp, "Last fsck run: Never with a version "
+ "that supports this feature.\n");
+ reiserfs_warning(fp, "Check interval in days: ");
+ if (get_sb_v2_check_interval(sb) &&
+ get_sb_v2_check_interval(sb) != UINT_MAX)
+ reiserfs_warning(fp, "%u\n",
+ get_sb_v2_check_interval(sb) / (24*60*60));
+ else if (get_sb_v2_check_interval(sb) == UINT_MAX)
+ reiserfs_warning(fp, "Administratively disabled.\n");
+ else
+ reiserfs_warning(fp, "Disabled. Run fsck.reiserfs(8) or use tunefs.reiserfs(8) to enable.\n"); }

return 0;

reiserfscore/reiserfslib.c 2008-03-23 22:12:37.000000000 -0400 renamed from reiserfscore/reiserfslib.c 2008-03-23 22:09:31.000000000 -0400 +0 -0
@@ -7,6 +7,7 @@
 

#include "includes.h"
#include <linux/kdev_t.h>
+#include <time.h>

struct key root_dir_key = {0, 0, {{0, 0},}};
struct key parent_root_dir_key = {0, 0, {{0, 0},}};
@@ -183,6 +184,7 @@ reiserfs_filsys_t * reiserfs_create (cha {
reiserfs_filsys_t * fs;
unsigned int bmap_nr = reiserfs_bmap_nr(block_count, block_size);;
+ time_t now;

/* convert root dir key and parent root dir key to little endian format */ @@ -285,6 +287,11 @@ reiserfs_filsys_t * reiserfs_create (cha reiserfs_bmap_over(bmap_nr) ? 0 : bmap_nr);

set_sb_version (fs->fs_ondisk_sb, version);
+ set_sb_v2_lastcheck(fs->fs_ondisk_sb, time(&now));
+ set_sb_v2_check_interval(fs->fs_ondisk_sb, DEFAULT_CHECK_INTERVAL);
+ set_sb_v2_mnt_count(fs->fs_ondisk_sb, 1);
+ set_sb_v2_max_mnt_count(fs->fs_ondisk_sb, DEFAULT_MAX_MNT_COUNT); +
/* sb_not_used1 */

mark_buffer_dirty (fs->fs_super_bh);

tune/reiserfstune.8 2008-03-23 22:09:44.000000000 -0400 renamed from tune/reiserfstune.8 2008-03-23 22:09:31.000000000 -0400 +0 -0
@@ -7,6 +7,7 @@ reiserfstune \- The tunning tool for the

.SH SYNOPSIS
.B reiserfstune
[ \fB-f\fR ]
+[ \fB-h\fR | \fB--help\fR ]
[ \fB-j\fR | \fB--journal-device\fR \fIFILE\fR ]
[ \fB--no-journal-available\fR ]
[ \fB--journal-new-device\fR \fIFILE\fR ] [ \fB--make-journal-standard\fR ] @@ -17,6 +18,10 @@ reiserfstune \- The tunning tool for the

[ \fB-B\fR | \fB--badblocks\fR \fIfile\fR ]
[ \fB-u\fR | \fB--uuid \fIUUID\fR ]
[ \fB-l\fR | \fB--label \fILABEL\fR ]
+[ \fB-c\fR | \fB--check-interval \fIinterval-in-days\fR ]
+[ \fB-C\fR | \fB--time-last-checked \fItimestamp\fR ]
+[ \fB-m\fR | \fB--max-mnt-count \fIcount\fR ]
+[ \fB-M\fR | \fB--mnt-count \fIcount\fR ]

.I device
.SH DESCRIPTION
\fBreiserfstune\fR is used for tuning the ReiserFS. It can change two journal
@@ -40,6 +45,9 @@ is the special file corresponding to the
/dev/hdXX for IDE disk partition or /dev/sdXX for the SCSI disk partition).
.SH OPTIONS
.TP
+\fB-h\fR | \fB--help\fR
+Print usage information and exit.
+.TP
\fB-j\fR | \fB--journal-device\fR \fIFILE
\fIFILE\fR is the file name of the block device the file system has
the current journal (the one prior to running reiserfstune) on. This option is required when the journal is @@ -114,6 +122,75 @@ series of hex digits separated by
\fB-l\fR | \fB--label \fILABEL\fR
Set the volume label of the filesystem. \fILABEL\fR can be at most 16
characters long; if it is longer than 16 characters, reiserfstune will truncate it.
+.TP
+\fB-c\fR | \fB--check-interval \fIinterval-in-days\fR
+Adjust the maximal time between two filesystem checks. A value of "disable"
+will disable the time-dependent checking. A value of "default" will restore
+the compile-time default.
+
+It is strongly recommended that either
+.B \-m
+(mount-count dependent) or
+.B \-c
+(time-dependent) checking be enabled to force periodic full
+.BR fsck.reiserfs(8)
+checking of the filesystem. Failure to do so may lead to
+filesystem corruption (due to bad disks, cables, memory, or kernel bugs)
+going unnoticed, ultimately resulting in data loss or corruption.
+.TP
+\fB-C\fR | \fB--time-last-checked \fItimestamp\fR
+Set the time the filesystem was last checked using fsck.reiserfs. This
+can be useful in scripts which use a Logical Volume Manager to make a
+consistent snapshot of a filesystem, and then check the filesystem during
+off hours to make sure it hasn't been corrupted due to hardware problems,
+etc. If the filesystem was clean, then this option can be used to set the
+last checked time on the original filesystem. The format of time-last-checked
+is the international date format, with an optional time specifier, i.e. +YYYYMMDD[HH[MM[SS]]]. The keyword
+.B now
+is also accepted, in which case the
+last checked time will be set to the current time.
+.TP
+\fB-m\fR | \fB--max-mnt-count \fImax-mount-count\fR
+Adjust the number of mounts after which the filesystem will be
+checked by
+.BR fsck.reiserfs(8).
+If max-mount-count is "disable", the number of times the filesystem
+is mounted will be disregarded by
+.BR fsck.reiserfs(8)
+and the kernel. A value of "default" will restore the compile-time default.
+
+Staggering the mount-counts at which filesystems are forcibly
+checked will avoid all filesystems being checked at one time
+when using journaled filesystems.
+
+You should strongly consider the consequences of disabling
+mount-count-dependent checking entirely. Bad disk drives,
+cables, memory, and kernel bugs could all corrupt a filesystem
+without marking the filesystem dirty or in error. If you are
+using journaling on your filesystem, your filesystem will never
+be marked dirty, so it will not normally be checked. A filesys‐
+tem error detected by the kernel will still force an fsck on the
+next reboot, but it may already be too late to prevent data loss
+at that point.
+
+This option requires a kernel which supports incrementing the
+count on each mount. This feature has not been incorporated into
+kernel versions older than 2.6.25.
+
+See also the
+.B \-c
+option for time-dependent checking.
+.TP
+\fB-M\fR | \fB--mnt-count \fIcount\fR
+Set the number of times the filesystem has been mounted. If set
+to a greater value than the max-mount-counts parameter set by
+the
+.B \-m
+option,
+.BR fsck.reiserfs(8)
+will check the filesystem at the next
+reboot.
.SH POSSIBLE SCENARIOS OF USING REISERFSTUNE:
1. You have ReiserFS on /dev/hda1, and you wish to have
it working with its journal on the device /dev/journal

tune/tune.c 2008-03-23 22:09:44.000000000 -0400 renamed from tune/tune.c 2008-03-23 22:09:31.000000000 -0400 +0 -0
@@ -11,6 +11,8 @@

#include <stdarg.h>
#include <string.h>
#include <errno.h>
+#include <limits.h>
+#include "parse_time.h"

char *program_name;

@@ -54,12 +56,27 @@ static void print_usage_and_exit(void)

" -u | --uuid UUID|random\tset new UUID\n"
" -l | --label LABEL\t\tset new label\n"
" -f | --force\t\t\tforce tuning, less confirmations\n"

- " -V\t\t\t\tprint version and exit\n", program_name);
+ " -c | --check-interval\t\tset interval in days for fsck -a to check,\n"
+ " \t\t\"disable\" to disable check,\n"
+ " \t\tor \"default\" to restore default\n"
+ " -C | --time-last-checked\tset the time the filesystem was last checked\n"
+ " \t(now or YYYYMMDD[HH[MM[SS]]])\n"
+ " -m | --max-mnt-count\t\tset maximum number of mounts before fsck -a\n"
+ " \t\tchecks, \"disable\" to disable check,\n"
+ " \t\tor \"default\" to restore default\n"
+ " -M | --mnt-count\t\tset the number of times the filesystem\n"
+ " \t\thas been mounted\n"
+ " -h | --help\t\t\tprint help and exit\n"
+ " -V\t\t\t\tprint version and exit\n", program_name);
exit (1);
}

unsigned long Journal_size = 0;
int Max_trans_size = JOURNAL_TRANS_MAX;
+unsigned short Max_mnt_count = 0;
+unsigned short Mnt_count = 0;
+unsigned int Check_interval = 0;
+time_t Time_last_checked = 0;
int Offset = 0;
__u16 Options = 0;
int Force = 0;
@@ -218,6 +235,41 @@ static void set_offset_in_journal_device Offset = str2int( str );
}

+static void set_max_mnt_count(char *str)
+{
+ if (!strcmp(str, "disable"))
+ Max_mnt_count = USHRT_MAX;
+ else if (!strcmp(str, "default"))
+ Max_mnt_count = DEFAULT_MAX_MNT_COUNT;
+ else
+ Max_mnt_count = str2int(str);
+}
+
+static void set_mnt_count(char *str)
+{
+ Mnt_count = str2int(str);
+}
+
+static void set_check_interval(char *str)
+{
+ if (!strcmp(str, "disable"))
+ Check_interval = UINT_MAX;
+ else if (!strcmp(str, "default"))
+ Check_interval = DEFAULT_CHECK_INTERVAL;
+ else
+ Check_interval = str2int(str) * 60 * 60 * 24;
+}
+
+static void set_time_last_checked(char *str)
+{
+ if (!strcmp(str, "now"))
+ Time_last_checked = time(NULL);
+ else
+ Time_last_checked = parse_time(str);
+
+ if (Time_last_checked == 0)
+ print_usage_and_exit ();
+}

static void callback_new_badblocks(reiserfs_filsys_t *fs, struct path *badblock_path,
@@ -347,6 +399,7 @@ int main (int argc, char **argv)

while (1) {
static struct option options[] = {
+ {"help", no_argument, 0, 'h'}, {"journal-device", required_argument, 0, 'j'}, {"journal-new-device", required_argument, &flag, OPT_NEW_J}, {"journal-new-size", required_argument, 0, 's'}, @@ -360,11 +413,15 @@ int main (int argc, char **argv) {"badblocks", required_argument, 0, 'B'}, {"force", no_argument, 0, 'f'}, {"make-journal-standard", no_argument, &flag, OPT_STANDARD},
+ {"check-interval", required_argument, 0, 'c'},
+ {"time-last-checked", required_argument, 0, 'C'},
+ {"max-mount-count", required_argument, 0, 'm'},
+ {"mount-count", required_argument, 0, 'M'},
{0, 0, 0, 0}
};
int option_index;

- c = getopt_long (argc, argv, "j:s:t:o:fu:l:b:B:V",
+ c = getopt_long (argc, argv, "hj:s:t:o:fu:l:b:B:Vc:C:m:M:", options, &option_index);
if (c == -1)
break;
@@ -439,6 +496,22 @@ int main (int argc, char **argv) case 'V':
print_banner("reiserfstune");
exit(0);
+ case 'h':
+ print_usage_and_exit();
+ break;
+ case 'c':
+ set_check_interval(optarg);
+ break;
+ case 'C':
+ set_time_last_checked(optarg);
+ break;
+ case 'm':
+ set_max_mnt_count(optarg);
+ break;
+ case 'M':
+ set_mnt_count(optarg);
+ break;
+
#if 0
case 'J': /* --journal-new-device */
Options |= OPT_NEW_J;
@@ -561,17 +634,50 @@ int main (int argc, char **argv)

/* set UUID and LABEL if specified */
if (fs->fs_format == REISERFS_FORMAT_3_6) {
+ int need_dirty = 0;
#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H)
if (!uuid_is_null(UUID)) {
memcpy (fs->fs_ondisk_sb->s_uuid, UUID, 16);
- mark_buffer_dirty (fs->fs_super_bh);
- fs->fs_dirt = 1;
+ need_dirty = 1;
}
#endif
if (LABEL != NULL) {
if (strlen (LABEL) > 16)
message ("Specified LABEL is longer then 16 characters, will be truncated\n"); strncpy (fs->fs_ondisk_sb->s_label, LABEL, 16);
+ need_dirty = 1;
+ }
+ if (Max_mnt_count &&
+ Max_mnt_count != get_sb_v2_max_mnt_count(fs->fs_ondisk_sb)) {
+ if (Max_mnt_count <= 0)
+ reiserfs_exit(1, "max-mnt-count must be > 0\n");
+ set_sb_v2_max_mnt_count(fs->fs_ondisk_sb, Max_mnt_count);
+ need_dirty = 1;
+ }
+
+ if (Mnt_count &&
+ Mnt_count != get_sb_v2_mnt_count(fs->fs_ondisk_sb)) {
+ if (Max_mnt_count <= 0)
+ reiserfs_exit(1, "max-mnt-count must be > 0\n");
+ set_sb_v2_mnt_count(fs->fs_ondisk_sb, Mnt_count);
+ need_dirty = 1;
+ }
+
+ if (Check_interval &&
+ Check_interval != get_sb_v2_check_interval(fs->fs_ondisk_sb)) {
+ if (Check_interval <= 0)
+ reiserfs_exit(1, "check-interval must be > 0\n");
+ set_sb_v2_check_interval(fs->fs_ondisk_sb,
+ Check_interval);
+ need_dirty = 1;
+ }
+ if (Time_last_checked &&
+ Time_last_checked != get_sb_v2_lastcheck(fs->fs_ondisk_sb)) {
+ set_sb_v2_lastcheck(fs->fs_ondisk_sb, Time_last_checked);
+ need_dirty = 1;
+ }
+
+ if (need_dirty) {
mark_buffer_dirty (fs->fs_super_bh);
fs->fs_dirt = 1;
}
@@ -582,8 +688,14 @@ int main (int argc, char **argv)
#endif
if (LABEL)
reiserfs_exit (1, "LABEL cannot be specified for 3.5 format\n"); +
+ if (Max_mnt_count)
+ reiserfs_exit (1, "max-mnt-count cannot be specified for 3.5 format\n");
+ if (Check_interval)
+ reiserfs_exit (1, "check-interval cannot be specified for 3.5 format\n"); }

+
if (!j_new_device_name) {

/* new journal device hasn't been specified */

-------------------------

Subject: [PATCH] reiserfsprogs: Warn on block sizes > 4k
From: Jeff Mahoney <[email protected]>

Filesystems created with block size > page size will not work until that support is added to the kernel. Filesystems with block size > 4k (lowest page size supported in Linux) will not work on all systems. This patch adds a check and a warning in those conditions, informing the user of the caveats of using a larger block size. It can be overridden with -f.

---
include/reiserfs_lib.h | 1 + mkreiserfs/mkreiserfs.c | 3 +++ reiserfscore/reiserfslib.c | 18 ++++++++++++++++++

3 files changed, 22 insertions(+)
include/reiserfs_lib.h 2008-03-23 22:07:01.000000000 -0400 renamed from include/reiserfs_lib.h 2004-10-01 12:19:34.000000000 -0400 +0 -0
@@ -92,6 +92,7 @@ void reiserfs_read_bitmap_blocks (reiser

void reiserfs_free_bitmap_blocks (reiserfs_filsys_t *);
*/
int no_reiserfs_found (reiserfs_filsys_t *);
+int block_size_ok(int blocksize, int force);
int is_block_count_correct (unsigned long block_of_super_block, unsigned int block_size, unsigned long block_count, unsigned long journal_size);
//unsigned long min_block_amount (int block_size, unsigned long journal_size);

mkreiserfs/mkreiserfs.c 2008-03-23 22:05:34.000000000 -0400 renamed from mkreiserfs/mkreiserfs.c 2008-03-23 22:05:33.000000000 -0400 +0 -0
@@ -686,6 +686,9 @@ int main (int argc, char **argv)
 

if (!(mode & QUIET_MODE) && !can_we_format_it (device_name, force)) return 1;
+
+ if (!(mode & QUIET_MODE) && !block_size_ok (Block_size, force))
+ return 1;

if (jdevice_name)
if (!(mode & QUIET_MODE) && !can_we_format_it (jdevice_name, force))

reiserfscore/reiserfslib.c 2008-03-23 22:05:34.000000000 -0400 renamed from reiserfscore/reiserfslib.c 2004-10-04 16:39:35.000000000 -0400 +0 -0
@@ -1175,6 +1175,24 @@ void make_sure_root_dir_exists (reiserfs

&parent_root_dir_key, ih_flags);
}

+int block_size_ok (int blocksize, int force)
+{
+ int pagesize = getpagesize();
+ if (blocksize > 4096) {
+ reiserfs_warning (stderr, "Block sizes larger than 4k are not "
+ "supported on all architectures.\n");
+ if (blocksize > pagesize)
+ reiserfs_warning (stderr, "The newly created filesystem will not "
+ "be mountable on this system.\n");
+ else
+ reiserfs_warning (stderr, "The newly created filesystem may not "
+ "be mountable on other systems.\n");
+ check_forcing_ask_confirmation (force);
+ }
+
+ return 1;
+}
+

/* we only can use a file for filesystem or journal if it is either not mounted block device or regular file and we are forced to use it */

--
To unsubscribe from this list: send the line "unsubscribe reiserfs-devel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#16 lore raw
Quoted 2 lines · Edward Shishkin

Well, I am about to release reiserfsprogs-3.6.21, which includes the following changes since 3.6.19:

Great!

Quoted 12 lines

Jeff Mahoney:
- mkreiserfs-quiet.diff
- reiserfsprogs-large-block-warning.diff
- reiserfsprogs-fsck-mapid.diff
- reiserfsprogs-external-journal-changes.diff
- reiserfsprogs-remove-stupid-fsck_sleep.diff
- reiserfsprogs-mkfs-use-o_excl.diff
- reiserfsprogs-enforce-block-limit.diff
- reiserfsprogs-large-fs.diff
- reiserfsprogs-better-fsck-a-behavior.diff
- reiserfsprogs-remove-dependency-on-asm_unaligned.h.diff

Quoted 8 lines

Ludwig Nussel:
- mkreiserfs-set-the-owner-of-the-root-directory-to-the-calling-user.diff

Edward Shishkin:
- mkreiserfs-disable-small-block-sizes.diff

Jeff, do you have something to add here?
Sorry for delay.

Yeah, I do. I have two more patches. The first adds a progress bar/spinner to fsck -a. The second reorders the link so that the right dependencies are met. See attached.

-Jeff

Signature · 2 lines
Jeff Mahoney
SUSE Labs

From: Jeff Mahoney <[email protected]>
Subject: [PATCH] reiserprogs: add spinner and progress bar for -a mode

This patch implements a progress bar with percentages and a plain spinner for when progress wants to be demonstrated but percentages aren't known.

These are used during journal replay and for the internal tree check.

---
 fsck/check_tree.c      |    2 
 fsck/ustree.c          |    7 ++
 include/progbar.h      |   32 +++++++++++++
 lib/Makefile.am        |    2 
 lib/progbar.c          |  117 +++++++++++++++++++++++++++++++++++++++++++++++++
 reiserfscore/journal.c |   16 +++++-
 6 files changed, 172 insertions(+), 4 deletions(-)
fsck/check_tree.c +1 -1
@@ -1124,7 +1124,7 @@ void check_fs_tree (reiserfs_filsys_t * 
 {
     before_check_fs_tree (fs);
     
-    fsck_progress ("Checking internal tree..");
+    fsck_progress ("Checking internal tree..  ");
     pass_through_tree (fs, bad_node, bad_path, fsck_mode(fs) == FSCK_AUTO ? 2 : -1);
     /* internal tree is correct (including all objects have correct
        sequences of items) */
fsck/ustree.c +7 -0
@@ -4,6 +4,7 @@
  */
 
 #include "fsck.h"
+#include "progbar.h"
 
 struct tree_balance * cur_tb = 0;
 
@@ -196,6 +197,9 @@ void pass_through_tree (reiserfs_filsys_
     int h = 0;
     unsigned long block = get_sb_root_block (fs->fs_ondisk_sb);
     int problem;
+    struct spinner spinner;
+
+    spinner_init(&spinner, fsck_progress_file(fs));
 
 
     if (block >= get_sb_block_count (fs->fs_ondisk_sb) || not_data_block (fs, block)) {
@@ -223,6 +227,8 @@ void pass_through_tree (reiserfs_filsys_
 	    }
 	    problem = 1;		
 	} else {
+
+	    spinner_touch(&spinner);
 	    path[h] = bread (fs->fs_dev, block, fs->fs_blocksize);
 	    if (path[h] == 0)
 		/* FIXME: handle case when read failed */
@@ -279,4 +285,5 @@ void pass_through_tree (reiserfs_filsys_
         block = first_child (path[h]);
         h ++;
     }
+    spinner_clear(&spinner);
 }
include/progbar.h new file +32 -0
@@ -0,0 +1,32 @@
+#ifndef _PROGBAR_H_
+#define _PROGBAR_H_
+
+enum {
+	E2F_FLAG_PROG_SUPPRESS = 1,
+	E2F_FLAG_PROG_BAR = 2,
+};
+
+struct progbar {
+	char units[16];
+	int progress_pos;
+	int progress_last_percent;
+	time_t progress_last_time;
+	int flags;
+	FILE *file;
+};
+
+struct spinner {
+	int count;
+	FILE *file;
+};
+
+void progbar_init(struct progbar *ctx, const char *units, FILE *fp);
+void progbar_clear(struct progbar * ctx);
+int progbar_update(struct progbar * ctx, const char *label, int curr, int max,
+                           unsigned int dpynum);
+
+void spinner_init(struct spinner *spinner, FILE *fp);
+void spinner_touch(struct spinner *spinner);
+void spinner_clear(struct spinner *spinner);
+
+#endif /* _PROGBAR_H_ */
lib/Makefile.am +1 -1
@@ -1,5 +1,5 @@
 noinst_LIBRARIES = libmisc.a
 
-libmisc_a_SOURCES = io.c misc.c 
+libmisc_a_SOURCES = io.c misc.c progbar.c
 ##reiserfs.c
 
lib/progbar.c new file +117 -0

117 lines not on this page · raw message

reiserfscore/journal.c +14 -2
@@ -6,6 +6,7 @@
 #define _GNU_SOURCE
 
 #include "includes.h"
+#include "progbar.h"
 
 /* compares description block with commit block. returns 0 if they differ, 1
    if they match */
@@ -799,6 +800,8 @@ int replay_journal (reiserfs_filsys_t * 
     struct reiserfs_journal_header * j_head;
     reiserfs_trans_t cur, newest, control;
     int replayed, ret;
+    struct progbar progbar;
+    int trans_count;
 
     if (!reiserfs_journal_opened (fs))
         reiserfs_panic ("replay_journal: journal is not opened");
@@ -806,7 +809,8 @@ int replay_journal (reiserfs_filsys_t * 
     if (!is_opened_rw (fs))
         reiserfs_panic ("replay_journal: fs is not opened with write perms");
 
-    reiserfs_warning (stderr, "Replaying journal..\n");
+
+    reiserfs_warning (stderr, "Replaying journal: ");
     bh = fs->fs_jh_bh;
 	
     j_head = (struct reiserfs_journal_header *)(bh->b_data);
@@ -819,12 +823,15 @@ int replay_journal (reiserfs_filsys_t * 
 	return 0;
     }
 
+    trans_count = newest.trans_id - cur.trans_id;
+
     /*  Smth strange with journal header or journal. We cannot say for sure what was the last 
 	replaied transaction, but relying on JH data is preferable. */
 
     replayed = 0;
     ret = TRANS_FOUND;
     
+    progbar_init(&progbar, " trans", stderr);
     /* Looking to the first valid not replayed transaction. */
     while (1) {
 	if (cur.mount_id == control.mount_id && 
@@ -842,6 +849,7 @@ int replay_journal (reiserfs_filsys_t * 
 	    break;
 	
 	if (!transaction_check_content(fs, &cur)) {
+	    progbar_clear(&progbar);
 	    reiserfs_warning (stderr, "Trans broken: mountid %lu, transid %lu, desc %lu, "
 		"len %lu, commit %lu, next trans offset %lu\n", cur.mount_id, cur.trans_id, 
 		cur.desc_blocknr, cur.trans_len, cur.commit_blocknr, cur.next_trans_offset);
@@ -857,10 +865,14 @@ int replay_journal (reiserfs_filsys_t * 
 	control = cur;
         replayed ++;
 
+	progbar_update(&progbar, "Replaying journal", replayed, trans_count,
+	               replayed);
+
 	ret = next_transaction (fs, &cur, newest);
     }
+    progbar_clear(&progbar);
 
-    reiserfs_warning (stderr, "Reiserfs journal '%s' in blocks [%u..%u]: %d "
+    reiserfs_warning (stderr, "\rReplaying journal: Done.\nReiserfs journal '%s' in blocks [%u..%u]: %d "
 		      "transactions replayed\n", fs->fs_j_file_name, 
 		      get_jp_journal_1st_block(sb_jp(fs->fs_ondisk_sb)),
 		      get_jp_journal_1st_block(sb_jp(fs->fs_ondisk_sb)) + 

From: Jeff Mahoney <[email protected]>
Subject: [PATCH] reiserfsprogs: reorder libcore and libmisc

For some reason, the spinner/progress bar patch didn't build without reordering the libs. I don't really care to find out why.

---
 debugreiserfs/Makefile.am   |    2 +-
 fsck/Makefile.am            |    2 +-
 mkreiserfs/Makefile.am      |    2 +-
 resize_reiserfs/Makefile.am |    2 +-
 tune/Makefile.am            |    2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)
debugreiserfs/Makefile.am +1 -1
@@ -4,4 +4,4 @@ debugreiserfs_SOURCES = debugreiserfs.c 
 man_MANS = debugreiserfs.8
 EXTRA_DIST = $(man_MANS)
 
-LDADD = $(top_srcdir)/lib/libmisc.a $(top_srcdir)/reiserfscore/libcore.a
+LDADD = $(top_srcdir)/reiserfscore/libcore.a $(top_srcdir)/lib/libmisc.a
fsck/Makefile.am +1 -1
@@ -7,5 +7,5 @@ ufile.c check_tree.c info.c super.c fsck
 man_MANS = reiserfsck.8
 EXTRA_DIST = $(man_MANS)
 
-reiserfsck_LDADD = $(top_srcdir)/lib/libmisc.a $(top_srcdir)/reiserfscore/libcore.a
+reiserfsck_LDADD = $(top_srcdir)/reiserfscore/libcore.a $(top_srcdir)/lib/libmisc.a
 
mkreiserfs/Makefile.am +1 -1
@@ -4,5 +4,5 @@ mkreiserfs_SOURCES = mkreiserfs.c
 man_MANS = mkreiserfs.8
 EXTRA_DIST = $(man_MANS)
 
-LDADD = $(top_srcdir)/lib/libmisc.a $(top_srcdir)/reiserfscore/libcore.a
+LDADD = $(top_srcdir)/reiserfscore/libcore.a $(top_srcdir)/lib/libmisc.a
 
resize_reiserfs/Makefile.am +1 -1
@@ -4,5 +4,5 @@ resize_reiserfs_SOURCES = fe.c resize_re
 man_MANS = resize_reiserfs.8
 EXTRA_DIST = $(man_MANS)
 
-LDADD = $(top_srcdir)/lib/libmisc.a $(top_srcdir)/reiserfscore/libcore.a
+LDADD = $(top_srcdir)/reiserfscore/libcore.a $(top_srcdir)/lib/libmisc.a
 
tune/Makefile.am +1 -1
@@ -5,5 +5,5 @@ reiserfstune_SOURCES = tune.c tune.h
 man_MANS = reiserfstune.8
 EXTRA_DIST = $(man_MANS)
 
-LDADD = $(top_srcdir)/lib/libmisc.a $(top_srcdir)/reiserfscore/libcore.a
+LDADD = $(top_srcdir)/reiserfscore/libcore.a $(top_srcdir)/lib/libmisc.a
 
#17 lore raw

PATCH 1/1 reiserfsprogs: remove dependency on asm/unaligned.h

In reply to Edward Shishkin

We probably shouldn't have ever been including asm/unaligned.h, though I think I'm the one who might've added it there in the first place.

This patch borrows the unaligned accessor functions from the 3.6.20 code.

---
 include/reiserfs_fs.h |   20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)
include/reiserfs_fs.h +14 -6
@@ -38,14 +38,22 @@
 # define extern_inline
 #endif
 
-#include <asm/unaligned.h>
-
 #ifndef get_unaligned
-#if defined(__ppc__) || defined(ppc) || defined(__ppc) || \
-    defined(__PPC) || defined(powerpc) || defined(__powerpc__)
-#	define get_unaligned(ptr)	(*(ptr))
-#	define put_unaligned(val,ptr)	((void)(*(ptr) = (val)))
+#define get_unaligned(ptr)				\
+({							\
+        __typeof__(*(ptr)) __tmp;			\
+        memcpy(&__tmp, (ptr), sizeof(*(ptr)));		\
+        __tmp;						\
+})
 #endif
+
+#ifndef put_unaligned
+#define put_unaligned(val, ptr)				\
+({							\
+        __typeof__(*(ptr)) __tmp = (val);		\
+        memcpy((ptr), &__tmp, sizeof(*(ptr)));		\
+        (void)0;					\
+})
 #endif
 
 #define get_leXX(xx,p,field)	(le##xx##_to_cpu ((p)->field))
Signature · 2 lines
Jeff Mahoney
SUSE Labs
#19 lore raw
Quoted 9 lines · Domenico Andreoli
Quoted 3 lines · Edward Shishkin

Thanks, queued.

queued for what, 3.6.20?

Nop, I guess it should be 3.6.19.xx, a stuff for
download available not only as a part of Suse.

Quoted 3 lines

any release date?

Maybe next month..

Thanks,
Edward.

Quoted 13 lines

cheers,
Domenico

-----[ Domenico Andreoli, aka cavok
--[ http://www.dandreoli.com/gpgkey.asc
---[ 3A0F 2F80 F79C 678A 8936 4FEE 0677 9033 A20E BC50
-
To unsubscribe from this list: send the line "unsubscribe reiserfs-devel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#20 lore raw

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 11 lines · Edward Shishkin
Quoted 8 lines · Domenico Andreoli
Quoted 2 lines · Edward Shishkin

Thanks, queued.

queued for what, 3.6.20?

Quoted 8 lines

Nop, I guess it should be 3.6.19.xx, a stuff for
download available not only as a part of Suse.

Quoted 3 lines

any release date?

Maybe next month..

Edward, is there a new place for the FTP site yet? We spoke briefly about getting space on kernel.org, has anything come of that?

ftp://ftp.kernel.org/pub/linux/utils/fs/reiser{fs,4} doesn't sound so bad. ;)

- -Jeff

- --
Jeff Mahoney
SUSE Labs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.4-svn0 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD8DBQFHwvO6LPWxlyuTD7IRAlLvAJ0QHnixqF8d+0gVbRhM5CdmrvCc7gCfdvo1 qggOqWs8J5ZQNl2YSa9/QYI=
=SOln
-----END PGP SIGNATURE-----

#21 lore raw
Quoted 18 lines · Jeff Mahoney
Quoted 16 lines · Edward Shishkin
Quoted 8 lines · Domenico Andreoli
Quoted 2 lines · Edward Shishkin

Thanks, queued.

queued for what, 3.6.20?

Nop, I guess it should be 3.6.19.xx, a stuff for
download available not only as a part of Suse.

Quoted 3 lines

any release date?

Quoted 9 lines
Quoted 1 line

Maybe next month..

Edward, is there a new place for the FTP site yet? We spoke briefly about getting space on kernel.org, has anything come of that?

ftp://ftp.kernel.org/pub/linux/utils/fs/reiser{fs,4} doesn't sound so bad. ;)

Sure it doesn't :)
I have asked for account with username "reiser" in accordance with the following FAQ: http://www.kernel.org/faq/#account

They have refused with the following explanation:

Quoted 9 lines · H. Peter Anvin

This sounds like you're asking for a role account. We do not issue role accounts on kernel.org under any circumstances; all accounts are personal, even if that means we need to register additional people (we can set up groups if necessary.)

-hpa

Getting a personal account requires a list of my personal contributions, I put this in longterm todo :)

Maybe I do something wrong?

Edward.

#22 lore raw
In reply to Jeff Mahoney
Quoted 18 lines · Jeff Mahoney
Quoted 16 lines · Edward Shishkin
Quoted 8 lines · Domenico Andreoli
Quoted 2 lines · Edward Shishkin

Thanks, queued.

queued for what, 3.6.20?

Nop, I guess it should be 3.6.19.xx, a stuff for
download available not only as a part of Suse.

Quoted 3 lines

any release date?

Quoted 9 lines
Quoted 1 line

Maybe next month..

Edward, is there a new place for the FTP site yet? We spoke briefly about getting space on kernel.org, has anything come of that?

ftp://ftp.kernel.org/pub/linux/utils/fs/reiser{fs,4} doesn't sound so bad. ;)

mm... sending a request:
this location can be qualified as "non-obvious"..