Author: pluto Date: Wed Jun 22 15:31:40 2005 GMT Module: SOURCES Tag: LINUX_2_6 ---- Log message: - extracted from 2.6.12-mm1.
---- Files affected: SOURCES: reiser4-2.6.12-mm1.patch (NONE -> 1.1.2.1) (NEW) ---- Diffs: ================================================================ Index: SOURCES/reiser4-2.6.12-mm1.patch diff -u /dev/null SOURCES/reiser4-2.6.12-mm1.patch:1.1.2.1 --- /dev/null Wed Jun 22 17:31:40 2005 +++ SOURCES/reiser4-2.6.12-mm1.patch Wed Jun 22 17:31:34 2005 @@ -0,0 +1,88736 @@ +applied patches: + +reiser4-sb_sync_inodes.patch +reiser4-sb_sync_inodes-cleanup.patch +reiser4-truncate_inode_pages_range.patch +reiser4-export-remove_from_page_cache.patch +reiser4-export-page_cache_readahead.patch +reiser4-reget-page-mapping.patch +reiser4-rcu-barrier.patch +reiser4-rcu-barrier-license-fix.patch +reiser4-export-pagevec-funcs.patch +reiser4-export-radix_tree_preload.patch +reiser4-export-find_get_pages.patch +reiser4-radix_tree_lookup_slot.patch +reiser4-include-reiser4.patch +reiser4-doc.patch +reiser4-only.patch +reiser4-mm-remove-pg_highmem-fix.patch +reiser4-kconfig-help-cleanup.patch +reiser4-update.patch + +diff -uNr a/Documentation/Changes b/Documentation/Changes +--- a/Documentation/Changes 2005-06-17 21:48:29.000000000 +0200 ++++ b/Documentation/Changes 2005-06-22 17:16:26.000000000 +0200 +@@ -56,6 +56,7 @@ + o e2fsprogs 1.29 # tune2fs + o jfsutils 1.1.3 # fsck.jfs -V + o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs ++o reiser4progs 1.0.0 # fsck.reiser4 -V + o xfsprogs 2.6.0 # xfs_db -V + o pcmcia-cs 3.1.21 # cardmgr -V + o quota-tools 3.09 # quota -V +@@ -177,6 +178,13 @@ + versions of mkreiserfs, resize_reiserfs, debugreiserfs and + reiserfsck. These utils work on both i386 and alpha platforms. + ++Reiser4progs ++------------ ++ ++The reiser4progs package contains utilities for the reiser4 file system. ++Detailed instructions are provided in the README file located at: ++<ftp://ftp.namesys.com/pub/reiser4progs/README>. ++ + Xfsprogs + -------- + +@@ -345,6 +353,10 @@ + ------------- + o <http://www.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.6.3.tar.gz> + ++Reiser4progs ++------------ ++o <ftp://ftp.namesys.com/pub/reiser4progs/> ++ + Xfsprogs + -------- + o <ftp://oss.sgi.com/projects/xfs/download/> +diff -uNr a/Documentation/filesystems/reiser4.txt b/Documentation/filesystems/reiser4.txt +--- a/Documentation/filesystems/reiser4.txt 1970-01-01 01:00:00.000000000 +0100 ++++ b/Documentation/filesystems/reiser4.txt 2005-06-22 17:16:26.000000000 +0200 +@@ -0,0 +1,75 @@ ++Reiser4 filesystem ++================== ++Reiser4 is a file system based on dancing tree algorithms, and is ++described at http://www.namesys.com ++ ++ ++References ++========== ++web page http://namesys.com/v4/v4.html ++source code and ++userland tools http://thebsh.namesys.com/snapshots/LATEST ++ ++ ++Compile options ++=============== ++Enable reiser4 debug mode ++ This checks everything imaginable while reiser4 ++ runs ++ ++Mount options ++============= ++tmgr.atom_max_size=N ++ Atoms containing more than N blocks will be forced to commit. ++ N is decimal. ++ Default is nr_free_pagecache_pages() / 2 at mount time. ++ ++tmgr.atom_max_age=N ++ Atoms older than N seconds will be forced to commit. N is decimal. ++ Default is 600. ++ ++tmgr.atom_max_flushers=N ++ Limit of concurrent flushers for one atom. 0 means no limit. ++ Default is 0. ++ ++tree.cbk_cache.nr_slots=N ++ Number of slots in the cbk cache. ++ ++flush.relocate_threshold=N ++ If flush finds more than N adjacent dirty leaf-level blocks it ++ will force them to be relocated. ++ Default is 64. ++ ++flush.relocate_distance=N ++ If flush finds can find a block allocation closer than at most ++ N from the preceder it will relocate to that position. ++ Default is 64. ++ ++flush.scan_maxnodes=N ++ The maximum number of nodes to scan left on a level during ++ flush. ++ Default is 10000. ++ ++optimal_io_size=N ++ Preferred IO size. This value is used to set st_blksize of ++ struct stat. ++ Default is 65536. ++ ++bsdgroups ++ Turn on BSD-style gid assignment. ++ ++32bittimes ++ By default file in reiser4 have 64 bit timestamps. Files ++ created when filesystem is mounted with 32bittimes mount ++ option will get 32 bit timestamps. ++ ++mtflush ++ Turn off concurrent flushing. ++ ++nopseudo ++ Disable pseudo files support. See ++ http://namesys.com/v4/pseudo.html for more about pseudo files. ++ ++dont_load_bitmap ++ Don't load all bitmap blocks at mount time, it is useful for ++ machines with tiny RAM and large disks. +diff -uNr a/fs/fs-writeback.c b/fs/fs-writeback.c +--- a/fs/fs-writeback.c 2005-06-17 21:48:29.000000000 +0200 ++++ b/fs/fs-writeback.c 2005-06-22 17:21:11.000000000 +0200 +@@ -283,8 +283,6 @@ + * WB_SYNC_HOLD is a hack for sys_sync(): reattach the inode to sb->s_dirty so + * that it can be located for waiting on in __writeback_single_inode(). + * +- * Called under inode_lock. +- * + * If `bdi' is non-zero then we're being asked to writeback a specific queue. + * This function assumes that the blockdev superblock's inodes are backed by + * a variety of queues, so all inodes are searched. For other superblocks, +@@ -300,11 +298,13 @@ + * on the writer throttling path, and we get decent balancing between many + * throttled threads: we don't want them all piling up on __wait_on_inode. + */ +-static void +-sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) ++void ++generic_sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) + { + const unsigned long start = jiffies; /* livelock avoidance */ + ++ spin_lock(&inode_lock); ++ + if (!wbc->for_kupdate || list_empty(&sb->s_io)) + list_splice_init(&sb->s_dirty, &sb->s_io); + +@@ -384,8 +384,19 @@ + if (wbc->nr_to_write <= 0) + break; + } ++ spin_unlock(&inode_lock); + return; /* Leave any unwritten inodes on s_io */ + } ++EXPORT_SYMBOL(generic_sync_sb_inodes); ++ ++static void ++sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) ++{ ++ if (sb->s_op->sync_inodes) ++ sb->s_op->sync_inodes(sb, wbc); ++ else ++ generic_sync_sb_inodes(sb, wbc); ++} + + /* + * Start writeback of dirty pagecache data against all unlocked inodes. +@@ -426,11 +437,8 @@ + * be unmounted by the time it is released. + */ + if (down_read_trylock(&sb->s_umount)) { +- if (sb->s_root) { +- spin_lock(&inode_lock); ++ if (sb->s_root) + sync_sb_inodes(sb, wbc); +- spin_unlock(&inode_lock); +- } + up_read(&sb->s_umount); + } + spin_lock(&sb_lock); +@@ -466,9 +474,7 @@ + (inodes_stat.nr_inodes - inodes_stat.nr_unused) + + nr_dirty + nr_unstable; + wbc.nr_to_write += wbc.nr_to_write / 2; /* Bit more for luck */ +- spin_lock(&inode_lock); + sync_sb_inodes(sb, &wbc); +- spin_unlock(&inode_lock); + } + + /* +diff -uNr a/fs/Kconfig b/fs/Kconfig +--- a/fs/Kconfig 2005-06-17 21:48:29.000000000 +0200 ++++ b/fs/Kconfig 2005-06-22 17:17:36.000000000 +0200 +@@ -160,6 +160,8 @@ + default y if EXT2_FS=y || EXT3_FS=y + default m if EXT2_FS=m || EXT3_FS=m + ++source "fs/reiser4/Kconfig" ++ + config REISERFS_FS + tristate "Reiserfs support" + help +diff -uNr a/fs/Makefile b/fs/Makefile +--- a/fs/Makefile 2005-06-17 21:48:29.000000000 +0200 ++++ b/fs/Makefile 2005-06-22 17:17:36.000000000 +0200 +@@ -48,6 +48,7 @@ + + # Do not add any filesystems before this line + obj-$(CONFIG_REISERFS_FS) += reiserfs/ ++obj-$(CONFIG_REISER4_FS) += reiser4/ + obj-$(CONFIG_EXT3_FS) += ext3/ # Before ext2 so root fs can be ext3 + obj-$(CONFIG_JBD) += jbd/ + obj-$(CONFIG_EXT2_FS) += ext2/ +diff -uNr a/fs/reiser4/as_ops.c b/fs/reiser4/as_ops.c +--- a/fs/reiser4/as_ops.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/fs/reiser4/as_ops.c 2005-06-22 17:21:39.000000000 +0200 +@@ -0,0 +1,645 @@ ++/* Copyright 2003 by Hans Reiser, licensing governed by reiser4/README */ ++ ++/* Interface to VFS. Reiser4 address_space_operations are defined here. */ ++ ++#include "forward.h" ++#include "debug.h" ++#include "dformat.h" ++#include "coord.h" ++#include "plugin/item/item.h" ++#include "plugin/file/file.h" ++#include "plugin/security/perm.h" ++#include "plugin/disk_format/disk_format.h" ++#include "plugin/plugin.h" ++#include "plugin/plugin_set.h" ++#include "plugin/object.h" ++#include "txnmgr.h" ++#include "jnode.h" ++#include "znode.h" ++#include "block_alloc.h" ++#include "tree.h" ++#include "vfs_ops.h" ++#include "inode.h" ++#include "page_cache.h" ++#include "ktxnmgrd.h" ++#include "super.h" ++#include "reiser4.h" ++#include "entd.h" ++#include "emergency_flush.h" ++ ++#include <linux/profile.h> ++#include <linux/types.h> ++#include <linux/mount.h> ++#include <linux/vfs.h> ++#include <linux/mm.h> ++#include <linux/buffer_head.h> ++#include <linux/dcache.h> ++#include <linux/list.h> ++#include <linux/pagemap.h> ++#include <linux/slab.h> ++#include <linux/seq_file.h> ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/writeback.h> ++#include <linux/backing-dev.h> ++#include <linux/quotaops.h> ++#include <linux/security.h> ++ ++/* address space operations */ ++ ++static int reiser4_readpage(struct file *, struct page *); ++ ++static int reiser4_prepare_write(struct file *, ++ struct page *, unsigned, unsigned); ++ ++static int reiser4_commit_write(struct file *, ++ struct page *, unsigned, unsigned); ++ ++static int reiser4_set_page_dirty (struct page *); ++static sector_t reiser4_bmap(struct address_space *, sector_t); ++/* static int reiser4_direct_IO(int, struct inode *, ++ struct kiobuf *, unsigned long, int); */ ++ ++/* address space operations */ ++ ++/* clear PAGECACHE_TAG_DIRTY tag of a page. This is used in uncapture_page. This resembles test_clear_page_dirty. The ++ only difference is that page's mapping exists and REISER4_MOVED tag is checked */ ++reiser4_internal void ++reiser4_clear_page_dirty(struct page *page) ++{ ++ struct address_space *mapping; ++ unsigned long flags; ++ ++ mapping = page->mapping; ++ BUG_ON(mapping == NULL); ++ ++ read_lock_irqsave(&mapping->tree_lock, flags); ++ if (TestClearPageDirty(page)) { ++ read_unlock_irqrestore(&mapping->tree_lock, flags); ++ if (mapping_cap_account_dirty(mapping)) ++ dec_page_state(nr_dirty); ++ return; ++ } ++ read_unlock_irqrestore(&mapping->tree_lock, flags); ++} ++ ++/* as_ops->set_page_dirty() VFS method in reiser4_address_space_operations. ++ ++ It is used by others (except reiser4) to set reiser4 pages dirty. Reiser4 ++ itself uses set_page_dirty_internal(). ++ ++ The difference is that reiser4_set_page_dirty sets MOVED tag on the page and clears DIRTY tag. Pages tagged as MOVED ++ get processed by reiser4_writepages() to do reiser4 specific work over dirty pages (allocation jnode, capturing, atom ++ creation) which cannot be done in the contexts where reiser4_set_page_dirty is called. ++ set_page_dirty_internal sets DIRTY tag and clear MOVED ++*/ ++static int reiser4_set_page_dirty(struct page *page /* page to mark dirty */) ++{ ++ /* this page can be unformatted only */ ++ assert("vs-1734", (page->mapping && ++ page->mapping->host && ++ get_super_fake(page->mapping->host->i_sb) != page->mapping->host && ++ get_cc_fake(page->mapping->host->i_sb) != page->mapping->host && ++ get_super_private(page->mapping->host->i_sb)->bitmap != page->mapping->host)); ++ ++ if (!TestSetPageDirty(page)) { ++ struct address_space *mapping = page->mapping; ++ ++ if (mapping) { ++ read_lock_irq(&mapping->tree_lock); ++ /* check for race with truncate */ ++ if (page->mapping) { ++ assert("vs-1652", page->mapping == mapping); ++ if (mapping_cap_account_dirty(mapping)) ++ inc_page_state(nr_dirty); ++ radix_tree_tag_set(&mapping->page_tree, ++ page->index, PAGECACHE_TAG_REISER4_MOVED); ++ } ++ read_unlock_irq(&mapping->tree_lock); ++ __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); ++ } ++ } ++ return 0; ++} ++ ++/* ->readpage() VFS method in reiser4 address_space_operations ++ method serving file mmapping ++*/ ++static int ++reiser4_readpage(struct file *f /* file to read from */ , ++ struct page *page /* page where to read data ++ * into */ ) ++{ ++ struct inode *inode; ++ file_plugin *fplug; ++ int result; ++ reiser4_context ctx; ++ ++ /* ++ * basically calls ->readpage method of object plugin and handles ++ * errors. ++ */ ++ ++ assert("umka-078", f != NULL); ++ assert("umka-079", page != NULL); ++ assert("nikita-2280", PageLocked(page)); ++ assert("vs-976", !PageUptodate(page)); ++ ++ assert("vs-318", page->mapping && page->mapping->host); ++ assert("nikita-1352", (f == NULL) || (f->f_dentry->d_inode == page->mapping->host)); ++ ++ /* ->readpage can be called from page fault service routine */ ++ assert("nikita-3174", schedulable()); ++ ++ inode = page->mapping->host; ++ init_context(&ctx, inode->i_sb); ++ fplug = inode_file_plugin(inode); ++ if (fplug->readpage != NULL) ++ result = fplug->readpage(f, page); ++ else ++ result = RETERR(-EINVAL); ++ ++ reiser4_exit_context(&ctx); ++ return result; ++} ++ ++static int filler(void *vp, struct page *page) ++{ ++ return reiser4_readpage(vp, page); ++} ++ ++/* ->readpages() VFS method in reiser4 address_space_operations ++ method serving page cache readahead ++ ++ if readpages hook is set in file data - it is called ++ otherwise read_cache_pages is used ++*/ ++static int ++reiser4_readpages(struct file *file, struct address_space *mapping, ++ struct list_head *pages, unsigned nr_pages) ++{ ++ reiser4_context ctx; ++ reiser4_file_fsdata *fsdata; ++ ++ init_context(&ctx, mapping->host->i_sb); ++ fsdata = reiser4_get_file_fsdata(file); ++ if (IS_ERR(fsdata)) { ++ reiser4_exit_context(&ctx); ++ return PTR_ERR(fsdata); ++ } ++ ++ if (fsdata->ra2.readpages) ++ fsdata->ra2.readpages(mapping, pages, fsdata->ra2.data); ++ else { ++ assert("vs-1738", lock_stack_isclean(get_current_lock_stack())); ++ read_cache_pages(mapping, pages, filler, file); ++ } ++ reiser4_exit_context(&ctx); ++ return 0; ++} ++ ++/* prepares @page to be written. This means, that if we want to modify only some ++ part of page, page should be read first and than modified. Actually this function ++ almost the same as reiser4_readpage(). The differentce is only that, it does not ++ unlock the page in the case of error. This is needed because loop back device ++ driver expects it locked. */ ++static int reiser4_prepare_write(struct file *file, struct page *page, ++ unsigned from, unsigned to) ++{ ++ int result; ++ file_plugin * fplug; ++ struct inode * inode; ++ reiser4_context ctx; ++ ++ inode = page->mapping->host; ++ init_context(&ctx, inode->i_sb); ++ fplug = inode_file_plugin(inode); ++ ++ if (fplug->prepare_write != NULL) ++ result = fplug->prepare_write(file, page, from, to); ++ else ++ result = RETERR(-EINVAL); ++ ++ /* don't commit transaction under inode semaphore */ ++ context_set_commit_async(&ctx); ++ reiser4_exit_context(&ctx); ++ ++ return result; ++} ++ ++/* captures jnode of @page to current atom. */ ++static int reiser4_commit_write(struct file *file, struct page *page, ++ unsigned from, unsigned to) ++{ ++ int result; ++ file_plugin *fplug; ++ struct inode *inode; ++ reiser4_context ctx; ++ ++ assert("umka-3101", file != NULL); ++ assert("umka-3102", page != NULL); ++ assert("umka-3093", PageLocked(page)); ++ ++ SetPageUptodate(page); ++ ++ inode = page->mapping->host; ++ init_context(&ctx, inode->i_sb); ++ fplug = inode_file_plugin(inode); ++ ++ if (fplug->capturepage) ++ result = fplug->capturepage(page); ++ else ++ result = RETERR(-EINVAL); ++ ++ /* here page is return locked. */ ++ assert("umka-3103", PageLocked(page)); ++ ++ /* don't commit transaction under inode semaphore */ ++ context_set_commit_async(&ctx); ++ reiser4_exit_context(&ctx); ++ return result; ++} ++ ++/* ->writepages() ++ ->vm_writeback() ++ ->set_page_dirty() ++ ->prepare_write() ++ ->commit_write() ++*/ ++ ++/* ->bmap() VFS method in reiser4 address_space_operations */ ++reiser4_internal int ++reiser4_lblock_to_blocknr(struct address_space *mapping, ++ sector_t lblock, reiser4_block_nr *blocknr) ++{ ++ file_plugin *fplug; ++ int result; ++ reiser4_context ctx; ++ ++ init_context(&ctx, mapping->host->i_sb); ++ ++ fplug = inode_file_plugin(mapping->host); ++ if (fplug && fplug->get_block) { ++ *blocknr = generic_block_bmap(mapping, lblock, fplug->get_block); ++ result = 0; ++ } else ++ result = RETERR(-EINVAL); ++ reiser4_exit_context(&ctx); ++ return result; ++} ++ ++/* ->bmap() VFS method in reiser4 address_space_operations */ ++static sector_t ++reiser4_bmap(struct address_space *mapping, sector_t lblock) ++{ ++ reiser4_block_nr blocknr; ++ int result; ++ ++ result = reiser4_lblock_to_blocknr(mapping, lblock, &blocknr); ++ if (result == 0) ++ if (sizeof blocknr == sizeof(sector_t) || ++ !blocknr_is_fake(&blocknr)) ++ return blocknr; ++ else ++ return 0; ++ else ++ return result; ++} ++ ++/* ->invalidatepage method for reiser4 */ ++ ++/* ++ * this is called for each truncated page from ++ * truncate_inode_pages()->truncate_{complete,partial}_page(). ++ * ++ * At the moment of call, page is under lock, and outstanding io (if any) has ++ * completed. ++ */ ++ ++reiser4_internal int ++reiser4_invalidatepage(struct page *page /* page to invalidate */, ++ unsigned long offset /* starting offset for partial ++ * invalidation */) ++{ ++ int ret = 0; ++ reiser4_context ctx; ++ struct inode *inode; ++ ++ /* ++ * This is called to truncate file's page. ++ * ++ * Originally, reiser4 implemented truncate in a standard way ++ * (vmtruncate() calls ->invalidatepage() on all truncated pages ++ * first, then file system ->truncate() call-back is invoked). ++ * ++ * This lead to the problem when ->invalidatepage() was called on a ++ * page with jnode that was captured into atom in ASTAGE_PRE_COMMIT ++ * process. That is, truncate was bypassing transactions. To avoid ++ * this, try_capture_page_to_invalidate() call was added here. ++ * ++ * After many troubles with vmtruncate() based truncate (including ++ * races with flush, tail conversion, etc.) it was re-written in the ++ * top-to-bottom style: items are killed in cut_tree_object() and ++ * pages belonging to extent are invalidated in kill_hook_extent(). So ++ * probably now additional call to capture is not needed here. ++ * ++ */ ++ ++ assert("nikita-3137", PageLocked(page)); ++ assert("nikita-3138", !PageWriteback(page)); ++ inode = page->mapping->host; ++ ++ /* ++ * ->invalidatepage() should only be called for the unformatted ++ * jnodes. Destruction of all other types of jnodes is performed ++ * separately. But, during some corner cases (like handling errors ++ * during mount) it is simpler to let ->invalidatepage to be called on ++ * them. Check for this, and do nothing. <<Diff was trimmed, longer than 597 lines>> _______________________________________________ pld-cvs-commit mailing list [email protected] http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit
