summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@novell.com>2004-10-18 09:07:45 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-10-18 09:07:45 -0700
commit6f2fb1255b052f8d797479a11d8bd474b35b0384 (patch)
treec6e4469a6427646235705685f68aadeedc0f5b7a /include/linux
parent5b7b40f5b6b0a3407b0d6e6d70d3d20d58731255 (diff)
[PATCH] ReiserFS: Add I/O error handling to journal operations
This patch allows ReiserFS to handle I/O errors in the journal (or journal flush) where it would have previously panicked. The new behavior is to mark the filesystem read-only, disallow new transactions to be started, and to allow existing transactions to complete (though not to commit). The resultant filesystem can be safely umounted, and checked via normal mechanisms. As it is a journaling filesystem, the filesystem itself will be in a similar state to the power being cut to the machine, once umounted. Signed-off-by: Jeff Mahoney <jeffm@novell.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/reiserfs_fs.h15
-rw-r--r--include/linux/reiserfs_fs_sb.h26
2 files changed, 35 insertions, 6 deletions
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 046fde1a95da..6eacc2c653f1 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -1751,6 +1751,7 @@ struct reiserfs_transaction_handle {
void *t_handle_save ; /* save existing current->journal_info */
unsigned displace_new_blocks:1; /* if new block allocation occurres, that block
should be displaced from others */
+ struct list_head t_list;
} ;
/* used to keep track of ordered and tail writes, attached to the buffer
@@ -1810,12 +1811,14 @@ int journal_mark_freed(struct reiserfs_transaction_handle *, struct super_block
int journal_transaction_should_end(struct reiserfs_transaction_handle *, int) ;
int reiserfs_in_journal(struct super_block *p_s_sb, int bmap_nr, int bit_nr, int searchall, b_blocknr_t *next) ;
int journal_begin(struct reiserfs_transaction_handle *, struct super_block *p_s_sb, unsigned long) ;
-
+int journal_join_abort(struct reiserfs_transaction_handle *, struct super_block *p_s_sb, unsigned long) ;
+void reiserfs_journal_abort (struct super_block *sb, int errno);
+void reiserfs_abort (struct super_block *sb, int errno, const char *fmt, ...);
int reiserfs_allocate_list_bitmaps(struct super_block *s, struct reiserfs_list_bitmap *, int) ;
void add_save_link (struct reiserfs_transaction_handle * th,
struct inode * inode, int truncate);
-void remove_save_link (struct inode * inode, int truncate);
+int remove_save_link (struct inode * inode, int truncate);
/* objectid.c */
__u32 reiserfs_get_unused_objectid (struct reiserfs_transaction_handle *th);
@@ -1911,8 +1914,8 @@ int reiserfs_delete_item (struct reiserfs_transaction_handle *th,
void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th,
struct inode *inode, struct key * key);
-void reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inode * p_s_inode);
-void reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
+int reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inode * p_s_inode);
+int reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
struct inode * p_s_inode, struct page *,
int update_timestamps);
@@ -1926,7 +1929,7 @@ void reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
void padd_item (char * item, int total_length, int length);
/* inode.c */
-void restart_transaction(struct reiserfs_transaction_handle *th, struct inode *inode, struct path *path);
+int restart_transaction(struct reiserfs_transaction_handle *th, struct inode *inode, struct path *path);
void reiserfs_read_locked_inode(struct inode * inode, struct reiserfs_iget_args *args) ;
int reiserfs_find_actor(struct inode * inode, void *p) ;
int reiserfs_init_locked_inode(struct inode * inode, void *p) ;
@@ -1941,7 +1944,7 @@ int reiserfs_encode_fh( struct dentry *dentry, __u32 *data, int *lenp,
int connectable );
int reiserfs_prepare_write(struct file *, struct page *, unsigned, unsigned) ;
-void reiserfs_truncate_file(struct inode *, int update_timestamps) ;
+int reiserfs_truncate_file(struct inode *, int update_timestamps) ;
void make_cpu_key (struct cpu_key * cpu_key, struct inode * inode, loff_t offset,
int type, int key_length);
void make_le_item_head (struct item_head * ih, const struct cpu_key * key,
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
index aaf872453e5a..891418bb525a 100644
--- a/include/linux/reiserfs_fs_sb.h
+++ b/include/linux/reiserfs_fs_sb.h
@@ -242,14 +242,24 @@ struct reiserfs_journal {
struct reiserfs_journal_cnode *j_list_hash_table[JOURNAL_HASH_SIZE] ; /* hash table for all the real buffer heads in all
the transactions */
struct list_head j_prealloc_list; /* list of inodes which have preallocated blocks */
+ int j_persistent_trans;
unsigned long j_max_trans_size ;
unsigned long j_max_batch_size ;
+ int j_errno;
+
/* when flushing ordered buffers, throttle new ordered writers */
struct work_struct j_work;
atomic_t j_async_throttle;
};
+enum journal_state_bits {
+ J_WRITERS_BLOCKED = 1, /* set when new writers not allowed */
+ J_WRITERS_QUEUED, /* set when log is full due to too many writers */
+ J_ABORTED, /* set when log is aborted */
+};
+
+
#define JOURNAL_DESC_MAGIC "ReIsErLB" /* ick. magic string to find desc blocks in the journal */
typedef __u32 (*hashf_t) (const signed char *, int);
@@ -399,6 +409,7 @@ struct reiserfs_sb_info
struct dentry *xattr_root; /* root of /.reiserfs_priv/.xa */
struct rw_semaphore xattr_dir_sem;
+ int j_errno;
};
/* Definitions of reiserfs on-disk properties: */
@@ -447,6 +458,11 @@ enum reiserfs_mount_options {
REISERFS_BARRIER_NONE,
REISERFS_BARRIER_FLUSH,
+ /* Actions on error */
+ REISERFS_ERROR_PANIC,
+ REISERFS_ERROR_RO,
+ REISERFS_ERROR_CONTINUE,
+
REISERFS_TEST1,
REISERFS_TEST2,
REISERFS_TEST3,
@@ -478,6 +494,10 @@ enum reiserfs_mount_options {
#define reiserfs_barrier_none(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_BARRIER_NONE))
#define reiserfs_barrier_flush(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_BARRIER_FLUSH))
+#define reiserfs_error_panic(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_ERROR_PANIC))
+#define reiserfs_error_ro(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_ERROR_RO))
+#define reiserfs_error_continue(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_ERROR_CONTINUE))
+
void reiserfs_file_buffer (struct buffer_head * bh, int list);
extern struct file_system_type reiserfs_fs_type;
int reiserfs_resize(struct super_block *, unsigned long) ;
@@ -502,4 +522,10 @@ static inline char *reiserfs_bdevname(struct super_block *s)
return (s == NULL) ? "Null superblock" : s -> s_id;
}
+#define reiserfs_is_journal_aborted(journal) (unlikely (__reiserfs_is_journal_aborted (journal)))
+static inline int __reiserfs_is_journal_aborted (struct reiserfs_journal *journal)
+{
+ return test_bit (J_ABORTED, &journal->j_state);
+}
+
#endif /* _LINUX_REISER_FS_SB */