* [patch 1/3] use kref for blk_queue_tag
From: Akinobu Mita @ 2006-04-26 2:11 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, Akinobu Mita, Jens Axboe, Greg KH
In-Reply-To: <20060426021059.235216000@localhost.localdomain>
[-- Attachment #1: blk-queue-tag-use-kref.patch --]
[-- Type: text/plain, Size: 2369 bytes --]
Use kref for reference counter of blk_queue_tag.
Signed-off-by: Akinobu Mita <mita@miraclelinux.com>
CC: Jens Axboe <axboe@suse.de>
CC: Greg KH <greg@kroah.com>
block/ll_rw_blk.c | 35 ++++++++++++++++++++---------------
include/linux/blkdev.h | 2 +-
2 files changed, 21 insertions(+), 16 deletions(-)
Index: 2.6-git/block/ll_rw_blk.c
===================================================================
--- 2.6-git.orig/block/ll_rw_blk.c
+++ 2.6-git/block/ll_rw_blk.c
@@ -848,6 +848,23 @@ struct request *blk_queue_find_tag(reque
EXPORT_SYMBOL(blk_queue_find_tag);
+static void release_blk_queue_tag(struct kref *kref)
+{
+ struct blk_queue_tag *bqt = container_of(kref, struct blk_queue_tag,
+ kref);
+
+ BUG_ON(bqt->busy);
+ BUG_ON(!list_empty(&bqt->busy_list));
+
+ kfree(bqt->tag_index);
+ bqt->tag_index = NULL;
+
+ kfree(bqt->tag_map);
+ bqt->tag_map = NULL;
+
+ kfree(bqt);
+}
+
/**
* __blk_queue_free_tags - release tag maintenance info
* @q: the request queue for the device
@@ -863,19 +880,7 @@ static void __blk_queue_free_tags(reques
if (!bqt)
return;
- if (atomic_dec_and_test(&bqt->refcnt)) {
- BUG_ON(bqt->busy);
- BUG_ON(!list_empty(&bqt->busy_list));
-
- kfree(bqt->tag_index);
- bqt->tag_index = NULL;
-
- kfree(bqt->tag_map);
- bqt->tag_map = NULL;
-
- kfree(bqt);
- }
-
+ kref_put(&bqt->kref, release_blk_queue_tag);
q->queue_tags = NULL;
q->queue_flags &= ~(1 << QUEUE_FLAG_QUEUED);
}
@@ -951,14 +956,14 @@ int blk_queue_init_tags(request_queue_t
INIT_LIST_HEAD(&tags->busy_list);
tags->busy = 0;
- atomic_set(&tags->refcnt, 1);
+ kref_init(&tags->kref);
} else if (q->queue_tags) {
if ((rc = blk_queue_resize_tags(q, depth)))
return rc;
set_bit(QUEUE_FLAG_QUEUED, &q->queue_flags);
return 0;
} else
- atomic_inc(&tags->refcnt);
+ kref_get(&tags->kref);
/*
* assign it, all done
Index: 2.6-git/include/linux/blkdev.h
===================================================================
--- 2.6-git.orig/include/linux/blkdev.h
+++ 2.6-git/include/linux/blkdev.h
@@ -315,7 +315,7 @@ struct blk_queue_tag {
int busy; /* current depth */
int max_depth; /* what we will send to device */
int real_max_depth; /* what the array can hold */
- atomic_t refcnt; /* map can be shared */
+ struct kref kref; /* map can be shared */
};
struct request_queue
--
^ permalink raw reply
* [patch 0/3] use kref
From: Akinobu Mita @ 2006-04-26 2:10 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm
Use kref instead of atomic reference counter at:
- blk_queue_tag
- io_context
- bio
--
^ permalink raw reply
* [Qemu-devel] [PATCH] Don't install HTML if its not generated
From: Chris Bagwell @ 2006-04-26 2:10 UTC (permalink / raw)
To: qemu-devel
Hi all,
There was a patch added to CVS that detects if tools exist to build
documentation. This helped me during the compile phase since I don't
have those tools installed.
I had a failure during the install phase because it still tried to
install the non-existent docs.
Following patch fixed that for me.
diff -r1.97 Makefile
58a59
> ifdef BUILD_DOCS
59a61
> endif
Chris
^ permalink raw reply
* Re: PCI ROM resource allocation issue with 2.6.17-rc2
From: Jon Smirl @ 2006-04-26 2:10 UTC (permalink / raw)
To: Dave Airlie
Cc: Linus Torvalds, Arjan van de Ven, Andrew Morton, Matthew Reppert,
linux-kernel, Antonino A. Daplas, Benjamin Herrenschmidt
In-Reply-To: <Pine.LNX.4.64.0604260221560.31555@skynet.skynet.ie>
On 4/25/06, Dave Airlie <airlied@linux.ie> wrote:
>
> >
> > Maybe just add a DRM command to do it, so that old X versions (who don't
> > know about it) will just do it by hand, and then new X versions can do
> >
> > if (drm_ioctl(fd, DRM_SETUP_THE_DAMN_RESOURCES) < 0) {
> > /*
> > * I don't know what errno the drm-ioctl actually
> > * returns for unrecognized commands, so this is
> > * just an example
> > */
> > if (errno == ENOTTY) {
> > old kernel: do it by hand
> > }
> > }
> >
> > which allows us to go forward in a sane way, and finally leave the broken
> > X PCI-configuration-by-hand crap behind.
>
> It doesn't help of course, the fb drivers also pci_enable the devices,
> really X needs a kicking square, I'm trying to figure out some sort of fix
> here, but X does't some really stupid things with PCI resources...
>
> We really need a userspace way to pci_enable_device that X can call (via
> sysfs) so for cards that don't have a DRM or fb loaded we still get
> something..
You could make a null DRM driver that is loaded for every card that
doesn't have a real one. Give it aliases to make it match the X driver
names.
The right answer here is to start working towards a solution where the
OS is actually in control of hardware resources instead of a user app.
There can only be one entity in charge of PCI space or we will all go
insane. If we continue to say that old X binaries have to work we will
still have these same problems in 2060.
>
> Dave.
>
> --
> David Airlie, Software Engineer
> http://www.skynet.ie/~airlied / airlied at skynet.ie
> Linux kernel - DRI, VAX / pam_smb / ILUG
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
* Re: Hypercall number assignment convension (was Re: Re: [PATCH]: kexec: framework and i386)
From: Isaku Yamahata @ 2006-04-26 2:09 UTC (permalink / raw)
To: Keir Fraser; +Cc: Mark Williamson, Magnus Damm, xen-devel, Akio Takebe, Horms
In-Reply-To: <78430b99202d9be921745fea24a8041c@cl.cam.ac.uk>
[-- Attachment #1: Type: text/plain, Size: 697 bytes --]
On Mon, Apr 24, 2006 at 08:32:09AM +0100, Keir Fraser wrote:
> The list of __HYPERVISOR_* defines in public/xen.h in the main xen
> repository is the canonical place. For hypercalls in our tree, simply
> grabbing the next number in sequence usually makes sense. I'm not sure
> whether having structure to the hypercall numbers makes sense (e.g., a
> range for arch-specific usage) -- if so then maybe allocating from 64
> upwards would make sense.
Actually xen/ia64 requires only one hypercall number for now.
I attached the patches to take one.
I'm not sure what name you prefer, so I attached two patches.
Please apply which you prefer. (or invent whatever name you like.)
--
yamahata
[-- Attachment #2: take_arch_specific_hypercall_number.patch --]
[-- Type: text/plain, Size: 532 bytes --]
take arch-specific purpose hypercall number.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
diff -r 1ad06bd6832d xen/include/public/xen.h
--- a/xen/include/public/xen.h Tue Apr 25 18:22:11 2006 +0100
+++ b/xen/include/public/xen.h Wed Apr 26 11:00:04 2006 +0900
@@ -62,6 +62,7 @@
#define __HYPERVISOR_sched_op 29
#define __HYPERVISOR_callback_op 30
#define __HYPERVISOR_xenoprof_op 31
+#define __HYPERVISOR_arch_specific_0 32 /* arch-specific purpose */
/*
* VIRTUAL INTERRUPTS
[-- Attachment #3: take_ia64_dom0vp_op.patch --]
[-- Type: text/plain, Size: 512 bytes --]
take ia64 specific hypercall number.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
diff -r 1ad06bd6832d xen/include/public/xen.h
--- a/xen/include/public/xen.h Tue Apr 25 18:22:11 2006 +0100
+++ b/xen/include/public/xen.h Wed Apr 26 11:01:19 2006 +0900
@@ -62,6 +62,7 @@
#define __HYPERVISOR_sched_op 29
#define __HYPERVISOR_callback_op 30
#define __HYPERVISOR_xenoprof_op 31
+#define __HYPERVISOR_ia64_dom0vp_op 32 /* ia64 only */
/*
* VIRTUAL INTERRUPTS
[-- Attachment #4: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply
* Re: --enable-mm-debug breakage
From: Hollis Blanchard @ 2006-04-26 2:06 UTC (permalink / raw)
To: Yoshinori K. Okuji; +Cc: The development of GRUB 2
In-Reply-To: <2b1a8b979a9e3455b8ff38c6fe24d2de@penguinppc.org>
On Apr 25, 2006, at 3:08 PM, Yoshinori K. Okuji wrote:
> Also, this change adds an
> intensive debugging feature for the memory manager via the
> configure option "--enable-mm-debug".
... and finally, the debug functions seem to introduce runtime breakage
(out of memory errors). I have no idea how, and I've wasted too much
time trying to figure that out. It's as easy as trying to load a
vmlinux: out of memory. When I hack out the EXPORT stuff so I can build
without --enable-mm-debug, everything runs fine.
-Hollis
^ permalink raw reply
* [Qemu-devel] gnu-c99-math.h file
From: Chris Bagwell @ 2006-04-26 2:04 UTC (permalink / raw)
To: qemu-devel
I just upgraded to current CVS to get all the changes submitted today.
The solaris port commits seems to have added a #include "gnu-c99-math.h"
file to fpu/softfloat-native.h.
This file doesn't exist on my Fedora Core 5 system with gcc32 installed
for compatibility. The mailing archive mentions something about this
missing file being a custom file for the solaris port. Should that file
only be referenced under solaris?
Qemu appears to compile fine on linux if I just comment that line out.
Chris
^ permalink raw reply
* Re: [Qemu-devel] Custom floppy image not booting, hanging at ramdisk...
From: Damien Mascord @ 2006-04-26 1:55 UTC (permalink / raw)
To: qemu-devel
In-Reply-To: <46d6db660604250747l192ccd7die167926243e6b542@mail.gmail.com>
Christian MICHON wrote:
> just send your kernel .config for cross verification
> :)
Heya Christian,
I use the same kernel to boot from a hard-disk, and also from a CD-ROM, and both work correctly.
The following patch (against latest CVS) enables the floppy to boot correctly. This patch was suggested by Jani Monoses
(http://lists.nongnu.org/archive/html/qemu-devel/2004-08/msg00132.html).
Given that it works with this patch, I can't see how it could be a kernel config issue, no offence intended :)
Damien
Index: block.c
===================================================================
RCS file: /cvsroot/qemu/qemu/block.c,v
retrieving revision 1.26
diff -u -r1.26 block.c
--- block.c 25 Apr 2006 22:36:06 -0000 1.26
+++ block.c 26 Apr 2006 01:52:26 -0000
@@ -729,7 +729,7 @@
lseek(s->fd, sector_num * 512, SEEK_SET);
ret = read(s->fd, buf, nb_sectors * 512);
- if (ret != nb_sectors * 512)
+ if (ret == -1)
return -1;
return 0;
}
> On 4/25/06, Damien Mascord <tusker@tusker.org> wrote:
>> Hi again,
>>
>> Sorry to top post, just wanted to know if anyone has had similar experiences to this?
>>
>> If not, can someone help me debug the issue (bug?) with qemu here?
>>
>
>
> _______________________________________________
> Qemu-devel mailing list
> Qemu-devel@nongnu.org
> http://lists.nongnu.org/mailman/listinfo/qemu-devel
^ permalink raw reply
* [Qemu-devel] [PATCH] fpu/softfloat-native.h incorrectly includes missing header (gnu-c99-math.h) in latest CVS
From: Damien Mascord @ 2006-04-26 1:50 UTC (permalink / raw)
To: qemu-devel
Hi,
Seems as though a missing header is being included in this file.
Removing it enables qemu to compile cleanly,
Damien
Index: fpu/softfloat-native.h
===================================================================
RCS file: /cvsroot/qemu/qemu/fpu/softfloat-native.h,v
retrieving revision 1.3
diff -u -r1.3 softfloat-native.h
--- fpu/softfloat-native.h 25 Apr 2006 22:36:06 -0000 1.3
+++ fpu/softfloat-native.h 26 Apr 2006 01:48:56 -0000
@@ -7,7 +7,6 @@
#include <fenv.h>
#endif
#endif
-#include "gnu-c99-math.h"
typedef float float32;
typedef double float64;
^ permalink raw reply
* [UPDATE][16/21]e2fsprogs enlarge file size and filesystem size
From: sho @ 2006-04-26 1:50 UTC (permalink / raw)
To: ext2-devel, linux-kernel
Summary of this patch:
[16/21] enlarge file size and filesystem size
- Add new option "-O large_block" in mke2fs.
- With this option, the maximum size of a file is (blocksize)
* (2^32-1) bytes, and of a filesystem is (pagesize) *
(2^32-1).
Signed-off-by: Takashi Sato sho@tnes.nec.co.jp
---
diff -upNr e2fsprogs-1.39/debugfs/debugfs.8.in e2fsprogs-1.39.tmp/debugfs/debugfs.8.in
--- e2fsprogs-1.39/debugfs/debugfs.8.in 2006-03-19 09:53:51.000000000 +0900
+++ e2fsprogs-1.39.tmp/debugfs/debugfs.8.in 2006-04-21 14:41:04.000000000 +0900
@@ -319,6 +319,8 @@ flag will list deleted entries in the di
.I modify_inode filespec
Modify the contents of the inode structure in the inode
.IR filespec .
+On filesystems with large_block feature, the field 'Block count' should be input
+in filesystem block units.
.TP
.I mkdir filespec
Make a directory.
@@ -402,6 +404,8 @@ has value
The list of valid inode fields which can be set via this command
can be displayed by using the command:
.B set_inode_field -l
+On filesystems with large_block feature, the field 'blocks' should be input in
+filesystem block units.
.TP
.I set_super_value field value
Set the superblock field
diff -upNr e2fsprogs-1.39/debugfs/debugfs.c e2fsprogs-1.39.tmp/debugfs/debugfs.c
--- e2fsprogs-1.39/debugfs/debugfs.c 2006-04-21 14:40:37.000000000 +0900
+++ e2fsprogs-1.39.tmp/debugfs/debugfs.c 2006-04-21 14:41:04.000000000 +0900
@@ -846,7 +846,10 @@ void do_modify_inode(int argc, char *arg
modify_u32(argv[0], "Access time", decimal_format, &inode.i_atime);
modify_u32(argv[0], "Deletion time", decimal_format, &inode.i_dtime);
modify_u16(argv[0], "Link count", decimal_format, &inode.i_links_count);
- modify_u32(argv[0], "Block count", unsignedlong_format, &inode.i_blocks);
+ if (current_fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_LARGE_BLOCK)
+ modify_u32(argv[0], "Block count (fsblocks)", unsignedlong_format, &inode.i_blocks);
+ else
+ modify_u32(argv[0], "Block count", unsignedlong_format, &inode.i_blocks);
modify_u32(argv[0], "File flags", hex_format, &inode.i_flags);
modify_u32(argv[0], "Generation", hex_format, &inode.i_generation);
#if 0
diff -upNr e2fsprogs-1.39/debugfs/set_fields.c e2fsprogs-1.39.tmp/debugfs/set_fields.c
--- e2fsprogs-1.39/debugfs/set_fields.c 2006-03-20 10:31:06.000000000 +0900
+++ e2fsprogs-1.39.tmp/debugfs/set_fields.c 2006-04-21 14:41:04.000000000 +0900
@@ -384,6 +384,9 @@ static void print_possible_fields(struct
else if (ss->func == parse_bmap)
type = "set physical->logical block map";
strcpy(name, ss->name);
+ if ((current_fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_LARGE_BLOCK) &&
+ (fields == inode_fields) && (!strcmp(name, "blocks")))
+ strcat(name, " (fsblocks)");
if (ss->flags & FLAG_ARRAY) {
if (ss->max_idx > 0)
sprintf(idx, "[%d]", ss->max_idx);
diff -upNr e2fsprogs-1.39/e2fsck/emptydir.c e2fsprogs-1.39.tmp/e2fsck/emptydir.c
--- e2fsprogs-1.39/e2fsck/emptydir.c 2006-03-19 11:34:00.000000000 +0900
+++ e2fsprogs-1.39.tmp/e2fsck/emptydir.c 2006-04-21 14:41:04.000000000 +0900
@@ -169,7 +169,7 @@ static int fix_directory(ext2_filsys fs,
if (edi->freed_blocks) {
edi->inode.i_size -= edi->freed_blocks * fs->blocksize;
edi->inode.i_blocks -= edi->freed_blocks *
- (fs->blocksize / 512);
+ (fs->blocksize / i_blocks_base(fs));
(void) ext2fs_write_inode(fs, db->ino, &edi->inode);
}
return 0;
diff -upNr e2fsprogs-1.39/e2fsck/pass1.c e2fsprogs-1.39.tmp/e2fsck/pass1.c
--- e2fsprogs-1.39/e2fsck/pass1.c 2006-04-21 14:40:37.000000000 +0900
+++ e2fsprogs-1.39.tmp/e2fsck/pass1.c 2006-04-21 14:41:04.000000000 +0900
@@ -177,7 +177,7 @@ int e2fsck_pass1_check_symlink(ext2_fils
blocks = ext2fs_inode_data_blocks(fs, inode);
if (blocks) {
if ((inode->i_size >= fs->blocksize) ||
- (blocks != fs->blocksize >> 9) ||
+ (blocks != fs->blocksize / i_blocks_base(fs)) ||
(inode->i_block[0] < fs->super->s_first_data_block) ||
(inode->i_block[0] >= fs->super->s_blocks_count))
return 0;
@@ -1470,7 +1470,7 @@ static void check_blocks(e2fsck_t ctx, s
}
}
- pb.num_blocks *= (fs->blocksize / 512);
+ pb.num_blocks *= (fs->blocksize / i_blocks_base(fs));
#if 0
printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n",
ino, inode->i_size, pb.last_block, inode->i_blocks,
@@ -1658,8 +1658,9 @@ static int process_block(ext2_filsys fs,
if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
problem = PR_1_TOOBIG_DIR;
- if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
- problem = PR_1_TOOBIG_REG;
+ if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_LARGE_BLOCK))
+ if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
+ problem = PR_1_TOOBIG_REG;
if (!p->is_dir && !p->is_reg && blockcnt > 0)
problem = PR_1_TOOBIG_SYMLINK;
diff -upNr e2fsprogs-1.39/e2fsck/pass2.c e2fsprogs-1.39.tmp/e2fsck/pass2.c
--- e2fsprogs-1.39/e2fsck/pass2.c 2006-04-21 14:40:37.000000000 +0900
+++ e2fsprogs-1.39.tmp/e2fsck/pass2.c 2006-04-21 14:41:04.000000000 +0900
@@ -1200,7 +1200,7 @@ extern int e2fsck_process_bad_inode(e2fs
*/
if (LINUX_S_ISLNK(inode.i_mode) &&
(fs->flags & EXT2_FLAG_SWAP_BYTES) &&
- (inode.i_blocks == fs->blocksize >> 9))
+ (inode.i_blocks == fs->blocksize / i_blocks_base(fs)))
inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
#endif
inode_modified++;
@@ -1375,7 +1375,7 @@ static int allocate_dir_block(e2fsck_t c
* Update the inode block count
*/
e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
- inode.i_blocks += fs->blocksize / 512;
+ inode.i_blocks += fs->blocksize / i_blocks_base(fs);
if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
inode.i_size = (db->blockcnt+1) * fs->blocksize;
e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
diff -upNr e2fsprogs-1.39/e2fsck/pass3.c e2fsprogs-1.39.tmp/e2fsck/pass3.c
--- e2fsprogs-1.39/e2fsck/pass3.c 2006-04-21 14:40:37.000000000 +0900
+++ e2fsprogs-1.39.tmp/e2fsck/pass3.c 2006-04-21 14:41:04.000000000 +0900
@@ -224,7 +224,7 @@ static void check_root(e2fsck_t ctx)
inode.i_size = fs->blocksize;
inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
inode.i_links_count = 2;
- inode.i_blocks = fs->blocksize / 512;
+ inode.i_blocks = fs->blocksize / i_blocks_base(fs);
inode.i_block[0] = blk;
/*
@@ -472,7 +472,7 @@ ext2_ino_t e2fsck_get_lost_and_found(e2f
inode.i_size = fs->blocksize;
inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now;
inode.i_links_count = 2;
- inode.i_blocks = fs->blocksize / 512;
+ inode.i_blocks = fs->blocksize / i_blocks_base(fs);
inode.i_block[0] = blk;
/*
@@ -795,7 +795,7 @@ errcode_t e2fsck_expand_directory(e2fsck
return retval;
inode.i_size = (es.last_block + 1) * fs->blocksize;
- inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
+ inode.i_blocks += (fs->blocksize / i_blocks_base(fs)) * es.newblocks;
e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
diff -upNr e2fsprogs-1.39/e2fsck/rehash.c e2fsprogs-1.39.tmp/e2fsck/rehash.c
--- e2fsprogs-1.39/e2fsck/rehash.c 2006-04-21 14:40:37.000000000 +0900
+++ e2fsprogs-1.39.tmp/e2fsck/rehash.c 2006-04-21 14:41:04.000000000 +0900
@@ -648,7 +648,7 @@ static errcode_t write_directory(e2fsck_
else
inode.i_flags |= EXT2_INDEX_FL;
inode.i_size = outdir->num * fs->blocksize;
- inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
+ inode.i_blocks -= (fs->blocksize / i_blocks_base(fs)) * wd.cleared;
e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
return 0;
diff -upNr e2fsprogs-1.39/e2fsck/super.c e2fsprogs-1.39.tmp/e2fsck/super.c
--- e2fsprogs-1.39/e2fsck/super.c 2006-04-21 14:40:37.000000000 +0900
+++ e2fsprogs-1.39.tmp/e2fsck/super.c 2006-04-21 14:41:04.000000000 +0900
@@ -209,7 +209,7 @@ static int release_inode_blocks(e2fsck_t
if (pb.truncated_blocks)
inode->i_blocks -= pb.truncated_blocks *
- (fs->blocksize / 512);
+ (fs->blocksize / i_blocks_base(fs));
if (inode->i_file_acl) {
retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
diff -upNr e2fsprogs-1.39/lib/e2p/feature.c e2fsprogs-1.39.tmp/lib/e2p/feature.c
--- e2fsprogs-1.39/lib/e2p/feature.c 2006-03-24 01:01:41.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/e2p/feature.c 2006-04-21 14:41:04.000000000 +0900
@@ -51,6 +51,8 @@ static struct feature feature_list[] = {
"extents" },
{ E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_META_BG,
"meta_bg" },
+ { E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_LARGE_BLOCK,
+ "large_block"},
{ 0, 0, 0 },
};
diff -upNr e2fsprogs-1.39/lib/ext2fs/bb_inode.c e2fsprogs-1.39.tmp/lib/ext2fs/bb_inode.c
--- e2fsprogs-1.39/lib/ext2fs/bb_inode.c 2006-04-21 14:40:37.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/bb_inode.c 2006-04-21 14:41:04.000000000 +0900
@@ -127,7 +127,7 @@ errcode_t ext2fs_update_bb_inode(ext2_fi
inode.i_atime = inode.i_mtime = fs->now ? fs->now : time(0);
if (!inode.i_ctime)
inode.i_ctime = fs->now ? fs->now : time(0);
- inode.i_blocks = rec.bad_block_count * (fs->blocksize / 512);
+ inode.i_blocks = rec.bad_block_count * (fs->blocksize / i_blocks_base(fs));
inode.i_size = rec.bad_block_count * fs->blocksize;
retval = ext2fs_write_inode(fs, EXT2_BAD_INO, &inode);
diff -upNr e2fsprogs-1.39/lib/ext2fs/bitops.h e2fsprogs-1.39.tmp/lib/ext2fs/bitops.h
--- e2fsprogs-1.39/lib/ext2fs/bitops.h 2006-04-21 14:40:37.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/bitops.h 2006-04-21 14:41:04.000000000 +0900
@@ -145,6 +145,7 @@ extern int ext2fs_unmark_generic_bitmap_
* functions at all; they will be included as normal functions in
* inline.c
*/
+
#ifdef NO_INLINE_FUNCS
#if (defined(__GNUC__) && (defined(__i386__) || defined(__i486__) || \
defined(__i586__) || defined(__mc68000__)))
@@ -165,6 +166,8 @@ extern int ext2fs_unmark_generic_bitmap_
#endif
#endif
+
+
/*
* Fast bit set/clear functions that doesn't need to return the
* previous bit value.
diff -upNr e2fsprogs-1.39/lib/ext2fs/bmap.c e2fsprogs-1.39.tmp/lib/ext2fs/bmap.c
--- e2fsprogs-1.39/lib/ext2fs/bmap.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/bmap.c 2006-04-21 14:41:04.000000000 +0900
@@ -260,7 +260,7 @@ done:
if (buf)
ext2fs_free_mem(&buf);
if ((retval == 0) && (blocks_alloc || inode_dirty)) {
- inode->i_blocks += (blocks_alloc * fs->blocksize) / 512;
+ inode->i_blocks += (blocks_alloc * fs->blocksize) / i_blocks_base(fs);
retval = ext2fs_write_inode(fs, ino, inode);
}
return retval;
diff -upNr e2fsprogs-1.39/lib/ext2fs/expanddir.c e2fsprogs-1.39.tmp/lib/ext2fs/expanddir.c
--- e2fsprogs-1.39/lib/ext2fs/expanddir.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/expanddir.c 2006-04-21 14:41:04.000000000 +0900
@@ -116,7 +116,7 @@ errcode_t ext2fs_expand_dir(ext2_filsys
return retval;
inode.i_size += fs->blocksize;
- inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
+ inode.i_blocks += (fs->blocksize / i_blocks_base(fs)) * es.newblocks;
retval = ext2fs_write_inode(fs, dir, &inode);
if (retval)
diff -upNr e2fsprogs-1.39/lib/ext2fs/ext2_fs.h e2fsprogs-1.39.tmp/lib/ext2fs/ext2_fs.h
--- e2fsprogs-1.39/lib/ext2fs/ext2_fs.h 2006-03-20 10:31:06.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/ext2_fs.h 2006-04-21 14:41:04.000000000 +0900
@@ -579,7 +579,7 @@ struct ext2_super_block {
#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */
#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010
#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040
-
+#define EXT2_FEATURE_INCOMPAT_LARGE_BLOCK 0x0080
#define EXT2_FEATURE_COMPAT_SUPP 0
#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE)
diff -upNr e2fsprogs-1.39/lib/ext2fs/ext2fs.h e2fsprogs-1.39.tmp/lib/ext2fs/ext2fs.h
--- e2fsprogs-1.39/lib/ext2fs/ext2fs.h 2006-04-21 14:40:37.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/ext2fs.h 2006-04-21 14:41:04.000000000 +0900
@@ -457,6 +457,7 @@ typedef struct ext2_icount *ext2_icount_
#define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
EXT2_FEATURE_INCOMPAT_META_BG|\
+ EXT2_FEATURE_INCOMPAT_LARGE_BLOCK|\
EXT3_FEATURE_INCOMPAT_RECOVER)
#endif
#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
@@ -1141,11 +1142,23 @@ _INLINE_ int ext2fs_group_of_ino(ext2_fi
return (ino - 1) / fs->super->s_inodes_per_group;
}
+/*
+ * `-O large_block' option support
+ * TODO: rework this function as a variable
+ */
+_INLINE_ int i_blocks_base(ext2_filsys fs)
+{
+ if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_LARGE_BLOCK)
+ return fs->blocksize;
+
+ return 512;
+}
+
_INLINE_ blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
struct ext2_inode *inode)
{
return inode->i_blocks -
- (inode->i_file_acl ? fs->blocksize >> 9 : 0);
+ (inode->i_file_acl ? fs->blocksize / i_blocks_base(fs) : 0);
}
#undef _INLINE_
#endif
diff -upNr e2fsprogs-1.39/lib/ext2fs/mkdir.c e2fsprogs-1.39.tmp/lib/ext2fs/mkdir.c
--- e2fsprogs-1.39/lib/ext2fs/mkdir.c 2005-09-25 09:06:42.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/mkdir.c 2006-04-21 14:41:04.000000000 +0900
@@ -82,7 +82,7 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, e
memset(&inode, 0, sizeof(struct ext2_inode));
inode.i_mode = LINUX_S_IFDIR | (0777 & ~fs->umask);
inode.i_uid = inode.i_gid = 0;
- inode.i_blocks = fs->blocksize / 512;
+ inode.i_blocks = fs->blocksize / i_blocks_base(fs);
inode.i_block[0] = blk;
inode.i_links_count = 2;
inode.i_ctime = inode.i_atime = inode.i_mtime = fs->now ? fs->now : time(NULL);
diff -upNr e2fsprogs-1.39/lib/ext2fs/mkjournal.c e2fsprogs-1.39.tmp/lib/ext2fs/mkjournal.c
--- e2fsprogs-1.39/lib/ext2fs/mkjournal.c 2006-04-05 08:12:30.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/mkjournal.c 2006-04-21 14:41:04.000000000 +0900
@@ -228,7 +228,7 @@ static errcode_t write_journal_inode(ext
goto errout;
inode.i_size += fs->blocksize * size;
- inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
+ inode.i_blocks += (fs->blocksize / i_blocks_base(fs)) * es.newblocks;
inode.i_mtime = inode.i_ctime = fs->now ? fs->now : time(0);
inode.i_links_count = 1;
inode.i_mode = LINUX_S_IFREG | 0600;
diff -upNr e2fsprogs-1.39/lib/ext2fs/read_bb.c e2fsprogs-1.39.tmp/lib/ext2fs/read_bb.c
--- e2fsprogs-1.39/lib/ext2fs/read_bb.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/read_bb.c 2006-04-21 14:41:04.000000000 +0900
@@ -76,7 +76,7 @@ errcode_t ext2fs_read_bb_inode(ext2_fils
return retval;
if (inode.i_blocks < 500)
numblocks = (inode.i_blocks /
- (fs->blocksize / 512)) + 20;
+ (fs->blocksize / i_blocks_base(fs))) + 20;
else
numblocks = 500;
retval = ext2fs_badblocks_list_create(bb_list, numblocks);
diff -upNr e2fsprogs-1.39/lib/ext2fs/res_gdt.c e2fsprogs-1.39.tmp/lib/ext2fs/res_gdt.c
--- e2fsprogs-1.39/lib/ext2fs/res_gdt.c 2005-12-11 01:44:25.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/res_gdt.c 2006-04-21 14:41:04.000000000 +0900
@@ -84,7 +84,7 @@ errcode_t ext2fs_create_resize_inode(ext
/* Maximum possible file size (we donly use the dindirect blocks) */
apb = EXT2_ADDR_PER_BLOCK(sb);
- rsv_add = fs->blocksize / 512;
+ rsv_add = fs->blocksize / i_blocks_base(fs);
if ((dindir_blk = inode.i_block[EXT2_DIND_BLOCK])) {
#ifdef RES_GDT_DEBUG
printf("reading GDT dindir %u\n", dindir_blk);
diff -upNr e2fsprogs-1.39/misc/mke2fs.8.in e2fsprogs-1.39.tmp/misc/mke2fs.8.in
--- e2fsprogs-1.39/misc/mke2fs.8.in 2006-03-27 15:16:49.000000000 +0900
+++ e2fsprogs-1.39.tmp/misc/mke2fs.8.in 2006-04-21 14:41:04.000000000 +0900
@@ -406,6 +406,12 @@ extended option.
.B sparse_super
Create a filesystem with fewer superblock backup copies
(saves space on large filesystems).
+.TP
+.B large_block
+The maximum size of a file can be (blocksize)x(232-1) bytes and the maximum
+size of a filesystem is (pagesize)x(232-1). Specifically on 32 bit platforms,
+a file size cannot exceed 4TB. With this feature enabled, users cannot make
+blocksize smaller than 4KB.
.RE
.TP
.B \-q
diff -upNr e2fsprogs-1.39/misc/mke2fs.c e2fsprogs-1.39.tmp/misc/mke2fs.c
--- e2fsprogs-1.39/misc/mke2fs.c 2006-04-21 14:40:37.000000000 +0900
+++ e2fsprogs-1.39.tmp/misc/mke2fs.c 2006-04-21 14:41:04.000000000 +0900
@@ -817,7 +817,8 @@ static __u32 ok_features[3] = {
EXT2_FEATURE_COMPAT_DIR_INDEX, /* Compat */
EXT2_FEATURE_INCOMPAT_FILETYPE| /* Incompat */
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|
- EXT2_FEATURE_INCOMPAT_META_BG,
+ EXT2_FEATURE_INCOMPAT_META_BG |
+ EXT2_FEATURE_INCOMPAT_LARGE_BLOCK,
EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER /* R/O compat */
};
@@ -1336,6 +1337,16 @@ static void PRS(int argc, char *argv[])
int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE);
blocksize = EXT2_BLOCK_SIZE(&fs_param);
+
+ /* We should have checked it earlier if we cared about the blocksize
+ * set by -b option. */
+ if ((fs_param.s_feature_incompat & EXT2_FEATURE_INCOMPAT_LARGE_BLOCK) &&
+ (blocksize < 4096)) {
+ com_err(program_name, 0,
+ _("Too small blocksize! You should specify more than "
+ "or equal to 4KB blocksize with the '-O large_block' option."));
+ exit(1);
+ }
if (extended_opts)
parse_extended_opts(&fs_param, extended_opts);
@@ -1360,7 +1371,8 @@ static void PRS(int argc, char *argv[])
}
}
- if (!force && fs_param.s_blocks_count >= (1 << 31)) {
+ if (!(fs_param.s_feature_incompat & EXT2_FEATURE_INCOMPAT_LARGE_BLOCK) &&
+ !force && fs_param.s_blocks_count >= (1 << 31)) {
com_err(program_name, 0,
_("Filesystem too large. No more than 2**31-1 blocks\n"
"\t (8TB using a blocksize of 4k) are currently supported."));
diff -upNr e2fsprogs-1.39/resize/resize2fs.c e2fsprogs-1.39.tmp/resize/resize2fs.c
--- e2fsprogs-1.39/resize/resize2fs.c 2006-04-21 14:40:37.000000000 +0900
+++ e2fsprogs-1.39.tmp/resize/resize2fs.c 2006-04-21 14:41:04.000000000 +0900
@@ -1520,7 +1520,7 @@ static errcode_t fix_resize_inode(ext2_f
retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
if (retval) goto errout;
- inode.i_blocks = fs->blocksize/512;
+ inode.i_blocks = fs->blocksize/i_blocks_base(fs);
retval = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode);
if (retval) goto errout;
^ permalink raw reply
* [UPDATE][15/21]e2fsprogs add new functions with 64-bit blk64_t
From: sho @ 2006-04-26 1:50 UTC (permalink / raw)
To: ext2-devel, linux-kernel
Summary of this patch:
[15/21] add new functions which manipulate bitmap with 64-bit blk64_t
- add new functions, which use 64-bit blk64_t and manipulate
bitmap, leaving existing functions as they are.
Signed-off-by: Takashi Sato sho@tnes.nec.co.jp
---
diff -upNr e2fsprogs-1.39/debugfs/debugfs.c e2fsprogs-1.39.tmp/debugfs/debugfs.c
--- e2fsprogs-1.39/debugfs/debugfs.c 2006-03-19 11:34:00.000000000 +0900
+++ e2fsprogs-1.39.tmp/debugfs/debugfs.c 2006-04-21 11:51:17.000000000 +0900
@@ -708,10 +708,10 @@ void do_freeb(int argc, char *argv[])
if (check_fs_read_write(argv[0]))
return;
while (count-- > 0) {
- if (!ext2fs_test_block_bitmap(current_fs->block_map,block))
+ if (!ext2fs_test_block_bitmap_64(current_fs->block_map,block))
com_err(argv[0], 0, "Warning: block %u already clear",
block);
- ext2fs_unmark_block_bitmap(current_fs->block_map,block);
+ ext2fs_unmark_block_bitmap_64(current_fs->block_map,block);
block++;
}
ext2fs_mark_bb_dirty(current_fs);
@@ -727,10 +727,10 @@ void do_setb(int argc, char *argv[])
if (check_fs_read_write(argv[0]))
return;
while (count-- > 0) {
- if (ext2fs_test_block_bitmap(current_fs->block_map,block))
+ if (ext2fs_test_block_bitmap_64(current_fs->block_map,block))
com_err(argv[0], 0, "Warning: block %u already set",
block);
- ext2fs_mark_block_bitmap(current_fs->block_map,block);
+ ext2fs_mark_block_bitmap_64(current_fs->block_map,block);
block++;
}
ext2fs_mark_bb_dirty(current_fs);
@@ -744,7 +744,7 @@ void do_testb(int argc, char *argv[])
if (common_block_args_process(argc, argv, &block, &count))
return;
while (count-- > 0) {
- if (ext2fs_test_block_bitmap(current_fs->block_map,block))
+ if (ext2fs_test_block_bitmap_64(current_fs->block_map,block))
printf("Block %u marked in use\n", block);
else
printf("Block %u not in use\n", block);
diff -upNr e2fsprogs-1.39/debugfs/logdump.c e2fsprogs-1.39.tmp/debugfs/logdump.c
--- e2fsprogs-1.39/debugfs/logdump.c 2005-12-11 09:48:13.000000000 +0900
+++ e2fsprogs-1.39.tmp/debugfs/logdump.c 2006-04-21 11:51:17.000000000 +0900
@@ -618,7 +618,7 @@ static void dump_metadata_block(FILE *ou
fprintf(out_file, " (block bitmap for block %u: "
"block is %s)\n",
block_to_dump,
- ext2fs_test_bit(offset, buf) ? "SET" : "CLEAR");
+ ext2fs_test_bit_64(offset, buf) ? "SET" : "CLEAR");
}
if (fs_blocknr == inode_block_to_dump) {
diff -upNr e2fsprogs-1.39/debugfs/lsdel.c e2fsprogs-1.39.tmp/debugfs/lsdel.c
--- e2fsprogs-1.39/debugfs/lsdel.c 2005-09-25 10:56:38.000000000 +0900
+++ e2fsprogs-1.39.tmp/debugfs/lsdel.c 2006-04-21 11:51:17.000000000 +0900
@@ -62,7 +62,7 @@ static int lsdel_proc(ext2_filsys fs,
return BLOCK_ABORT;
}
- if (!ext2fs_test_block_bitmap(fs->block_map,*block_nr))
+ if (!ext2fs_test_block_bitmap_64(fs->block_map,*block_nr))
lsd->free_blocks++;
return 0;
diff -upNr e2fsprogs-1.39/debugfs/unused.c e2fsprogs-1.39.tmp/debugfs/unused.c
--- e2fsprogs-1.39/debugfs/unused.c 2006-03-19 11:34:00.000000000 +0900
+++ e2fsprogs-1.39.tmp/debugfs/unused.c 2006-04-21 11:51:17.000000000 +0900
@@ -33,7 +33,7 @@ void do_dump_unused(int argc EXT2FS_ATTR
for (blk=current_fs->super->s_first_data_block;
blk < current_fs->super->s_blocks_count; blk++) {
- if (ext2fs_test_block_bitmap(current_fs->block_map,blk))
+ if (ext2fs_test_block_bitmap_64(current_fs->block_map,blk))
continue;
retval = io_channel_read_blk(current_fs->io, blk, 1, buf);
if (retval) {
diff -upNr e2fsprogs-1.39/e2fsck/pass1.c e2fsprogs-1.39.tmp/e2fsck/pass1.c
--- e2fsprogs-1.39/e2fsck/pass1.c 2006-04-21 11:51:04.000000000 +0900
+++ e2fsprogs-1.39.tmp/e2fsck/pass1.c 2006-04-21 11:51:17.000000000 +0900
@@ -1081,7 +1081,7 @@ static _INLINE_ void mark_block_used(e2f
clear_problem_context(&pctx);
- if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
+ if (ext2fs_fast_test_block_bitmap_64(ctx->block_found_map, block)) {
if (!ctx->block_dup_map) {
pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
_("multiply claimed block map"),
@@ -1095,9 +1095,9 @@ static _INLINE_ void mark_block_used(e2f
return;
}
}
- ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
+ ext2fs_fast_mark_block_bitmap_64(ctx->block_dup_map, block);
} else {
- ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
+ ext2fs_fast_mark_block_bitmap_64(ctx->block_found_map, block);
}
}
@@ -1210,7 +1210,7 @@ static int check_ext_attr(e2fsck_t ctx,
#endif
/* Have we seen this EA block before? */
- if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
+ if (ext2fs_fast_test_block_bitmap_64(ctx->block_ea_map, blk)) {
if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
return 1;
/* Ooops, this EA was referenced more than it stated */
@@ -1299,7 +1299,7 @@ static int check_ext_attr(e2fsck_t ctx,
if (count)
ea_refcount_store(ctx->refcount, blk, count);
mark_block_used(ctx, blk);
- ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
+ ext2fs_fast_mark_block_bitmap_64(ctx->block_ea_map, blk);
return 1;
@@ -1761,13 +1761,13 @@ static int process_bad_block(ext2_filsys
}
if (blockcnt < 0) {
- if (ext2fs_test_block_bitmap(p->fs_meta_blocks, blk)) {
+ if (ext2fs_test_block_bitmap_64(p->fs_meta_blocks, blk)) {
p->bbcheck = 1;
if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
*block_nr = 0;
return BLOCK_CHANGED;
}
- } else if (ext2fs_test_block_bitmap(ctx->block_found_map,
+ } else if (ext2fs_test_block_bitmap_64(ctx->block_found_map,
blk)) {
p->bbcheck = 1;
if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK,
@@ -1791,8 +1791,8 @@ static int process_bad_block(ext2_filsys
* there's an overlap between the filesystem table blocks
* (bitmaps and inode table) and the bad block list.
*/
- if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
- ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
+ if (!ext2fs_test_block_bitmap_64(ctx->block_found_map, blk)) {
+ ext2fs_mark_block_bitmap_64(ctx->block_found_map, blk);
return 0;
}
/*
@@ -1927,7 +1927,7 @@ static void new_table_block(e2fsck_t ctx
pctx.blk2 = 0;
for (i = 0; i < num; i++) {
pctx.blk = i;
- ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i);
+ ext2fs_mark_block_bitmap_64(ctx->block_found_map, (*new_block)+i);
if (old_block) {
pctx.errcode = io_channel_read_blk(fs->io,
old_block + i, 1, buf);
@@ -2005,7 +2005,7 @@ static void mark_table_blocks(e2fsck_t c
for (j = 0, b = fs->group_desc[i].bg_inode_table;
j < fs->inode_blocks_per_group;
j++, b++) {
- if (ext2fs_test_block_bitmap(ctx->block_found_map,
+ if (ext2fs_test_block_bitmap_64(ctx->block_found_map,
b)) {
pctx.blk = b;
if (fix_problem(ctx,
@@ -2014,7 +2014,7 @@ static void mark_table_blocks(e2fsck_t c
ctx->invalid_bitmaps++;
}
} else {
- ext2fs_mark_block_bitmap(ctx->block_found_map,
+ ext2fs_mark_block_bitmap_64(ctx->block_found_map,
b);
}
}
@@ -2024,7 +2024,7 @@ static void mark_table_blocks(e2fsck_t c
* Mark block used for the block bitmap
*/
if (fs->group_desc[i].bg_block_bitmap) {
- if (ext2fs_test_block_bitmap(ctx->block_found_map,
+ if (ext2fs_test_block_bitmap_64(ctx->block_found_map,
fs->group_desc[i].bg_block_bitmap)) {
pctx.blk = fs->group_desc[i].bg_block_bitmap;
if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
@@ -2032,7 +2032,7 @@ static void mark_table_blocks(e2fsck_t c
ctx->invalid_bitmaps++;
}
} else {
- ext2fs_mark_block_bitmap(ctx->block_found_map,
+ ext2fs_mark_block_bitmap_64(ctx->block_found_map,
fs->group_desc[i].bg_block_bitmap);
}
@@ -2041,7 +2041,7 @@ static void mark_table_blocks(e2fsck_t c
* Mark block used for the inode bitmap
*/
if (fs->group_desc[i].bg_inode_bitmap) {
- if (ext2fs_test_block_bitmap(ctx->block_found_map,
+ if (ext2fs_test_block_bitmap_64(ctx->block_found_map,
fs->group_desc[i].bg_inode_bitmap)) {
pctx.blk = fs->group_desc[i].bg_inode_bitmap;
if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
@@ -2049,7 +2049,7 @@ static void mark_table_blocks(e2fsck_t c
ctx->invalid_bitmaps++;
}
} else {
- ext2fs_mark_block_bitmap(ctx->block_found_map,
+ ext2fs_mark_block_bitmap_64(ctx->block_found_map,
fs->group_desc[i].bg_inode_bitmap);
}
}
diff -upNr e2fsprogs-1.39/e2fsck/pass1b.c e2fsprogs-1.39.tmp/e2fsck/pass1b.c
--- e2fsprogs-1.39/e2fsck/pass1b.c 2006-03-19 11:34:00.000000000 +0900
+++ e2fsprogs-1.39.tmp/e2fsck/pass1b.c 2006-04-21 11:51:17.000000000 +0900
@@ -320,7 +320,7 @@ static int process_pass1b_block(ext2_fil
p = (struct process_block_struct *) priv_data;
ctx = p->ctx;
- if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
+ if (!ext2fs_test_block_bitmap_64(ctx->block_dup_map, *block_nr))
return 0;
/* OK, this is a duplicate block */
@@ -527,7 +527,7 @@ static void decrement_badcount(e2fsck_t
p->num_bad--;
if (p->num_bad <= 0 ||
(p->num_bad == 1 && !check_if_fs_block(ctx, block)))
- ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
+ ext2fs_unmark_block_bitmap_64(ctx->block_dup_map, block);
}
static int delete_file_block(ext2_filsys fs,
@@ -548,7 +548,7 @@ static int delete_file_block(ext2_filsys
if (HOLE_BLKADDR(*block_nr))
return 0;
- if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
+ if (ext2fs_test_block_bitmap_64(ctx->block_dup_map, *block_nr)) {
n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
if (n) {
p = (struct dup_block *) dnode_get(n);
@@ -558,7 +558,7 @@ static int delete_file_block(ext2_filsys
_("internal error; can't find dup_blk for %u\n"),
*block_nr);
} else {
- ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
+ ext2fs_unmark_block_bitmap_64(ctx->block_found_map, *block_nr);
ext2fs_block_alloc_stats(fs, *block_nr, -1);
}
@@ -616,7 +616,7 @@ static void delete_file(e2fsck_t ctx, ex
* of keeping the accounting straight.
*/
if ((count == 0) ||
- ext2fs_test_block_bitmap(ctx->block_dup_map,
+ ext2fs_test_block_bitmap_64(ctx->block_dup_map,
inode.i_file_acl))
delete_file_block(fs, &inode.i_file_acl,
BLOCK_COUNT_EXTATTR, 0, 0, &pb);
@@ -650,7 +650,7 @@ static int clone_file_block(ext2_filsys
if (HOLE_BLKADDR(*block_nr))
return 0;
- if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
+ if (ext2fs_test_block_bitmap_64(ctx->block_dup_map, *block_nr)) {
n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
if (n) {
p = (struct dup_block *) dnode_get(n);
@@ -686,9 +686,9 @@ static int clone_file_block(ext2_filsys
}
decrement_badcount(ctx, *block_nr, p);
*block_nr = new_block;
- ext2fs_mark_block_bitmap(ctx->block_found_map,
+ ext2fs_mark_block_bitmap_64(ctx->block_found_map,
new_block);
- ext2fs_mark_block_bitmap(fs->block_map, new_block);
+ ext2fs_mark_block_bitmap_64(fs->block_map, new_block);
return BLOCK_CHANGED;
} else
com_err("clone_file_block", 0,
diff -upNr e2fsprogs-1.39/e2fsck/pass2.c e2fsprogs-1.39.tmp/e2fsck/pass2.c
--- e2fsprogs-1.39/e2fsck/pass2.c 2006-03-19 11:34:00.000000000 +0900
+++ e2fsprogs-1.39.tmp/e2fsck/pass2.c 2006-04-21 11:51:17.000000000 +0900
@@ -1079,7 +1079,7 @@ static int deallocate_inode_block(ext2_f
if ((*block_nr < fs->super->s_first_data_block) ||
(*block_nr >= fs->super->s_blocks_count))
return 0;
- ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
+ ext2fs_unmark_block_bitmap_64(ctx->block_found_map, *block_nr);
ext2fs_block_alloc_stats(fs, *block_nr, -1);
return 0;
}
@@ -1127,7 +1127,7 @@ static void deallocate_inode(e2fsck_t ct
return;
}
if (count == 0) {
- ext2fs_unmark_block_bitmap(ctx->block_found_map,
+ ext2fs_unmark_block_bitmap_64(ctx->block_found_map,
inode.i_file_acl);
ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
}
@@ -1344,8 +1344,8 @@ static int allocate_dir_block(e2fsck_t c
fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
return 1;
}
- ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
- ext2fs_mark_block_bitmap(fs->block_map, blk);
+ ext2fs_mark_block_bitmap_64(ctx->block_found_map, blk);
+ ext2fs_mark_block_bitmap_64(fs->block_map, blk);
ext2fs_mark_bb_dirty(fs);
/*
diff -upNr e2fsprogs-1.39/e2fsck/pass3.c e2fsprogs-1.39.tmp/e2fsck/pass3.c
--- e2fsprogs-1.39/e2fsck/pass3.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/e2fsck/pass3.c 2006-04-21 11:51:17.000000000 +0900
@@ -191,8 +191,8 @@ static void check_root(e2fsck_t ctx)
ctx->flags |= E2F_FLAG_ABORT;
return;
}
- ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
- ext2fs_mark_block_bitmap(fs->block_map, blk);
+ ext2fs_mark_block_bitmap_64(ctx->block_found_map, blk);
+ ext2fs_mark_block_bitmap_64(fs->block_map, blk);
ext2fs_mark_bb_dirty(fs);
/*
@@ -429,7 +429,7 @@ ext2_ino_t e2fsck_get_lost_and_found(e2f
fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
return 0;
}
- ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
+ ext2fs_mark_block_bitmap_64(ctx->block_found_map, blk);
ext2fs_block_alloc_stats(fs, blk, +1);
/*
@@ -743,7 +743,7 @@ static int expand_dir_proc(ext2_filsys f
}
ext2fs_free_mem(&block);
*blocknr = new_blk;
- ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
+ ext2fs_mark_block_bitmap_64(ctx->block_found_map, new_blk);
ext2fs_block_alloc_stats(fs, new_blk, +1);
es->newblocks++;
diff -upNr e2fsprogs-1.39/e2fsck/pass5.c e2fsprogs-1.39.tmp/e2fsck/pass5.c
--- e2fsprogs-1.39/e2fsck/pass5.c 2006-04-21 11:51:04.000000000 +0900
+++ e2fsprogs-1.39.tmp/e2fsck/pass5.c 2006-04-21 11:51:17.000000000 +0900
@@ -163,8 +163,8 @@ redo_counts:
for (i = fs->super->s_first_data_block;
i < fs->super->s_blocks_count;
i++) {
- actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
- bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
+ actual = ext2fs_fast_test_block_bitmap_64(ctx->block_found_map, i);
+ bitmap = ext2fs_fast_test_block_bitmap_64(fs->block_map, i);
if (actual == bitmap)
goto do_counts;
@@ -509,7 +509,7 @@ static void check_block_end(e2fsck_t ctx
end = fs->block_map->start +
(EXT2_BLOCKS_PER_GROUP(fs->super) * (__u64)fs->group_desc_count) - 1;
- pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
+ pctx.errcode = ext2fs_fudge_block_bitmap_end_64(fs->block_map, end,
&save_blocks_count);
if (pctx.errcode) {
pctx.num = 3;
@@ -521,10 +521,10 @@ static void check_block_end(e2fsck_t ctx
return;
for (i = save_blocks_count + 1; i <= end; i++) {
- if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
+ if (!ext2fs_test_block_bitmap_64(fs->block_map, i)) {
if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
for (i = save_blocks_count + 1; i <= end; i++)
- ext2fs_mark_block_bitmap(fs->block_map,
+ ext2fs_mark_block_bitmap_64(fs->block_map,
i);
ext2fs_mark_bb_dirty(fs);
} else
@@ -533,7 +533,7 @@ static void check_block_end(e2fsck_t ctx
}
}
- pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
+ pctx.errcode = ext2fs_fudge_block_bitmap_end_64(fs->block_map,
save_blocks_count, 0);
if (pctx.errcode) {
pctx.num = 4;
diff -upNr e2fsprogs-1.39/e2fsck/rehash.c e2fsprogs-1.39.tmp/e2fsck/rehash.c
--- e2fsprogs-1.39/e2fsck/rehash.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/e2fsck/rehash.c 2006-04-21 11:51:17.000000000 +0900
@@ -602,7 +602,7 @@ static int write_dir_block(ext2_filsys f
if (blockcnt >= wd->outdir->num) {
e2fsck_read_bitmaps(wd->ctx);
blk = *block_nr;
- ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
+ ext2fs_unmark_block_bitmap_64(wd->ctx->block_found_map, blk);
ext2fs_block_alloc_stats(fs, blk, -1);
*block_nr = 0;
wd->cleared++;
diff -upNr e2fsprogs-1.39/e2fsck/super.c e2fsprogs-1.39.tmp/e2fsck/super.c
--- e2fsprogs-1.39/e2fsck/super.c 2006-03-19 11:33:56.000000000 +0900
+++ e2fsprogs-1.39.tmp/e2fsck/super.c 2006-04-21 11:51:17.000000000 +0900
@@ -97,7 +97,7 @@ static int release_inode_block(ext2_fils
return BLOCK_ABORT;
}
- if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
+ if (!ext2fs_test_block_bitmap_64(fs->block_map, blk)) {
fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
goto return_abort;
}
diff -upNr e2fsprogs-1.39/lib/ext2fs/alloc.c e2fsprogs-1.39.tmp/lib/ext2fs/alloc.c
--- e2fsprogs-1.39/lib/ext2fs/alloc.c 2006-04-21 11:51:04.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/alloc.c 2006-04-21 11:51:17.000000000 +0900
@@ -88,7 +88,7 @@ errcode_t ext2fs_new_block(ext2_filsys f
goal = fs->super->s_first_data_block;
i = goal;
do {
- if (!ext2fs_fast_test_block_bitmap(map, i)) {
+ if (!ext2fs_fast_test_block_bitmap_64(map, i)) {
*ret = i;
return 0;
}
@@ -162,7 +162,7 @@ errcode_t ext2fs_get_free_blocks(ext2_fi
if (b+num-1 >= fs->super->s_blocks_count)
b = fs->super->s_first_data_block;
do {
- if (ext2fs_fast_test_block_bitmap_range(map, b, num)) {
+ if (ext2fs_fast_test_block_bitmap_range_64(map, b, num)) {
*ret = b;
return 0;
}
diff -upNr e2fsprogs-1.39/lib/ext2fs/alloc_sb.c e2fsprogs-1.39.tmp/lib/ext2fs/alloc_sb.c
--- e2fsprogs-1.39/lib/ext2fs/alloc_sb.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/alloc_sb.c 2006-04-21 11:51:17.000000000 +0900
@@ -44,14 +44,14 @@ int ext2fs_reserve_super_and_bgd(ext2_fi
fs->desc_blocks + fs->super->s_reserved_gdt_blocks;
if (super_blk || (group == 0))
- ext2fs_mark_block_bitmap(bmap, super_blk);
+ ext2fs_mark_block_bitmap_64(bmap, super_blk);
if (old_desc_blk) {
for (j=0; j < old_desc_blocks; j++)
- ext2fs_mark_block_bitmap(bmap, old_desc_blk + j);
+ ext2fs_mark_block_bitmap_64(bmap, old_desc_blk + j);
}
if (new_desc_blk)
- ext2fs_mark_block_bitmap(bmap, new_desc_blk);
+ ext2fs_mark_block_bitmap_64(bmap, new_desc_blk);
return num_blocks;
}
diff -upNr e2fsprogs-1.39/lib/ext2fs/alloc_stats.c e2fsprogs-1.39.tmp/lib/ext2fs/alloc_stats.c
--- e2fsprogs-1.39/lib/ext2fs/alloc_stats.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/alloc_stats.c 2006-04-21 11:51:17.000000000 +0900
@@ -42,9 +42,9 @@ void ext2fs_block_alloc_stats(ext2_filsy
int group = ext2fs_group_of_blk(fs, blk);
if (inuse > 0)
- ext2fs_mark_block_bitmap(fs->block_map, blk);
+ ext2fs_mark_block_bitmap_64(fs->block_map, blk);
else
- ext2fs_unmark_block_bitmap(fs->block_map, blk);
+ ext2fs_unmark_block_bitmap_64(fs->block_map, blk);
fs->group_desc[group].bg_free_blocks_count -= inuse;
fs->super->s_free_blocks_count -= inuse;
ext2fs_mark_super_dirty(fs);
diff -upNr e2fsprogs-1.39/lib/ext2fs/alloc_tables.c e2fsprogs-1.39.tmp/lib/ext2fs/alloc_tables.c
--- e2fsprogs-1.39/lib/ext2fs/alloc_tables.c 2006-04-21 11:51:04.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/alloc_tables.c 2006-04-21 11:51:17.000000000 +0900
@@ -65,7 +65,7 @@ errcode_t ext2fs_allocate_group_table(ex
last_blk, 1, bmap, &new_blk);
if (retval)
return retval;
- ext2fs_mark_block_bitmap(bmap, new_blk);
+ ext2fs_mark_block_bitmap_64(bmap, new_blk);
fs->group_desc[group].bg_block_bitmap = new_blk;
}
@@ -77,7 +77,7 @@ errcode_t ext2fs_allocate_group_table(ex
last_blk, 1, bmap, &new_blk);
if (retval)
return retval;
- ext2fs_mark_block_bitmap(bmap, new_blk);
+ ext2fs_mark_block_bitmap_64(bmap, new_blk);
fs->group_desc[group].bg_inode_bitmap = new_blk;
}
@@ -93,7 +93,7 @@ errcode_t ext2fs_allocate_group_table(ex
for (j=0, blk = new_blk;
j < fs->inode_blocks_per_group;
j++, blk++)
- ext2fs_mark_block_bitmap(bmap, blk);
+ ext2fs_mark_block_bitmap_64(bmap, blk);
fs->group_desc[group].bg_inode_table = new_blk;
}
diff -upNr e2fsprogs-1.39/lib/ext2fs/bb_inode.c e2fsprogs-1.39.tmp/lib/ext2fs/bb_inode.c
--- e2fsprogs-1.39/lib/ext2fs/bb_inode.c 2005-09-25 09:06:42.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/bb_inode.c 2006-04-21 11:51:17.000000000 +0900
@@ -235,7 +235,7 @@ static int set_bad_block_proc(ext2_filsy
retry:
if (rec->ind_blocks_ptr < rec->ind_blocks_size) {
blk = rec->ind_blocks[rec->ind_blocks_ptr++];
- if (ext2fs_test_block_bitmap(fs->block_map, blk))
+ if (ext2fs_test_block_bitmap_64(fs->block_map, blk))
goto retry;
} else {
retval = ext2fs_new_block(fs, 0, 0, &blk);
diff -upNr e2fsprogs-1.39/lib/ext2fs/bitmaps.c e2fsprogs-1.39.tmp/lib/ext2fs/bitmaps.c
--- e2fsprogs-1.39/lib/ext2fs/bitmaps.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/bitmaps.c 2006-04-21 11:51:17.000000000 +0900
@@ -27,7 +27,7 @@
#include "ext2_fs.h"
#include "ext2fs.h"
-static errcode_t make_bitmap(__u32 start, __u32 end, __u32 real_end,
+static errcode_t make_bitmap(__u32 start, __u32 end, __u64 real_end,
const char *descr, char *init_map,
ext2fs_generic_bitmap *ret)
{
@@ -78,6 +78,15 @@ errcode_t ext2fs_allocate_generic_bitmap
const char *descr,
ext2fs_generic_bitmap *ret)
{
+ return make_bitmap(start, end, real_end, descr, 0, ret);
+}
+
+errcode_t ext2fs_allocate_generic_bitmap_64(__u32 start,
+ __u32 end,
+ __u64 real_end,
+ const char *descr,
+ ext2fs_generic_bitmap *ret)
+{
return make_bitmap(start, end, real_end, descr, 0, ret);
}
@@ -103,7 +112,7 @@ void ext2fs_set_bitmap_padding(ext2fs_ge
__u32 i, j;
for (i=map->end+1, j = i - map->start; i <= map->real_end; i++, j++)
- ext2fs_set_bit(j, map->bitmap);
+ ext2fs_set_bit_64(j, map->bitmap);
return;
}
@@ -124,7 +133,7 @@ errcode_t ext2fs_allocate_inode_bitmap(e
end = fs->super->s_inodes_count;
real_end = (EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count);
- retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
+ retval = ext2fs_allocate_generic_bitmap_64(start, end, real_end,
descr, &bitmap);
if (retval)
return retval;
@@ -143,7 +152,8 @@ errcode_t ext2fs_allocate_block_bitmap(e
{
ext2fs_block_bitmap bitmap;
errcode_t retval;
- __u32 start, end, real_end;
+ __u32 start, end;
+ __u64 real_end;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
@@ -151,10 +161,10 @@ errcode_t ext2fs_allocate_block_bitmap(e
start = fs->super->s_first_data_block;
end = fs->super->s_blocks_count-1;
- real_end = (EXT2_BLOCKS_PER_GROUP(fs->super)
+ real_end = ((__u64)EXT2_BLOCKS_PER_GROUP(fs->super)
* fs->group_desc_count)-1 + start;
- retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
+ retval = ext2fs_allocate_generic_bitmap_64(start, end, real_end,
descr, &bitmap);
if (retval)
return retval;
@@ -183,6 +193,12 @@ errcode_t ext2fs_fudge_inode_bitmap_end(
errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
blk_t end, blk_t *oend)
{
+ ext2fs_fudge_block_bitmap_end_64(bitmap, end, (blk64_t *)oend);
+}
+
+errcode_t ext2fs_fudge_block_bitmap_end_64(ext2fs_block_bitmap bitmap,
+ blk64_t end, blk64_t *oend)
+{
EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
if (end > bitmap->real_end)
diff -upNr e2fsprogs-1.39/lib/ext2fs/bitops.c e2fsprogs-1.39.tmp/lib/ext2fs/bitops.c
--- e2fsprogs-1.39/lib/ext2fs/bitops.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/bitops.c 2006-04-21 11:51:17.000000000 +0900
@@ -77,6 +77,17 @@ void ext2fs_warn_bitmap(errcode_t errcod
#endif
}
+void ext2fs_warn_bitmap_64(errcode_t errcode, blk64_t arg,
+ const char *description)
+{
+#ifndef OMIT_COM_ERR
+ if (description)
+ com_err(0, errcode, "#%llu for %s", arg, description);
+ else
+ com_err(0, errcode, "#%llu", arg);
+#endif
+}
+
void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
int code, unsigned long arg)
{
@@ -89,3 +100,15 @@ void ext2fs_warn_bitmap2(ext2fs_generic_
#endif
}
+void ext2fs_warn_bitmap2_64(ext2fs_generic_bitmap bitmap,
+ int code, blk64_t arg)
+{
+#ifndef OMIT_COM_ERR
+ if (bitmap->description)
+ com_err(0, bitmap->base_error_code+code,
+ "#%llu for %s", arg, bitmap->description);
+ else
+ com_err(0, bitmap->base_error_code + code, "#%llu", arg);
+#endif
+}
+
diff -upNr e2fsprogs-1.39/lib/ext2fs/bitops.h e2fsprogs-1.39.tmp/lib/ext2fs/bitops.h
--- e2fsprogs-1.39/lib/ext2fs/bitops.h 2006-03-30 02:51:53.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/bitops.h 2006-04-21 13:04:17.000000000 +0900
@@ -13,12 +13,16 @@
* Linus Torvalds.
*/
-
extern int ext2fs_set_bit(unsigned int nr,void * addr);
+extern int ext2fs_set_bit_64(blk64_t nr,void * addr);
extern int ext2fs_clear_bit(unsigned int nr, void * addr);
+extern int ext2fs_clear_bit_64(blk64_t nr, void * addr);
extern int ext2fs_test_bit(unsigned int nr, const void * addr);
+extern int ext2fs_test_bit_64(blk64_t nr, const void * addr);
extern void ext2fs_fast_set_bit(unsigned int nr,void * addr);
+extern void ext2fs_fast_set_bit_64(blk64_t nr,void * addr);
extern void ext2fs_fast_clear_bit(unsigned int nr, void * addr);
+extern void ext2fs_fast_clear_bit_64(blk64_t nr, void * addr);
extern __u16 ext2fs_swab16(__u16 val);
extern __u32 ext2fs_swab32(__u32 val);
@@ -54,13 +58,21 @@ extern const char *ext2fs_unmark_string;
extern const char *ext2fs_test_string;
extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
const char *description);
+extern void ext2fs_warn_bitmap_64(errcode_t errcode, blk64_t arg,
+ const char *description);
extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
int code, unsigned long arg);
+extern void ext2fs_warn_bitmap2_64(ext2fs_generic_bitmap bitmap,
+ int code, blk64_t arg);
extern int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
+extern int ext2fs_mark_block_bitmap_64 (ext2fs_block_bitmap bitmap, blk64_t block);
extern int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block);
+extern int ext2fs_unmark_block_bitmap_64(ext2fs_block_bitmap bitmap,
+ blk64_t block);
extern int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
+extern int ext2fs_test_block_bitmap_64(ext2fs_block_bitmap bitmap, blk64_t block);
extern int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
extern int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
@@ -69,10 +81,16 @@ extern int ext2fs_test_inode_bitmap(ext2
extern void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block);
+extern void ext2fs_fast_mark_block_bitmap_64(ext2fs_block_bitmap bitmap,
+ blk64_t block);
extern void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block);
+extern void ext2fs_fast_unmark_block_bitmap_64(ext2fs_block_bitmap bitmap,
+ blk64_t block);
extern int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block);
+extern int ext2fs_fast_test_block_bitmap_64(ext2fs_block_bitmap bitmap,
+ blk64_t block);
extern void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode);
@@ -87,23 +105,39 @@ extern ext2_ino_t ext2fs_get_inode_bitma
extern void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num);
+extern void ext2fs_mark_block_bitmap_range_64(ext2fs_block_bitmap bitmap,
+ blk64_t block, int num);
extern void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num);
+extern void ext2fs_unmark_block_bitmap_range_64(ext2fs_block_bitmap bitmap,
+ blk64_t block, int num);
extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num);
+extern int ext2fs_test_block_bitmap_range_64(ext2fs_block_bitmap bitmap,
+ blk64_t block, int num);
extern void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num);
+extern void ext2fs_fast_mark_block_bitmap_range_64(ext2fs_block_bitmap bitmap,
+ blk64_t block, int num);
extern void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num);
+extern void ext2fs_fast_unmark_block_bitmap_range_64(ext2fs_block_bitmap bitmap,
+ blk64_t block, int num);
extern int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num);
+extern int ext2fs_fast_test_block_bitmap_range_64(ext2fs_block_bitmap bitmap,
+ blk64_t block, int num);
extern void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map);
/* These two routines moved to gen_bitmap.c */
extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
__u32 bitno);
+extern int ext2fs_mark_generic_bitmap_64(ext2fs_generic_bitmap bitmap,
+ __u64 bitno);
extern int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
blk_t bitno);
+extern int ext2fs_unmark_generic_bitmap_64(ext2fs_generic_bitmap bitmap,
+ blk64_t bitno);
/*
* The inline routines themselves...
*
@@ -136,22 +170,32 @@ extern int ext2fs_unmark_generic_bitmap(
* previous bit value.
*/
-_INLINE_ void ext2fs_fast_set_bit(unsigned int nr,void * addr)
+_INLINE_ void ext2fs_fast_set_bit_64(blk64_t nr,void * addr)
{
- unsigned char *ADDR = (unsigned char *) addr;
+ unsigned char *ADDR = (unsigned char *) addr;
ADDR += nr >> 3;
*ADDR |= (1 << (nr & 0x07));
}
-_INLINE_ void ext2fs_fast_clear_bit(unsigned int nr, void * addr)
+_INLINE_ void ext2fs_fast_set_bit(unsigned int nr,void * addr)
{
- unsigned char *ADDR = (unsigned char *) addr;
+ ext2fs_fast_set_bit_64(nr, addr);
+}
+
+_INLINE_ void ext2fs_fast_clear_bit_64(blk64_t nr, void * addr)
+{
+ unsigned char *ADDR = (unsigned char *) addr;
ADDR += nr >> 3;
*ADDR &= ~(1 << (nr & 0x07));
}
+_INLINE_ void ext2fs_fast_clear_bit(unsigned int nr, void * addr)
+{
+ ext2fs_fast_clear_bit_64(nr, addr);
+}
+
#if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
(defined(__i386__) || defined(__i486__) || defined(__i586__)))
@@ -175,7 +219,8 @@ struct __dummy_h { unsigned long a[100];
#define EXT2FS_ADDR (*(struct __dummy_h *) addr)
#define EXT2FS_CONST_ADDR (*(const struct __dummy_h *) addr)
-_INLINE_ int ext2fs_set_bit(unsigned int nr, void * addr)
+
+_INLINE_ int ext2fs_set_bit_64(blk64_t nr, void * addr)
{
int oldbit;
@@ -186,7 +231,12 @@ _INLINE_ int ext2fs_set_bit(unsigned int
return oldbit;
}
-_INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
+_INLINE_ int ext2fs_set_bit(unsigned int nr, void * addr)
+{
+ ext2fs_set_bit_64(nr, addr);
+}
+
+_INLINE_ int ext2fs_clear_bit_64(blk64_t nr, void * addr)
{
int oldbit;
@@ -197,7 +247,12 @@ _INLINE_ int ext2fs_clear_bit(unsigned i
return oldbit;
}
-_INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
+_INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
+{
+ ext2fs_clear_bit_64(nr, addr);
+}
+
+_INLINE_ int ext2fs_test_bit_64(blk64_t nr, const void * addr)
{
int oldbit;
@@ -208,6 +263,11 @@ _INLINE_ int ext2fs_test_bit(unsigned in
return oldbit;
}
+_INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
+{
+ ext2fs_test_bit_64(nr, addr);
+}
+
#if 0
_INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size)
{
@@ -295,7 +355,7 @@ _INLINE_ __u16 ext2fs_swab16(__u16 val)
#define _EXT2_HAVE_ASM_BITOPS_
-_INLINE_ int ext2fs_set_bit(unsigned int nr,void * addr)
+_INLINE_ int ext2fs_set_bit_64(blk64_t nr,void * addr)
{
char retval;
@@ -305,7 +365,12 @@ _INLINE_ int ext2fs_set_bit(unsigned int
return retval;
}
-_INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
+_INLINE_ int ext2fs_set_bit(unsigned int nr, void * addr)
+{
+ ext2fs_set_bit_64(nr, addr);
+}
+
+_INLINE_ int ext2fs_clear_bit_64(blk64_t nr, void * addr)
{
char retval;
@@ -315,7 +380,12 @@ _INLINE_ int ext2fs_clear_bit(unsigned i
return retval;
}
-_INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
+_INLINE_ int ext2fs_clear_bit(unsigned int nr, void * addr)
+{
+ ext2fs_clear_bit_64(nr, addr);
+}
+
+_INLINE_ int ext2fs_test_bit_64(blk64_t nr, const void * addr)
{
char retval;
@@ -325,6 +395,11 @@ _INLINE_ int ext2fs_test_bit(unsigned in
return retval;
}
+_INLINE_ int ext2fs_test_bit(unsigned int nr, const void * addr)
+{
+ ext2fs_test_bit_64(nr, addr);
+}
+
#endif /* __mc68000__ */
@@ -403,6 +478,19 @@ _INLINE_ int ext2fs_test_generic_bitmap(
return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
}
+_INLINE_ int ext2fs_test_generic_bitmap_64(ext2fs_generic_bitmap bitmap,
+ blk64_t bitno);
+
+_INLINE_ int ext2fs_test_generic_bitmap_64(ext2fs_generic_bitmap bitmap,
+ blk64_t bitno)
+{
+ if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_warn_bitmap2_64(bitmap, EXT2FS_TEST_ERROR, bitno);
+ return 0;
+ }
+ return ext2fs_test_bit_64(bitno - bitmap->start, bitmap->bitmap);
+}
+
_INLINE_ int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block)
{
@@ -411,6 +499,13 @@ _INLINE_ int ext2fs_mark_block_bitmap(ex
block);
}
+_INLINE_ int ext2fs_mark_block_bitmap_64(ext2fs_block_bitmap bitmap,
+ blk64_t block)
+{
+ return ext2fs_mark_generic_bitmap_64((ext2fs_generic_bitmap)
+ bitmap, block);
+}
+
_INLINE_ int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block)
{
@@ -418,6 +513,13 @@ _INLINE_ int ext2fs_unmark_block_bitmap(
block);
}
+_INLINE_ int ext2fs_unmark_block_bitmap_64(ext2fs_block_bitmap bitmap,
+ blk64_t block)
+{
+ return ext2fs_unmark_generic_bitmap_64((ext2fs_generic_bitmap) bitmap,
+ block);
+}
+
_INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block)
{
@@ -425,24 +527,31 @@ _INLINE_ int ext2fs_test_block_bitmap(ex
block);
}
+_INLINE_ int ext2fs_test_block_bitmap_64(ext2fs_block_bitmap bitmap,
+ blk64_t block)
+{
+ return ext2fs_test_generic_bitmap_64((ext2fs_generic_bitmap) bitmap,
+ block);
+}
+
_INLINE_ int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode)
{
- return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
+ return ext2fs_mark_generic_bitmap_64((ext2fs_generic_bitmap) bitmap,
inode);
}
_INLINE_ int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode)
{
- return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
+ return ext2fs_unmark_generic_bitmap_64((ext2fs_generic_bitmap) bitmap,
inode);
}
_INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode)
{
- return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
+ return ext2fs_test_generic_bitmap_64((ext2fs_generic_bitmap) bitmap,
inode);
}
@@ -459,6 +568,19 @@ _INLINE_ void ext2fs_fast_mark_block_bit
ext2fs_fast_set_bit(block - bitmap->start, bitmap->bitmap);
}
+_INLINE_ void ext2fs_fast_mark_block_bitmap_64(ext2fs_block_bitmap bitmap,
+ blk64_t block)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block > bitmap->end)) {
+ ext2fs_warn_bitmap_64(EXT2_ET_BAD_BLOCK_MARK, block,
+ bitmap->description);
+ return;
+ }
+#endif
+ ext2fs_fast_set_bit_64(block - bitmap->start, bitmap->bitmap);
+}
+
_INLINE_ void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block)
{
@@ -472,6 +594,19 @@ _INLINE_ void ext2fs_fast_unmark_block_b
ext2fs_fast_clear_bit(block - bitmap->start, bitmap->bitmap);
}
+_INLINE_ void ext2fs_fast_unmark_block_bitmap_64(ext2fs_block_bitmap bitmap,
+ blk64_t block)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block > bitmap->end)) {
+ ext2fs_warn_bitmap_64(EXT2_ET_BAD_BLOCK_UNMARK,
+ block, bitmap->description);
+ return;
+ }
+#endif
+ ext2fs_fast_clear_bit_64(block - bitmap->start, bitmap->bitmap);
+}
+
_INLINE_ int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
blk_t block)
{
@@ -485,17 +620,30 @@ _INLINE_ int ext2fs_fast_test_block_bitm
return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
}
+_INLINE_ int ext2fs_fast_test_block_bitmap_64(ext2fs_block_bitmap bitmap,
+ blk64_t block)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block > bitmap->end)) {
+ ext2fs_warn_bitmap_64(EXT2_ET_BAD_BLOCK_TEST,
+ block, bitmap->description);
+ return 0;
+ }
+#endif
+ return ext2fs_test_bit_64(block - bitmap->start, bitmap->bitmap);
+}
+
_INLINE_ void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
ext2_ino_t inode)
{
#ifdef EXT2FS_DEBUG_FAST_OPS
if ((inode < bitmap->start) || (inode > bitmap->end)) {
- ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK,
+ ext2fs_warn_bitmap_64(EXT2_ET_BAD_INODE_MARK,
inode, bitmap->description);
return;
}
#endif
- ext2fs_fast_set_bit(inode - bitmap->start, bitmap->bitmap);
+ ext2fs_fast_set_bit_64(inode - bitmap->start, bitmap->bitmap);
}
_INLINE_ void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
@@ -503,12 +651,12 @@ _INLINE_ void ext2fs_fast_unmark_inode_b
{
#ifdef EXT2FS_DEBUG_FAST_OPS
if ((inode < bitmap->start) || (inode > bitmap->end)) {
- ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK,
+ ext2fs_warn_bitmap_64(EXT2_ET_BAD_INODE_UNMARK,
inode, bitmap->description);
return;
}
#endif
- ext2fs_fast_clear_bit(inode - bitmap->start, bitmap->bitmap);
+ ext2fs_fast_clear_bit_64(inode - bitmap->start, bitmap->bitmap);
}
_INLINE_ int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
@@ -516,12 +664,12 @@ _INLINE_ int ext2fs_fast_test_inode_bitm
{
#ifdef EXT2FS_DEBUG_FAST_OPS
if ((inode < bitmap->start) || (inode > bitmap->end)) {
- ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
+ ext2fs_warn_bitmap_64(EXT2_ET_BAD_INODE_TEST,
inode, bitmap->description);
return 0;
}
#endif
- return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
+ return ext2fs_test_bit_64(inode - bitmap->start, bitmap->bitmap);
}
_INLINE_ blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
@@ -561,6 +709,23 @@ _INLINE_ int ext2fs_test_block_bitmap_ra
return 1;
}
+_INLINE_ int ext2fs_test_block_bitmap_range_64(ext2fs_block_bitmap bitmap,
+ blk64_t block, int num)
+{
+ int i;
+
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap_64(EXT2_ET_BAD_BLOCK_TEST,
+ block, bitmap->description);
+ return 0;
+ }
+ for (i=0; i < num; i++) {
+ if (ext2fs_fast_test_block_bitmap_64(bitmap, block+i))
+ return 0;
+ }
+ return 1;
+}
+
_INLINE_ int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num)
{
@@ -580,6 +745,25 @@ _INLINE_ int ext2fs_fast_test_block_bitm
return 1;
}
+_INLINE_ int ext2fs_fast_test_block_bitmap_range_64(ext2fs_block_bitmap bitmap,
+ blk64_t block, int num)
+{
+ int i;
+
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap_64(EXT2_ET_BAD_BLOCK_TEST,
+ block, bitmap->description);
+ return 0;
+ }
+#endif
+ for (i=0; i < num; i++) {
+ if (ext2fs_fast_test_block_bitmap_64(bitmap, block+i))
+ return 0;
+ }
+ return 1;
+}
+
_INLINE_ void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num)
{
@@ -594,6 +778,20 @@ _INLINE_ void ext2fs_mark_block_bitmap_r
ext2fs_fast_set_bit(block + i - bitmap->start, bitmap->bitmap);
}
+_INLINE_ void ext2fs_mark_block_bitmap_range_64(ext2fs_block_bitmap bitmap,
+ blk64_t block, int num)
+{
+ int i;
+
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap_64(EXT2_ET_BAD_BLOCK_MARK, block,
+ bitmap->description);
+ return;
+ }
+ for (i=0; i < num; i++)
+ ext2fs_fast_set_bit_64(block + i - bitmap->start, bitmap->bitmap);
+}
+
_INLINE_ void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num)
{
@@ -610,6 +808,22 @@ _INLINE_ void ext2fs_fast_mark_block_bit
ext2fs_fast_set_bit(block + i - bitmap->start, bitmap->bitmap);
}
+_INLINE_ void ext2fs_fast_mark_block_bitmap_range_64(ext2fs_block_bitmap bitmap,
+ blk64_t block, int num)
+{
+ int i;
+
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap_64(EXT2_ET_BAD_BLOCK_MARK, block,
+ bitmap->description);
+ return;
+ }
+#endif
+ for (i=0; i < num; i++)
+ ext2fs_fast_set_bit_64(block + i - bitmap->start, bitmap->bitmap);
+}
+
_INLINE_ void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num)
{
@@ -625,6 +839,21 @@ _INLINE_ void ext2fs_unmark_block_bitmap
bitmap->bitmap);
}
+_INLINE_ void ext2fs_unmark_block_bitmap_range_64(ext2fs_block_bitmap bitmap,
+ blk64_t block, int num)
+{
+ int i;
+
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap_64(EXT2_ET_BAD_BLOCK_UNMARK, block,
+ bitmap->description);
+ return;
+ }
+ for (i=0; i < num; i++)
+ ext2fs_fast_clear_bit_64(block + i - bitmap->start,
+ bitmap->bitmap);
+}
+
_INLINE_ void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
blk_t block, int num)
{
@@ -641,6 +870,23 @@ _INLINE_ void ext2fs_fast_unmark_block_b
ext2fs_fast_clear_bit(block + i - bitmap->start,
bitmap->bitmap);
}
+
+_INLINE_ void ext2fs_fast_unmark_block_bitmap_range_64(ext2fs_block_bitmap bitmap,
+ blk64_t block, int num)
+{
+ int i;
+
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap64(EXT2_ET_BAD_BLOCK_UNMARK, block,
+ bitmap->description);
+ return;
+ }
+#endif
+ for (i=0; i < num; i++)
+ ext2fs_fast_clear_bit_64(block + i - bitmap->start,
+ bitmap->bitmap);
+}
#undef _INLINE_
#endif
diff -upNr e2fsprogs-1.39/lib/ext2fs/ext2fs.h e2fsprogs-1.39.tmp/lib/ext2fs/ext2fs.h
--- e2fsprogs-1.39/lib/ext2fs/ext2fs.h 2006-04-21 11:51:04.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/ext2fs.h 2006-04-21 11:51:17.000000000 +0900
@@ -103,7 +103,7 @@ struct ext2fs_struct_generic_bitmap {
errcode_t magic;
ext2_filsys fs;
__u32 start, end;
- __u32 real_end;
+ __u64 real_end;
char * description;
char * bitmap;
errcode_t base_error_code;
@@ -549,6 +549,11 @@ extern errcode_t ext2fs_allocate_generic
__u32 real_end,
const char *descr,
ext2fs_generic_bitmap *ret);
+extern errcode_t ext2fs_allocate_generic_bitmap_64(__u32 start,
+ __u32 end,
+ __u64 real_end,
+ const char *descr,
+ ext2fs_generic_bitmap *ret);
extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
const char *descr,
ext2fs_block_bitmap *ret);
@@ -559,6 +564,8 @@ extern errcode_t ext2fs_fudge_inode_bitm
ext2_ino_t end, ext2_ino_t *oend);
extern errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
blk_t end, blk_t *oend);
+extern errcode_t ext2fs_fudge_block_bitmap_end_64(ext2fs_block_bitmap bitmap,
+ blk64_t end, blk64_t *oend);
extern void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap);
extern void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap);
extern errcode_t ext2fs_read_bitmaps(ext2_filsys fs);
@@ -917,10 +924,15 @@ extern errcode_t ext2fs_create_resize_in
extern errcode_t ext2fs_resize_generic_bitmap(__u32 new_end,
__u32 new_real_end,
ext2fs_generic_bitmap bmap);
+extern errcode_t ext2fs_resize_generic_bitmap_64(__u32 new_end,
+ __u64 new_real_end,
+ ext2fs_generic_bitmap bmap);
extern errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
ext2fs_inode_bitmap bmap);
extern errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
ext2fs_block_bitmap bmap);
+extern errcode_t ext2fs_resize_block_bitmap_64(__u32 new_end, __u64 new_real_end,
+ ext2fs_block_bitmap bmap);
extern errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
ext2fs_generic_bitmap *dest);
diff -upNr e2fsprogs-1.39/lib/ext2fs/gen_bitmap.c e2fsprogs-1.39.tmp/lib/ext2fs/gen_bitmap.c
--- e2fsprogs-1.39/lib/ext2fs/gen_bitmap.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/gen_bitmap.c 2006-04-21 11:51:17.000000000 +0900
@@ -34,7 +34,17 @@ int ext2fs_mark_generic_bitmap(ext2fs_ge
ext2fs_warn_bitmap2(bitmap, EXT2FS_MARK_ERROR, bitno);
return 0;
}
- return ext2fs_set_bit(bitno - bitmap->start, bitmap->bitmap);
+ return ext2fs_set_bit_64(bitno - bitmap->start, bitmap->bitmap);
+}
+
+int ext2fs_mark_generic_bitmap_64(ext2fs_generic_bitmap bitmap,
+ __u64 bitno)
+{
+ if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_warn_bitmap2_64(bitmap, EXT2FS_MARK_ERROR, bitno);
+ return 0;
+ }
+ return ext2fs_set_bit_64(bitno - bitmap->start, bitmap->bitmap);
}
int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
@@ -44,5 +54,15 @@ int ext2fs_unmark_generic_bitmap(ext2fs_
ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
return 0;
}
- return ext2fs_clear_bit(bitno - bitmap->start, bitmap->bitmap);
+ return ext2fs_clear_bit_64(bitno - bitmap->start, bitmap->bitmap);
+}
+
+int ext2fs_unmark_generic_bitmap_64(ext2fs_generic_bitmap bitmap,
+ blk64_t bitno)
+{
+ if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_warn_bitmap2_64(bitmap, EXT2FS_UNMARK_ERROR, bitno);
+ return 0;
+ }
+ return ext2fs_clear_bit_64(bitno - bitmap->start, bitmap->bitmap);
}
diff -upNr e2fsprogs-1.39/lib/ext2fs/rs_bitmap.c e2fsprogs-1.39.tmp/lib/ext2fs/rs_bitmap.c
--- e2fsprogs-1.39/lib/ext2fs/rs_bitmap.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/rs_bitmap.c 2006-04-21 11:51:17.000000000 +0900
@@ -47,7 +47,51 @@ errcode_t ext2fs_resize_generic_bitmap(_
if (bitno > new_end)
bitno = new_end;
for (; bitno > bmap->end; bitno--)
- ext2fs_clear_bit(bitno - bmap->start, bmap->bitmap);
+ ext2fs_clear_bit_64(bitno - bmap->start, bmap->bitmap);
+ }
+ if (new_real_end == bmap->real_end) {
+ bmap->end = new_end;
+ return 0;
+ }
+
+ size = ((bmap->real_end - bmap->start) / 8) + 1;
+ new_size = ((new_real_end - bmap->start) / 8) + 1;
+
+ if (size != new_size) {
+ retval = ext2fs_resize_mem(size, new_size, &bmap->bitmap);
+ if (retval)
+ return retval;
+ }
+ if (new_size > size)
+ memset(bmap->bitmap + size, 0, new_size - size);
+
+ bmap->end = new_end;
+ bmap->real_end = new_real_end;
+ return 0;
+}
+
+errcode_t ext2fs_resize_generic_bitmap_64(__u32 new_end, __u64 new_real_end,
+ ext2fs_generic_bitmap bmap)
+{
+ errcode_t retval;
+ size_t size, new_size;
+ __u32 bitno;
+
+ if (!bmap)
+ return EXT2_ET_INVALID_ARGUMENT;
+
+ EXT2_CHECK_MAGIC(bmap, EXT2_ET_MAGIC_GENERIC_BITMAP);
+
+ /*
+ * If we're expanding the bitmap, make sure all of the new
+ * parts of the bitmap are zero.
+ */
+ if (new_end > bmap->end) {
+ bitno = bmap->real_end;
+ if (bitno > new_end)
+ bitno = new_end;
+ for (; bitno > bmap->end; bitno--)
+ ext2fs_clear_bit_64(bitno - bmap->start, bmap->bitmap);
}
if (new_real_end == bmap->real_end) {
bmap->end = new_end;
@@ -81,7 +125,7 @@ errcode_t ext2fs_resize_inode_bitmap(__u
EXT2_CHECK_MAGIC(bmap, EXT2_ET_MAGIC_INODE_BITMAP);
bmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
- retval = ext2fs_resize_generic_bitmap(new_end, new_real_end,
+ retval = ext2fs_resize_generic_bitmap_64(new_end, new_real_end,
bmap);
bmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
return retval;
@@ -89,6 +133,23 @@ errcode_t ext2fs_resize_inode_bitmap(__u
errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
ext2fs_block_bitmap bmap)
+{
+ errcode_t retval;
+
+ if (!bmap)
+ return EXT2_ET_INVALID_ARGUMENT;
+
+ EXT2_CHECK_MAGIC(bmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
+
+ bmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
+ retval = ext2fs_resize_generic_bitmap(new_end, new_real_end,
+ bmap);
+ bmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP;
+ return retval;
+}
+
+errcode_t ext2fs_resize_block_bitmap_64(__u32 new_end, __u64 new_real_end,
+ ext2fs_block_bitmap bmap)
{
errcode_t retval;
@@ -98,7 +159,7 @@ errcode_t ext2fs_resize_block_bitmap(__u
EXT2_CHECK_MAGIC(bmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
bmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
- retval = ext2fs_resize_generic_bitmap(new_end, new_real_end,
+ retval = ext2fs_resize_generic_bitmap_64(new_end, new_real_end,
bmap);
bmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP;
return retval;
diff -upNr e2fsprogs-1.39/lib/ext2fs/rw_bitmaps.c e2fsprogs-1.39.tmp/lib/ext2fs/rw_bitmaps.c
--- e2fsprogs-1.39/lib/ext2fs/rw_bitmaps.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/rw_bitmaps.c 2006-04-21 11:51:17.000000000 +0900
@@ -124,7 +124,7 @@ errcode_t ext2fs_write_block_bitmap (ext
% EXT2_BLOCKS_PER_GROUP(fs->super));
if (nbits)
for (j = nbits; j < fs->blocksize * 8; j++)
- ext2fs_set_bit(j, bitmap_block);
+ ext2fs_set_bit_64(j, bitmap_block);
}
blk = fs->group_desc[i].bg_block_bitmap;
if (blk) {
diff -upNr e2fsprogs-1.39/lib/ext2fs/tst_iscan.c e2fsprogs-1.39.tmp/lib/ext2fs/tst_iscan.c
--- e2fsprogs-1.39/lib/ext2fs/tst_iscan.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/tst_iscan.c 2006-04-21 11:51:17.000000000 +0900
@@ -174,19 +174,19 @@ static void check_map(void)
unsigned long blk;
for (i=0; test_vec[i]; i++) {
- if (ext2fs_test_block_bitmap(touched_map, test_vec[i])) {
+ if (ext2fs_test_block_bitmap_64(touched_map, test_vec[i])) {
printf("Bad block was touched --- %d\n", test_vec[i]);
failed++;
first_no_comma = 1;
}
- ext2fs_mark_block_bitmap(touched_map, test_vec[i]);
+ ext2fs_mark_block_bitmap_64(touched_map, test_vec[i]);
}
for (i = 0; i < test_fs->group_desc_count; i++) {
for (j=0, blk = test_fs->group_desc[i].bg_inode_table;
j < test_fs->inode_blocks_per_group;
j++, blk++) {
- if (!ext2fs_test_block_bitmap(touched_map, blk) &&
- !ext2fs_test_block_bitmap(bad_block_map, blk)) {
+ if (!ext2fs_test_block_bitmap_64(touched_map, blk) &&
+ !ext2fs_test_block_bitmap_64(bad_block_map, blk)) {
printf("Missing block --- %lu\n", blk);
failed++;
}
diff -upNr e2fsprogs-1.39/misc/dumpe2fs.c e2fsprogs-1.39.tmp/misc/dumpe2fs.c
--- e2fsprogs-1.39/misc/dumpe2fs.c 2006-03-30 03:15:29.000000000 +0900
+++ e2fsprogs-1.39.tmp/misc/dumpe2fs.c 2006-04-21 11:51:17.000000000 +0900
@@ -42,7 +42,7 @@ extern int optind;
#include "../version.h"
#include "nls-enable.h"
-#define in_use(m, x) (ext2fs_test_bit ((x), (m)))
+#define in_use(m, x) (ext2fs_test_bit_64 ((x), (m)))
const char * program_name = "dumpe2fs";
char * device_name = NULL;
diff -upNr e2fsprogs-1.39/misc/e2image.c e2fsprogs-1.39.tmp/misc/e2image.c
--- e2fsprogs-1.39/misc/e2image.c 2006-03-19 11:34:00.000000000 +0900
+++ e2fsprogs-1.39.tmp/misc/e2image.c 2006-04-21 11:51:17.000000000 +0900
@@ -223,9 +223,9 @@ static int process_dir_block(ext2_filsys
p = (struct process_block_struct *) priv_data;
- ext2fs_mark_block_bitmap(meta_block_map, *block_nr);
+ ext2fs_mark_block_bitmap_64(meta_block_map, *block_nr);
if (scramble_block_map && p->is_dir && blockcnt >= 0)
- ext2fs_mark_block_bitmap(scramble_block_map, *block_nr);
+ ext2fs_mark_block_bitmap_64(scramble_block_map, *block_nr);
return 0;
}
@@ -237,7 +237,7 @@ static int process_file_block(ext2_filsy
void *priv_data EXT2FS_ATTR((unused)))
{
if (blockcnt < 0) {
- ext2fs_mark_block_bitmap(meta_block_map, *block_nr);
+ ext2fs_mark_block_bitmap_64(meta_block_map, *block_nr);
}
return 0;
}
@@ -251,13 +251,13 @@ static void mark_table_blocks(ext2_filsy
/*
* Mark primary superblock
*/
- ext2fs_mark_block_bitmap(meta_block_map, block);
+ ext2fs_mark_block_bitmap_64(meta_block_map, block);
/*
* Mark the primary superblock descriptors
*/
for (j = 0; j < fs->desc_blocks; j++) {
- ext2fs_mark_block_bitmap(meta_block_map,
+ ext2fs_mark_block_bitmap_64(meta_block_map,
ext2fs_descriptor_block_loc(fs, block, j));
}
@@ -269,14 +269,14 @@ static void mark_table_blocks(ext2_filsy
for (j = 0, b = fs->group_desc[i].bg_inode_table;
j < (unsigned) fs->inode_blocks_per_group;
j++, b++)
- ext2fs_mark_block_bitmap(meta_block_map, b);
+ ext2fs_mark_block_bitmap_64(meta_block_map, b);
}
/*
* Mark block used for the block bitmap
*/
if (fs->group_desc[i].bg_block_bitmap) {
- ext2fs_mark_block_bitmap(meta_block_map,
+ ext2fs_mark_block_bitmap_64(meta_block_map,
fs->group_desc[i].bg_block_bitmap);
}
@@ -284,7 +284,7 @@ static void mark_table_blocks(ext2_filsy
* Mark block used for the inode bitmap
*/
if (fs->group_desc[i].bg_inode_bitmap) {
- ext2fs_mark_block_bitmap(meta_block_map,
+ ext2fs_mark_block_bitmap_64(meta_block_map,
fs->group_desc[i].bg_inode_bitmap);
}
block += fs->super->s_blocks_per_group;
@@ -414,14 +414,14 @@ static void output_meta_data_blocks(ext2
memset(zero_buf, 0, fs->blocksize);
for (blk = 0; blk < fs->super->s_blocks_count; blk++) {
if ((blk >= fs->super->s_first_data_block) &&
- ext2fs_test_block_bitmap(meta_block_map, blk)) {
+ ext2fs_test_block_bitmap_64(meta_block_map, blk)) {
retval = io_channel_read_blk(fs->io, blk, 1, buf);
if (retval) {
com_err(program_name, retval,
"error reading block %d", blk);
}
if (scramble_block_map &&
- ext2fs_test_block_bitmap(scramble_block_map, blk))
+ ext2fs_test_block_bitmap_64(scramble_block_map, blk))
scramble_dir_block(fs, blk, buf);
if ((fd != 1) && check_zero_block(buf, fs->blocksize))
goto sparse_write;
@@ -500,7 +500,7 @@ static void write_raw_image_file(ext2_fi
if (!inode.i_links_count)
continue;
if (inode.i_file_acl) {
- ext2fs_mark_block_bitmap(meta_block_map,
+ ext2fs_mark_block_bitmap_64(meta_block_map,
inode.i_file_acl);
}
if (!ext2fs_inode_has_valid_blocks(&inode))
diff -upNr e2fsprogs-1.39/misc/mke2fs.c e2fsprogs-1.39.tmp/misc/mke2fs.c
--- e2fsprogs-1.39/misc/mke2fs.c 2006-04-21 11:51:04.000000000 +0900
+++ e2fsprogs-1.39.tmp/misc/mke2fs.c 2006-04-21 11:51:17.000000000 +0900
@@ -277,7 +277,7 @@ _("Warning: the backup superblock/group
exit(1);
}
while (ext2fs_badblocks_list_iterate(bb_iter, &blk))
- ext2fs_mark_block_bitmap(fs->block_map, blk);
+ ext2fs_mark_block_bitmap_64(fs->block_map, blk);
ext2fs_badblocks_list_iterate_end(bb_iter);
}
diff -upNr e2fsprogs-1.39/misc/tune2fs.c e2fsprogs-1.39.tmp/misc/tune2fs.c
--- e2fsprogs-1.39/misc/tune2fs.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/misc/tune2fs.c 2006-04-21 11:51:17.000000000 +0900
@@ -210,7 +210,7 @@ static int release_blocks_proc(ext2_fils
int group;
block = *blocknr;
- ext2fs_unmark_block_bitmap(fs->block_map,block);
+ ext2fs_unmark_block_bitmap_64(fs->block_map,block);
group = ext2fs_group_of_blk(fs, block);
fs->group_desc[group].bg_free_blocks_count++;
fs->super->s_free_blocks_count++;
diff -upNr e2fsprogs-1.39/resize/resize2fs.c e2fsprogs-1.39.tmp/resize/resize2fs.c
--- e2fsprogs-1.39/resize/resize2fs.c 2006-04-21 11:51:04.000000000 +0900
+++ e2fsprogs-1.39.tmp/resize/resize2fs.c 2006-04-21 11:51:17.000000000 +0900
@@ -268,7 +268,7 @@ retry:
real_end = ((EXT2_BLOCKS_PER_GROUP(fs->super)
* (__u64)fs->group_desc_count)) - 1 +
fs->super->s_first_data_block;
- retval = ext2fs_resize_block_bitmap(fs->super->s_blocks_count-1,
+ retval = ext2fs_resize_block_bitmap_64(fs->super->s_blocks_count-1,
real_end, fs->block_map);
if (retval) goto errout;
@@ -381,7 +381,7 @@ retry:
has_super = ext2fs_bg_has_super(fs, i);
if (has_super) {
- ext2fs_mark_block_bitmap(fs->block_map, group_block);
+ ext2fs_mark_block_bitmap_64(fs->block_map, group_block);
adjblocks++;
}
meta_bg_size = (fs->blocksize /
@@ -392,7 +392,7 @@ retry:
(meta_bg < fs->super->s_first_meta_bg)) {
if (has_super) {
for (j=0; j < old_desc_blocks; j++)
- ext2fs_mark_block_bitmap(fs->block_map,
+ ext2fs_mark_block_bitmap_64(fs->block_map,
group_block + 1 + j);
adjblocks += old_desc_blocks;
}
@@ -402,7 +402,7 @@ retry:
if (((i % meta_bg_size) == 0) ||
((i % meta_bg_size) == 1) ||
((i % meta_bg_size) == (meta_bg_size-1)))
- ext2fs_mark_block_bitmap(fs->block_map,
+ ext2fs_mark_block_bitmap_64(fs->block_map,
group_block + has_super);
}
@@ -567,18 +567,18 @@ static errcode_t mark_table_blocks(ext2_
for (j = 0, b = fs->group_desc[i].bg_inode_table;
j < (unsigned int) fs->inode_blocks_per_group;
j++, b++)
- ext2fs_mark_block_bitmap(bmap, b);
+ ext2fs_mark_block_bitmap_64(bmap, b);
/*
* Mark block used for the block bitmap
*/
- ext2fs_mark_block_bitmap(bmap,
+ ext2fs_mark_block_bitmap_64(bmap,
fs->group_desc[i].bg_block_bitmap);
/*
* Mark block used for the inode bitmap
*/
- ext2fs_mark_block_bitmap(bmap,
+ ext2fs_mark_block_bitmap_64(bmap,
fs->group_desc[i].bg_inode_bitmap);
block += fs->super->s_blocks_per_group;
}
@@ -596,8 +596,8 @@ static void mark_fs_metablock(ext2_resiz
{
ext2_filsys fs = rfs->new_fs;
- ext2fs_mark_block_bitmap(rfs->reserve_blocks, blk);
- ext2fs_mark_block_bitmap(fs->block_map, blk);
+ ext2fs_mark_block_bitmap_64(rfs->reserve_blocks, blk);
+ ext2fs_mark_block_bitmap_64(fs->block_map, blk);
/*
* Check to see if we overlap with the inode or block bitmap,
@@ -613,9 +613,9 @@ static void mark_fs_metablock(ext2_resiz
} else if (IS_INODE_TB(fs, group, blk)) {
FS_INODE_TB(fs, group) = 0;
rfs->needed_blocks++;
- } else if (ext2fs_test_block_bitmap(rfs->old_fs->block_map, blk) &&
- !ext2fs_test_block_bitmap(meta_bmap, blk)) {
- ext2fs_mark_block_bitmap(rfs->move_blocks, blk);
+ } else if (ext2fs_test_block_bitmap_64(rfs->old_fs->block_map, blk) &&
+ !ext2fs_test_block_bitmap_64(meta_bmap, blk)) {
+ ext2fs_mark_block_bitmap_64(rfs->move_blocks, blk);
rfs->needed_blocks++;
}
}
@@ -669,12 +669,12 @@ static errcode_t blocks_to_move(ext2_res
*/
for (blk = fs->super->s_blocks_count;
blk < old_fs->super->s_blocks_count; blk++) {
- if (ext2fs_test_block_bitmap(old_fs->block_map, blk) &&
- !ext2fs_test_block_bitmap(meta_bmap, blk)) {
- ext2fs_mark_block_bitmap(rfs->move_blocks, blk);
+ if (ext2fs_test_block_bitmap_64(old_fs->block_map, blk) &&
+ !ext2fs_test_block_bitmap_64(meta_bmap, blk)) {
+ ext2fs_mark_block_bitmap_64(rfs->move_blocks, blk);
rfs->needed_blocks++;
}
- ext2fs_mark_block_bitmap(rfs->reserve_blocks, blk);
+ ext2fs_mark_block_bitmap_64(rfs->reserve_blocks, blk);
}
if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) {
@@ -707,7 +707,7 @@ static errcode_t blocks_to_move(ext2_res
}
for (blk = group_blk+1+new_blocks;
blk < group_blk+1+old_blocks; blk++) {
- ext2fs_unmark_block_bitmap(fs->block_map,
+ ext2fs_unmark_block_bitmap_64(fs->block_map,
blk);
rfs->needed_blocks--;
}
@@ -756,15 +756,15 @@ static errcode_t blocks_to_move(ext2_res
* aren't to be moved.
*/
if (fs->group_desc[i].bg_block_bitmap)
- ext2fs_mark_block_bitmap(rfs->reserve_blocks,
+ ext2fs_mark_block_bitmap_64(rfs->reserve_blocks,
fs->group_desc[i].bg_block_bitmap);
if (fs->group_desc[i].bg_inode_bitmap)
- ext2fs_mark_block_bitmap(rfs->reserve_blocks,
+ ext2fs_mark_block_bitmap_64(rfs->reserve_blocks,
fs->group_desc[i].bg_inode_bitmap);
if (fs->group_desc[i].bg_inode_table)
for (blk = fs->group_desc[i].bg_inode_table, j=0;
j < fs->inode_blocks_per_group ; j++, blk++)
- ext2fs_mark_block_bitmap(rfs->reserve_blocks,
+ ext2fs_mark_block_bitmap_64(rfs->reserve_blocks,
blk);
/*
@@ -781,18 +781,18 @@ static errcode_t blocks_to_move(ext2_res
*/
if (FS_BLOCK_BM(old_fs, i) !=
(blk = FS_BLOCK_BM(fs, i))) {
- ext2fs_mark_block_bitmap(fs->block_map, blk);
- if (ext2fs_test_block_bitmap(old_fs->block_map, blk) &&
- !ext2fs_test_block_bitmap(meta_bmap, blk))
- ext2fs_mark_block_bitmap(rfs->move_blocks,
+ ext2fs_mark_block_bitmap_64(fs->block_map, blk);
+ if (ext2fs_test_block_bitmap_64(old_fs->block_map, blk) &&
+ !ext2fs_test_block_bitmap_64(meta_bmap, blk))
+ ext2fs_mark_block_bitmap_64(rfs->move_blocks,
blk);
}
if (FS_INODE_BM(old_fs, i) !=
(blk = FS_INODE_BM(fs, i))) {
- ext2fs_mark_block_bitmap(fs->block_map, blk);
- if (ext2fs_test_block_bitmap(old_fs->block_map, blk) &&
- !ext2fs_test_block_bitmap(meta_bmap, blk))
- ext2fs_mark_block_bitmap(rfs->move_blocks,
+ ext2fs_mark_block_bitmap_64(fs->block_map, blk);
+ if (ext2fs_test_block_bitmap_64(old_fs->block_map, blk) &&
+ !ext2fs_test_block_bitmap_64(meta_bmap, blk))
+ ext2fs_mark_block_bitmap_64(rfs->move_blocks,
blk);
}
@@ -815,10 +815,10 @@ static errcode_t blocks_to_move(ext2_res
*/
for (blk = fs->group_desc[i].bg_inode_table, j=0;
j < fs->inode_blocks_per_group ; j++, blk++) {
- ext2fs_mark_block_bitmap(fs->block_map, blk);
- if (ext2fs_test_block_bitmap(old_fs->block_map, blk) &&
- !ext2fs_test_block_bitmap(meta_bmap, blk))
- ext2fs_mark_block_bitmap(rfs->move_blocks,
+ ext2fs_mark_block_bitmap_64(fs->block_map, blk);
+ if (ext2fs_test_block_bitmap_64(old_fs->block_map, blk) &&
+ !ext2fs_test_block_bitmap_64(meta_bmap, blk))
+ ext2fs_mark_block_bitmap_64(rfs->move_blocks,
blk);
}
@@ -828,7 +828,7 @@ static errcode_t blocks_to_move(ext2_res
*/
for (blk = rfs->old_fs->group_desc[i].bg_inode_table, j=0;
j < fs->inode_blocks_per_group ; j++, blk++)
- ext2fs_mark_block_bitmap(rfs->reserve_blocks, blk);
+ ext2fs_mark_block_bitmap_64(rfs->reserve_blocks, blk);
next_group:
group_blk += rfs->new_fs->super->s_blocks_per_group;
@@ -889,12 +889,12 @@ static blk_t get_new_block(ext2_resize_t
rfs->new_blk = fs->super->s_first_data_block;
continue;
}
- if (ext2fs_test_block_bitmap(fs->block_map, rfs->new_blk) ||
- ext2fs_test_block_bitmap(rfs->reserve_blocks,
+ if (ext2fs_test_block_bitmap_64(fs->block_map, rfs->new_blk) ||
+ ext2fs_test_block_bitmap_64(rfs->reserve_blocks,
rfs->new_blk) ||
((rfs->alloc_state == AVOID_OLD) &&
(rfs->new_blk < rfs->old_fs->super->s_blocks_count) &&
- ext2fs_test_block_bitmap(rfs->old_fs->block_map,
+ ext2fs_test_block_bitmap_64(rfs->old_fs->block_map,
rfs->new_blk))) {
rfs->new_blk++;
continue;
@@ -938,9 +938,9 @@ static errcode_t block_mover(ext2_resize
init_block_alloc(rfs);
for (blk = old_fs->super->s_first_data_block;
blk < old_fs->super->s_blocks_count; blk++) {
- if (!ext2fs_test_block_bitmap(old_fs->block_map, blk))
+ if (!ext2fs_test_block_bitmap_64(old_fs->block_map, blk))
continue;
- if (!ext2fs_test_block_bitmap(rfs->move_blocks, blk))
+ if (!ext2fs_test_block_bitmap_64(rfs->move_blocks, blk))
continue;
if (ext2fs_badblocks_list_test(badblock_list, blk)) {
ext2fs_badblocks_list_del(badblock_list, blk);
@@ -953,7 +953,7 @@ static errcode_t block_mover(ext2_resize
retval = ENOSPC;
goto errout;
}
- ext2fs_mark_block_bitmap(fs->block_map, new_blk);
+ ext2fs_mark_block_bitmap_64(fs->block_map, new_blk);
ext2fs_add_extent_entry(rfs->bmap, blk, new_blk);
to_move++;
}
@@ -1476,7 +1476,7 @@ static errcode_t move_itables(ext2_resiz
for (blk = rfs->old_fs->group_desc[i].bg_inode_table, j=0;
j < fs->inode_blocks_per_group ; j++, blk++)
- ext2fs_unmark_block_bitmap(fs->block_map, blk);
+ ext2fs_unmark_block_bitmap_64(fs->block_map, blk);
rfs->old_fs->group_desc[i].bg_inode_table = new_blk;
ext2fs_mark_super_dirty(rfs->old_fs);
@@ -1569,7 +1569,7 @@ static errcode_t ext2fs_calculate_summar
*/
for (blk = fs->super->s_first_data_block;
blk < fs->super->s_blocks_count; blk++) {
- if (!ext2fs_fast_test_block_bitmap(fs->block_map, blk)) {
+ if (!ext2fs_fast_test_block_bitmap_64(fs->block_map, blk)) {
group_free++;
total_free++;
}
^ permalink raw reply
* [UPDATE][14/21]e2fsprogs modify variables to exceed 2G
From: sho @ 2006-04-26 1:49 UTC (permalink / raw)
To: ext2-devel, linux-kernel
Summary of this patch:
[14/21] change the type of variables for a block or an inode
- Change the type of 4byte variables manipulating a block or
an inode from signed to unsigned.
- Cast the type of operation in which an overflow occurs to
long long.
Signed-off-by: Takashi Sato sho@tnes.nec.co.jp
---
diff -upNr e2fsprogs-1.39/e2fsck/pass1.c e2fsprogs-1.39.tmp/e2fsck/pass1.c
--- e2fsprogs-1.39/e2fsck/pass1.c 2006-03-19 11:33:56.000000000 +0900
+++ e2fsprogs-1.39.tmp/e2fsck/pass1.c 2006-04-19 16:43:02.000000000 +0900
@@ -1893,6 +1893,7 @@ static void new_table_block(e2fsck_t ctx
int i;
char *buf;
struct problem_context pctx;
+ blk64_t last_block;
clear_problem_context(&pctx);
@@ -1900,8 +1901,11 @@ static void new_table_block(e2fsck_t ctx
pctx.blk = old_block;
pctx.str = name;
- pctx.errcode = ext2fs_get_free_blocks(fs, first_block,
- first_block + fs->super->s_blocks_per_group,
+ last_block = (blk64_t) first_block + fs->super->s_blocks_per_group - 1;
+ if (last_block >= fs->super->s_blocks_count)
+ last_block = fs->super->s_blocks_count - 1;
+
+ pctx.errcode = ext2fs_get_free_blocks(fs, first_block, last_block,
num, ctx->block_found_map, new_block);
if (pctx.errcode) {
pctx.num = num;
diff -upNr e2fsprogs-1.39/e2fsck/pass5.c e2fsprogs-1.39.tmp/e2fsck/pass5.c
--- e2fsprogs-1.39/e2fsck/pass5.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/e2fsck/pass5.c 2006-04-19 16:43:42.000000000 +0900
@@ -502,13 +502,13 @@ static void check_inode_end(e2fsck_t ctx
static void check_block_end(e2fsck_t ctx)
{
ext2_filsys fs = ctx->fs;
- blk_t end, save_blocks_count, i;
+ blk64_t end, save_blocks_count, i;
struct problem_context pctx;
clear_problem_context(&pctx);
end = fs->block_map->start +
- (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
+ (EXT2_BLOCKS_PER_GROUP(fs->super) * (__u64)fs->group_desc_count) - 1;
pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
&save_blocks_count);
if (pctx.errcode) {
diff -upNr e2fsprogs-1.39/lib/ext2fs/alloc.c e2fsprogs-1.39.tmp/lib/ext2fs/alloc.c
--- e2fsprogs-1.39/lib/ext2fs/alloc.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/alloc.c 2006-04-19 16:43:02.000000000 +0900
@@ -159,15 +159,15 @@ errcode_t ext2fs_get_free_blocks(ext2_fi
finish = start;
if (!num)
num = 1;
+ if (b+num-1 >= fs->super->s_blocks_count)
+ b = fs->super->s_first_data_block;
do {
- if (b+num-1 > fs->super->s_blocks_count)
- b = fs->super->s_first_data_block;
if (ext2fs_fast_test_block_bitmap_range(map, b, num)) {
*ret = b;
return 0;
}
b++;
- } while (b != finish);
+ } while (b <= finish);
return EXT2_ET_BLOCK_ALLOC_FAIL;
}
diff -upNr e2fsprogs-1.39/lib/ext2fs/alloc_tables.c e2fsprogs-1.39.tmp/lib/ext2fs/alloc_tables.c
--- e2fsprogs-1.39/lib/ext2fs/alloc_tables.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/alloc_tables.c 2006-04-19 16:43:02.000000000 +0900
@@ -31,13 +31,14 @@ errcode_t ext2fs_allocate_group_table(ex
ext2fs_block_bitmap bmap)
{
errcode_t retval;
- blk_t group_blk, start_blk, last_blk, new_blk, blk;
+ blk_t group_blk, new_blk, blk;
+ blk64_t start_blk, last_blk;
int j;
group_blk = fs->super->s_first_data_block +
(group * fs->super->s_blocks_per_group);
- last_blk = group_blk + fs->super->s_blocks_per_group;
+ last_blk = (__u64) group_blk + fs->super->s_blocks_per_group - 1;
if (last_blk >= fs->super->s_blocks_count)
last_blk = fs->super->s_blocks_count - 1;
@@ -48,9 +49,9 @@ errcode_t ext2fs_allocate_group_table(ex
* Allocate the block and inode bitmaps, if necessary
*/
if (fs->stride) {
- start_blk = group_blk + fs->inode_blocks_per_group;
+ start_blk = (__u64) group_blk + fs->inode_blocks_per_group;
start_blk += ((fs->stride * group) %
- (last_blk - start_blk));
+ (last_blk - start_blk + 1));
if (start_blk > last_blk)
start_blk = group_blk;
} else
diff -upNr e2fsprogs-1.39/lib/ext2fs/check_desc.c e2fsprogs-1.39.tmp/lib/ext2fs/check_desc.c
--- e2fsprogs-1.39/lib/ext2fs/check_desc.c 2005-09-06 18:40:14.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/check_desc.c 2006-04-19 16:43:02.000000000 +0900
@@ -33,12 +33,12 @@ errcode_t ext2fs_check_desc(ext2_filsys
{
dgrp_t i;
blk_t block = fs->super->s_first_data_block;
- blk_t next;
+ blk64_t next;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
for (i = 0; i < fs->group_desc_count; i++) {
- next = block + fs->super->s_blocks_per_group;
+ next = (blk64_t) block + fs->super->s_blocks_per_group;
/*
* Check to make sure block bitmap for group is
* located within the group.
diff -upNr e2fsprogs-1.39/lib/ext2fs/ext2fs.h e2fsprogs-1.39.tmp/lib/ext2fs/ext2fs.h
--- e2fsprogs-1.39/lib/ext2fs/ext2fs.h 2006-03-19 08:58:00.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/ext2fs.h 2006-04-19 16:43:02.000000000 +0900
@@ -72,6 +72,7 @@ extern "C" {
typedef __u32 ext2_ino_t;
typedef __u32 blk_t;
+typedef __u64 blk64_t;
typedef __u32 dgrp_t;
typedef __u32 ext2_off_t;
typedef __s64 e2_blkcnt_t;
diff -upNr e2fsprogs-1.39/lib/ext2fs/initialize.c e2fsprogs-1.39.tmp/lib/ext2fs/initialize.c
--- e2fsprogs-1.39/lib/ext2fs/initialize.c 2006-03-19 08:59:47.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/initialize.c 2006-04-19 16:43:02.000000000 +0900
@@ -77,7 +77,7 @@ static unsigned int calc_reserved_gdt_bl
*/
if (sb->s_blocks_count < max_blocks / 1024)
max_blocks = sb->s_blocks_count * 1024;
- rsv_groups = (max_blocks - sb->s_first_data_block + bpg - 1) / bpg;
+ rsv_groups = ((__u64)max_blocks - sb->s_first_data_block + bpg - 1) / bpg;
rsv_gdb = (rsv_groups + gdpb - 1) / gdpb - fs->desc_blocks;
if (rsv_gdb > EXT2_ADDR_PER_BLOCK(sb))
rsv_gdb = EXT2_ADDR_PER_BLOCK(sb);
@@ -205,7 +205,7 @@ errcode_t ext2fs_initialize(const char *
}
retry:
- fs->group_desc_count = (super->s_blocks_count -
+ fs->group_desc_count = ((__u64) super->s_blocks_count -
super->s_first_data_block +
EXT2_BLOCKS_PER_GROUP(super) - 1)
/ EXT2_BLOCKS_PER_GROUP(super);
@@ -233,7 +233,7 @@ retry:
* should be. But make sure that we don't allocate more than
* one bitmap's worth of inodes each group.
*/
- ipg = (super->s_inodes_count + fs->group_desc_count - 1) /
+ ipg = ((__u64) super->s_inodes_count + fs->group_desc_count - 1) /
fs->group_desc_count;
if (ipg > fs->blocksize * 8) {
if (super->s_blocks_per_group >= 256) {
@@ -250,8 +250,9 @@ retry:
if (ipg > (unsigned) EXT2_MAX_INODES_PER_GROUP(super))
ipg = EXT2_MAX_INODES_PER_GROUP(super);
+ipg_try:
super->s_inodes_per_group = ipg;
- if (super->s_inodes_count > ipg * fs->group_desc_count)
+ if (super->s_inodes_count > (__u64) ipg * fs->group_desc_count)
super->s_inodes_count = ipg * fs->group_desc_count;
/*
@@ -277,6 +278,11 @@ retry:
EXT2_BLOCK_SIZE(super) - 1) /
EXT2_BLOCK_SIZE(super));
+ if ((__u64) super->s_inodes_per_group * fs->group_desc_count > ~0U) {
+ ipg--;
+ goto ipg_try;
+ }
+
/*
* adjust inode count to reflect the adjusted inodes_per_group
*/
diff -upNr e2fsprogs-1.39/lib/ext2fs/openfs.c e2fsprogs-1.39.tmp/lib/ext2fs/openfs.c
--- e2fsprogs-1.39/lib/ext2fs/openfs.c 2006-03-18 12:56:25.000000000 +0900
+++ e2fsprogs-1.39.tmp/lib/ext2fs/openfs.c 2006-04-19 16:43:02.000000000 +0900
@@ -258,7 +258,7 @@ errcode_t ext2fs_open2(const char *name,
retval = EXT2_ET_CORRUPT_SUPERBLOCK;
goto cleanup;
}
- fs->group_desc_count = (fs->super->s_blocks_count -
+ fs->group_desc_count = ((__u64) fs->super->s_blocks_count -
fs->super->s_first_data_block +
blocks_per_group - 1) / blocks_per_group;
fs->desc_blocks = (fs->group_desc_count +
diff -upNr e2fsprogs-1.39/misc/mke2fs.c e2fsprogs-1.39.tmp/misc/mke2fs.c
--- e2fsprogs-1.39/misc/mke2fs.c 2006-04-19 16:42:26.000000000 +0900
+++ e2fsprogs-1.39.tmp/misc/mke2fs.c 2006-04-19 16:43:02.000000000 +0900
@@ -780,11 +780,11 @@ static void parse_extended_opts(struct e
if (!bpg)
bpg = blocksize * 8;
gdpb = blocksize / sizeof(struct ext2_group_desc);
- group_desc_count = (param->s_blocks_count +
+ group_desc_count = ((__u64) param->s_blocks_count +
bpg - 1) / bpg;
desc_blocks = (group_desc_count +
gdpb - 1) / gdpb;
- rsv_groups = (resize + bpg - 1) / bpg;
+ rsv_groups = ((__u64) resize + bpg - 1) / bpg;
rsv_gdb = (rsv_groups + gdpb - 1) / gdpb -
desc_blocks;
if (rsv_gdb > (int) EXT2_ADDR_PER_BLOCK(param))
@@ -855,7 +855,7 @@ static void PRS(int argc, char *argv[])
double reserved_ratio = 5.0;
int sector_size = 0;
int show_version_only = 0;
- ext2_ino_t num_inodes = 0;
+ __u64 num_inodes = 0;
errcode_t retval;
char * oldpath = getenv("PATH");
char * extended_opts = 0;
@@ -1221,7 +1221,7 @@ static void PRS(int argc, char *argv[])
}
if (!fs_type) {
- int megs = fs_param.s_blocks_count *
+ int megs = (__u64) fs_param.s_blocks_count *
(EXT2_BLOCK_SIZE(&fs_param) / 1024) / 1024;
if (megs <= 3)
@@ -1390,6 +1390,22 @@ static void PRS(int argc, char *argv[])
fs_param.s_inode_size = inode_size;
}
+ /* inodes safty check */
+ if (num_inodes == 0) {
+ __u64 n;
+
+ n = (__u64) fs_param.s_blocks_count * blocksize / inode_ratio;
+ if (n > ~0U) {
+ com_err(program_name, 0,
+ _("inodes_count must be less than 4G!"));
+ exit(1);
+ }
+ } else if (num_inodes > ~0U) {
+ com_err(program_name, 0,
+ _("inodes_count must be less than 4G!"));
+ exit(1);
+ }
+
/*
* Calculate number of inodes based on the inode ratio
*/
@@ -1400,7 +1416,7 @@ static void PRS(int argc, char *argv[])
/*
* Calculate number of blocks to reserve
*/
- fs_param.s_r_blocks_count = (fs_param.s_blocks_count * reserved_ratio)
+ fs_param.s_r_blocks_count = ((__u64) fs_param.s_blocks_count * reserved_ratio)
/ 100;
}
diff -upNr e2fsprogs-1.39/resize/resize2fs.c e2fsprogs-1.39.tmp/resize/resize2fs.c
--- e2fsprogs-1.39/resize/resize2fs.c 2006-03-19 11:34:00.000000000 +0900
+++ e2fsprogs-1.39.tmp/resize/resize2fs.c 2006-04-19 16:44:26.000000000 +0900
@@ -181,7 +181,7 @@ errcode_t adjust_fs_info(ext2_filsys fs,
int overhead = 0;
int rem;
blk_t blk, group_block;
- ext2_ino_t real_end;
+ blk64_t real_end;
int adj, old_numblocks, numblocks, adjblocks;
unsigned long i, j, old_desc_blocks, max_group;
unsigned int meta_bg, meta_bg_size;
@@ -190,7 +190,7 @@ errcode_t adjust_fs_info(ext2_filsys fs,
fs->super->s_blocks_count = new_size;
retry:
- fs->group_desc_count = (fs->super->s_blocks_count -
+ fs->group_desc_count = ((__u64) fs->super->s_blocks_count -
fs->super->s_first_data_block +
EXT2_BLOCKS_PER_GROUP(fs->super) - 1)
/ EXT2_BLOCKS_PER_GROUP(fs->super);
@@ -225,6 +225,13 @@ retry:
fs->super->s_blocks_count -= rem;
goto retry;
}
+
+ if ((__u64) fs->super->s_inodes_per_group * fs->group_desc_count > ~0U)
+ {
+ fprintf(stderr, _("inodes_count must be less than 4G!\n"));
+ return EXT2_ET_TOO_MANY_INODES;
+ }
+
/*
* Adjust the number of inodes
*/
@@ -245,9 +252,9 @@ retry:
/*
* Adjust the number of reserved blocks
*/
- blk = old_fs->super->s_r_blocks_count * 100 /
+ blk = (__u64) old_fs->super->s_r_blocks_count * 100 /
old_fs->super->s_blocks_count;
- fs->super->s_r_blocks_count = ((fs->super->s_blocks_count * blk)
+ fs->super->s_r_blocks_count = (((__u64) fs->super->s_blocks_count * blk)
/ 100);
/*
@@ -259,7 +266,7 @@ retry:
if (retval) goto errout;
real_end = ((EXT2_BLOCKS_PER_GROUP(fs->super)
- * fs->group_desc_count)) - 1 +
+ * (__u64)fs->group_desc_count)) - 1 +
fs->super->s_first_data_block;
retval = ext2fs_resize_block_bitmap(fs->super->s_blocks_count-1,
real_end, fs->block_map);
^ permalink raw reply
* [UPDATE][13/21]e2fsprogs modify format strings
From: sho @ 2006-04-26 1:49 UTC (permalink / raw)
To: ext2-devel, linux-kernel
Summary of this patch:
[13/21] modify format strings in print
- change the format strings "%d" and "%ld" to "%u" and "%lu"
respectively.
Signed-off-by: Takashi Sato sho@tnes.nec.co.jp
---
diff -upNr e2fsprogs-1.39/debugfs/htree.c e2fsprogs-1.39.tmp/debugfs/htree.c
--- e2fsprogs-1.39/debugfs/htree.c 2006-04-12 11:21:58.000000000 +0900
+++ e2fsprogs-1.39.tmp/debugfs/htree.c 2006-04-12 11:38:34.000000000 +0900
@@ -114,7 +114,7 @@ static void htree_dump_int_node(ext2_fil
for (i=0; i < limit.count; i++) {
hash = i ? ext2fs_le32_to_cpu(ent[i].hash) : 0;
- fprintf(pager, "Entry #%d: Hash 0x%08x%s, block %d\n", i,
+ fprintf(pager, "Entry #%d: Hash 0x%08x%s, block %u\n", i,
hash, (hash & 1) ? " (**)" : "",
ext2fs_le32_to_cpu(ent[i].block));
}
diff -upNr e2fsprogs-1.39/e2fsck/unix.c e2fsprogs-1.39.tmp/e2fsck/unix.c
--- e2fsprogs-1.39/e2fsck/unix.c 2006-04-12 11:21:58.000000000 +0900
+++ e2fsprogs-1.39.tmp/e2fsck/unix.c 2006-04-12 11:46:23.000000000 +0900
@@ -118,49 +118,49 @@ static void show_stats(e2fsck_t ctx)
frag_percent = (frag_percent + 5) / 10;
if (!verbose) {
- printf(_("%s: %d/%d files (%0d.%d%% non-contiguous), %u/%u blocks\n"),
+ printf(_("%s: %u/%u files (%0d.%d%% non-contiguous), %u/%u blocks\n"),
ctx->device_name, inodes_used, inodes,
frag_percent / 10, frag_percent % 10,
blocks_used, blocks);
return;
}
- printf (P_("\n%8d inode used (%d%%)\n", "\n%8d inodes used (%d%%)\n",
- inodes_used), inodes_used, 100 * inodes_used / inodes);
+ printf (P_("\n%8d inode used (%u%%)\n", "\n%8d inodes used (%u%%)\n",
+ inodes_used), inodes_used, 100 * (__u64)inodes_used / inodes);
printf (P_("%8d non-contiguous inode (%0d.%d%%)\n",
"%8d non-contiguous inodes (%0d.%d%%)\n",
ctx->fs_fragmented),
ctx->fs_fragmented, frag_percent / 10, frag_percent % 10);
- printf (_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
+ printf (_(" # of inodes with ind/dind/tind blocks: %u/%u/%u\n"),
ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
printf (P_("%8u block used (%d%%)\n", "%8u blocks used (%d%%)\n",
blocks_used),
blocks_used, (int) ((long long) 100 * blocks_used / blocks));
printf (P_("%8d bad block\n", "%8d bad blocks\n",
ctx->fs_badblocks_count), ctx->fs_badblocks_count);
- printf (P_("%8d large file\n", "%8d large files\n",
+ printf (P_("%8u large file\n", "%8u large files\n",
ctx->large_files), ctx->large_files);
- printf (P_("\n%8d regular file\n", "\n%8d regular files\n",
+ printf (P_("\n%8u regular file\n", "\n%8u regular files\n",
ctx->fs_regular_count), ctx->fs_regular_count);
- printf (P_("%8d directory\n", "%8d directories\n",
+ printf (P_("%8u directory\n", "%8u directories\n",
ctx->fs_directory_count), ctx->fs_directory_count);
- printf (P_("%8d character device file\n",
- "%8d character device files\n", ctx->fs_chardev_count),
+ printf (P_("%8u character device file\n",
+ "%8u character device files\n", ctx->fs_chardev_count),
ctx->fs_chardev_count);
- printf (P_("%8d block device file\n", "%8d block device files\n",
+ printf (P_("%8u block device file\n", "%8u block device files\n",
ctx->fs_blockdev_count), ctx->fs_blockdev_count);
- printf (P_("%8d fifo\n", "%8d fifos\n", ctx->fs_fifo_count),
+ printf (P_("%8u fifo\n", "%8u fifos\n", ctx->fs_fifo_count),
ctx->fs_fifo_count);
- printf (P_("%8d link\n", "%8d links\n",
+ printf (P_("%8u link\n", "%8u links\n",
ctx->fs_links_count - dir_links),
ctx->fs_links_count - dir_links);
- printf (P_("%8d symbolic link", "%8d symbolic links",
+ printf (P_("%8u symbolic link", "%8u symbolic links",
ctx->fs_symlinks_count), ctx->fs_symlinks_count);
- printf (P_(" (%d fast symbolic link)\n", " (%d fast symbolic links)\n",
+ printf (P_(" (%u fast symbolic link)\n", " (%u fast symbolic links)\n",
ctx->fs_fast_symlinks_count), ctx->fs_fast_symlinks_count);
- printf (P_("%8d socket\n", "%8d sockets\n", ctx->fs_sockets_count),
+ printf (P_("%8u socket\n", "%8u sockets\n", ctx->fs_sockets_count),
ctx->fs_sockets_count);
printf ("--------\n");
- printf (P_("%8d file\n", "%8d files\n",
+ printf (P_("%8u file\n", "%8u files\n",
ctx->fs_total_count - dir_links),
ctx->fs_total_count - dir_links);
}
@@ -300,7 +300,7 @@ static void check_if_skip(e2fsck_t ctx)
fputs(_(", check forced.\n"), stdout);
return;
}
- printf(_("%s: clean, %d/%d files, %u/%u blocks"), ctx->device_name,
+ printf(_("%s: clean, %u/%u files, %u/%u blocks"), ctx->device_name,
fs->super->s_inodes_count - fs->super->s_free_inodes_count,
fs->super->s_inodes_count,
fs->super->s_blocks_count - fs->super->s_free_blocks_count,
diff -upNr e2fsprogs-1.39/misc/mke2fs.c e2fsprogs-1.39.tmp/misc/mke2fs.c
--- e2fsprogs-1.39/misc/mke2fs.c 2006-04-12 11:21:58.000000000 +0900
+++ e2fsprogs-1.39.tmp/misc/mke2fs.c 2006-04-12 11:49:33.000000000 +0900
@@ -644,8 +644,8 @@ static void show_stats(ext2_filsys fs)
100.0 * s->s_r_blocks_count / s->s_blocks_count);
printf(_("First data block=%u\n"), s->s_first_data_block);
if (s->s_reserved_gdt_blocks)
- printf(_("Maximum filesystem blocks=%lu\n"),
- (s->s_reserved_gdt_blocks + fs->desc_blocks) *
+ printf(_("Maximum filesystem blocks=%llu\n"),
+ ((__u64)s->s_reserved_gdt_blocks + fs->desc_blocks) *
(fs->blocksize / sizeof(struct ext2_group_desc)) *
s->s_blocks_per_group);
if (fs->group_desc_count > 1)
^ permalink raw reply
* [UPDATE][0/21]extend file size and filesystem size
From: sho @ 2006-04-26 1:48 UTC (permalink / raw)
To: ext2-devel, linux-kernel
Hi all,
On Thu, 13 Apr 2006 12:20:28 -0400, Theodore Ts'o wrote:
> Generalized NACK. We can't just blindly change function signatures
> of pre-existing functions in libext2fs, since this breaks the ABI
> with pre-existing applications linked with current shared libraries
> of libext2fs.
I see.
Since I updated the following 4 patches, please replace old patches
with new ones.
These patches are against e2fsprogs-1.39-WIP-2006-04-09.
[13/21] modify format strings in print
- change the format strings "%d" and "%ld" to "%u" and "%lu"
respectively.
[14/21] change the type of variables for a block or an inode
- Change the type of 4byte variables manipulating a block or
an inode from signed to unsigned.
- Cast the type of operation in which an overflow occurs to
long long.
[15/21] add new functions which manipulate bitmap with 64-bit blk64_t
- add new functions, which use 64-bit blk64_t and manipulate
bitmap, leaving existing functions as they are.
[16/21] enlarge file size and filesystem size
- Add new option "-O large_block" in mke2fs.
- With this option, the maximum size of a file is (blocksize)
* (2^32-1) bytes, and of a filesystem is (pagesize) *
(2^32-1).
Any feedback and comments are welcome.
Cheers, sho
^ permalink raw reply
* [PATCH 3/3] Rough VJ Channel Implementation - vj_udp.patch
From: Kelly Daly @ 2006-04-26 11:47 UTC (permalink / raw)
To: netdev; +Cc: rusty, davem
Signed-off-by: Kelly Daly <kelly@au.ibm.com>
Hacked udp.c to receive directly to VJ Channel socket.
Breaks normal UDP - sockets don't speak non-VJ anymore!
----
diff -r 47031a1f466c linux-2.6.16/include/linux/udp.h
--- linux-2.6.16/include/linux/udp.h Thu Mar 23 06:32:12 2006
+++ linux-2.6.16/include/linux/udp.h Mon Apr 24 19:50:46 2006
@@ -51,6 +51,8 @@
* when the socket is uncorked.
*/
__u16 len; /* total length of pending frames */
+ struct vj_channel *chan; /* VJ net channel */
+ int vj_reg_flag; /* is the vj channel registered */
};
static inline struct udp_sock *udp_sk(const struct sock *sk)
diff -r 47031a1f466c linux-2.6.16/net/ipv4/udp.c
--- linux-2.6.16/net/ipv4/udp.c Thu Mar 23 06:32:12 2006
+++ linux-2.6.16/net/ipv4/udp.c Mon Apr 24 19:50:46 2006
@@ -1,3 +1,4 @@
+
/*
* INET An implementation of the TCP/IP protocol suite for the LINUX
* operating system. INET is implemented using the BSD Socket
@@ -89,6 +90,7 @@
#include <linux/igmp.h>
#include <linux/in.h>
#include <linux/errno.h>
+#include <linux/err.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/config.h>
@@ -109,6 +111,7 @@
#include <net/inet_common.h>
#include <net/checksum.h>
#include <net/xfrm.h>
+#include <linux/vjchan.h>
/*
* Snmp MIB for the UDP layer
@@ -127,6 +130,7 @@
struct hlist_node *node;
struct sock *sk2;
struct inet_sock *inet = inet_sk(sk);
+ struct vj_flowid flowid;
write_lock_bh(&udp_hash_lock);
if (snum == 0) {
@@ -195,6 +199,17 @@
sk_add_node(sk, h);
sock_prot_inc_use(sk->sk_prot);
}
+
+ /* copied from udp_v4_lookup_longway */
+ flowid.saddr = inet->daddr;
+ flowid.daddr = inet->rcv_saddr;
+ flowid.sport = inet->dport;
+ flowid.dport = htons(inet->num);
+ flowid.ifindex = sk->sk_bound_dev_if;
+ flowid.proto = IPPROTO_UDP;
+ vj_register_chan(udp_sk(sk)->chan, &flowid);
+ udp_sk(sk)->vj_reg_flag = 1;
+
write_unlock_bh(&udp_hash_lock);
return 0;
@@ -771,18 +786,158 @@
__udp_checksum_complete(skb);
}
+static inline unsigned short int vj_udp_csum(struct vj_buffer *buffer)
+{
+ struct iphdr *ip = (struct iphdr *)(buffer->data + buffer->header_len);
+ int udpoff = buffer->header_len + (ip->ihl * 4);
+ struct udphdr *up = (struct udphdr *)(buffer->data + udpoff);
+
+ if (up->check == 0)
+ return 0;
+
+ return csum_tcpudp_magic(ip->saddr,
+ ip->daddr,
+ (buffer->data_len - (ip->ihl * 4)),
+ IPPROTO_UDP,
+ csum_partial((buffer->data + udpoff),
+ (buffer->data_len - (ip->ihl * 4)),
+ 0));
+}
+
+/*
+ * Is a socket 'connection oriented' ?
+ */
+static inline int connection_based(struct sock *sk)
+{
+ return sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM;
+}
+
+/* returns 1 if if we need to keep waiting, <= 0 indicates stop waiting */
+static int wait_for_vj_buffer(struct sock *sk, long *timeo_p)
+{
+ int error;
+ wait_queue_head_t *wq = &udp_sk(sk)->chan->wq;
+ DEFINE_WAIT(wait);
+
+ prepare_to_wait(wq, &wait, TASK_INTERRUPTIBLE);
+ vj_inc_wakecnt(udp_sk(sk)->chan);
+
+ error = sock_error(sk);
+ if (error)
+ goto out;
+ if (vj_peek_next_buffer(udp_sk(sk)->chan)) {
+ error = 1;
+ goto out;
+ }
+ if (sk->sk_shutdown & RCV_SHUTDOWN) {
+ error = 0;
+ goto out;
+ }
+ if (connection_based(sk) && !(sk->sk_state == TCP_ESTABLISHED ||
+ sk->sk_state == TCP_LISTEN)) {
+ error = -ENOTCONN;
+ goto out;
+ }
+ if (signal_pending(current)) {
+ error = sock_intr_errno(*timeo_p);
+ goto out;
+ }
+
+ error = 1;
+
+ *timeo_p = schedule_timeout(*timeo_p);
+out:
+ finish_wait(wq, &wait);
+ return error;
+}
+
+/* almost a direct copy of skb_recv_datagram to get all req'd information while using a vj buffer instead of skb */
+struct vj_buffer *vj_recv_datagram(struct sock *sk, unsigned flags,
+ int noblock, int *err)
+{
+ struct vj_buffer *buffer;
+ long timeo;
+ *err = sock_error(sk);
+
+ if (*err)
+ return NULL;
+
+ timeo = sock_rcvtimeo(sk, noblock);
+ do {
+//we can just grab the buffer and return it seeing as either way will be a "peek". Then after we consume we can figure out if (flags & MSG_PEEK) and move to the next buffer at that time... we need to consume the buffer, write barrier before we move on to avoid a race condition.
+
+ buffer = vj_peek_next_buffer(udp_sk(sk)->chan);
+ if (buffer)
+ return buffer;
+
+ /* User doesn't want to wait */
+ *err = -EAGAIN;
+ if (!timeo) {
+ return NULL;
+ }
+ } while ((*err = wait_for_vj_buffer(sk, &timeo)) > 0);
+
+ return NULL;
+}
+
+static int vj_copy_datagram_iovec(struct vj_buffer *buffer, int offset,
+ struct iovec *to, int len)
+{
+// offset to be taken from buffer->header_len (which contains eth hdr + ip hdr)
+ if(memcpy_toiovec(to, buffer->data + offset, len))
+ return -EFAULT;
+ return 0;
+}
+
+/* FIXME: original code did timestamp in netif_rx */
+static __inline__ void vj_sock_recv_timestamp(struct msghdr *msg,
+ struct sock *sk)
+{
+ do_gettimeofday(&sk->sk_stamp);
+ put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP, sizeof(struct timeval), &sk->sk_stamp);
+}
+
+/* Returns offset in buffer past ip hdr, or 0 if something wrong. */
+static unsigned check_ip_packet(struct vj_buffer *buffer)
+{
+ struct iphdr *iph;
+
+ iph = (struct iphdr *)(buffer->data + buffer->header_len);
+
+ if (buffer->data_len < sizeof(*iph))
+ return 0;
+
+ if (iph->ihl < 5 || iph->version != 4)
+ return 0;
+
+ if (iph->ihl * 4 > ntohs(iph->tot_len)) //less than 0 data?
+ return 0;
+
+ if (ntohs(iph->tot_len) > buffer->data_len) { //truncated
+ return 0;
+ } else if (ntohs(iph->tot_len) < buffer->data_len) { //padded - trim it
+ buffer->data_len = ntohs(iph->tot_len);
+ }
+
+ if (ip_fast_csum((u8 *)iph, iph->ihl) != 0)
+ return 0;
+
+ return buffer->header_len + iph->ihl*4;
+}
+
/*
* This should be easy, if there is something there we
* return it, otherwise we block.
*/
-
static int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
size_t len, int noblock, int flags, int *addr_len)
{
struct inet_sock *inet = inet_sk(sk);
struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
- struct sk_buff *skb;
- int copied, err;
+ struct vj_buffer *buffer;
+ struct iphdr *ip;
+ struct udphdr *udph;
+ int copied, err, udpoff;
/*
* Check any passed addresses
@@ -794,63 +949,71 @@
return ip_recv_error(sk, msg, len);
try_again:
- skb = skb_recv_datagram(sk, flags, noblock, &err);
- if (!skb)
+ buffer = vj_recv_datagram(sk, flags, noblock, &err);
+ if (!buffer)
goto out;
-
- copied = skb->len - sizeof(struct udphdr);
+
+ ip = (struct iphdr *)(buffer->data + buffer->header_len);
+ udpoff = check_ip_packet(buffer);
+ if (udpoff == 0)
+ goto bad_packet;
+
+ udph = (struct udphdr *)(buffer->data + udpoff);
+
+ buffer->data_len = ntohs(ip->tot_len);
+
+ if (((ip->ihl * 4) + ntohs(udph->len)) > buffer->data_len)
+ goto bad_packet;
+ buffer->data_len = (ip->ihl * 4) + ntohs(udph->len);
+
+ copied = buffer->data_len - ((ip->ihl * 4) + sizeof(struct udphdr));
+
if (copied > len) {
copied = len;
msg->msg_flags |= MSG_TRUNC;
}
- if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
- err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
- copied);
- } else if (msg->msg_flags&MSG_TRUNC) {
- if (__udp_checksum_complete(skb))
- goto csum_copy_err;
- err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov,
- copied);
- } else {
- err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
-
- if (err == -EINVAL)
- goto csum_copy_err;
- }
-
- if (err)
- goto out_free;
-
- sock_recv_timestamp(msg, sk, skb);
+/* FIXME: if card is calculating csum, should be using that rather
+ * than calculating here */
+ if (vj_udp_csum(buffer) != 0) //bad checksum
+ goto bad_packet;
+
+ err = vj_copy_datagram_iovec(buffer, udpoff + sizeof(struct udphdr), msg->msg_iov, copied);
+
+ if (err) {
+ vj_done_with_buffer(udp_sk(sk)->chan);
+ return err;
+ }
+
+ vj_sock_recv_timestamp(msg, sk);
/* Copy the address. */
if (sin)
{
sin->sin_family = AF_INET;
- sin->sin_port = skb->h.uh->source;
- sin->sin_addr.s_addr = skb->nh.iph->saddr;
+ sin->sin_port = udph->source;
+ sin->sin_addr.s_addr = ip->saddr;
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
}
+
+#if 0 /* FIXME: implement this! */
if (inet->cmsg_flags)
ip_cmsg_recv(msg, skb);
+#endif
err = copied;
if (flags & MSG_TRUNC)
- err = skb->len - sizeof(struct udphdr);
+ err = buffer->data_len - (ip->ihl * 4) - sizeof(struct udphdr);
+ if (!(flags & MSG_PEEK))
+ vj_done_with_buffer(udp_sk(sk)->chan);
-out_free:
- skb_free_datagram(sk, skb);
out:
return err;
-csum_copy_err:
- UDP_INC_STATS_BH(UDP_MIB_INERRORS);
-
- skb_kill_datagram(sk, skb, flags);
-
- if (noblock)
- return -EAGAIN;
+bad_packet:
+ vj_done_with_buffer(udp_sk(sk)->chan);
+ if(noblock)
+ return -EAGAIN;
goto try_again;
}
@@ -858,10 +1021,15 @@
int udp_disconnect(struct sock *sk, int flags)
{
struct inet_sock *inet = inet_sk(sk);
+ struct udp_sock *up = udp_sk(sk);
/*
* 1003.1g - break association.
*/
-
+ if (up->vj_reg_flag) {
+ vj_unregister_chan(up->chan);
+ up->vj_reg_flag = 0;
+ }
+
sk->sk_state = TCP_CLOSE;
inet->daddr = 0;
inet->dport = 0;
@@ -879,6 +1047,14 @@
static void udp_close(struct sock *sk, long timeout)
{
+ struct udp_sock *up = udp_sk(sk);
+
+ if (up->vj_reg_flag) {
+ vj_unregister_chan(up->chan);
+ up->vj_reg_flag = 0;
+ }
+ vj_free_chan(up->chan);
+
sk_common_release(sk);
}
@@ -1293,6 +1469,46 @@
return 0;
}
+unsigned int vj_datagram_poll(struct file *file, struct socket *sock, poll_table *wait)
+{
+ struct sock *sk = sock->sk;
+ unsigned int mask;
+
+ poll_wait(file, &udp_sk(sk)->chan->wq, wait);
+ vj_inc_wakecnt(udp_sk(sk)->chan);
+
+ mask = 0;
+
+ /* exceptional events? */
+ if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
+ mask |= POLLERR;
+ if (sk->sk_shutdown == SHUTDOWN_MASK)
+ mask |= POLLHUP;
+
+
+ /* readable? */
+ if (vj_peek_next_buffer(udp_sk(sk)->chan) ||
+ (sk->sk_shutdown & RCV_SHUTDOWN))
+ mask |= POLLIN | POLLRDNORM;
+
+ /* Connection-based need to check for termination and startup */
+ if (connection_based(sk)) {
+ if (sk->sk_state == TCP_CLOSE)
+ mask |= POLLHUP;
+ /* connection hasn't started yet? */
+ if (sk->sk_state == TCP_SYN_SENT)
+ return mask;
+ }
+
+ /* writable? */
+ if (sock_writeable(sk))
+ mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
+ else
+ set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
+
+ return mask;
+}
+
/**
* udp_poll - wait for a UDP event.
* @file - file struct
@@ -1308,41 +1524,47 @@
*/
unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
{
- unsigned int mask = datagram_poll(file, sock, wait);
+ unsigned int mask = vj_datagram_poll(file, sock, wait);
struct sock *sk = sock->sk;
/* Check for false positives due to checksum errors */
if ( (mask & POLLRDNORM) &&
!(file->f_flags & O_NONBLOCK) &&
!(sk->sk_shutdown & RCV_SHUTDOWN)){
- struct sk_buff_head *rcvq = &sk->sk_receive_queue;
- struct sk_buff *skb;
-
- spin_lock_bh(&rcvq->lock);
- while ((skb = skb_peek(rcvq)) != NULL) {
- if (udp_checksum_complete(skb)) {
- UDP_INC_STATS_BH(UDP_MIB_INERRORS);
- __skb_unlink(skb, rcvq);
- kfree_skb(skb);
- } else {
- skb->ip_summed = CHECKSUM_UNNECESSARY;
+ struct vj_buffer *buffer;
+
+ while ((buffer = vj_peek_next_buffer(udp_sk(sk)->chan)) != NULL) {
+//test that this fixes the csum
+ check_ip_packet(buffer);
+ if (vj_udp_csum(buffer) == 0)
break;
- }
- }
- spin_unlock_bh(&rcvq->lock);
+ UDP_INC_STATS_BH(UDP_MIB_INERRORS);
+ vj_done_with_buffer(udp_sk(sk)->chan);
+ }
/* nothing to see, move along */
- if (skb == NULL)
+ if (buffer == NULL)
mask &= ~(POLLIN | POLLRDNORM);
}
return mask;
}
+
+static int udp_init(struct sock *sk)
+{
+ udp_sk(sk)->chan = vj_alloc_chan(0);
+ udp_sk(sk)->vj_reg_flag = 0;
+ if (!udp_sk(sk)->chan)
+ return -ENOMEM;
+ return 0;
+}
+
struct proto udp_prot = {
.name = "UDP",
.owner = THIS_MODULE,
+ .init = udp_init,
.close = udp_close,
.connect = ip4_datagram_connect,
.disconnect = udp_disconnect,
^ permalink raw reply
* [PATCH 2/3] Rough VJ Channel Implementation - vj_ne2k.patch
From: Kelly Daly @ 2006-04-26 11:47 UTC (permalink / raw)
To: netdev; +Cc: rusty, davem
Today 11:25:13
Signed-off-by: Kelly Daly <kelly@au.ibm.com>
Hacked NE2K driver using VJ Channels on receive.
Takes packet data and dumps it into a VJ buffer instead of skb.
Not implemented on transmit.
Useful for testing under QEMU.
-----
diff -r 47031a1f466c linux-2.6.16/drivers/net/8390.c
--- linux-2.6.16/drivers/net/8390.c Thu Mar 23 06:32:12 2006
+++ linux-2.6.16/drivers/net/8390.c Mon Apr 24 19:50:46 2006
@@ -74,6 +74,8 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+
+#include <linux/vjchan.h>
#define NS8390_CORE
#include "8390.h"
@@ -718,31 +720,30 @@
}
else if ((pkt_stat & 0x0F) == ENRSR_RXOK)
{
- struct sk_buff *skb;
-
- skb = dev_alloc_skb(pkt_len+2);
- if (skb == NULL)
- {
+
+//NOT make skb - make a buffer!
+ struct vj_buffer *vjbuffer;
+ int desc_num;
+
+ vjbuffer = vj_get_buffer(&desc_num);
+ if (vjbuffer == NULL) {
+//fail
if (ei_debug > 1)
- printk(KERN_DEBUG "%s: Couldn't allocate a sk_buff of size %d.\n",
- dev->name, pkt_len);
+ printk(KERN_DEBUG "%s: Couldn't allocate a vj buffer.\n",
+ dev->name);
ei_local->stat.rx_dropped++;
break;
}
- else
- {
- skb_reserve(skb,2); /* IP headers on 16 byte boundaries */
- skb->dev = dev;
- skb_put(skb, pkt_len); /* Make room */
- ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame));
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- dev->last_rx = jiffies;
- ei_local->stat.rx_packets++;
- ei_local->stat.rx_bytes += pkt_len;
- if (pkt_stat & ENRSR_PHY)
- ei_local->stat.multicast++;
- }
+ vjbuffer->data_len = pkt_len;
+ vjbuffer->ifindex = dev->ifindex;
+ ei_block_input(dev, pkt_len, vjbuffer->data, current_offset + sizeof(rx_frame));
+ vj_netif_rx(vjbuffer, desc_num, eth_vj_type_trans(vjbuffer));
+ dev->last_rx = jiffies;
+ ei_local->stat.rx_packets++;
+ ei_local->stat.rx_bytes += pkt_len;
+ if (pkt_stat & ENRSR_PHY)
+ ei_local->stat.multicast++;
+
}
else
{
diff -r 47031a1f466c linux-2.6.16/drivers/net/8390.h
--- linux-2.6.16/drivers/net/8390.h Thu Mar 23 06:32:12 2006
+++ linux-2.6.16/drivers/net/8390.h Mon Apr 24 19:50:46 2006
@@ -10,7 +10,6 @@
#include <linux/config.h>
#include <linux/if_ether.h>
#include <linux/ioport.h>
-#include <linux/skbuff.h>
#define TX_PAGES 12 /* Two Tx slots */
@@ -49,7 +48,7 @@
void (*reset_8390)(struct net_device *);
void (*get_8390_hdr)(struct net_device *, struct e8390_pkt_hdr *, int);
void (*block_output)(struct net_device *, int, const unsigned char *, int);
- void (*block_input)(struct net_device *, int, struct sk_buff *, int);
+ void (*block_input)(struct net_device *, int, char *, int);
unsigned long rmem_start;
unsigned long rmem_end;
void __iomem *mem;
diff -r 47031a1f466c linux-2.6.16/drivers/net/ne2k-pci.c
--- linux-2.6.16/drivers/net/ne2k-pci.c Thu Mar 23 06:32:12 2006
+++ linux-2.6.16/drivers/net/ne2k-pci.c Mon Apr 24 19:50:46 2006
@@ -172,7 +172,7 @@
static void ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
int ring_page);
static void ne2k_pci_block_input(struct net_device *dev, int count,
- struct sk_buff *skb, int ring_offset);
+ char *data, int ring_offset);
static void ne2k_pci_block_output(struct net_device *dev, const int count,
const unsigned char *buf, const int start_page);
static struct ethtool_ops ne2k_pci_ethtool_ops;
@@ -503,10 +503,9 @@
the packet out through the "remote DMA" dataport using outb. */
static void ne2k_pci_block_input(struct net_device *dev, int count,
- struct sk_buff *skb, int ring_offset)
+ char *buf, int ring_offset)
{
long nic_base = dev->base_addr;
- char *buf = skb->data;
/* This *shouldn't* happen. If it does, it's the last thing you'll see */
if (ei_status.dmaing) {
^ permalink raw reply
* [PATCH 1/3] Rough VJ Channel Implementation - vj_core.patch
From: Kelly Daly @ 2006-04-26 11:47 UTC (permalink / raw)
To: netdev; +Cc: rusty, davem
Hey guys... I've been working with Rusty on a VJ Channel implementation.
Noting Dave's recent release of his implementation, we thought we'd better
get this "out there" so we can do some early comparison/combining and
come up with the best possible implementation.
There are three patches in total:
1) vj_core.patch - core files for VJ to userspace
2) vj_udp.patch - badly hacked up UDP receive implementation - basically just to test what logic may be like!
3) vj_ne2k.patch - modified NE2K and 8390 used for testing on QEMU
Notes:
* channels can have global or local buffers (local for userspace. Could be used directly by intelligent NIC)
* UDP receive breaks real UDP - doesn't talk anything except VJ Channels anymore. Needs integration with normal sources.
* Userspace test app (below) uses VJ protocol family to mmap space for local buffers, if it receives buffers in kernel space sends a request for that buffer to be copied to local buffer.
* Default channel converts to skb and feeds through normal receive path.
TODO:
* send not yet implemented
* integrate non vj
* LOTS of fixmes
Cheers,
Kelly
Test userspace app:
/* Van Jacobson net channels implementation for Linux
Copyright (C) 2006 Kelly Daly <kdaly@au.ibm.com> IBM Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include <sys/poll.h>
#include <netinet/in.h>
#include "linux-2.6.16/include/linux/types.h"
#include "linux-2.6.16/include/linux/vjchan.h"
//flowid
#define SADDR 0
#define DADDR 0
#define SPORT 0
#define DPORT 60000
#define IFINDEX 0
#define PF_VJCHAN 27
static struct vj_buffer *get_buffer(struct vj_channel_ring *ring, int desc_num)
{
printf("desc_num %i\n", desc_num);
return (void *)ring + (desc_num + 1) * getpagesize();
}
/* return the next buffer, but do not move on */
static struct vj_buffer *vj_peek_next_buffer(struct vj_channel_ring *ring)
{
if (ring->c.head == ring->p.tail)
return NULL;
return get_buffer(ring, ring->q[ring->c.head]);
}
/* move on to next buffer */
static void vj_done_with_buffer(struct vj_channel_ring *ring)
{
ring->c.head = (ring->c.head+1)%VJ_NET_CHANNEL_ENTRIES;
printf("done_with_buffer\n\n");
}
int main(int argc, char *argv[])
{
int sk, cls, bnd, pll;
void * mmapped;
struct vj_flowid flowid;
struct vj_channel_ring *ring;
struct vj_buffer *buf;
struct pollfd pfd;
printf("\nstart of vjchannel socket test app\n");
sk = socket(PF_VJCHAN, SOCK_DGRAM, IPPROTO_UDP);
if (sk == -1) {
perror("Unable to open socket!");
return -1;
}
printf("socket open with ret code %i\n\n", sk);
//create flowid!!!
flowid.saddr = SADDR;
flowid.daddr = DADDR;
flowid.sport = SPORT;
flowid.dport = htons(DPORT);
flowid.ifindex = IFINDEX;
flowid.proto = IPPROTO_UDP;
printf("flowid created\n");
bnd = bind(sk, (struct sockaddr *)&flowid, sizeof(struct vj_flowid));
if (bnd == -1) {
perror("Unable to bind socket!");
return -1;
}
printf("socket bound with ret code %i\n\n", bnd);
ring = mmap(0, (getpagesize() * (VJ_NET_CHANNEL_ENTRIES+1)), PROT_READ|PROT_WRITE, MAP_SHARED, sk, 0);
if (ring == MAP_FAILED) {
perror ("Unable to mmap socket!");
return -1;
}
printf("socket mmapped to address %lu\n\n", (unsigned long)mmapped);
pfd.fd = sk;
pfd.events = POLLIN;
for (;;) {
pll = poll(&pfd, 1, -1);
if (pll < 0) {
perror("polling failed!");
return -1;
}
//consume
buf = vj_peek_next_buffer(ring);
printf("buf %p\n", buf);
//print data, not headers
printf(" Buffer Length = %i\n", buf->data_len);
printf(" Header Length = %i\n", buf->header_len);
printf(" Buffer Data: '%.*s'\n", buf->data_len - 28, buf->data + buf->header_len + 28);
vj_done_with_buffer(ring);
}
cls = close(sk);
if (cls != 0) {
perror("Unable to close socket!");
return -2;
}
printf("socket closed with ret code %i\n\n", cls);
return 0;
}
-------------------------
Signed-off-by: Kelly Daly <kelly@au.ibm.com>
Basic infrastructure for Van Jacobson net channels: lockless ringbuffer for buffer transport. Entries in ring buffer are descriptors for global or local buffers: ring and local buffers are mmapped into userspace.
Channels are registered with the core by flowid, and a thread services the default channel for any non-matching packets. Drivers get (global) buffers from vj_get_buffer, and dispatch them through vj_netif_rx.
As userspace mmap cannot reach global buffers, select() copies global buffers into local buffers if required.
diff -r 47031a1f466c linux-2.6.16/include/linux/socket.h
--- linux-2.6.16/include/linux/socket.h Thu Mar 23 06:32:12 2006
+++ linux-2.6.16/include/linux/socket.h Mon Apr 24 19:50:46 2006
@@ -186,6 +187,7 @@
#define AF_PPPOX 24 /* PPPoX sockets */
#define AF_WANPIPE 25 /* Wanpipe API Sockets */
#define AF_LLC 26 /* Linux LLC */
+#define AF_VJCHAN 27 /* VJ Channel */
#define AF_TIPC 30 /* TIPC sockets */
#define AF_BLUETOOTH 31 /* Bluetooth sockets */
#define AF_MAX 32 /* For now.. */
@@ -219,7 +221,8 @@
#define PF_PPPOX AF_PPPOX
#define PF_WANPIPE AF_WANPIPE
#define PF_LLC AF_LLC
+#define PF_VJCHAN AF_VJCHAN
#define PF_TIPC AF_TIPC
#define PF_BLUETOOTH AF_BLUETOOTH
#define PF_MAX AF_MAX
diff -r 47031a1f466c linux-2.6.16/net/Kconfig
--- linux-2.6.16/net/Kconfig Thu Mar 23 06:32:12 2006
+++ linux-2.6.16/net/Kconfig Mon Apr 24 19:50:46 2006
@@ -65,6 +65,12 @@
source "net/ipv6/Kconfig"
endif # if INET
+
+config VJCHAN
+ bool "Van Jacobson Net Channel Support (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ ---help---
+ This adds a userspace-accessible packet receive interface. Say N.
menuconfig NETFILTER
bool "Network packet filtering (replaces ipchains)"
diff -r 47031a1f466c linux-2.6.16/net/Makefile
--- linux-2.6.16/net/Makefile Thu Mar 23 06:32:12 2006
+++ linux-2.6.16/net/Makefile Mon Apr 24 19:50:46 2006
@@ -46,6 +46,7 @@
obj-$(CONFIG_IP_SCTP) += sctp/
obj-$(CONFIG_IEEE80211) += ieee80211/
obj-$(CONFIG_TIPC) += tipc/
+obj-$(CONFIG_VJCHAN) += vjchan/
ifeq ($(CONFIG_NET),y)
obj-$(CONFIG_SYSCTL) += sysctl_net.o
diff -r 47031a1f466c linux-2.6.16/include/linux/vjchan.h
--- /dev/null Thu Mar 23 06:32:12 2006
+++ linux-2.6.16/include/linux/vjchan.h Mon Apr 24 19:50:46 2006
@@ -0,0 +1,79 @@
+#ifndef _LINUX_VJCHAN_H
+#define _LINUX_VJCHAN_H
+
+/* num entries in channel q: set so consumer is at offset 1024. */
+#define VJ_NET_CHANNEL_ENTRIES 254
+/* identifies non-local buffers (ie. need kernel to copy to a local) */
+#define VJ_HIGH_BIT 0x80000000
+
+struct vj_producer {
+ __u16 tail; /* next element to add */
+ __u8 wakecnt; /* do wakeup if != consumer wakecnt */
+ __u8 pad;
+ __u16 old_head; /* last cleared buffer posn +1 */
+ __u16 pad2;
+};
+
+struct vj_consumer {
+ __u16 head; /* next element to remove */
+ __u8 wakecnt; /* increment to request wakeup */
+};
+
+/* mmap returns one of these, followed by 254 pages with a buffer each */
+struct vj_channel_ring {
+ struct vj_producer p; /* producer's header */
+ __u32 q[VJ_NET_CHANNEL_ENTRIES];
+ struct vj_consumer c; /* consumer's header */
+};
+
+struct vj_buffer {
+ __u32 data_len; /* length of actual data in buffer */
+ __u32 header_len; /* offset eth + ip header (true for now) */
+ __u32 ifindex; /* interface the packet came in on. */
+ char data[0];
+};
+
+/* Currently assumed IPv4 */
+struct vj_flowid
+{
+ __u32 saddr, daddr;
+ __u16 sport, dport;
+ __u32 ifindex;
+ __u16 proto;
+};
+
+#ifdef __KERNEL__
+struct net_device;
+struct sk_buff;
+
+struct vj_descriptor {
+ unsigned long address; /* address of net_channel_buffer */
+ unsigned long buffer_len; /* max length including header */
+};
+
+/* Everything about a vj_channel */
+struct vj_channel
+{
+ struct vj_channel_ring *ring;
+ wait_queue_head_t wq;
+ struct list_head list;
+ struct vj_flowid flowid;
+ int num_local_buffers;
+ struct vj_descriptor *descs;
+ unsigned long * used_descs;
+};
+
+void vj_inc_wakecnt(struct vj_channel *chan);
+struct vj_buffer *vj_get_buffer(int *desc_num);
+void vj_netif_rx(struct vj_buffer *buffer, int desc_num, unsigned short proto);
+int vj_xmit(struct sk_buff *skb, struct net_device *dev);
+struct vj_channel *vj_alloc_chan(int num_buffers);
+void vj_register_chan(struct vj_channel *chan, const struct vj_flowid *flowid);
+void vj_unregister_chan(struct vj_channel *chan);
+void vj_free_chan(struct vj_channel *chan);
+struct vj_buffer *vj_peek_next_buffer(struct vj_channel *chan);
+void vj_done_with_buffer(struct vj_channel *chan);
+unsigned short eth_vj_type_trans(struct vj_buffer *buffer);
+int vj_need_local_buffer(struct vj_channel *chan);
+#endif
+#endif /* _LINUX_VJCHAN_H */
diff -r 47031a1f466c linux-2.6.16/net/vjchan/Makefile
--- /dev/null Thu Mar 23 06:32:12 2006
+++ linux-2.6.16/net/vjchan/Makefile Mon Apr 24 19:50:46 2006
@@ -0,0 +1,3 @@
+#obj-m += vjtest.o
+obj-y += vjnet.o
+obj-y += af_vjchan.o
diff -r 47031a1f466c linux-2.6.16/net/vjchan/af_vjchan.c
--- /dev/null Thu Mar 23 06:32:12 2006
+++ linux-2.6.16/net/vjchan/af_vjchan.c Mon Apr 24 19:50:46 2006
@@ -0,0 +1,198 @@
+/* Van Jacobson net channels implementation for Linux
+ Copyright (C) 2006 Kelly Daly <kdaly@au.ibm.com> IBM Corporation
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/socket.h>
+#include <linux/vjchan.h>
+#include <net/sock.h>
+
+struct vjchan_sock
+{
+ struct sock sk;
+ struct vj_channel *chan;
+ int vj_reg_flag;
+};
+
+static inline struct vjchan_sock *vj_sk(struct sock *sk)
+{
+ return (struct vjchan_sock *)sk;
+}
+
+static struct proto vjchan_proto = {
+ .name = "VJCHAN",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct vjchan_sock),
+};
+
+int vjchan_release(struct socket *sock)
+{
+ struct sock *sk = sock->sk;
+
+ sock_orphan(sk);
+ sock->sk = NULL;
+ sock_put(sk);
+ return 0;
+}
+
+int vjchan_bind(struct socket *sock, struct sockaddr *addr, int sockaddr_len)
+{
+ struct sock *sk = sock->sk;
+ struct vjchan_sock *vjsk;
+ struct vj_flowid *flowid = (struct vj_flowid *)addr;
+
+ /* FIXME: avoid clashing with normal sockets, replace zeroes. */
+ vjsk = vj_sk(sk);
+ vj_register_chan(vjsk->chan, flowid);
+ vjsk->vj_reg_flag = 1;
+
+ return 0;
+}
+
+int vjchan_getname(struct socket *sock, struct sockaddr *addr,
+ int *sockaddr_len, int peer)
+{
+ /* FIXME: Implement */
+ return 0;
+}
+
+unsigned int vjchan_poll(struct file *file, struct socket *sock,
+ struct poll_table_struct *wait)
+{
+ struct sock *sk = sock->sk;
+ struct vj_channel *chan = vj_sk(sk)->chan;
+
+ poll_wait(file, &chan->wq, wait);
+ vj_inc_wakecnt(chan);
+
+ if (vj_peek_next_buffer(chan) && vj_need_local_buffer(chan) == 0)
+ return POLLIN | POLLRDNORM;
+
+ return 0;
+}
+
+/* We map the ring first, then one page per buffer. */
+int vjchan_mmap(struct file *file, struct socket *sock,
+ struct vm_area_struct *vma)
+{
+ struct sock *sk = sock->sk;
+ struct vj_channel *chan = vj_sk(sk)->chan;
+ int i, vip;
+ unsigned long pos;
+
+ if (vma->vm_end - vma->vm_start !=
+ (1 + chan->num_local_buffers)*PAGE_SIZE)
+ return -EINVAL;
+
+ pos = vma->vm_start;
+ vip = vm_insert_page(vma, pos, virt_to_page(chan->ring));
+ pos += PAGE_SIZE;
+ for (i = 0; i < chan->num_local_buffers; i++) {
+ vip = vm_insert_page(vma, pos, virt_to_page(chan->descs[i].address));
+ pos += PAGE_SIZE;
+ }
+ return 0;
+}
+
+const struct proto_ops vjchan_ops = {
+ .family = PF_VJCHAN,
+ .owner = THIS_MODULE,
+ .release = vjchan_release,
+ .bind = vjchan_bind,
+ .socketpair = sock_no_socketpair,
+ .accept = sock_no_accept,
+ .getname = vjchan_getname,
+ .poll = vjchan_poll,
+ .ioctl = sock_no_ioctl,
+ .shutdown = sock_no_shutdown,
+ .setsockopt = sock_common_setsockopt,
+ .getsockopt = sock_common_getsockopt,
+ .sendmsg = sock_no_sendmsg,
+ .recvmsg = sock_no_recvmsg,
+ .mmap = vjchan_mmap,
+ .sendpage = sock_no_sendpage
+};
+
+static void vjchan_destruct(struct sock *sk)
+{
+ struct vjchan_sock *vjsk;
+
+ vjsk = vj_sk(sk);
+ if (vjsk->vj_reg_flag) {
+ vj_unregister_chan(vjsk->chan);
+ vjsk->vj_reg_flag = 0;
+ }
+ vj_free_chan(vjsk->chan);
+
+}
+
+static int vjchan_create(struct socket *sock, int protocol)
+{
+ struct sock *sk;
+ struct vjchan_sock *vjsk;
+ int err;
+
+ if (!capable(CAP_NET_RAW))
+ return -EPERM;
+ if (sock->type != SOCK_DGRAM
+ && sock->type != SOCK_RAW
+ && sock->type != SOCK_PACKET)
+ return -ESOCKTNOSUPPORT;
+
+ sock->state = SS_UNCONNECTED;
+
+ err = -ENOBUFS;
+ sk = sk_alloc(PF_VJCHAN, GFP_KERNEL, &vjchan_proto, 1);
+ if (sk == NULL)
+ goto out;
+
+ sock->ops = &vjchan_ops;
+
+ sock_init_data(sock, sk);
+ sk->sk_family = PF_VJCHAN;
+ sk->sk_destruct = vjchan_destruct;
+
+ vjsk = vj_sk(sk);
+ vjsk->chan = vj_alloc_chan(VJ_NET_CHANNEL_ENTRIES);
+ vjsk->vj_reg_flag = 0;
+ if (!vjsk->chan)
+ return -ENOMEM;
+ return 0;
+out:
+ return err;
+}
+
+static struct net_proto_family vjchan_family_ops = {
+ .family = PF_VJCHAN,
+ .create = vjchan_create,
+ .owner = THIS_MODULE,
+};
+
+static void __exit vjchan_exit(void)
+{
+ sock_unregister(PF_VJCHAN);
+}
+
+static int __init vjchan_init(void)
+{
+ return sock_register(&vjchan_family_ops);
+}
+
+module_init(vjchan_init);
+module_exit(vjchan_exit);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_NETPROTO(PF_VJCHAN);
diff -r 47031a1f466c linux-2.6.16/net/vjchan/vjnet.c
--- /dev/null Thu Mar 23 06:32:12 2006
+++ linux-2.6.16/net/vjchan/vjnet.c Mon Apr 24 19:50:46 2006
@@ -0,0 +1,550 @@
+/* Van Jacobson net channels implementation for Linux
+ Copyright (C) 2006 Kelly Daly <kdaly@au.ibm.com> IBM Corporation
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/spinlock.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+#include <linux/vjchan.h>
+
+#define BUFFER_DATA_LEN 2048
+#define NUM_GLOBAL_DESCRIPTORS 1024
+
+/* All our channels. FIXME: Lockless funky hash structure please... */
+static LIST_HEAD(channels);
+static spinlock_t chan_lock = SPIN_LOCK_UNLOCKED;
+
+/* Default channel, also holds global buffers (userspace-mapped
+ * channels have local buffers, which they prefer to use). */
+static struct vj_channel *default_chan;
+
+/* need to increment for wake in udp.c wait_for_vj_buffer */
+void vj_inc_wakecnt(struct vj_channel *chan)
+{
+ chan->ring->c.wakecnt++;
+ pr_debug("*** incremented wakecnt - should allow wake up\n");
+}
+EXPORT_SYMBOL(vj_inc_wakecnt);
+
+static int is_empty(struct vj_channel_ring *ring)
+{
+ if (ring->c.head == ring->p.tail)
+ return 1;
+ return 0;
+}
+
+static struct vj_buffer *get_buffer(unsigned int desc_num,
+ struct vj_channel *chan)
+{
+ struct vj_buffer *buf;
+
+ if ((desc_num & VJ_HIGH_BIT) || (chan->num_local_buffers == 0)) {
+ desc_num &= ~VJ_HIGH_BIT;
+ BUG_ON(desc_num >= default_chan->num_local_buffers);
+ buf = (struct vj_buffer*)default_chan->descs[desc_num].address;
+ } else {
+ BUG_ON(desc_num >= chan->num_local_buffers);
+ buf = (struct vj_buffer *)chan->descs[desc_num].address;
+ }
+
+ pr_debug(" received desc_num is %i\n", desc_num);
+ pr_debug("get_buffer %p (%s) %i: %p (len=%li ifind=%i hlen=%li) %#02X %#02X %#02X %#02X %#02X %#02X %#02X %#02X\n",
+ current, current->comm, desc_num, buf, buf->data_len, buf->ifindex, buf->header_len + (sizeof(struct iphdr *) * 4),
+ buf->data[0], buf->data[1], buf->data[2], buf->data[3], buf->data[4], buf->data[5], buf->data[6], buf->data[7]);
+
+ return buf;
+}
+
+static void release_buffer(struct vj_channel *chan, unsigned int descnum)
+{
+ if (descnum & VJ_HIGH_BIT) {
+ BUG_ON(test_bit(descnum & ~VJ_HIGH_BIT,
+ default_chan->used_descs) == 0);
+ clear_bit(descnum & ~VJ_HIGH_BIT, default_chan->used_descs);
+ } else {
+ BUG_ON(test_bit(descnum, chan->used_descs) == 0);
+ clear_bit(descnum, chan->used_descs);
+ }
+}
+
+/* Free all descriptors for the current channel between where we last
+ * freed to and where the consumer has not yet consumed. chan->c.head
+ * is not cleared because it may not have been consumed, therefore
+ * chan->p.old_head is not cleared. If chan->p.old_head ==
+ * chan->c.head then nothing more has been consumed since we last
+ * freed the descriptors.
+ *
+ * Because we're using local and global channels we need to select the
+ * bitmap according to the channel. Local channels may be pointing to
+ * local or global buffers, so we need to select the bitmap according
+ * to the buffer type */
+
+/* Free descriptors consumer has consumed since last free */
+static void free_descs_for_channel(struct vj_channel *chan)
+{
+ struct vj_channel_ring *ring = chan->ring;
+ int desc_num;
+
+ while (ring->p.old_head != ring->c.head) {
+ printk("ring->p.old_head %i, ring->c.head %i\n", ring->p.old_head, ring->c.head);
+ desc_num = ring->q[ring->p.old_head];
+
+ printk("desc_num %i\n", desc_num);
+
+ /* FIXME: Security concerns: make sure this descriptor
+ * really used by this vjchannel. Userspace could
+ * have changed it. */
+ release_buffer(chan, desc_num);
+ ring->p.old_head = (ring->p.old_head + 1) % VJ_NET_CHANNEL_ENTRIES;
+ printk("ring->p.old_head %i, ring->c.head %i\n\n", ring->p.old_head, ring->c.head);
+ }
+}
+
+/* return -1 if no descriptor found and none can be freed */
+static int get_free_descriptor(struct vj_channel *chan)
+{
+ int free_desc, bitval;
+
+ BUG_ON(chan->num_local_buffers == 0);
+ do {
+ free_desc = find_first_zero_bit(chan->used_descs,
+ chan->num_local_buffers);
+ pr_debug("free_desc = %i\n", free_desc);
+ if (free_desc >= chan->num_local_buffers) {
+ /* no descriptors, refresh bitmap and try again! */
+ free_descs_for_channel(chan);
+ free_desc = find_first_zero_bit(chan->used_descs,
+ chan->num_local_buffers);
+ if (free_desc >= chan->num_local_buffers)
+ /* still no descriptors */
+ return -1;
+ }
+ bitval = test_and_set_bit(free_desc, chan->used_descs);
+ pr_debug("bitval = %i\n", bitval);
+ } while (bitval == 1); //keep going until we get a FREE free bit!
+
+ /* We set high bit to indicate a global channel. */
+ if (chan == default_chan)
+ free_desc |= VJ_HIGH_BIT;
+ return free_desc;
+}
+
+/* This function puts a buffer into a local address space for a
+ * channel that is unable to use a kernel address space. If address
+ * high bit is set then the buffer is in kernel space - get a free
+ * local buffer and copy it across. Set local buf to used (done when
+ * finding free buffer), kernel buf to unused. */
+/* FIXME: Loop, do as many as possible at once. */
+int vj_need_local_buffer(struct vj_channel *chan)
+{
+ struct vj_channel_ring *ring = chan->ring;
+ u32 new_desc, k_desc;
+
+ k_desc = ring->q[ring->c.head];
+
+ if (ring->q[ring->c.head] & VJ_HIGH_BIT) {
+ struct vj_buffer *buf, *kbuf;
+
+ kbuf = get_buffer(k_desc, chan);
+ new_desc = get_free_descriptor(chan);
+ if (new_desc == -1)
+ return -ENOBUFS;
+ buf = get_buffer(new_desc, chan);
+ memcpy (buf, kbuf, sizeof(struct vj_buffer)
+ + kbuf->data_len + kbuf->header_len);
+/* clear the old descriptor and set q to new one */
+ k_desc &= ~VJ_HIGH_BIT;
+ clear_bit(k_desc, default_chan->used_descs);
+ ring->q[ring->c.head] = new_desc;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(vj_need_local_buffer);
+
+struct vj_buffer *vj_get_buffer(int *desc_num)
+{
+ *desc_num = get_free_descriptor(default_chan);
+
+ if (*desc_num == -1) {
+ printk("no free bits!\n");
+ return NULL;
+ }
+
+ return get_buffer(*desc_num, default_chan);
+}
+EXPORT_SYMBOL(vj_get_buffer);
+
+static void enqueue_buffer(struct vj_channel *chan, struct vj_buffer *buffer, int desc_num)
+{
+ u16 tail, nxt;
+ int i;
+
+ pr_debug("*** in enqueue buffer\n");
+ pr_debug(" desc_num = %i\n", desc_num);
+ pr_debug(" Buffer Data Length = %lu\n", buffer->data_len);
+ pr_debug(" Buffer Header Length = %lu\n", buffer->header_len);
+ pr_debug(" Buffer Data:\n");
+ for (i = 0; i < buffer->data_len; i++) {
+ pr_debug("%i ", buffer->data[i]);
+ if (i % 20 == 0)
+ pr_debug("\n");
+ }
+ pr_debug("\n");
+
+ tail = chan->ring->p.tail;
+ nxt = (tail + 1) % VJ_NET_CHANNEL_ENTRIES;
+
+ pr_debug("nxt = %i and chan->c.head = %i\n", nxt, chan->ring->c.head);
+ if (nxt != chan->ring->c.head) {
+ chan->ring->q[tail] = desc_num;
+
+ smp_wmb();
+ chan->ring->p.tail=nxt;
+ pr_debug("chan->p.wakecnt = %i and chan->c.wakecnt = %i\n", chan->ring->p.wakecnt, chan->ring->c.wakecnt);
+ free_descs_for_channel(chan);
+ if (chan->ring->p.wakecnt != chan->ring->c.wakecnt) {
+ ++chan->ring->p.wakecnt;
+ /* consume whatever is available */
+ pr_debug("WAKE UP, CONSUMER!!!\n\n");
+ wake_up(&chan->wq);
+ }
+ } else //if can't add it to chan, may as well allow it to be reused
+ release_buffer(chan, desc_num);
+}
+
+/* FIXME: If we're going to do wildcards here, we need to do ordering between different partial matches... */
+static struct vj_channel *find_channel(u32 saddr, u32 daddr, u16 proto, u16 sport, u16 dport, u32 ifindex)
+{
+ struct vj_channel *i;
+
+ pr_debug("args saddr %u, daddr %u, sport %u, dport %u, ifindex %u, proto %u\n", saddr, daddr, sport, dport, ifindex, proto);
+
+ list_for_each_entry(i, &channels, list) {
+ pr_debug("saddr %u, daddr %u, sport %u, dport %u, ifindex %u, proto %u\n", i->flowid.saddr, i->flowid.daddr, i->flowid.sport, i->flowid.dport, i->flowid.ifindex, i->flowid.proto);
+
+ if ((!i->flowid.saddr || i->flowid.saddr == saddr) &&
+ (!i->flowid.daddr || i->flowid.daddr == daddr) &&
+ (!i->flowid.proto || i->flowid.proto == proto) &&
+ (!i->flowid.sport || i->flowid.sport == sport) &&
+ (!i->flowid.dport || i->flowid.dport == dport) &&
+ (!i->flowid.ifindex || i->flowid.ifindex == ifindex)) {
+ pr_debug("Found channel %p\n", i);
+ return i;
+ }
+ }
+ pr_debug("using default channel %p\n", default_chan);
+ return default_chan;
+}
+
+void vj_netif_rx(struct vj_buffer *buffer, int desc_num,
+ unsigned short proto)
+{
+ struct vj_channel *chan;
+ struct iphdr *ip;
+ int iphl, offset, real_data_len;
+ u16 *ports;
+ unsigned long flags;
+
+ offset = sizeof(struct iphdr) + sizeof(struct udphdr);
+ real_data_len = buffer->data_len - offset;
+
+
+ pr_debug("data_len = %lu, offset = %i, real data? = %i\n\n\n", buffer->data_len, offset, real_data_len);
+ /* this is always 18 when there's 18 or less characters in buffer->data */
+
+ pr_debug("rx) desc_num = %i\n\n", desc_num);
+
+ spin_lock_irqsave(&chan_lock, flags);
+ if (proto == __constant_htons(ETH_P_IP)) {
+
+ ip = (struct iphdr *)(buffer->data + buffer->header_len);
+ ports = (u16 *)(ip + 1);
+ iphl = ip->ihl * 4;
+
+ if ((buffer->data_len < (iphl + 4)) ||
+ (iphl != sizeof(struct iphdr))) {
+ pr_debug("Bad data, default chan\n");
+ pr_debug("buffer data_len = %li, header len = %li, ip->ihl = %i\n", buffer->data_len, buffer->header_len, ip->ihl);
+ chan = default_chan;
+ } else {
+ chan = find_channel(ip->saddr, ip->daddr,
+ ip->protocol, ports[0],
+ ports[1], buffer->ifindex);
+
+ }
+ } else
+ chan = default_chan;
+ enqueue_buffer(chan, buffer, desc_num);
+
+ spin_unlock_irqrestore(&chan_lock, flags);
+}
+EXPORT_SYMBOL(vj_netif_rx);
+
+/*
+ * Determine the packet's protocol ID. The rule here is that we
+ * assume 802.3 if the type field is short enough to be a length.
+ * This is normal practice and works for any 'now in use' protocol.
+ */
+
+unsigned short eth_vj_type_trans(struct vj_buffer *buffer)
+{
+ struct ethhdr *eth;
+ unsigned char *rawp;
+
+ eth = (struct ethhdr *)buffer->data;
+ buffer->header_len = ETH_HLEN;
+
+ BUG_ON(buffer->header_len > buffer->data_len);
+
+ buffer->data_len -= buffer->header_len;
+ if (ntohs(eth->h_proto) >= 1536)
+ return eth->h_proto;
+
+ rawp = buffer->data;
+
+ /*
+ * This is a magic hack to spot IPX packets. Older Novell breaks
+ * the protocol design and runs IPX over 802.3 without an 802.2 LLC
+ * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
+ * won't work for fault tolerant netware but does for the rest.
+ */
+ if (*(unsigned short *)rawp == 0xFFFF)
+ return htons(ETH_P_802_3);
+
+ /*
+ * Real 802.2 LLC
+ */
+ return htons(ETH_P_802_2);
+}
+EXPORT_SYMBOL(eth_vj_type_trans);
+
+static void send_to_netif_rx(struct vj_buffer *buffer)
+{
+ struct sk_buff *skb;
+ struct net_device *dev;
+ int i;
+
+ dev = dev_get_by_index(buffer->ifindex);
+ if (!dev)
+ return;
+ skb = dev_alloc_skb(buffer->data_len + 2);
+ if (skb == NULL) {
+ dev_put(dev);
+ return;
+ }
+
+ skb_reserve(skb, 2);
+ skb->dev = dev;
+
+ skb_put(skb, buffer->data_len);
+ memcpy(skb->data, buffer->data, buffer->data_len);
+
+ pr_debug(" *** C buffer data_len = %lu and skb->len = %i\n", buffer->data_len, skb->len);
+ for (i = 0; i < 10; i++)
+ pr_debug("%i\n", skb->data[i]);
+
+ skb->protocol = eth_type_trans(skb, skb->dev);
+
+ netif_receive_skb(skb);
+}
+
+/* handles default_chan (buffers that nobody else wants) */
+static int default_thread(void *unused)
+{
+ int consumed = 0;
+ int woken = 0;
+ struct vj_buffer *buffer;
+ wait_queue_t wait;
+
+ /* When we get woken up, don't want to be removed from waitqueue! */
+//no more wait.task struct task_struct * task is now void *private
+ wait.private = current;
+ wait.func = default_wake_function;
+ INIT_LIST_HEAD(&wait.task_list);
+
+ add_wait_queue(&default_chan->wq, &wait);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ while (!kthread_should_stop()) {
+ /* FIXME: if we do this before prepare_to_wait, avoids wmb */
+ default_chan->ring->c.wakecnt++;
+ smp_wmb();
+
+ while (!is_empty(default_chan->ring)) {
+ smp_read_barrier_depends();
+ buffer = get_buffer(default_chan->ring->q[default_chan->ring->c.head], default_chan);
+ pr_debug("calling send_to_netif_rx\n");
+ send_to_netif_rx(buffer);
+ smp_rmb();
+ default_chan->ring->c.head = (default_chan->ring->c.head+1)%VJ_NET_CHANNEL_ENTRIES;
+ consumed++;
+ }
+
+ schedule();
+ woken++;
+ set_current_state(TASK_INTERRUPTIBLE);
+ }
+ remove_wait_queue(&default_chan->wq, &wait);
+
+ __set_current_state(TASK_RUNNING);
+
+ pr_debug("consumer finished! consumed %i and woke %i\n", consumed, woken);
+ return 0;
+}
+
+/* return the next buffer, but do not move on */
+struct vj_buffer *vj_peek_next_buffer(struct vj_channel *chan)
+{
+ struct vj_channel_ring *ring = chan->ring;
+
+ if (is_empty(ring))
+ return NULL;
+ return get_buffer(ring->q[ring->c.head], chan);
+}
+EXPORT_SYMBOL(vj_peek_next_buffer);
+
+/* move on to next buffer */
+void vj_done_with_buffer(struct vj_channel *chan)
+{
+ struct vj_channel_ring *ring = chan->ring;
+
+ ring->c.head = (ring->c.head+1)%VJ_NET_CHANNEL_ENTRIES;
+
+ pr_debug("done_with_buffer\n\n");
+}
+EXPORT_SYMBOL(vj_done_with_buffer);
+
+struct vj_channel *vj_alloc_chan(int num_buffers)
+{
+ int i;
+ struct vj_channel *chan = kmalloc(sizeof(*chan), GFP_KERNEL);
+
+ if (!chan)
+ return NULL;
+
+ chan->ring = (void *)get_zeroed_page(GFP_KERNEL);
+ if (chan->ring == NULL)
+ goto free_chan;
+
+ init_waitqueue_head(&chan->wq);
+ chan->ring->p.tail = chan->ring->p.wakecnt = chan->ring->p.old_head = chan->ring->c.head = chan->ring->c.wakecnt = 0;
+
+ chan->num_local_buffers = num_buffers;
+ if (chan->num_local_buffers == 0)
+ return chan;
+
+ chan->used_descs = kzalloc(BITS_TO_LONGS(chan->num_local_buffers)
+ * sizeof(long), GFP_KERNEL);
+ if (chan->used_descs == NULL)
+ goto free_ring;
+ chan->descs = kmalloc(sizeof(*chan->descs)*num_buffers, GFP_KERNEL);
+ if (chan->descs == NULL)
+ goto free_used_descs;
+ for (i = 0; i < chan->num_local_buffers; i++) {
+ chan->descs[i].buffer_len = PAGE_SIZE;
+ chan->descs[i].address = get_zeroed_page(GFP_KERNEL);
+ if (chan->descs[i].address == 0)
+ goto free_descs;
+ }
+
+ return chan;
+
+free_descs:
+ for (--i; i >= 0; i--)
+ free_page(chan->descs[i].address);
+ kfree(chan->descs);
+free_used_descs:
+ kfree(chan->used_descs);
+free_ring:
+ free_page((unsigned long)chan->ring);
+free_chan:
+ kfree(chan);
+ return NULL;
+}
+EXPORT_SYMBOL(vj_alloc_chan);
+
+void vj_register_chan(struct vj_channel *chan, const struct vj_flowid *flowid)
+{
+ pr_debug("%p %s: registering channel %p\n",
+ current, current->comm, chan);
+ chan->flowid = *flowid;
+ spin_lock_irq(&chan_lock);
+ list_add(&chan->list, &channels);
+ spin_unlock_irq(&chan_lock);
+}
+EXPORT_SYMBOL(vj_register_chan);
+
+void vj_unregister_chan(struct vj_channel *chan)
+{
+ pr_debug("%p %s: unregistering channel %p\n",
+ current, current->comm, chan);
+ spin_lock_irq(&chan_lock);
+ list_del(&chan->list);
+ spin_unlock_irq(&chan_lock);
+}
+EXPORT_SYMBOL(vj_unregister_chan);
+
+void vj_free_chan(struct vj_channel *chan)
+{
+ pr_debug("%p %s: freeing channel %p\n",
+ current, current->comm, chan);
+ /* FIXME: Mark any buffer still in channel as free! */
+ kfree(chan);
+}
+EXPORT_SYMBOL(vj_free_chan);
+
+
+
+/* not using at the mo - working on rx, not tx */
+int vj_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct vj_buffer *buffer;
+ /* first element in dev priv data must be addr of net_channel */
+// struct net_channel *chan = *(struct net_channel **) netdev_priv(dev) + 1;
+ int desc_num;
+
+ buffer = vj_get_buffer(&desc_num);
+ buffer->data_len = skb->len;
+ memcpy(buffer->data, skb->data, buffer->data_len);
+// enqueue_buffer(chan, buffer, desc_num);
+
+ kfree(skb);
+ return 0;
+}
+EXPORT_SYMBOL(vj_xmit);
+
+static int __init init(void)
+{
+ default_chan = vj_alloc_chan(NUM_GLOBAL_DESCRIPTORS);
+ if (!default_chan)
+ return -ENOMEM;
+
+ kthread_run(default_thread, NULL, "kvj_net");
+ return 0;
+}
+
+module_init(init);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("VJ Channel Networking Module.");
+MODULE_AUTHOR("Kelly Daly <kelly@au1.ibm.com>");
^ permalink raw reply
* Unlocking Intel flash
From: Peter Buelow @ 2006-04-25 20:19 UTC (permalink / raw)
To: linux-mtd
Ok, hoping someone knows, because Google isn't helping oddly enough. I've
just started putting together some work that includes adding a JFFS2
partition using MTD (obviously) that sits on it's own (ie, it's not
bootable and is just a small area that I would like to read/write to where
the rest of the FS is squashfs read only). Basically, an rc script either
creates it, or mounts it depending, and then I would use it mounted under
/store. Here's what's happening.
I can create the JFFS2 fielsystem, no errors. I can mount the new
filesystem, no errors. I can initially write to the filesystem, but then
the writes fail (usually after the first write) with the following error
Write of 68 bytes at 0x000e0214 failed. returned 0, retlen 0
This happens after initial creation and will happen immediately after
reboot and remount of the existing partition. OK, so I need to unlock the
flash maybe? I try the unlock command, and get the following.
# unlock /dev/mtdblock/8
Could not get MTD device info from /dev/mtdblock/8
I've looked at the error leg in the kernel, but am not familiar enough
with MTD to make an informed decision as to why it's failing. Hoping
someone here can help.
This is a stock 2.4.17 kernel, no patches to MTD (yet?) and gcc version
2.95.3. It's Intel Strata flash, the P30 family. Many thanks in advance to
anyone who can help.
--
"Knowledge is in every country the surest basis of public happiness."
George Washington (State of the Union address, 1790)
--
Pete
^ permalink raw reply
* Re: [PATCH][RFC] NFS: Improving the access cache
From: Matthew Wilcox @ 2006-04-26 1:31 UTC (permalink / raw)
To: Steve Dickson; +Cc: nfs, linux-fsdevel
In-Reply-To: <444EC96B.80400@RedHat.com>
On Tue, Apr 25, 2006 at 09:14:19PM -0400, Steve Dickson wrote:
> The attached patch used a hash table to store the nfs_access_entry
> entires which cause the ACCESS request to only happen when the
> attributes timeout.. The table is indexed by the addition of the
> nfs_inode pointer and the cr_uid in the cred structure which should
> spread things out nicely for some decent scalability (although the
> locking scheme may need to be reworked a bit). The table has 256 entries
> of struct list_head giving it a total size of 2k.
Seems to me like you could use an hlist instead, saving you 1k.
^ permalink raw reply
* Re: CROSS_COMPILE in environment variable
From: Atsushi Nemoto @ 2006-04-26 1:36 UTC (permalink / raw)
To: geoffrey.levand; +Cc: linux-mips
In-Reply-To: <444E6B4E.5000608@am.sony.com>
On Tue, 25 Apr 2006 11:32:46 -0700, Geoff Levand <geoffrey.levand@am.sony.com> wrote:
> I think the Kconfig could be changed to say that CONFIG_CROSSCOMPILE
> makes the build system use a built-in default tool prefix.
Already done by Ralf a few days ago :-)
---
Atsushi Nemoto
^ permalink raw reply
* Re: PCI ROM resource allocation issue with 2.6.17-rc2
From: Dave Airlie @ 2006-04-26 1:23 UTC (permalink / raw)
To: Linus Torvalds
Cc: Arjan van de Ven, Andrew Morton, Matthew Reppert, linux-kernel,
Antonino A. Daplas, Benjamin Herrenschmidt
In-Reply-To: <Pine.LNX.4.64.0604241025120.3701@g5.osdl.org>
>
> Maybe just add a DRM command to do it, so that old X versions (who don't
> know about it) will just do it by hand, and then new X versions can do
>
> if (drm_ioctl(fd, DRM_SETUP_THE_DAMN_RESOURCES) < 0) {
> /*
> * I don't know what errno the drm-ioctl actually
> * returns for unrecognized commands, so this is
> * just an example
> */
> if (errno == ENOTTY) {
> old kernel: do it by hand
> }
> }
>
> which allows us to go forward in a sane way, and finally leave the broken
> X PCI-configuration-by-hand crap behind.
It doesn't help of course, the fb drivers also pci_enable the devices,
really X needs a kicking square, I'm trying to figure out some sort of fix
here, but X does't some really stupid things with PCI resources...
We really need a userspace way to pci_enable_device that X can call (via
sysfs) so for cards that don't have a DRM or fb loaded we still get
something..
Dave.
--
David Airlie, Software Engineer
http://www.skynet.ie/~airlied / airlied at skynet.ie
Linux kernel - DRI, VAX / pam_smb / ILUG
^ permalink raw reply
* Re: [PATCH 1/1] ia64: enable dumps to capture second page of kernel
From: Nick Piggin @ 2006-04-26 1:19 UTC (permalink / raw)
To: linux-ia64
In-Reply-To: <20060425154748.GA29493@sgi.com>
Cliff Wickman wrote:
>In SLES10 (2.6.16) crash dumping (in my experience, LKCD) is unable to
>capture the second page of the 2-page task/stack allocation.
>This is particularly troublesome for dump analysis, as the stack traceback
>cannot be done.
> (A similar convention is probably needed throughout the kernel to make
> kernel multi-page allocations detectable for dumping)
>
>Multi-page kernel allocations are represented by the single page structure
>associated with the first page of the allocation. The page structures
>associated with the other pages are unintialized.
>
>If the dumper is selecting only kernel pages it has no way to identify
>any but the first page of the allocation.
>
>The fix is to make the task/stack allocation a compound page.
>
>Diffed against 2.6.16
>
>Signed-off-by: Cliff Wickman <cpw@sgi.com>
>---
>
>---
> include/asm-ia64/thread_info.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
>Index: linux/include/asm-ia64/thread_info.h
>=================================>--- linux.orig/include/asm-ia64/thread_info.h
>+++ linux/include/asm-ia64/thread_info.h
>@@ -74,7 +74,7 @@ struct thread_info {
> #define end_of_stack(p) (unsigned long *)((void *)(p) + IA64_RBS_OFFSET)
>
> #define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
>-#define alloc_task_struct() ((task_t *)__get_free_pages(GFP_KERNEL, KERNEL_STACK_SIZE_ORDER))
>+#define alloc_task_struct() ((task_t *)__get_free_pages(GFP_KERNEL | __GFP_COMP, KERNEL_STACK_SIZE_ORDER))
> #define free_task_struct(tsk) free_pages((unsigned long) (tsk), KERNEL_STACK_SIZE_ORDER)
>
> #endif /* !__ASSEMBLY */
>
>---------
>
>Nick,
>
> You had copied me on a reply on this subject earlier:
> Date: Sat, 22 Apr 2006 13:56:12 +1000
> From: Nick Piggin <nickpiggin@yahoo.com.au>
> Yeah, we're moving toward compound pages for all these types of things
> (including nommu). So making those pages compound pages should be the
> right thing to do.
>
> Still agree?
>
Does the dumper actually _crash_ without this patch? Or does it have some
page_count test that means it doesn't even attempt to take a ref to the 2nd
page?
Either way, I don't think your patch is a problem. If it works, I think it
should go in. Maybe a little comment there would be helpful.
Thanks,
Nick
--
Send instant messages to your online friends http://au.messenger.yahoo.com
^ permalink raw reply
* Re: [Qemu-devel] Patch for kqemu-1.3.0pre5 on Fedora Core 4 x86_64
From: Troy Benjegerdes @ 2006-04-26 1:18 UTC (permalink / raw)
To: qemu-devel
In-Reply-To: <444EA7A8.1000308@bellard.org>
On Wed, Apr 26, 2006 at 12:50:16AM +0200, Fabrice Bellard wrote:
> Well, there is a change log in the archive and here it is:
>
> version 1.3.0pre6:
>
> - compile fix for Linux kernel version >= 2.6.16
> - better null LDT handling (aka Plan9 and ReactOS bug)
> - moved monitor code to another address (aka win2k 256 MB bug)
FYI, the windows 2000 install blows up right away with -kernel-kqemu on
an x86_64 host with qemu-system-x86_64 .
an install with kqemu-user seems to be going okay so far
^ permalink raw reply
* Re: [patch/rft 2.6.17-rc2] swsusp resume must not device_suspend()
From: Nigel Cunningham @ 2006-04-26 1:16 UTC (permalink / raw)
To: David Brownell; +Cc: Andrew Morton, linux-pm, linux-usb-devel
In-Reply-To: <200604251655.01988.david-b@pacbell.net>
[-- Attachment #1.1: Type: text/plain, Size: 2045 bytes --]
Hi.
On Wednesday 26 April 2006 09:55, David Brownell wrote:
> On Tuesday 25 April 2006 3:18 pm, Nigel Cunningham wrote:
> > I saw the 2 suspends, 1 resume comment in another part of the thread, but
> > don't believe a driver would be able to detect that 2 suspends and 1
> > resume call had been made - at least not without some non volatile ram.
>
> The extra suspend is just IMO a symptom of sloppiness, like a "here may be
> bugs" sign. Not necessarily an issue in its own right.
>
> In fact if you count carefully, it's three suspends and one resume: one
> suspend before calling swsusp_resume, one inside swsusp_resume -- replaced
> by my patch -- and a correctly matched pair in the kernel being resumed.
That doesn't sound right. Let' see - where's this third one?
Real Effective
SUSPEND
Pre-copy suspend(freeze) suspend(freeze)
powerdown(freeze) powerdown(freeze)
Post-copy powerup
resume
Powerdown shutdown_prepare/kernel_power_off/...
RESUME
bios & kernel init
Pre-restore suspend(freeze)
powerdown(freeze)
Post-restore powerup powerup
resume resume
> Raising two points: (1) for those who think suspend is right, you can
> think of it as replacing one of the extra ones with
> kernel_restart_prepare(); and (2) not very much code interacts with that
> restart prep, that's a sane audit problem.
>
>
> Also, about non-volatile RAM. Not necessary ... the device hardware holds
> all the relevant state. The problem is that swsusp is now trashing it with
> those suspend calls before resuming the real kernel. On the plus side, we
> already have code being used to resolve the identical issue for kexec(),
> and all my patch does is to use it.
If devices really do get powered down, then they won't retain the state. If
they don't actually powerdown, then I see your point.
Regards,
Nigel
--
See our web page for Howtos, FAQs, the Wiki and mailing list info.
http://www.suspend2.net IRC: #suspend2 on Freenode
[-- Attachment #1.2: Type: application/pgp-signature, Size: 189 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply
* [PATCH][RFC] NFS: Improving the access cache
From: Steve Dickson @ 2006-04-26 1:14 UTC (permalink / raw)
To: nfs; +Cc: linux-fsdevel
[-- Attachment #1: Type: text/plain, Size: 743 bytes --]
Currently the NFS client caches ACCESS information on a per uid basis
which fall apart when different process with different uid consistently
access the same directory. The end result being a storm of needless
ACCESS calls...
The attached patch used a hash table to store the nfs_access_entry
entires which cause the ACCESS request to only happen when the
attributes timeout.. The table is indexed by the addition of the
nfs_inode pointer and the cr_uid in the cred structure which should
spread things out nicely for some decent scalability (although the
locking scheme may need to be reworked a bit). The table has 256 entries
of struct list_head giving it a total size of 2k.
The patch is based on Trond's GIT tree...
Comments?
steved.
[-- Attachment #2: linux-2.6.17.rc2-nfs-accesscache-hash.patch --]
[-- Type: text/x-patch, Size: 6231 bytes --]
This patch improves the caching of ACCESS information by storing
the information in hash table. The patch will greatly decrease the
number of ACCESS calls with processes with different uids access
the same directory.
Signed-off-by: Steve Dickson <steved@redhat.com>
----------------------------------------------------
--- mynfs-2.6/fs/nfs/inode.c.acc 2006-04-21 15:02:07.000000000 -0400
+++ mynfs-2.6/fs/nfs/inode.c 2006-04-25 19:12:05.000000000 -0400
@@ -74,6 +74,9 @@ static void nfs_zap_acl_cache(struct ino
static struct rpc_program nfs_program;
+extern void nfs_zap_access_cache(struct inode *);
+extern void nfs_init_access_cache(void);
+
static struct super_operations nfs_sops = {
.alloc_inode = nfs_alloc_inode,
.destroy_inode = nfs_destroy_inode,
@@ -170,14 +173,11 @@ static void
nfs_clear_inode(struct inode *inode)
{
struct nfs_inode *nfsi = NFS_I(inode);
- struct rpc_cred *cred;
nfs_wb_all(inode);
BUG_ON (!list_empty(&nfsi->open_files));
nfs_zap_acl_cache(inode);
- cred = nfsi->cache_access.cred;
- if (cred)
- put_rpccred(cred);
+ nfs_zap_access_cache(inode);
BUG_ON(atomic_read(&nfsi->data_updates) != 0);
}
@@ -940,7 +940,6 @@ nfs_fhget(struct super_block *sb, struct
nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
nfsi->attrtimeo_timestamp = jiffies;
memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
- nfsi->cache_access.cred = NULL;
unlock_new_inode(inode);
} else
@@ -2892,6 +2891,8 @@ static int __init init_nfs_fs(void)
{
int err;
+ nfs_init_access_cache();
+
err = nfs_init_nfspagecache();
if (err)
goto out4;
--- mynfs-2.6/fs/nfs/dir.c.acc 2006-04-21 15:02:07.000000000 -0400
+++ mynfs-2.6/fs/nfs/dir.c 2006-04-25 19:13:01.000000000 -0400
@@ -54,6 +54,16 @@ static int nfs_rename(struct inode *, st
static int nfs_fsync_dir(struct file *, struct dentry *, int);
static loff_t nfs_llseek_dir(struct file *, loff_t, int);
+/*
+ * access cache
+ */
+#define ACCESS_HASH_BITS 8
+#define ACCESS_HASH_SIZE (1 << ACCESS_HASH_BITS)
+#define ACCESS_HASH_MASK (ACCESS_HASH_SIZE - 1)
+#define access_hashval(iptr, id) ((((uid_t)iptr) + (id)) & ACCESS_HASH_MASK)
+static struct list_head access_hashtbl[ACCESS_HASH_SIZE];
+static spinlock_t access_hashlock;
+
const struct file_operations nfs_dir_operations = {
.llseek = nfs_llseek_dir,
.read = generic_read_dir,
@@ -1635,36 +1645,102 @@ out:
unlock_kernel();
return error;
}
+void nfs_init_access_cache(void)
+{
+ int i;
-int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res)
+ for (i=0; i < ACCESS_HASH_SIZE; i++)
+ INIT_LIST_HEAD(&access_hashtbl[i]);
+
+ spin_lock_init(&access_hashlock);
+
+ return;
+}
+void nfs_zap_access_cache(struct inode *inode)
{
struct nfs_inode *nfsi = NFS_I(inode);
- struct nfs_access_entry *cache = &nfsi->cache_access;
+ struct nfs_access_entry *cache;
+ struct list_head *head, *pos, *next;
+ int i;
+
+ spin_lock(&access_hashlock);
+ for (i=0; i < ACCESS_HASH_SIZE; i++) {
+ head = &access_hashtbl[access_hashval(nfsi, i)];
+ if (list_empty(head))
+ continue;
- if (cache->cred != cred
- || time_after(jiffies, cache->jiffies + NFS_ATTRTIMEO(inode))
- || (nfsi->cache_validity & NFS_INO_INVALID_ACCESS))
- return -ENOENT;
- memcpy(res, cache, sizeof(*res));
- return 0;
+ list_for_each_safe(pos, next, head) {
+ cache = list_entry(pos, struct nfs_access_entry, acc_list);
+ if (cache->id != (void *)nfsi)
+ continue;
+
+ list_del(&cache->acc_list);
+ put_rpccred(cache->cred);
+ kfree(cache);
+ }
+ }
+ spin_unlock(&access_hashlock);
+ return;
}
-void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
+int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res)
{
struct nfs_inode *nfsi = NFS_I(inode);
- struct nfs_access_entry *cache = &nfsi->cache_access;
+ int invalid = (nfsi->cache_validity & NFS_INO_INVALID_ACCESS);
+ struct nfs_access_entry *cache = NULL;
+ struct list_head *head;
+ int expired;
+
+ spin_lock(&access_hashlock);
+ head = &access_hashtbl[access_hashval(nfsi, cred->cr_uid)];
+ list_for_each_entry(cache, head, acc_list) {
+ if (cache->id != nfsi)
+ continue;
+ if (cache->cred != cred)
+ continue;
- if (cache->cred != set->cred) {
- if (cache->cred)
+ expired = time_after(jiffies,
+ cache->jiffies + NFS_ATTRTIMEO(inode));
+ if (expired || invalid) {
+ list_del(&cache->acc_list);
+ spin_unlock(&access_hashlock);
put_rpccred(cache->cred);
- cache->cred = get_rpccred(set->cred);
+ kfree(cache);
+ goto nolock;
+ }
+ memcpy(res, cache, sizeof(*res));
+ spin_unlock(&access_hashlock);
+ return 0;
}
- /* FIXME: replace current access_cache BKL reliance with inode->i_lock */
- spin_lock(&inode->i_lock);
+ spin_unlock(&access_hashlock);
+
+nolock:
+ return -ENOENT;
+}
+
+void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
+{
+ struct nfs_inode *nfsi = NFS_I(inode);
+ struct nfs_access_entry *cache = NULL;
+ struct list_head *head;
+
+ cache = (struct nfs_access_entry *)kmalloc(sizeof(*cache), GFP_KERNEL);
+ if (!cache)
+ return;
+
+ spin_lock(&access_hashlock);
+ head = &access_hashtbl[access_hashval(nfsi, set->cred->cr_uid)];
nfsi->cache_validity &= ~NFS_INO_INVALID_ACCESS;
- spin_unlock(&inode->i_lock);
+ INIT_LIST_HEAD(&cache->acc_list);
+ list_add(&cache->acc_list, head);
+ spin_unlock(&access_hashlock);
+
+ cache->cred = get_rpccred(set->cred);
cache->jiffies = set->jiffies;
cache->mask = set->mask;
+ cache->id = (void *)nfsi;
+
+ return;
}
static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
--- mynfs-2.6/include/linux/nfs_fs.h.acc 2006-04-21 15:02:08.000000000 -0400
+++ mynfs-2.6/include/linux/nfs_fs.h 2006-04-25 19:12:05.000000000 -0400
@@ -72,6 +72,8 @@ struct nfs_access_entry {
unsigned long jiffies;
struct rpc_cred * cred;
int mask;
+ void *id;
+ struct list_head acc_list;
};
struct nfs4_state;
@@ -145,7 +147,6 @@ struct nfs_inode {
*/
atomic_t data_updates;
- struct nfs_access_entry cache_access;
#ifdef CONFIG_NFS_V3_ACL
struct posix_acl *acl_access;
struct posix_acl *acl_default;
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.