This is reiser4 update for 2.6.12-rc2-mm3
fs/reiser4/plugin/compress/compress.h | 2
fs/reiser4/plugin/plugin.h | 1
fs/reiser4/status_flags.c | 1
fs/reiser4/txnmgr.c | 2
fs/reiser4/vfs_ops.c | 2
diff -puN fs/reiser4/plugin/compress/compress.c~reiser4-crc-update-1.900 fs/reiser4/plugin/compress/compress.c
fs/reiser4/as_ops.c | 6 --
fs/reiser4/cluster.h | 16 ++---
fs/reiser4/flush.c | 14 +---
fs/reiser4/plugin/compress/compress.c | 5 +
fs/reiser4/plugin/compress/compress.h | 2
fs/reiser4/plugin/compress/minilzo.c | 10 ---
fs/reiser4/plugin/cryptcompress.c | 89 ++++++++++++++++++------------
fs/reiser4/plugin/cryptcompress.h | 13 +++-
fs/reiser4/plugin/file/file.c | 75 ++++++++++++-------------
fs/reiser4/plugin/file/file.h | 4 +
fs/reiser4/plugin/file/tail_conversion.c | 13 ++++
fs/reiser4/plugin/item/ctail.c | 32 +++++-----
fs/reiser4/plugin/item/extent_file_ops.c | 40 +++++++++----
fs/reiser4/plugin/item/extent_flush_ops.c | 14 ++++
fs/reiser4/plugin/item/tail.c | 26 ++++++--
fs/reiser4/plugin/plugin.h | 1
fs/reiser4/plugin/space/bitmap.c | 8 +-
fs/reiser4/status_flags.c | 1
fs/reiser4/super.h | 4 +
fs/reiser4/tree_walk.c | 4 -
fs/reiser4/txnmgr.c | 8 +-
fs/reiser4/vfs_ops.c | 8 +-
22 files changed, 239 insertions(+), 154 deletions(-)
diff -puN fs/reiser4/cluster.h~reiser4-update-2 fs/reiser4/cluster.h
--- linux-2.6.12-rc2-mm3/fs/reiser4/cluster.h~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/cluster.h 2005-04-29 15:12:56.000000000 +0400
@@ -26,34 +26,34 @@ static inline int inode_cluster_shift (s
}
static inline unsigned
-page_cluster_shift(struct inode * inode)
+cluster_nrpages_shift(struct inode * inode)
{
- return inode_cluster_shift(inode) + PAGE_CACHE_SHIFT;
+ return inode_cluster_shift(inode) - PAGE_CACHE_SHIFT;
}
/* cluster size in page units */
static inline unsigned cluster_nrpages (struct inode * inode)
{
- return (1U << inode_cluster_shift(inode));
+ return 1U << cluster_nrpages_shift(inode);
}
static inline size_t inode_cluster_size (struct inode * inode)
{
assert("edward-96", inode != NULL);
- return (PAGE_CACHE_SIZE << inode_cluster_shift(inode));
+ return 1U << inode_cluster_shift(inode);
}
static inline unsigned long
pg_to_clust(unsigned long idx, struct inode * inode)
{
- return idx >> inode_cluster_shift(inode);
+ return idx >> cluster_nrpages_shift(inode);
}
static inline unsigned long
clust_to_pg(unsigned long idx, struct inode * inode)
{
- return idx << inode_cluster_shift(inode);
+ return idx << cluster_nrpages_shift(inode);
}
static inline unsigned long
@@ -103,14 +103,14 @@ count_to_nrpages(loff_t count)
static inline unsigned long
count_to_nrclust(loff_t count, struct inode * inode)
{
- return count_to_nr(count, page_cluster_shift(inode));
+ return count_to_nr(count, inode_cluster_shift(inode));
}
/* number of clusters occupied by @count pages */
static inline cloff_t
pgcount_to_nrclust(pgoff_t count, struct inode * inode)
{
- return count_to_nr(count, inode_cluster_shift(inode));
+ return count_to_nr(count, cluster_nrpages_shift(inode));
}
static inline loff_t
diff -puN fs/reiser4/flush.c~reiser4-update-2 fs/reiser4/flush.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/flush.c~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/flush.c 2005-04-29 15:12:56.000000000 +0400
@@ -440,9 +440,6 @@ assert("nikita-3435", \
ON_DEBUG(atomic_t flush_cnt;)
-/* FIXME: remove me */#define FLUSH_CHECKS_CONGESTION 1
-
-#if defined (FLUSH_CHECKS_CONGESTION)
/* check fs backing device for write congestion */
static int check_write_congestion (void)
{
@@ -453,10 +450,9 @@ static int check_write_congestion (void)
bdi = get_super_fake(sb)->i_mapping->backing_dev_info;
return bdi_write_congested(bdi);
}
-#endif /* FLUSH_CHECKS_CONGESTION */
/* conditionally write flush queue */
-static int write_prepped_nodes (flush_pos_t * pos, int check_congestion)
+static int write_prepped_nodes (flush_pos_t * pos)
{
int ret;
@@ -466,10 +462,8 @@ static int write_prepped_nodes (flush_po
if (!(pos->flags & JNODE_FLUSH_WRITE_BLOCKS))
return 0;
-#if defined (FLUSH_CHECKS_CONGESTION)
- if (check_congestion && check_write_congestion())
+ if (check_write_congestion())
return 0;
-#endif /* FLUSH_CHECKS_CONGESTION */
ret = write_fq(pos->fq, pos->nr_written,
WRITEOUT_SINGLE_STREAM | WRITEOUT_FOR_PAGE_RECLAIM);
@@ -889,7 +883,7 @@ static int rapid_flush (flush_pos_t * po
if (!wbq_available())
return 0;
- return write_prepped_nodes(pos, 1);
+ return write_prepped_nodes(pos);
}
#else
@@ -1483,7 +1477,7 @@ out:
int ret1;
/* NOTE: seems like io is done under long term locks. */
- ret1 = write_prepped_nodes(pos, 1);
+ ret1 = write_prepped_nodes(pos);
if (ret1 < 0)
return ret1;
}
diff -puN fs/reiser4/plugin/compress/compress.c~reiser4-update-2 fs/reiser4/plugin/compress/compress.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/plugin/compress/compress.c~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/plugin/compress/compress.c 2005-04-29 15:12:56.000000000 +0400
@@ -372,6 +372,7 @@ compression_plugin compression_plugins[L
.alloc = NULL,
.free = NULL,
.min_tfm_size = NULL,
+ .checksum = NULL,
.compress = NULL,
.decompress = NULL}
,
@@ -391,6 +392,7 @@ compression_plugin compression_plugins[L
.alloc = lzo1_alloc,
.free = lzo1_free,
.min_tfm_size = lzo1_min_tfm_size,
+ .checksum = reiser4_adler32,
.compress = lzo1_compress,
.decompress = lzo1_decompress}
,
@@ -410,6 +412,7 @@ compression_plugin compression_plugins[L
.alloc = NULL,
.free = NULL,
.min_tfm_size = NULL,
+ .checksum = reiser4_adler32,
.compress = NULL,
.decompress = lzo1_decompress}
,
@@ -429,6 +432,7 @@ compression_plugin compression_plugins[L
.alloc = gzip1_alloc,
.free = gzip1_free,
.min_tfm_size = gzip1_min_tfm_size,
+ .checksum = NULL,
.compress = gzip1_compress,
.decompress = gzip1_decompress}
,
@@ -448,6 +452,7 @@ compression_plugin compression_plugins[L
.alloc = gzip1_nocompress_alloc,
.free = gzip1_nocompress_free,
.min_tfm_size = NULL,
+ .checksum = NULL,
.compress = NULL,
.decompress = gzip1_decompress}
};
diff -puN fs/reiser4/plugin/compress/compress.h~reiser4-update-2 fs/reiser4/plugin/compress/compress.h
--- linux-2.6.12-rc2-mm3/fs/reiser4/plugin/compress/compress.h~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/plugin/compress/compress.h 2005-04-29 15:12:56.000000000 +0400
@@ -23,6 +23,8 @@ typedef enum {
typedef void * coa_t;
typedef coa_t coa_set[LAST_COMPRESSION_ID];
+__u32 reiser4_adler32(char * data, __u32 len);
+
#endif /* __FS_REISER4_COMPRESS_H__ */
/* Make Linus happy.
diff -puN fs/reiser4/plugin/compress/minilzo.c~reiser4-update-2 fs/reiser4/plugin/compress/minilzo.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/plugin/compress/minilzo.c~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/plugin/compress/minilzo.c 2005-04-29 15:12:56.000000000 +0400
@@ -1110,16 +1110,6 @@ _lzo_config_check(void)
COMPILE_TIME_ASSERT(lzo_sizeof_dict_t == sizeof(lzo_dict_t));
-#if defined(__LZO_IN_MINLZO)
- if (r == 1)
- {
- lzo_uint32 adler;
- adler = lzo_adler32(0, NULL, 0);
- adler = lzo_adler32(adler, lzo_copyright(), 200);
- r &= __lzo_assert(adler == 0xc76f1751L);
- }
-#endif
-
if (r == 1)
{
r &= __lzo_assert(!schedule_insns_bug());
diff -puN fs/reiser4/plugin/cryptcompress.c~reiser4-update-2 fs/reiser4/plugin/cryptcompress.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/plugin/cryptcompress.c~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/plugin/cryptcompress.c 2005-04-29 19:10:38.000000000 +0400
@@ -98,7 +98,7 @@ crc_inode_ok(struct inode * inode)
reiser4_inode * info = reiser4_inode_data(inode);
cryptcompress_info_t * data = cryptcompress_inode_data(inode);
- if ((info->cluster_shift <= MAX_CLUSTER_SHIFT) &&
+ if (cluster_shift_ok(info->cluster_shift) &&
(data->tfm[CRYPTO_TFM] == NULL) &&
(data->tfm[DIGEST_TFM] == NULL))
return 1;
@@ -338,7 +338,7 @@ inode_invert_compression(struct inode *
assert("edward-1308", inode != NULL);
- result = force_plugin(inode,
+ result = force_plugin(inode,
PSET_COMPRESSION,
compression_plugin_to_plugin
(dual_compression(inode_compression_plugin(inode))));
@@ -386,12 +386,12 @@ inode_set_cluster(struct inode * object,
this is a necessary parameter for cryptcompress object */
warning("edward-418", "create_cryptcompress: default cluster size"
" (%u) was assigned for the object %llu\n",
- (1U << PAGE_CACHE_SHIFT << DEFAULT_CLUSTER_SHIFT),
+ (1U << DEFAULT_CLUSTER_SHIFT),
(unsigned long long)get_inode_oid(object));
init_default_cluster(&def);
data = &def;
}
- assert("edward-697", *data <= MAX_CLUSTER_SHIFT);
+ assert("edward-697", cluster_shift_ok(*data));
info->cluster_shift = *data;
info->extmask |= (1 << CLUSTER_STAT);
@@ -863,7 +863,7 @@ try_encrypt(struct inode * inode)
static int
save_compressed(int old_size, int new_size, struct inode * inode)
{
- return (new_size + DC_CHECKSUM_SIZE + max_crypto_overhead(inode) < old_size);
+ return (new_size + (int)DC_CHECKSUM_SIZE + max_crypto_overhead(inode) < old_size);
}
/* guess if the cluster was compressed */
@@ -882,11 +882,40 @@ need_decompression(reiser4_cluster_t * c
fsize_to_count(clust, inode));
}
-static void set_compression_magic(__u8 * magic)
+/* append checksum at the end of input transform stream
+ and increment its length */
+static void
+dc_set_checksum(compression_plugin * cplug, tfm_cluster_t * tc)
{
- /* FIXME-EDWARD: Use a checksum here */
- assert("edward-279", magic != NULL);
- memset(magic, 0, DC_CHECKSUM_SIZE);
+ __u32 checksum;
+
+ assert("edward-1309", tc != NULL);
+ assert("edward-1310", tc->len > 0);
+ assert("edward-1311", cplug->checksum != NULL);
+
+ checksum = cplug->checksum(tfm_stream_data(tc, OUTPUT_STREAM), tc->len);
+ cputod32(checksum, (d32 *)(tfm_stream_data(tc, OUTPUT_STREAM) + tc->len));
+ tc->len += (int)DC_CHECKSUM_SIZE;
+}
+
+/* returns 0 if checksums coincide, otherwise returns 1,
+ decremrnt the length of input transform stream */
+static int
+dc_check_checksum(compression_plugin * cplug, tfm_cluster_t * tc)
+{
+ assert("edward-1312", tc != NULL);
+ assert("edward-1313", tc->len > (int)DC_CHECKSUM_SIZE);
+ assert("edward-1314", cplug->checksum != NULL);
+
+ if (cplug->checksum(tfm_stream_data(tc, INPUT_STREAM), tc->len - (int)DC_CHECKSUM_SIZE) !=
+ d32tocpu((d32 *)(tfm_stream_data(tc, INPUT_STREAM) + tc->len - (int)DC_CHECKSUM_SIZE))) {
+ warning("edward-156", "bad disk cluster checksum %d, (should be %d)\n",
+ (int)d32tocpu((d32 *)(tfm_stream_data(tc, INPUT_STREAM) + tc->len - (int)DC_CHECKSUM_SIZE)),
+ (int)cplug->checksum(tfm_stream_data(tc, INPUT_STREAM), tc->len - (int)DC_CHECKSUM_SIZE));
+ return 1;
+ }
+ tc->len -= (int)DC_CHECKSUM_SIZE;
+ return 0;
}
reiser4_internal int
@@ -951,9 +980,8 @@ deflate_cluster(reiser4_cluster_t * clus
if (save_compressed(tc->len, dst_len, inode)) {
/* accept */
tc->len = dst_len;
-
- set_compression_magic(tfm_stream_data(tc, OUTPUT_STREAM) + tc->len);
- tc->len += DC_CHECKSUM_SIZE;
+ if (cplug->checksum != NULL)
+ dc_set_checksum(cplug, tc);
transformed = 1;
}
#if defined(SMART_COMPRESSION_MODE)
@@ -1020,7 +1048,6 @@ inflate_cluster(reiser4_cluster_t * clus
transformed = 1;
}
if (need_decompression(clust, inode, 0)) {
- __u8 magic[DC_CHECKSUM_SIZE];
unsigned dst_len = inode_cluster_size(inode);
compression_plugin * cplug = inode_compression_plugin(inode);
@@ -1033,12 +1060,12 @@ inflate_cluster(reiser4_cluster_t * clus
assert("edward-1305", cplug->decompress != NULL);
assert("edward-910", tfm_cluster_is_set(tc));
- /* Check compression magic for possible IO errors.
+ /* Check compression checksum for possible IO errors.
End-of-cluster format created before encryption:
data
- compression_magic (4) Indicates presence of compression
+ checksum (4) Indicates presence of compression
infrastructure, should be private.
Can be absent.
crypto_overhead Created by ->align() method of crypto-plugin,
@@ -1050,17 +1077,11 @@ inflate_cluster(reiser4_cluster_t * clus
tail_size (1) size of aligning tail,
1 <= tail_size <= blksize
*/
- set_compression_magic(magic);
-
- if (memcmp(tfm_stream_data(tc, INPUT_STREAM) + (tc->len - (size_t)DC_CHECKSUM_SIZE),
- magic, (size_t)DC_CHECKSUM_SIZE)) {
- printk("edward-156: wrong compression magic %d (should be %d)\n",
- *((int *)(tfm_stream_data(tc, INPUT_STREAM) + (tc->len - (size_t)DC_CHECKSUM_SIZE))), *((int *)magic));
- result = -EIO;
- return result;
+ if (cplug->checksum != NULL) {
+ result = dc_check_checksum(cplug, tc);
+ if (result)
+ return RETERR(-EIO);
}
- tc->len -= (size_t)DC_CHECKSUM_SIZE;
-
/* decompress cluster */
cplug->decompress(get_coa(tc, cplug->h.id),
tfm_stream_data(tc, INPUT_STREAM), tc->len,
@@ -1328,13 +1349,13 @@ try_capture_cluster(reiser4_cluster_t *
assert("edward-1033", clust->pages[0] != NULL);
node = jprivate(clust->pages[0]);
-
+
assert("edward-1035", node != NULL);
-
+
LOCK_JNODE(node);
if (clust->win)
inode_set_new_size(clust, inode);
-
+
result = try_capture(node, ZNODE_WRITE_LOCK, 0, 0);
if (result)
goto exit;
@@ -2183,8 +2204,10 @@ jnode_truncate_ok(struct inode *inode, c
{
jnode * node;
node = jlookup(current_tree, get_inode_oid(inode), clust_to_pg(index, inode));
- if (node)
+ if (node) {
+ warning("edward-1315", "jnode %p is untruncated\n", node);
jput(node);
+ }
return (node == NULL);
}
#endif
@@ -2362,7 +2385,7 @@ set_cluster_params(struct inode * inode,
assert("edward-197", clust != NULL);
assert("edward-1072", win != NULL);
assert("edward-198", inode != NULL);
- assert("edward-747", reiser4_inode_data(inode)->cluster_shift <= MAX_CLUSTER_SHIFT);
+ assert("edward-747", cluster_shift_ok(reiser4_inode_data(inode)->cluster_shift));
result = alloc_cluster_pgset(clust, cluster_nrpages(inode));
if (result)
@@ -2418,7 +2441,7 @@ write_cryptcompress_flow(struct file * f
assert("edward-161", schedulable());
assert("edward-748", crc_inode_ok(inode));
assert("edward-159", current_blocksize == PAGE_CACHE_SIZE);
- assert("edward-749", reiser4_inode_data(inode)->cluster_shift <= MAX_CLUSTER_SHIFT);
+ assert("edward-749", cluster_shift_ok(reiser4_inode_data(inode)->cluster_shift));
assert("edward-1274", get_current_context()->grabbed_blocks == 0);
result = check_cryptcompress(inode);
@@ -2674,7 +2697,7 @@ static void
set_append_cluster_key(const coord_t *coord, reiser4_key *key, struct inode *inode)
{
item_key_by_coord(coord, key);
- set_key_offset(key, ((__u64)(clust_by_coord(coord, inode)) + 1) << inode_cluster_shift(inode) << PAGE_CACHE_SHIFT);
+ set_key_offset(key, clust_to_off(clust_by_coord(coord, inode) + 1, inode));
}
/* If @index > 0, find real disk cluster of the index (@index - 1),
@@ -3286,7 +3309,7 @@ capture_cryptcompress(struct inode *inod
return 0;
info = cryptcompress_inode_data(inode);
- nrpages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+ nrpages = count_to_nrpages(i_size_read(inode));
if (wbc->sync_mode != WB_SYNC_ALL)
to_capture = min_count(wbc->nr_to_write, MAX_CLUSTERS_TO_CAPTURE(inode));
diff -puN fs/reiser4/plugin/cryptcompress.h~reiser4-update-2 fs/reiser4/plugin/cryptcompress.h
--- linux-2.6.12-rc2-mm3/fs/reiser4/plugin/cryptcompress.h~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/plugin/cryptcompress.h 2005-04-29 15:12:56.000000000 +0400
@@ -11,13 +11,22 @@
#include <linux/vmalloc.h>
#define MIN_CLUSTER_SIZE PAGE_CACHE_SIZE
-#define MAX_CLUSTER_SHIFT 4
-#define MAX_CLUSTER_NRPAGES (1 << MAX_CLUSTER_SHIFT)
+#define MIN_CLUSTER_SHIFT PAGE_CACHE_SHIFT
+#define MAX_CLUSTER_SHIFT 16
+#define MAX_CLUSTER_NRPAGES (1U << MAX_CLUSTER_SHIFT >> PAGE_CACHE_SHIFT)
#define DEFAULT_CLUSTER_SHIFT 0
#define DC_CHECKSUM_SIZE 4
#define MIN_CRYPTO_BLOCKSIZE 8
//#define LAZY_COMPRESSION_MODE
+#if REISER4_DEBUG
+static inline int
+cluster_shift_ok (int shift)
+{
+ return (shift >= MIN_CLUSTER_SHIFT) && (shift <= MAX_CLUSTER_SHIFT);
+}
+#endif
+
typedef unsigned long cloff_t;
/* Set of transform id's supported by reiser4,
diff -puN fs/reiser4/plugin/file/file.c~reiser4-update-2 fs/reiser4/plugin/file/file.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/plugin/file/file.c~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/plugin/file/file.c 2005-04-29 19:10:38.000000000 +0400
@@ -733,8 +733,10 @@ load_file_hint(struct file *file, hint_t
if (IS_ERR(fsdata))
return PTR_ERR(fsdata);
+ spin_lock_inode(file->f_dentry->d_inode);
if (seal_is_set(&fsdata->reg.hint.seal)) {
*hint = fsdata->reg.hint;
+ spin_unlock_inode(file->f_dentry->d_inode);
/* force re-validation of the coord on the first
* iteration of the read/write loop. */
hint->ext_coord.valid = 0;
@@ -743,6 +745,7 @@ load_file_hint(struct file *file, hint_t
return 0;
}
memset(&fsdata->reg.hint, 0, sizeof(hint_t));
+ spin_unlock_inode(file->f_dentry->d_inode);
}
hint_init_zero(hint);
return 0;
@@ -762,7 +765,10 @@ save_file_hint(struct file *file, const
assert("vs-965", !IS_ERR(fsdata));
assert("nikita-19891",
coords_equal(&hint->seal.coord1, &hint->ext_coord.coord));
+
+ spin_lock_inode(file->f_dentry->d_inode);
fsdata->reg.hint = *hint;
+ spin_unlock_inode(file->f_dentry->d_inode);
return;
}
@@ -1341,6 +1347,9 @@ capture_unix_file(struct inode *inode, s
* this function is out of reiser4 context and may safely
* sleep on semaphore.
*/
+ assert("", LOCK_CNT_NIL(inode_sem_w));
+ assert("", LOCK_CNT_NIL(inode_sem_r));
+#if 0
if (is_in_reiser4_context()) {
if (down_read_trylock(&uf_info->latch) == 0) {
/* ZAM-FIXME-HANS: please explain this error handling here, grep for
@@ -1348,6 +1357,7 @@ capture_unix_file(struct inode *inode, s
* represent busy loops that we should recode. Also tell me whether
* any of them fail to return EBUSY to user space, and if yes, then
* recode them to not use the EBUSY macro.*/
+ warning("", "does this ever happen?");
result = RETERR(-EBUSY);
reiser4_exit_context(&ctx);
break;
@@ -1355,7 +1365,9 @@ capture_unix_file(struct inode *inode, s
} else
down_read(&uf_info->latch);
LOCK_CNT_INC(inode_sem_r);
-
+#endif
+ txn_restart_current();
+ get_nonexclusive_access(uf_info, 0);
while (to_capture > 0) {
pgoff_t start;
@@ -1390,8 +1402,11 @@ capture_unix_file(struct inode *inode, s
/* there may be left more pages */
redirty_inode(inode);
+ drop_nonexclusive_access(uf_info);
+/*
up_read(&uf_info->latch);
LOCK_CNT_DEC(inode_sem_r);
+*/
if (result < 0) {
/* error happened */
reiser4_exit_context(&ctx);
@@ -1502,12 +1517,13 @@ readpage_unix_file(void *vp, struct page
if (result != CBK_COORD_FOUND) {
/* this indicates file corruption */
done_lh(&lh);
+ unlock_page(page);
return result;
}
if (PageUptodate(page)) {
done_lh(&lh);
- unlock_page(page);
+ unlock_page(page);
return 0;
}
@@ -1515,6 +1531,7 @@ readpage_unix_file(void *vp, struct page
result = zload(coord->node);
if (result) {
done_lh(&lh);
+ unlock_page(page);
return result;
}
@@ -1531,6 +1548,7 @@ readpage_unix_file(void *vp, struct page
zrelse(coord->node);
done_lh(&lh);
+ unlock_page(page);
return RETERR(-EIO);
}
@@ -1546,14 +1564,17 @@ readpage_unix_file(void *vp, struct page
set_key_offset(&key, (loff_t) (page->index + 1) << PAGE_CACHE_SHIFT);
/* FIXME should call set_hint() */
unset_hint(&hint);
- } else
+ } else {
+ unlock_page(page);
unset_hint(&hint);
+ }
zrelse(coord->node);
done_lh(&lh);
save_file_hint(file, &hint);
- assert("vs-979", ergo(result == 0, (PageLocked(page) || PageUptodate(page))));
+ assert("vs-979", ergo(result == 0, (PageLocked(page) || PageUptodate(page))));
+ assert("vs-9791", ergo(result != 0, !PageLocked(page)));
return result;
}
@@ -1631,7 +1652,7 @@ reiser4_put_user_pages(struct page **pag
/* this is called with nonexclusive access obtained, file's container can not change */
static size_t
-read_file(hint_t *hint, file_container_t container,
+read_file(hint_t *hint,
struct file *file, /* file to write to */
char *buf, /* address of user-space buffer */
size_t count, /* number of bytes to write */
@@ -1646,33 +1667,6 @@ read_file(hint_t *hint, file_container_t
inode = file->f_dentry->d_inode;
- /* we have nonexclusive access (NA) obtained. File's container may not
- change until we drop NA. If possible - calculate read function
- beforehand */
- switch(container) {
- case UF_CONTAINER_EXTENTS:
- read_f = item_plugin_by_id(EXTENT_POINTER_ID)->s.file.read;
- break;
-
- case UF_CONTAINER_TAILS:
- /* this is read-ahead for tails-only files */
- result = reiser4_file_readahead(file, *off, count);
- if (result)
- return result;
-
- read_f = item_plugin_by_id(FORMATTING_ID)->s.file.read;
- break;
-
- case UF_CONTAINER_UNKNOWN:
- read_f = 0;
- break;
-
- case UF_CONTAINER_EMPTY:
- default:
- warning("vs-1297", "File (ino %llu) has unexpected state: %d\n",
- (unsigned long long)get_inode_oid(inode), container);
- return RETERR(-EIO);
- }
/* build flow */
assert("vs-1250", inode_file_plugin(inode)->flow_by_inode == flow_by_inode_unix_file);
@@ -1704,9 +1698,9 @@ read_file(hint_t *hint, file_container_t
if (hint->ext_coord.valid == 0)
validate_extended_coord(&hint->ext_coord, get_key_offset(&flow.key));
+ assert("vs-4", hint->ext_coord.valid == 1);
/* call item's read method */
- if (!read_f)
- read_f = item_plugin_by_coord(coord)->s.file.read;
+ read_f = item_plugin_by_coord(coord)->s.file.read;
result = read_f(file, &flow, hint);
zrelse(loaded);
done_lh(hint->ext_coord.lh);
@@ -1807,7 +1801,7 @@ read_unix_file(struct file *file, char *
to_read = inode->i_size - *off;
assert("vs-1706", to_read <= left);
- read = read_file(&hint, uf_info->container, file, buf, to_read, off);
+ read = read_file(&hint, file, buf, to_read, off);
if (user_space)
reiser4_put_user_pages(pages, nr_pages);
@@ -2059,6 +2053,7 @@ mmap_unix_file(struct file *file, struct
inode = file->f_dentry->d_inode;
uf_info = unix_file_inode_data(inode);
+ down(&uf_info->write);
get_exclusive_access(uf_info);
if (!IS_RDONLY(inode) && (vma->vm_flags & (VM_MAYWRITE | VM_SHARED))) {
@@ -2067,12 +2062,14 @@ mmap_unix_file(struct file *file, struct
result = finish_conversion(inode);
if (result) {
drop_exclusive_access(uf_info);
+ up(&uf_info->write);
return result;
}
result = find_file_state(uf_info);
if (result != 0) {
drop_exclusive_access(uf_info);
+ up(&uf_info->write);
return result;
}
@@ -2084,6 +2081,7 @@ mmap_unix_file(struct file *file, struct
result = check_pages_unix_file(inode);
if (result) {
drop_exclusive_access(uf_info);
+ up(&uf_info->write);
return result;
}
}
@@ -2097,6 +2095,7 @@ mmap_unix_file(struct file *file, struct
}
drop_exclusive_access(uf_info);
+ up(&uf_info->write);
return result;
}
@@ -2299,9 +2298,9 @@ write_unix_file(struct file *file, /* fi
(unsigned long long)get_inode_oid(inode));
}
+ save_file_hint(file, &hint);
up(&uf_info->write);
current->backing_dev_info = 0;
- save_file_hint(file, &hint);
return count ? count : result;
}
@@ -2317,6 +2316,7 @@ release_unix_file(struct inode *object,
uf_info = unix_file_inode_data(object);
result = 0;
+ down(&uf_info->write);
get_exclusive_access(uf_info);
if (atomic_read(&file->f_dentry->d_count) == 1 &&
uf_info->container == UF_CONTAINER_EXTENTS &&
@@ -2329,6 +2329,7 @@ release_unix_file(struct inode *object,
}
}
drop_exclusive_access(uf_info);
+ up(&uf_info->write);
return 0;
}
@@ -2578,7 +2579,7 @@ init_inode_data_unix_file(struct inode *
init_inode_ordering(inode, crd, create);
}
-/* plugin->u.file.pre_delete
+/* plugin->u.file.pre_delete
We need this because generic_delete_inode calls truncate_inode_pages before
filesystem's delete_inode method. As result of this, reiser4 tree may have
diff -puN fs/reiser4/plugin/file/file.h~reiser4-update-2 fs/reiser4/plugin/file/file.h
--- linux-2.6.12-rc2-mm3/fs/reiser4/plugin/file/file.h~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/plugin/file/file.h 2005-04-29 15:12:56.000000000 +0400
@@ -85,6 +85,10 @@ typedef struct unix_file_info {
} unix_file_info_t;
struct unix_file_info *unix_file_inode_data(const struct inode * inode);
+void get_exclusive_access(unix_file_info_t *);
+void drop_exclusive_access(unix_file_info_t *);
+void get_nonexclusive_access(unix_file_info_t *, int);
+void drop_nonexclusive_access(unix_file_info_t *);
#include "../item/extent.h"
#include "../item/tail.h"
diff -puN fs/reiser4/plugin/file/tail_conversion.c~reiser4-update-2 fs/reiser4/plugin/file/tail_conversion.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/plugin/file/tail_conversion.c~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/plugin/file/tail_conversion.c 2005-04-29 15:12:56.000000000 +0400
@@ -32,6 +32,7 @@ get_exclusive_access(unix_file_info_t *u
BUG_ON(get_current_context()->trans->atom != NULL);
LOCK_CNT_INC(inode_sem_w);
down_write(&uf_info->latch);
+ uf_info->exclusive_use = 1;
assert("vs-1713", uf_info->ea_owner == NULL);
assert("vs-1713", atomic_read(&uf_info->nr_neas) == 0);
ON_DEBUG(uf_info->ea_owner = current);
@@ -43,6 +44,7 @@ drop_exclusive_access(unix_file_info_t *
assert("vs-1714", uf_info->ea_owner == current);
assert("vs-1715", atomic_read(&uf_info->nr_neas) == 0);
ON_DEBUG(uf_info->ea_owner = NULL);
+ uf_info->exclusive_use = 0;
up_write(&uf_info->latch);
assert("nikita-3049", LOCK_CNT_NIL(inode_sem_r));
assert("nikita-3049", LOCK_CNT_GTZ(inode_sem_w));
@@ -408,8 +410,19 @@ tail2extent(unix_file_info_t *uf_info)
release_all_pages(pages, sizeof_array(pages));
if (result)
goto error;
+ /* we have to drop exclusive access to avoid deadlock
+ * which may happen because called by
+ * reiser4_writepages capture_unix_file requires to get
+ * non-exclusive access to a file. It is safe to drop
+ * EA in the middle of tail2extent conversion because
+ * write_unix_file/unix_setattr(truncate)/release_unix_file(extent2tail)
+ * are serialized by uf_info->write semaphore and
+ * because read_unix_file works (should at least) on
+ * partially converted files */
+ drop_exclusive_access(uf_info);
/* throttle the conversion */
reiser4_throttle_write(inode);
+ get_exclusive_access(uf_info);
}
}
diff -puN fs/reiser4/plugin/item/ctail.c~reiser4-update-2 fs/reiser4/plugin/item/ctail.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/plugin/item/ctail.c~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/plugin/item/ctail.c 2005-04-29 19:10:38.000000000 +0400
@@ -54,11 +54,10 @@ cluster_shift_by_coord(const coord_t * c
}
static unsigned long
-pg_by_coord(const coord_t * coord)
+off_by_coord(const coord_t * coord)
{
reiser4_key key;
-
- return get_key_offset(item_key_by_coord(coord, &key)) >> PAGE_CACHE_SHIFT;
+ return get_key_offset(item_key_by_coord(coord, &key));
}
static int
@@ -88,7 +87,7 @@ clust_by_coord(const coord_t * coord, st
assert("edward-1237", !coord_is_unprepped_ctail(coord));
shift = cluster_shift_by_coord(coord);
}
- return pg_by_coord(coord) >> shift;
+ return off_by_coord(coord) >> shift;
}
static int unsigned long
@@ -100,7 +99,7 @@ disk_cluster_size (const coord_t * coord
is meaninless if ctail is unprepped */
assert("edward-1238", !coord_is_unprepped_ctail(coord));
- return PAGE_CACHE_SIZE << cluster_shift_by_coord(coord);
+ return 1 << cluster_shift_by_coord(coord);
}
/* true if the key is of first disk cluster item */
@@ -235,15 +234,18 @@ init_ctail(coord_t * to /* coord of item
return 0;
}
+/* plugin->u.item.b.lookup:
+ NULL: We are looking for item keys only */
+
+#if REISER4_DEBUG
reiser4_internal int
ctail_ok (const coord_t *coord)
{
return coord_is_unprepped_ctail(coord) ||
- (cluster_shift_by_coord(coord) <= MAX_CLUSTER_SHIFT);
+ cluster_shift_ok(cluster_shift_by_coord(coord));
}
-/* plugin->u.item.b.lookup:
- NULL: We are looking for item keys only */
+/* plugin->u.item.b.check */
reiser4_internal int
check_ctail (const coord_t * coord, const char **error)
{
@@ -254,9 +256,7 @@ check_ctail (const coord_t * coord, cons
}
return 0;
}
-
-/* plugin->u.item.b.check */
-
+#endif
/* plugin->u.item.b.paste */
reiser4_internal int
@@ -860,7 +860,7 @@ reiser4_internal reiser4_key *
append_key_ctail(const coord_t *coord, reiser4_key *key)
{
assert("edward-1241", item_id_by_coord(coord) == CTAIL_ID);
- assert("edward-1242", cluster_shift_by_coord(coord) <= MAX_CLUSTER_SHIFT);
+ assert("edward-1242", cluster_shift_ok(cluster_shift_by_coord(coord)));
item_key_by_coord(coord, key);
set_key_offset(key, ((__u64)(clust_by_coord(coord, NULL)) + 1) << cluster_shift_by_coord(coord) << PAGE_CACHE_SHIFT);
@@ -1067,7 +1067,7 @@ do_convert_ctail(flush_pos_t * pos, crc_
switch (mode) {
case CRC_APPEND_ITEM:
assert("edward-1229", info->flow.length != 0);
- assert("edward-1256", cluster_shift_by_coord(&pos->coord) <= MAX_CLUSTER_SHIFT);
+ assert("edward-1256", cluster_shift_ok(cluster_shift_by_coord(&pos->coord)));
result = insert_crc_flow_in_place(&pos->coord, &pos->lock, &info->flow, info->inode);
break;
case CRC_OVERWRITE_ITEM:
@@ -1360,7 +1360,9 @@ utmost_child_ctail(const coord_t * coord
if (!is_disk_cluster_key(&key, coord))
*child = NULL;
else
- *child = jlookup(current_tree, get_key_objectid(item_key_by_coord(coord, &key)), pg_by_coord(coord));
+ *child = jlookup(current_tree,
+ get_key_objectid(item_key_by_coord(coord, &key)),
+ off_to_pg(get_key_offset(&key)));
return 0;
}
@@ -1601,7 +1603,7 @@ convert_ctail(flush_pos_t * pos)
/* convert unpprepped ctail to prepped one */
int shift;
shift = inode_cluster_shift(item_convert_data(pos)->inode);
- assert("edward-1259", shift <= MAX_CLUSTER_SHIFT);
+ assert("edward-1259", cluster_shift_ok(shift));
cputod8(shift, &ctail_formatted_at(&pos->coord)->cluster_shift);
}
break;
diff -puN fs/reiser4/plugin/item/extent_file_ops.c~reiser4-update-2 fs/reiser4/plugin/item/extent_file_ops.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/plugin/item/extent_file_ops.c~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/plugin/item/extent_file_ops.c 2005-04-29 19:10:38.000000000 +0400
@@ -644,6 +644,8 @@ extent_balance_dirty_pages(struct inode
hint_t *hint)
{
int result;
+ int excl;
+ unix_file_info_t *uf_info;
if (hint->ext_coord.valid)
set_hint(hint, &f->key, ZNODE_WRITE_LOCK);
@@ -666,7 +668,19 @@ extent_balance_dirty_pages(struct inode
return result;
}
- reiser4_throttle_write(inode);
+ if (!reiser4_is_set(inode->i_sb, REISER4_ATOMIC_WRITE)) {
+ uf_info = unix_file_inode_data(inode);
+ excl = unix_file_inode_data(inode)->exclusive_use;
+ if (excl)
+ drop_exclusive_access(uf_info);
+ else
+ drop_nonexclusive_access(uf_info);
+ reiser4_throttle_write(inode);
+ if (excl)
+ get_exclusive_access(uf_info);
+ else
+ get_nonexclusive_access(uf_info, 0);
+ }
return 0;
}
@@ -1185,7 +1199,6 @@ extent_readpage_filler(void *data, struc
TWIG_LEVEL, CBK_UNIQUE, NULL);
if (result != CBK_COORD_FOUND) {
unset_hint(hint);
- lock_page(page);
return result;
}
ext_coord->valid = 0;
@@ -1194,7 +1207,12 @@ extent_readpage_filler(void *data, struc
if (zload(ext_coord->coord.node)) {
unset_hint(hint);
done_lh(ext_coord->lh);
- lock_page(page);
+ return RETERR(-EIO);
+ }
+ if (!item_is_extent(&ext_coord->coord)) {
+ /* tail conversion is running in parallel */
+ unset_hint(hint);
+ done_lh(ext_coord->lh);
return RETERR(-EIO);
}
@@ -1208,6 +1226,8 @@ extent_readpage_filler(void *data, struc
if (!PageUptodate(page)) {
result = do_readpage_extent(ext_by_ext_coord(ext_coord),
ext_coord->extension.extent.pos_in_unit, page);
+ if (result)
+ unlock_page(page);
} else {
unlock_page(page);
result = 0;
@@ -1262,16 +1282,14 @@ call_readpage(struct file *file, struct
if (result)
return result;
+ lock_page(page);
if (!PageUptodate(page)) {
- lock_page(page);
- if (!PageUptodate(page)) {
- unlock_page(page);
- page_detach_jnode(page, page->mapping, page->index);
- warning("jmacd-97178", "page is not up to date");
- return RETERR(-EIO);
- }
unlock_page(page);
+ page_detach_jnode(page, page->mapping, page->index);
+ warning("jmacd-97178", "page is not up to date");
+ return RETERR(-EIO);
}
+ unlock_page(page);
return 0;
}
@@ -1349,7 +1367,7 @@ read_extent(struct file *file, flow_t *f
} else {
if (!PageUptodate(page)) {
lock_page(page);
-
+
assert("", page->mapping == mapping);
if (PageUptodate(page))
unlock_page(page);
diff -puN fs/reiser4/plugin/item/extent_flush_ops.c~reiser4-update-2 fs/reiser4/plugin/item/extent_flush_ops.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/plugin/item/extent_flush_ops.c~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/plugin/item/extent_flush_ops.c 2005-04-29 15:12:56.000000000 +0400
@@ -279,7 +279,9 @@ exit:
/* ask block allocator for some blocks */
static void
extent_allocate_blocks(reiser4_blocknr_hint *preceder,
- reiser4_block_nr wanted_count, reiser4_block_nr *first_allocated, reiser4_block_nr *allocated, block_stage_t block_stage)
+ reiser4_block_nr wanted_count,
+ reiser4_block_nr *first_allocated, reiser4_block_nr *allocated,
+ block_stage_t block_stage)
{
*allocated = wanted_count;
preceder->max_dist = 0; /* scan whole disk, if needed */
@@ -288,7 +290,7 @@ extent_allocate_blocks(reiser4_blocknr_h
preceder->block_stage = block_stage;
/* FIXME: we do not handle errors here now */
- check_me("vs-420", reiser4_alloc_blocks (preceder, first_allocated, allocated, BA_PERMANENT) == 0);
+ check_me("vs-420", reiser4_alloc_blocks(preceder, first_allocated, allocated, BA_PERMANENT) == 0);
/* update flush_pos's preceder to last allocated block number */
preceder->blk = *first_allocated + *allocated - 1;
}
@@ -795,6 +797,10 @@ alloc_extent(flush_pos_t *flush_pos)
else
block_stage = BLOCK_UNALLOCATED;
+ /* look at previous unit if possible. If it is allocated, make preceder more precise */
+ if (coord->unit_pos && (state_of_extent(ext - 1) == ALLOCATED_EXTENT))
+ pos_hint(flush_pos)->blk = extent_get_start(ext - 1) + extent_get_width(ext - 1);
+
/* allocate new block numbers for protected nodes */
extent_allocate_blocks(pos_hint(flush_pos), protected, &first_allocated, &allocated, block_stage);
@@ -934,6 +940,10 @@ squalloc_extent(znode *left, const coord
else
block_stage = BLOCK_UNALLOCATED;
+ /* look at previous unit if possible. If it is allocated, make preceder more precise */
+ if (coord->unit_pos && (state_of_extent(ext - 1) == ALLOCATED_EXTENT))
+ pos_hint(flush_pos)->blk = extent_get_start(ext - 1) + extent_get_width(ext - 1);
+
/* allocate new block numbers for protected nodes */
extent_allocate_blocks(pos_hint(flush_pos), protected, &first_allocated, &allocated, block_stage);
if (allocated != protected)
diff -puN fs/reiser4/plugin/item/tail.c~reiser4-update-2 fs/reiser4/plugin/item/tail.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/plugin/item/tail.c~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/plugin/item/tail.c 2005-04-29 19:10:38.000000000 +0400
@@ -454,6 +454,8 @@ tail_balance_dirty_pages(struct address_
{
int result;
struct inode *inode;
+ int excl;
+ unix_file_info_t *uf_info;
if (hint->ext_coord.valid)
set_hint(hint, &f->key, ZNODE_WRITE_LOCK);
@@ -475,12 +477,24 @@ tail_balance_dirty_pages(struct address_
return result;
}
- /* FIXME-VS: this is temporary: the problem is that bdp takes inodes
- from sb's dirty list and it looks like nobody puts there inodes of
- files which are built of tails */
- move_inode_out_from_sync_inodes_loop(mapping);
-
- reiser4_throttle_write(inode);
+ if (!reiser4_is_set(inode->i_sb, REISER4_ATOMIC_WRITE)) {
+ /* FIXME-VS: this is temporary: the problem is that bdp takes
+ inodes from sb's dirty list and it looks like nobody puts
+ there inodes of files which are built of tails */
+ move_inode_out_from_sync_inodes_loop(mapping);
+
+ uf_info = unix_file_inode_data(inode);
+ excl = unix_file_inode_data(inode)->exclusive_use;
+ if (excl)
+ drop_exclusive_access(uf_info);
+ else
+ drop_nonexclusive_access(uf_info);
+ reiser4_throttle_write(inode);
+ if (excl)
+ get_exclusive_access(uf_info);
+ else
+ get_nonexclusive_access(uf_info, 0);
+ }
return 0;
}
diff -puN fs/reiser4/plugin/plugin.h~reiser4-update-2 fs/reiser4/plugin/plugin.h
--- linux-2.6.12-rc2-mm3/fs/reiser4/plugin/plugin.h~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/plugin/plugin.h 2005-04-29 15:12:56.000000000 +0400
@@ -454,6 +454,7 @@ typedef struct compression_plugin {
void (*free) (coa_t coa, tfm_action act);
/* minimal size of the flow we still try to compress */
int (*min_tfm_size) (void);
+ __u32 (*checksum) (char * data, __u32 length);
/* main transform procedures */
void (*compress) (coa_t coa, __u8 *src_first, unsigned src_len,
__u8 *dst_first, unsigned *dst_len);
diff -puN fs/reiser4/plugin/space/bitmap.c~reiser4-update-2 fs/reiser4/plugin/space/bitmap.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/plugin/space/bitmap.c~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/plugin/space/bitmap.c 2005-04-29 15:12:56.000000000 +0400
@@ -461,11 +461,11 @@ reiser4_set_bits(char *addr, bmap_off_t
Jean-loup Gailly Mark Adler
[email protected] [email protected]
- The above comment applies only to the adler32 function.
+ The above comment applies only to the reiser4_adler32 function.
*/
-static __u32
-adler32(char *data, __u32 len)
+reiser4_internal __u32
+reiser4_adler32(char *data, __u32 len)
{
unsigned char *t = data;
__u32 s1 = 1;
@@ -493,7 +493,7 @@ adler32(char *data, __u32 len)
static __u32
bnode_calc_crc(const struct bitmap_node *bnode, unsigned long size)
{
- return adler32(bnode_commit_data(bnode), bmap_size(size));
+ return reiser4_adler32(bnode_commit_data(bnode), bmap_size(size));
}
diff -puN fs/reiser4/status_flags.c~reiser4-update-2 fs/reiser4/status_flags.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/status_flags.c~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/status_flags.c 2005-04-29 15:12:56.000000000 +0400
@@ -3,7 +3,6 @@
/* Functions that deal with reiser4 status block, query status and update it, if needed */
-#include <linux/page-flags.h>
#include <linux/bio.h>
#include <linux/highmem.h>
#include <linux/fs.h>
diff -puN fs/reiser4/super.h~reiser4-update-2 fs/reiser4/super.h
--- linux-2.6.12-rc2-mm3/fs/reiser4/super.h~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/super.h 2005-04-29 15:12:56.000000000 +0400
@@ -63,7 +63,9 @@ typedef enum {
* directories. */
REISER4_NO_PSEUDO = 5,
/* load all bitmap blocks at mount time */
- REISER4_DONT_LOAD_BITMAP = 6
+ REISER4_DONT_LOAD_BITMAP = 6,
+ /* enforce atomicity during write(2) */
+ REISER4_ATOMIC_WRITE = 7
} reiser4_fs_flag;
/*
diff -puN fs/reiser4/tree_walk.c~reiser4-update-2 fs/reiser4/tree_walk.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/tree_walk.c~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/tree_walk.c 2005-04-29 15:12:56.000000000 +0400
@@ -238,7 +238,7 @@ link_left_and_right(znode * left, znode
ON_DEBUG(left->right_version = atomic_inc_return(&delim_key_version););
- } else if (ZF_ISSET(left->right, JNODE_HEARD_BANSHEE)) {
+ } else if (ZF_ISSET(left->right, JNODE_HEARD_BANSHEE) && left->right != right) {
ON_DEBUG(
left->right->left_version = atomic_inc_return(&delim_key_version);
@@ -271,7 +271,7 @@ link_left_and_right(znode * left, znode
ON_DEBUG(right->left_version = atomic_inc_return(&delim_key_version););
- } else if (ZF_ISSET(right->left, JNODE_HEARD_BANSHEE)) {
+ } else if (ZF_ISSET(right->left, JNODE_HEARD_BANSHEE) && right->left != left) {
ON_DEBUG(
right->left->right_version = atomic_inc_return(&delim_key_version);
diff -puN fs/reiser4/txnmgr.c~reiser4-update-2 fs/reiser4/txnmgr.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/txnmgr.c~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/txnmgr.c 2005-04-29 19:10:38.000000000 +0400
@@ -1385,7 +1385,7 @@ static int txn_try_to_fuse_small_atom (t
int atom_stage;
txn_atom *atom_2;
int repeat;
-
+
assert ("zam-1051", atom->stage < ASTAGE_PRE_COMMIT);
atom_stage = atom->stage;
@@ -1415,9 +1415,9 @@ static int txn_try_to_fuse_small_atom (t
UNLOCK_ATOM(atom_2);
}
}
- spin_unlock_txnmgr(tmgr);
atom->flags |= ATOM_CANCEL_FUSION;
- out:
+ out:
+ spin_unlock_txnmgr(tmgr);
if (repeat) {
UNLOCK_ATOM(atom);
return -E_REPEAT;
@@ -1507,7 +1507,7 @@ flush_some_atom(long *nr_submitted, cons
ret = flush_current_atom(flags, nr_submitted, &atom);
if (ret == 0) {
if (*nr_submitted == 0 || atom_should_commit_asap(atom)) {
- if (atom->capture_count < tmgr->atom_min_size &&
+ if (atom->capture_count < tmgr->atom_min_size &&
!(atom->flags & ATOM_CANCEL_FUSION)) {
ret =txn_try_to_fuse_small_atom(tmgr, atom);
if (ret == -E_REPEAT)
diff -puN fs/reiser4/vfs_ops.c~reiser4-update-2 fs/reiser4/vfs_ops.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/vfs_ops.c~reiser4-update-2 2005-04-29 15:12:56.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/vfs_ops.c 2005-04-29 19:10:38.000000000 +0400
@@ -530,7 +530,7 @@ reiser4_destroy_inode(struct inode *inod
kmem_cache_free(inode_cache, container_of(info, reiser4_inode_object, p));
}
-/* put_inode of super_operations
+/* put_inode of super_operations
we use put_inode to call pre_delete method of file plugin if it is defined
and if inode is unlinked and if it is about to drop inode reference count to
@@ -542,7 +542,7 @@ reiser4_put_inode(struct inode *inode)
file_plugin *fplug;
fplug = inode_file_plugin(inode);
- if (fplug == NULL ||
+ if (fplug == NULL ||
inode->i_nlink != 0 ||
atomic_read(&inode->i_count) > 1 ||
fplug->pre_delete == NULL)
@@ -551,7 +551,7 @@ reiser4_put_inode(struct inode *inode)
init_context(&ctx, inode->i_sb);
/* kill cursors which might be attached to inode if it were a directory one */
kill_cursors(inode);
- fplug->pre_delete(inode);
+ fplug->pre_delete(inode);
reiser4_exit_context(&ctx);
}
@@ -1022,6 +1022,8 @@ do { \
/* Don't load all bitmap blocks at mount time, it is useful
for machines with tiny RAM and large disks. */
PUSH_BIT_OPT("dont_load_bitmap", REISER4_DONT_LOAD_BITMAP);
+ /* disable transaction commits during write() */
+ PUSH_BIT_OPT("atomic_write", REISER4_ATOMIC_WRITE);
PUSH_OPT ({
/* tree traversal readahead parameters:
diff -puN fs/reiser4/as_ops.c~reiser4-update-2 fs/reiser4/as_ops.c
--- linux-2.6.12-rc2-mm3/fs/reiser4/as_ops.c~reiser4-update-2 2005-04-29 18:48:49.000000000 +0400
+++ linux-2.6.12-rc2-mm3-root/fs/reiser4/as_ops.c 2005-04-29 18:48:49.000000000 +0400
@@ -158,13 +158,9 @@ reiser4_readpage(struct file *f /* file
result = fplug->readpage(f, page);
else
result = RETERR(-EINVAL);
- if (result != 0) {
- SetPageError(page);
- unlock_page(page);
- }
reiser4_exit_context(&ctx);
- return 0;
+ return result;
}
static int filler(void *vp, struct page *page)
_