Commit 6aea1666 authored by Linus Torvalds's avatar Linus Torvalds

v2.4.0.3 -> v2.4.0.4

  - ReiserFS merge
  - fix DRM R128/AGP dependency
parent 448ba078
...@@ -10745,6 +10745,46 @@ CONFIG_MINIX_FS ...@@ -10745,6 +10745,46 @@ CONFIG_MINIX_FS
called minix.o. Note that the file system of your root partition called minix.o. Note that the file system of your root partition
(the one containing the directory /) cannot be compiled as a module. (the one containing the directory /) cannot be compiled as a module.
Reiserfs support
CONFIG_REISERFS_FS
Stores not just filenames but the files themselves in a balanced
tree. Uses journaling.
Balanced trees are more efficient than traditional
filesystem architectural foundations.
You can use reiserfs in all cases where you use the ext2fs file
system, and you will gain in speed and disk space. It has fewer
worst case performance situations than other file systems
because balanced trees are hardier creatures than other algorithms
are (if that is not technical enough, read www.namesys.com....:-) )
It is more easily extended to have features currently found in
database and keyword search systems than block allocation based
filesystems are. The next version will be so extended, and will
support plugins consistent with our motto ``It takes more than a
license to make source code open.''
Read www.namesys.com to learn more about reiserfs.
Sponsored by Threshold Networks, Emusic.com, and Bigstorage.com.
If you like it, you can pay us to add new features to it that you
need, buy a support contract, or pay us to port it to another OS.
Enable Reiserfs consistency checks
CONFIG_REISERFS_CHECK
If you set this to yes, then ReiserFS will perform every check it
can possibly imagine of its internal consistency throughout its
operation. It will also go substantially slower. More than once we
have forgotten that this was on, and then gone despondent over the
latest benchmarks.:-) Use of this option allows our team to go all
out in checking for consistency when debugging without fear of its
effect on end users. If you are on the verge of sending in a bug
report, say yes and you might get a useful error message. Almost
everyone should say no.
Second extended fs support Second extended fs support
CONFIG_EXT2_FS CONFIG_EXT2_FS
This is the de facto standard Linux file system (method to organize This is the de facto standard Linux file system (method to organize
......
VERSION = 2 VERSION = 2
PATCHLEVEL = 4 PATCHLEVEL = 4
SUBLEVEL = 1 SUBLEVEL = 1
EXTRAVERSION =-pre2 EXTRAVERSION =-pre4
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
......
...@@ -2008,7 +2008,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c) ...@@ -2008,7 +2008,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
*/ */
/* TSC disabled? */ /* TSC disabled? */
#ifdef CONFIG_TSC #ifndef CONFIG_X86_TSC
if ( tsc_disable ) if ( tsc_disable )
clear_bit(X86_FEATURE_TSC, &c->x86_capability); clear_bit(X86_FEATURE_TSC, &c->x86_capability);
#endif #endif
......
...@@ -317,7 +317,7 @@ static void __init pagetable_init (void) ...@@ -317,7 +317,7 @@ static void __init pagetable_init (void)
pgd_t *pgd, *pgd_base; pgd_t *pgd, *pgd_base;
int i, j, k; int i, j, k;
pmd_t *pmd; pmd_t *pmd;
pte_t *pte; pte_t *pte, *pte_base;
/* /*
* This can be zero as well - no problem, in that case we exit * This can be zero as well - no problem, in that case we exit
...@@ -366,11 +366,7 @@ static void __init pagetable_init (void) ...@@ -366,11 +366,7 @@ static void __init pagetable_init (void)
continue; continue;
} }
pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); pte_base = pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
if (pte != pte_offset(pmd, 0))
BUG();
for (k = 0; k < PTRS_PER_PTE; pte++, k++) { for (k = 0; k < PTRS_PER_PTE; pte++, k++) {
vaddr = i*PGDIR_SIZE + j*PMD_SIZE + k*PAGE_SIZE; vaddr = i*PGDIR_SIZE + j*PMD_SIZE + k*PAGE_SIZE;
...@@ -378,6 +374,10 @@ static void __init pagetable_init (void) ...@@ -378,6 +374,10 @@ static void __init pagetable_init (void)
break; break;
*pte = mk_pte_phys(__pa(vaddr), PAGE_KERNEL); *pte = mk_pte_phys(__pa(vaddr), PAGE_KERNEL);
} }
set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte_base)));
if (pte_base != pte_offset(pmd, 0))
BUG();
} }
} }
......
...@@ -9,7 +9,7 @@ bool 'Direct Rendering Manager (XFree86 DRI support)' CONFIG_DRM ...@@ -9,7 +9,7 @@ bool 'Direct Rendering Manager (XFree86 DRI support)' CONFIG_DRM
if [ "$CONFIG_DRM" != "n" ]; then if [ "$CONFIG_DRM" != "n" ]; then
tristate ' 3dfx Banshee/Voodoo3+' CONFIG_DRM_TDFX tristate ' 3dfx Banshee/Voodoo3+' CONFIG_DRM_TDFX
tristate ' 3dlabs GMX 2000' CONFIG_DRM_GAMMA tristate ' 3dlabs GMX 2000' CONFIG_DRM_GAMMA
tristate ' ATI Rage 128' CONFIG_DRM_R128 dep_tristate ' ATI Rage 128' CONFIG_DRM_R128 $CONFIG_AGP
dep_tristate ' Intel I810' CONFIG_DRM_I810 $CONFIG_AGP dep_tristate ' Intel I810' CONFIG_DRM_I810 $CONFIG_AGP
dep_tristate ' Matrox g200/g400' CONFIG_DRM_MGA $CONFIG_AGP dep_tristate ' Matrox g200/g400' CONFIG_DRM_MGA $CONFIG_AGP
fi fi
...@@ -33,13 +33,6 @@ ...@@ -33,13 +33,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#ifndef spin_trylock_bh
#define spin_trylock_bh(lock) ({ int __r; local_bh_disable(); \
__r = spin_trylock(lock); \
if (!__r) local_bh_enable(); \
__r; })
#endif
#define PPP_VERSION "2.4.1" #define PPP_VERSION "2.4.1"
#define OBUFSIZE 256 #define OBUFSIZE 256
...@@ -76,6 +69,7 @@ struct asyncppp { ...@@ -76,6 +69,7 @@ struct asyncppp {
/* Bit numbers in xmit_flags */ /* Bit numbers in xmit_flags */
#define XMIT_WAKEUP 0 #define XMIT_WAKEUP 0
#define XMIT_FULL 1 #define XMIT_FULL 1
#define XMIT_BUSY 2
/* State bits */ /* State bits */
#define SC_TOSS 0x20000000 #define SC_TOSS 0x20000000
...@@ -181,18 +175,14 @@ ppp_asynctty_close(struct tty_struct *tty) ...@@ -181,18 +175,14 @@ ppp_asynctty_close(struct tty_struct *tty)
} }
/* /*
* Read does nothing. * Read does nothing - no data is ever available this way.
* Pppd reads and writes packets via /dev/ppp instead.
*/ */
static ssize_t static ssize_t
ppp_asynctty_read(struct tty_struct *tty, struct file *file, ppp_asynctty_read(struct tty_struct *tty, struct file *file,
unsigned char *buf, size_t count) unsigned char *buf, size_t count)
{ {
/* For now, do the same as the old 2.3.x code useta */ return -EAGAIN;
struct asyncppp *ap = tty->disc_data;
if (ap == 0)
return -ENXIO;
return ppp_channel_read(&ap->chan, file, buf, count);
} }
/* /*
...@@ -203,12 +193,7 @@ static ssize_t ...@@ -203,12 +193,7 @@ static ssize_t
ppp_asynctty_write(struct tty_struct *tty, struct file *file, ppp_asynctty_write(struct tty_struct *tty, struct file *file,
const unsigned char *buf, size_t count) const unsigned char *buf, size_t count)
{ {
/* For now, do the same as the old 2.3.x code useta */ return -EAGAIN;
struct asyncppp *ap = tty->disc_data;
if (ap == 0)
return -ENXIO;
return ppp_channel_write(&ap->chan, buf, count);
} }
static int static int
...@@ -259,25 +244,6 @@ ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file, ...@@ -259,25 +244,6 @@ ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
err = 0; err = 0;
break; break;
/*
* For now, do the same as the old 2.3 driver useta
*/
case PPPIOCGFLAGS:
case PPPIOCSFLAGS:
case PPPIOCGASYNCMAP:
case PPPIOCSASYNCMAP:
case PPPIOCGRASYNCMAP:
case PPPIOCSRASYNCMAP:
case PPPIOCGXASYNCMAP:
case PPPIOCSXASYNCMAP:
case PPPIOCGMRU:
case PPPIOCSMRU:
err = -EPERM;
if (!capable(CAP_NET_ADMIN))
break;
err = ppp_async_ioctl(&ap->chan, cmd, arg);
break;
case PPPIOCATTACH: case PPPIOCATTACH:
case PPPIOCDETACH: case PPPIOCDETACH:
err = ppp_channel_ioctl(&ap->chan, cmd, arg); err = ppp_channel_ioctl(&ap->chan, cmd, arg);
...@@ -294,18 +260,7 @@ ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file, ...@@ -294,18 +260,7 @@ ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
static unsigned int static unsigned int
ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait) ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
{ {
unsigned int mask; return 0;
struct asyncppp *ap = tty->disc_data;
mask = POLLOUT | POLLWRNORM;
/*
* For now, do the same as the old 2.3 driver useta
*/
if (ap != 0)
mask |= ppp_channel_poll(&ap->chan, file, wait);
if (test_bit(TTY_OTHER_CLOSED, &tty->flags) || tty_hung_up_p(file))
mask |= POLLHUP;
return mask;
} }
static int static int
...@@ -637,8 +592,18 @@ ppp_async_push(struct asyncppp *ap) ...@@ -637,8 +592,18 @@ ppp_async_push(struct asyncppp *ap)
int tty_stuffed = 0; int tty_stuffed = 0;
set_bit(XMIT_WAKEUP, &ap->xmit_flags); set_bit(XMIT_WAKEUP, &ap->xmit_flags);
if (!spin_trylock_bh(&ap->xmit_lock)) /*
* We can get called recursively here if the tty write
* function calls our wakeup function. This can happen
* for example on a pty with both the master and slave
* set to PPP line discipline.
* We use the XMIT_BUSY bit to detect this and get out,
* leaving the XMIT_WAKEUP bit set to tell the other
* instance that it may now be able to write more now.
*/
if (test_and_set_bit(XMIT_BUSY, &ap->xmit_flags))
return 0; return 0;
spin_lock_bh(&ap->xmit_lock);
for (;;) { for (;;) {
if (test_and_clear_bit(XMIT_WAKEUP, &ap->xmit_flags)) if (test_and_clear_bit(XMIT_WAKEUP, &ap->xmit_flags))
tty_stuffed = 0; tty_stuffed = 0;
...@@ -653,7 +618,7 @@ ppp_async_push(struct asyncppp *ap) ...@@ -653,7 +618,7 @@ ppp_async_push(struct asyncppp *ap)
tty_stuffed = 1; tty_stuffed = 1;
continue; continue;
} }
if (ap->optr == ap->olim && ap->tpkt != 0) { if (ap->optr >= ap->olim && ap->tpkt != 0) {
if (ppp_async_encode(ap)) { if (ppp_async_encode(ap)) {
/* finished processing ap->tpkt */ /* finished processing ap->tpkt */
clear_bit(XMIT_FULL, &ap->xmit_flags); clear_bit(XMIT_FULL, &ap->xmit_flags);
...@@ -661,17 +626,29 @@ ppp_async_push(struct asyncppp *ap) ...@@ -661,17 +626,29 @@ ppp_async_push(struct asyncppp *ap)
} }
continue; continue;
} }
/* haven't made any progress */ /*
spin_unlock_bh(&ap->xmit_lock); * We haven't made any progress this time around.
* Clear XMIT_BUSY to let other callers in, but
* after doing so we have to check if anyone set
* XMIT_WAKEUP since we last checked it. If they
* did, we should try again to set XMIT_BUSY and go
* around again in case XMIT_BUSY was still set when
* the other caller tried.
*/
clear_bit(XMIT_BUSY, &ap->xmit_flags);
/* any more work to do? if not, exit the loop */
if (!(test_bit(XMIT_WAKEUP, &ap->xmit_flags) if (!(test_bit(XMIT_WAKEUP, &ap->xmit_flags)
|| (!tty_stuffed && ap->tpkt != 0))) || (!tty_stuffed && ap->tpkt != 0)))
break; break;
if (!spin_trylock_bh(&ap->xmit_lock)) /* more work to do, see if we can do it now */
if (test_and_set_bit(XMIT_BUSY, &ap->xmit_flags))
break; break;
} }
spin_unlock_bh(&ap->xmit_lock);
return done; return done;
flush: flush:
clear_bit(XMIT_BUSY, &ap->xmit_flags);
if (ap->tpkt != 0) { if (ap->tpkt != 0) {
kfree_skb(ap->tpkt); kfree_skb(ap->tpkt);
ap->tpkt = 0; ap->tpkt = 0;
......
...@@ -8,6 +8,8 @@ bool 'Quota support' CONFIG_QUOTA ...@@ -8,6 +8,8 @@ bool 'Quota support' CONFIG_QUOTA
tristate 'Kernel automounter support' CONFIG_AUTOFS_FS tristate 'Kernel automounter support' CONFIG_AUTOFS_FS
tristate 'Kernel automounter version 4 support (also supports v3)' CONFIG_AUTOFS4_FS tristate 'Kernel automounter version 4 support (also supports v3)' CONFIG_AUTOFS4_FS
dep_tristate 'Reiserfs support' CONFIG_REISERFS_FS $CONFIG_EXPERIMENTAL
dep_mbool ' Have reiserfs do extra internal checking' CONFIG_REISERFS_CHECK $CONFIG_REISERFS_FS $CONFIG_EXPERIMENTAL
dep_tristate 'ADFS file system support' CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL dep_tristate 'ADFS file system support' CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL
dep_mbool ' ADFS write support (DANGEROUS)' CONFIG_ADFS_FS_RW $CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL dep_mbool ' ADFS write support (DANGEROUS)' CONFIG_ADFS_FS_RW $CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL
......
...@@ -58,6 +58,7 @@ subdir-$(CONFIG_UDF_FS) += udf ...@@ -58,6 +58,7 @@ subdir-$(CONFIG_UDF_FS) += udf
subdir-$(CONFIG_AUTOFS_FS) += autofs subdir-$(CONFIG_AUTOFS_FS) += autofs
subdir-$(CONFIG_AUTOFS4_FS) += autofs4 subdir-$(CONFIG_AUTOFS4_FS) += autofs4
subdir-$(CONFIG_ADFS_FS) += adfs subdir-$(CONFIG_ADFS_FS) += adfs
subdir-$(CONFIG_REISERFS_FS) += reiserfs
subdir-$(CONFIG_DEVPTS_FS) += devpts subdir-$(CONFIG_DEVPTS_FS) += devpts
subdir-$(CONFIG_SUN_OPENPROMFS) += openpromfs subdir-$(CONFIG_SUN_OPENPROMFS) += openpromfs
......
...@@ -834,6 +834,10 @@ static void end_buffer_io_async(struct buffer_head * bh, int uptodate) ...@@ -834,6 +834,10 @@ static void end_buffer_io_async(struct buffer_head * bh, int uptodate)
return; return;
} }
void set_buffer_async_io(struct buffer_head *bh) {
bh->b_end_io = end_buffer_io_async ;
}
/* /*
* Synchronise all the inode's dirty buffers to the disk. * Synchronise all the inode's dirty buffers to the disk.
* *
...@@ -2411,6 +2415,7 @@ int try_to_free_buffers(struct page * page, int wait) ...@@ -2411,6 +2415,7 @@ int try_to_free_buffers(struct page * page, int wait)
loop = 1; loop = 1;
goto cleaned_buffers_try_again; goto cleaned_buffers_try_again;
} }
wakeup_bdflush(0);
} }
return 0; return 0;
} }
......
...@@ -134,8 +134,12 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) ...@@ -134,8 +134,12 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
void __mark_inode_dirty(struct inode *inode, int flags) void __mark_inode_dirty(struct inode *inode, int flags)
{ {
struct super_block * sb = inode->i_sb; struct super_block * sb = inode->i_sb;
if (sb) { if (sb) {
/* Don't do this for I_DIRTY_PAGES - that doesn't actually dirty the inode itself */
if (flags & (I_DIRTY | I_DIRTY_SYNC)) {
if (sb->s_op && sb->s_op->dirty_inode)
sb->s_op->dirty_inode(inode);
}
spin_lock(&inode_lock); spin_lock(&inode_lock);
if ((inode->i_state & flags) != flags) { if ((inode->i_state & flags) != flags) {
inode->i_state |= flags; inode->i_state |= flags;
...@@ -676,7 +680,17 @@ static struct inode * get_new_inode(struct super_block *sb, unsigned long ino, s ...@@ -676,7 +680,17 @@ static struct inode * get_new_inode(struct super_block *sb, unsigned long ino, s
spin_unlock(&inode_lock); spin_unlock(&inode_lock);
clean_inode(inode); clean_inode(inode);
sb->s_op->read_inode(inode);
/* reiserfs specific hack right here. We don't
** want this to last, and are looking for VFS changes
** that will allow us to get rid of it.
** -- mason@suse.com
*/
if (sb->s_op->read_inode2) {
sb->s_op->read_inode2(inode, opaque) ;
} else {
sb->s_op->read_inode(inode);
}
/* /*
* This is special! We do not need the spinlock * This is special! We do not need the spinlock
......
#
# Makefile for the linux reiser-filesystem routines.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definitions are now in the main makefile...
O_TARGET := reiserfs.o
obj-y := bitmap.o do_balan.o namei.o inode.o file.o dir.o fix_node.o super.o prints.o objectid.o \
lbalance.o ibalance.o stree.o hashes.o buffer2.o tail_conversion.o journal.o resize.o tail_conversion.o version.o item_ops.o ioctl.o
obj-m := $(O_TARGET)
include $(TOPDIR)/Rules.make
TAGS:
etags *.c
[LICENSING]
ReiserFS is hereby licensed under the GNU General
Public License version 2.
Source code files that contain the phrase "licensing governed by
reiserfs/README" are "governed files" throughout this file. Governed
files are licensed under the GPL. The portions of them owned by Hans
Reiser, or authorized to be licensed by him, have been in the past,
and likely will be in the future, licensed to other parties under
other licenses. If you add your code to governed files, and don't
want it to be owned by Hans Reiser, put your copyright label on that
code so the poor blight and his customers can keep things straight.
All portions of governed files not labeled otherwise are owned by Hans
Reiser, and by adding your code to it, widely distributing it to
others or sending us a patch, and leaving the sentence in stating that
licensing is governed by the statement in this file, you accept this.
It will be a kindness if you identify whether Hans Reiser is allowed
to license code labeled as owned by you on your behalf other than
under the GPL, because he wants to know if it is okay to do so and put
a check in the mail to you (for non-trivial improvements) when he
makes his next sale. He makes no guarantees as to the amount if any,
though he feels motivated to motivate contributors, and you can surely
discuss this with him before or after contributing. You have the
right to decline to allow him to license your code contribution other
than under the GPL.
Further licensing options are available for commercial and/or other
interests directly from Hans Reiser: hans@reiser.to. If you interpret
the GPL as not allowing those additional licensing options, you read
it wrongly, and Richard Stallman agrees with me, when carefully read
you can see that those restrictions on additional terms do not apply
to the owner of the copyright, and my interpretation of this shall
govern for this license.
Finally, nothing in this license shall be interpreted to allow you to
fail to fairly credit me, or to remove my credits, without my
permission, unless you are an end user not redistributing to others.
If you have doubts about how to properly do that, or about what is
fair, ask. (Last I spoke with him Richard was contemplating how best
to address the fair crediting issue in the next GPL version.)
[END LICENSING]
Reiserfs is a file system based on balanced tree algorithms, which is
described at http://devlinux.com/namesys.
Stop reading here. Go there, then return.
Send bug reports to yura@namesys.botik.ru.
mkreiserfs and other utilities are in reiserfs/utils, or wherever your
Linux provider put them. There is some disagreement about how useful
it is for users to get their fsck and mkreiserfs out of sync with the
version of reiserfs that is in their kernel, with many important
distributors wanting them out of sync.:-) Please try to remember to
recompile and reinstall fsck and mkreiserfs with every update of
reiserfs, this is a common source of confusion. Note that some of the
utilities cannot be compiled without accessing the balancing code
which is in the kernel code, and relocating the utilities may require
you to specify where that code can be found.
Yes, if you update your reiserfs kernel module you do have to
recompile your kernel, most of the time. The errors you get will be
quite cryptic if your forget to do so.
Real users, as opposed to folks who want to hack and then understand
what went wrong, will want REISERFS_CHECK off.
Hideous Commercial Pitch: Spread your development costs across other OS
vendors. Select from the best in the world, not the best in your
building, by buying from third party OS component suppliers. Leverage
the software component development power of the internet. Be the most
aggressive in taking advantage of the commercial possibilities of
decentralized internet development, and add value through your branded
integration that you sell as an operating system. Let your competitors
be the ones to compete against the entire internet by themselves. Be
hip, get with the new economic trend, before your competitors do. Send
email to hans@reiser.to.
To understand the code, after reading the website, start reading the
code by reading reiserfs_fs.h first.
Hans Reiser was the project initiator, primary architect, source of all
funding for the first 5.5 years, and one of the programmers. He owns
the copyright.
Vladimir Saveljev was one of the programmers, and he worked long hours
writing the cleanest code. He always made the effort to be the best he
could be, and to make his code the best that it could be. What resulted
was quite remarkable. I don't think that money can ever motivate someone
to work the way he did, he is one of the most selfless men I know.
Yura helps with benchmarking, coding hashes, and block pre-allocation
code.
Anatoly Pinchuk is a former member of our team who worked closely with
Vladimir throughout the project's development. He wrote a quite
substantial portion of the total code. He realized that there was a
space problem with packing tails of files for files larger than a node
that start on a node aligned boundary (there are reasons to want to node
align files), and he invented and implemented indirect items and
unformatted nodes as the solution.
Konstantin Shvachko, with the help of the Russian version of a VC,
tried to put me in a position where I was forced into giving control
of the project to him. (Fortunately, as the person paying the money
for all salaries from my dayjob I owned all copyrights, and you can't
really force takeovers of sole proprietorships.) This was something
curious, because he never really understood the value of our project,
why we should do what we do, or why innovation was possible in
general, but he was sure that he ought to be controlling it. Every
innovation had to be forced past him while he was with us. He added
two years to the time required to complete reiserfs, and was a net
loss for me. Mikhail Gilula was a brilliant innovator who also left
in a destructive way that erased the value of his contributions, and
that he was shown much generosity just makes it more painful.
Grigory Zaigralin was an extremely effective system administrator for
our group.
Igor Krasheninnikov was wonderful at hardware procurement, repair, and
network installation.
Jeremy Fitzhardinge wrote the teahash.c code, and he gives credit to a
textbook he got the algorithm from in the code. Note that his analysis
of how we could use the hashing code in making 32 bit NFS cookies work
was probably more important than the actual algorithm. Colin Plumb also
contributed to it.
Chris Mason dived right into our code, and in just a few months produced
the journaling code that dramatically increased the value of ReiserFS.
He is just an amazing programmer.
Igor Zagorovsky is writing much of the new item handler and extent code
for our next major release.
Alexander Zarochentcev (sometimes known as zam, or sasha), wrote the
resizer, and is hard at work on implementing allocate on flush. SGI
implemented allocate on flush before us for XFS, and generously took
the time to convince me we should do it also. They are great people,
and a great company.
Yuri Shevchuk and Nikita Danilov are doing squid cache optimization.
Vitaly Fertman is doing fsck.
SuSE, IntegratedLinux.com, Ecila, MP3.com, bigstorage.com, and the
Alpha PC Company made it possible for me to not have a day job
anymore, and to dramatically increase our staffing. Ecila funded
hypertext feature development, MP3.com funded journaling, SuSE funded
core development, IntegratedLinux.com funded squid web cache
appliances, bigstorage.com funded HSM, and the alpha PC company funded
the alpha port. Many of these tasks were helped by sponsors other
than the ones just named. SuSE has helped in much more than just
funding....
This diff is collapsed.
This diff is collapsed.
/*
* Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
*/
#ifdef __KERNEL__
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/reiserfs_fs.h>
#include <linux/stat.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#else
#include "nokernel.h"
#endif
extern struct key MIN_KEY;
static int reiserfs_readdir (struct file *, void *, filldir_t);
int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) ;
struct file_operations reiserfs_dir_operations = {
read: generic_read_dir,
readdir: reiserfs_readdir,
fsync: reiserfs_dir_fsync,
};
/*
* directories can handle most operations...
*/
struct inode_operations reiserfs_dir_inode_operations = {
//&reiserfs_dir_operations, /* default_file_ops */
create: reiserfs_create,
lookup: reiserfs_lookup,
link: reiserfs_link,
unlink: reiserfs_unlink,
symlink: reiserfs_symlink,
mkdir: reiserfs_mkdir,
rmdir: reiserfs_rmdir,
mknod: reiserfs_mknod,
rename: reiserfs_rename,
};
int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) {
int ret = 0 ;
int windex ;
struct reiserfs_transaction_handle th ;
journal_begin(&th, dentry->d_inode->i_sb, 1) ;
windex = push_journal_writer("dir_fsync") ;
reiserfs_prepare_for_journal(th.t_super, SB_BUFFER_WITH_SB(th.t_super), 1) ;
journal_mark_dirty(&th, dentry->d_inode->i_sb, SB_BUFFER_WITH_SB (dentry->d_inode->i_sb)) ;
pop_journal_writer(windex) ;
journal_end_sync(&th, dentry->d_inode->i_sb, 1) ;
return ret ;
}
#define store_ih(where,what) copy_item_head (where, what)
//
static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldir)
{
struct inode *inode = filp->f_dentry->d_inode;
struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */
INITIALIZE_PATH (path_to_entry);
struct buffer_head * bh;
int item_num, entry_num;
struct key * rkey;
struct item_head * ih, tmp_ih;
int search_res;
char * local_buf;
loff_t next_pos;
char small_buf[32] ; /* avoid kmalloc if we can */
struct reiserfs_dir_entry de;
reiserfs_check_lock_depth("readdir") ;
/* form key for search the next directory entry using f_pos field of
file structure */
make_cpu_key (&pos_key, inode, (filp->f_pos) ? (filp->f_pos) : DOT_OFFSET,
TYPE_DIRENTRY, 3);
next_pos = cpu_key_k_offset (&pos_key);
/* reiserfs_warning ("reiserfs_readdir 1: f_pos = %Ld\n", filp->f_pos);*/
while (1) {
research:
/* search the directory item, containing entry with specified key */
search_res = search_by_entry_key (inode->i_sb, &pos_key, &path_to_entry, &de);
if (search_res == IO_ERROR) {
// FIXME: we could just skip part of directory which could
// not be read
return -EIO;
}
entry_num = de.de_entry_num;
bh = de.de_bh;
item_num = de.de_item_num;
ih = de.de_ih;
store_ih (&tmp_ih, ih);
#ifdef CONFIG_REISERFS_CHECK
/* we must have found item, that is item of this directory, */
if (COMP_SHORT_KEYS (&(ih->ih_key), &pos_key))
reiserfs_panic (inode->i_sb, "vs-9000: reiserfs_readdir: "
"found item %h does not match to dir we readdir %k",
ih, &pos_key);
if (item_num > B_NR_ITEMS (bh) - 1)
reiserfs_panic (inode->i_sb, "vs-9005: reiserfs_readdir: "
"item_num == %d, item amount == %d",
item_num, B_NR_ITEMS (bh));
/* and entry must be not more than number of entries in the item */
if (I_ENTRY_COUNT (ih) < entry_num)
reiserfs_panic (inode->i_sb, "vs-9010: reiserfs_readdir: "
"entry number is too big %d (%d)",
entry_num, I_ENTRY_COUNT (ih));
#endif /* CONFIG_REISERFS_CHECK */
if (search_res == POSITION_FOUND || entry_num < I_ENTRY_COUNT (ih)) {
/* go through all entries in the directory item beginning from the entry, that has been found */
struct reiserfs_de_head * deh = B_I_DEH (bh, ih) + entry_num;
for (; entry_num < I_ENTRY_COUNT (ih); entry_num ++, deh ++) {
int d_reclen;
char * d_name;
off_t d_off;
ino_t d_ino;
if (!de_visible (deh))
/* it is hidden entry */
continue;
d_reclen = entry_length (bh, ih, entry_num);
d_name = B_I_DEH_ENTRY_FILE_NAME (bh, ih, deh);
if (!d_name[d_reclen - 1])
d_reclen = strlen (d_name);
d_off = deh_offset (deh);
filp->f_pos = d_off ;
d_ino = deh_objectid (deh);
if (d_reclen <= 32) {
local_buf = small_buf ;
} else {
local_buf = kmalloc(d_reclen, GFP_BUFFER) ;
if (!local_buf) {
pathrelse (&path_to_entry);
return -ENOMEM ;
}
if (item_moved (&tmp_ih, &path_to_entry)) {
kfree(local_buf) ;
goto research;
}
}
// Note, that we copy name to user space via temporary
// buffer (local_buf) because filldir will block if
// user space buffer is swapped out. At that time
// entry can move to somewhere else
memcpy (local_buf, d_name, d_reclen);
if (filldir (dirent, d_name, d_reclen, d_off, d_ino,
DT_UNKNOWN) < 0) {
if (local_buf != small_buf) {
kfree(local_buf) ;
}
goto end;
}
if (local_buf != small_buf) {
kfree(local_buf) ;
}
// next entry should be looked for with such offset
next_pos = deh_offset (deh) + 1;
if (item_moved (&tmp_ih, &path_to_entry)) {
reiserfs_warning ("vs-9020: reiserfs_readdir "
"things are moving under hands. Researching..\n");
goto research;
}
} /* for */
}
if (item_num != B_NR_ITEMS (bh) - 1)
// end of directory has been reached
goto end;
/* item we went through is last item of node. Using right
delimiting key check is it directory end */
rkey = get_rkey (&path_to_entry, inode->i_sb);
if (! comp_le_keys (rkey, &MIN_KEY)) {
#ifdef CONFIG_REISERFS_CHECK
reiserfs_warning ("vs-9025: reiserfs_readdir:"
"get_rkey failed. Researching..\n");
#endif
/* set pos_key to key, that is the smallest and greater
that key of the last entry in the item */
set_cpu_key_k_offset (&pos_key, next_pos);
continue;
}
if ( COMP_SHORT_KEYS (rkey, &pos_key)) {
// end of directory has been reached
goto end;
}
/* directory continues in the right neighboring block */
set_cpu_key_k_offset (&pos_key, le_key_k_offset (ITEM_VERSION_1, rkey));
} /* while */
end:
// FIXME: ext2_readdir does not reset f_pos
filp->f_pos = next_pos;
pathrelse (&path_to_entry);
reiserfs_check_path(&path_to_entry) ;
return 0;
}
This diff is collapsed.
/*
* Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
*/
#ifdef __KERNEL__
#include <linux/sched.h>
#include <linux/reiserfs_fs.h>
#include <linux/smp_lock.h>
#else
#include "nokernel.h"
#endif
/*
** We pack the tails of files on file close, not at the time they are written.
** This implies an unnecessary copy of the tail and an unnecessary indirect item
** insertion/balancing, for files that are written in one write.
** It avoids unnecessary tail packings (balances) for files that are written in
** multiple writes and are small enough to have tails.
**
** file_release is called by the VFS layer when the file is closed. If
** this is the last open file descriptor, and the file
** small enough to have a tail, and the tail is currently in an
** unformatted node, the tail is converted back into a direct item.
**
** We use reiserfs_truncate_file to pack the tail, since it already has
** all the conditions coded.
*/
static int reiserfs_file_release (struct inode * inode, struct file * filp)
{
struct reiserfs_transaction_handle th ;
int windex ;
if (!S_ISREG (inode->i_mode))
BUG ();
/* fast out for when nothing needs to be done */
if ((atomic_read(&inode->i_count) > 1 ||
!inode->u.reiserfs_i.i_pack_on_close ||
!tail_has_to_be_packed(inode)) &&
inode->u.reiserfs_i.i_prealloc_count <= 0) {
return 0;
}
lock_kernel() ;
down (&inode->i_sem);
journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
#ifdef REISERFS_PREALLOCATE
reiserfs_discard_prealloc (&th, inode);
#endif
journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
if (atomic_read(&inode->i_count) <= 1 &&
inode->u.reiserfs_i.i_pack_on_close &&
tail_has_to_be_packed (inode)) {
/* if regular file is released by last holder and it has been
appended (we append by unformatted node only) or its direct
item(s) had to be converted, then it may have to be
indirect2direct converted */
windex = push_journal_writer("file_release") ;
reiserfs_truncate_file(inode) ;
pop_journal_writer(windex) ;
}
up (&inode->i_sem);
unlock_kernel() ;
return 0;
}
/* Sync a reiserfs file. */
static int reiserfs_sync_file(
struct file * p_s_filp,
struct dentry * p_s_dentry,
int datasync
) {
struct inode * p_s_inode = p_s_dentry->d_inode;
struct reiserfs_transaction_handle th ;
int n_err = 0;
int windex ;
int jbegin_count = 1 ;
lock_kernel() ;
if (!S_ISREG(p_s_inode->i_mode))
BUG ();
n_err = fsync_inode_buffers(p_s_inode) ;
/* commit the current transaction to flush any metadata
** changes. sys_fsync takes care of flushing the dirty pages for us
*/
journal_begin(&th, p_s_inode->i_sb, jbegin_count) ;
windex = push_journal_writer("sync_file") ;
reiserfs_update_sd(&th, p_s_inode);
pop_journal_writer(windex) ;
journal_end_sync(&th, p_s_inode->i_sb,jbegin_count) ;
unlock_kernel() ;
return ( n_err < 0 ) ? -EIO : 0;
}
struct file_operations reiserfs_file_operations = {
read: generic_file_read,
write: generic_file_write,
ioctl: reiserfs_ioctl,
mmap: generic_file_mmap,
release: reiserfs_file_release,
fsync: reiserfs_sync_file,
};
struct inode_operations reiserfs_file_inode_operations = {
truncate: reiserfs_truncate_file,
};
This diff is collapsed.
/*
* Keyed 32-bit hash function using TEA in a Davis-Meyer function
* H0 = Key
* Hi = E Mi(Hi-1) + Hi-1
*
* (see Applied Cryptography, 2nd edition, p448).
*
* Jeremy Fitzhardinge <jeremy@zip.com.au> 1998
*
* Jeremy has agreed to the contents of reiserfs/README. -Hans
* Yura's function is added (04/07/2000)
*/
//
// keyed_hash
// yura_hash
// r5_hash
//
#include <asm/types.h>
#define DELTA 0x9E3779B9
#define FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */
#define PARTROUNDS 6 /* 6 gets complete mixing */
#ifndef __KERNEL__
typedef __u32 u32;
#endif
/* a, b, c, d - data; h0, h1 - accumulated hash */
#define TEACORE(rounds) \
do { \
u32 sum = 0; \
int n = rounds; \
u32 b0, b1; \
\
b0 = h0; \
b1 = h1; \
\
do \
{ \
sum += DELTA; \
b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b); \
b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d); \
} while(--n); \
\
h0 += b0; \
h1 += b1; \
} while(0)
u32 keyed_hash(const char *msg, int len)
{
u32 k[] = { 0x9464a485, 0x542e1a94, 0x3e846bff, 0xb75bcfc3};
u32 h0 = k[0], h1 = k[1];
u32 a, b, c, d;
u32 pad;
int i;
// assert(len >= 0 && len < 256);
pad = (u32)len | ((u32)len << 8);
pad |= pad << 16;
while(len >= 16)
{
a = (u32)msg[ 0] |
(u32)msg[ 1] << 8 |
(u32)msg[ 2] << 16|
(u32)msg[ 3] << 24;
b = (u32)msg[ 4] |
(u32)msg[ 5] << 8 |
(u32)msg[ 6] << 16|
(u32)msg[ 7] << 24;
c = (u32)msg[ 8] |
(u32)msg[ 9] << 8 |
(u32)msg[10] << 16|
(u32)msg[11] << 24;
d = (u32)msg[12] |
(u32)msg[13] << 8 |
(u32)msg[14] << 16|
(u32)msg[15] << 24;
TEACORE(PARTROUNDS);
len -= 16;
msg += 16;
}
if (len >= 12)
{
//assert(len < 16);
if (len >= 16)
*(int *)0 = 0;
a = (u32)msg[ 0] |
(u32)msg[ 1] << 8 |
(u32)msg[ 2] << 16|
(u32)msg[ 3] << 24;
b = (u32)msg[ 4] |
(u32)msg[ 5] << 8 |
(u32)msg[ 6] << 16|
(u32)msg[ 7] << 24;
c = (u32)msg[ 8] |
(u32)msg[ 9] << 8 |
(u32)msg[10] << 16|
(u32)msg[11] << 24;
d = pad;
for(i = 12; i < len; i++)
{
d <<= 8;
d |= msg[i];
}
}
else if (len >= 8)
{
//assert(len < 12);
if (len >= 12)
*(int *)0 = 0;
a = (u32)msg[ 0] |
(u32)msg[ 1] << 8 |
(u32)msg[ 2] << 16|
(u32)msg[ 3] << 24;
b = (u32)msg[ 4] |
(u32)msg[ 5] << 8 |
(u32)msg[ 6] << 16|
(u32)msg[ 7] << 24;
c = d = pad;
for(i = 8; i < len; i++)
{
c <<= 8;
c |= msg[i];
}
}
else if (len >= 4)
{
//assert(len < 8);
if (len >= 8)
*(int *)0 = 0;
a = (u32)msg[ 0] |
(u32)msg[ 1] << 8 |
(u32)msg[ 2] << 16|
(u32)msg[ 3] << 24;
b = c = d = pad;
for(i = 4; i < len; i++)
{
b <<= 8;
b |= msg[i];
}
}
else
{
//assert(len < 4);
if (len >= 4)
*(int *)0 = 0;
a = b = c = d = pad;
for(i = 0; i < len; i++)
{
a <<= 8;
a |= msg[i];
}
}
TEACORE(FULLROUNDS);
/* return 0;*/
return h0^h1;
}
/* What follows in this file is copyright 2000 by Hans Reiser, and the
* licensing of what follows is governed by reiserfs/README */
u32 yura_hash (const char *msg, int len)
{
int j, pow;
u32 a, c;
int i;
for (pow=1,i=1; i < len; i++) pow = pow * 10;
if (len == 1)
a = msg[0]-48;
else
a = (msg[0] - 48) * pow;
for (i=1; i < len; i++) {
c = msg[i] - 48;
for (pow=1,j=i; j < len-1; j++) pow = pow * 10;
a = a + c * pow;
}
for (; i < 40; i++) {
c = '0' - 48;
for (pow=1,j=i; j < len-1; j++) pow = pow * 10;
a = a + c * pow;
}
for (; i < 256; i++) {
c = i;
for (pow=1,j=i; j < len-1; j++) pow = pow * 10;
a = a + c * pow;
}
a = a << 7;
return a;
}
u32 r5_hash (const char *msg, int len)
{
u32 a=0;
while(*msg) {
a += *msg << 4;
a += *msg >> 4;
a *= 11;
msg++;
}
return a;
}
This diff is collapsed.
This diff is collapsed.
/*
* Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
*/
#ifdef __KERNEL__
#include <linux/fs.h>
#include <linux/reiserfs_fs.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
#include <linux/smp_lock.h>
#include <linux/locks.h>
#else
#include "nokernel.h"
#endif
/*
** reiserfs_ioctl - handler for ioctl for inode
** supported commands:
** 1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect
** and prevent packing file (argument arg has to be non-zero)
** 2) That's all for a while ...
*/
int reiserfs_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
unsigned long arg)
{
switch (cmd) {
case REISERFS_IOC_UNPACK:
if (arg)
return reiserfs_unpack (inode, filp);
default:
return -ENOTTY;
}
}
/*
** reiserfs_unpack
** Function try to convert tail from direct item into indirect.
** It set up nopack attribute in the inode.u.reiserfs_i.nopack
*/
int reiserfs_unpack (struct inode * inode, struct file * filp)
{
int retval = 0;
int index ;
struct page *page ;
unsigned long write_from ;
unsigned long blocksize = inode->i_sb->s_blocksize ;
if (inode->i_size == 0) {
return -EINVAL ;
}
/* ioctl already done */
if (inode->u.reiserfs_i.nopack) {
return 0 ;
}
lock_kernel();
/* we need to make sure nobody is changing the file size beneath
** us
*/
down(&inode->i_sem) ;
write_from = inode->i_size & (blocksize - 1) ;
/* if we are on a block boundary, we are already unpacked. */
if ( write_from == 0) {
inode->u.reiserfs_i.nopack = 1;
goto out ;
}
/* we unpack by finding the page with the tail, and calling
** reiserfs_prepare_write on that page. This will force a
** reiserfs_get_block to unpack the tail for us.
*/
index = inode->i_size >> PAGE_CACHE_SHIFT ;
page = grab_cache_page(inode->i_mapping, index) ;
retval = PTR_ERR(page) ;
if (IS_ERR(page)) {
goto out ;
}
retval = reiserfs_prepare_write(NULL, page, write_from, blocksize) ;
if (retval)
goto out_unlock ;
/* conversion can change page contents, must flush */
flush_dcache_page(page) ;
inode->u.reiserfs_i.nopack = 1;
kunmap(page) ; /* mapped by prepare_write */
out_unlock:
UnlockPage(page) ;
page_cache_release(page) ;
out:
up(&inode->i_sem) ;
unlock_kernel();
return retval;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
*/
char *reiserfs_get_version_string(void) {
return "ReiserFS version 3.6.25" ;
}
...@@ -139,4 +139,6 @@ ...@@ -139,4 +139,6 @@
#define ENOMEDIUM 129 /* No medium found */ #define ENOMEDIUM 129 /* No medium found */
#define EMEDIUMTYPE 130 /* Wrong medium type */ #define EMEDIUMTYPE 130 /* Wrong medium type */
#define EHASHCOLLISION 131 /* Number of hash collisons exceeds maximum generation counter value. */
#endif #endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment