revert-mm-fix-blkdev-size-calculation-in-generic_write_checks
[linux-2.6/linux-trees-mm.git] / fs / reiser4 / status_flags.c
blob646bfa20a7a3f79c32ea9e98d6f5742f0360f5e1
1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by
2 * reiser4/README */
4 /* Functions that deal with reiser4 status block, query status and update it, if needed */
6 #include <linux/bio.h>
7 #include <linux/highmem.h>
8 #include <linux/fs.h>
9 #include <linux/blkdev.h>
10 #include "debug.h"
11 #include "dformat.h"
12 #include "status_flags.h"
13 #include "super.h"
15 /* This is our end I/O handler that marks page uptodate if IO was successful. It also
16 unconditionally unlocks the page, so we can see that io was done.
17 We do not free bio, because we hope to reuse that. */
18 static void reiser4_status_endio(struct bio *bio, int err)
20 if (test_bit(BIO_UPTODATE, &bio->bi_flags)) {
21 SetPageUptodate(bio->bi_io_vec->bv_page);
22 } else {
23 ClearPageUptodate(bio->bi_io_vec->bv_page);
24 SetPageError(bio->bi_io_vec->bv_page);
26 unlock_page(bio->bi_io_vec->bv_page);
29 /* Initialise status code. This is expected to be called from the disk format
30 code. block paremeter is where status block lives. */
31 int reiser4_status_init(reiser4_block_nr block)
33 struct super_block *sb = reiser4_get_current_sb();
34 struct reiser4_status *statuspage;
35 struct bio *bio;
36 struct page *page;
38 get_super_private(sb)->status_page = NULL;
39 get_super_private(sb)->status_bio = NULL;
41 page = alloc_pages(reiser4_ctx_gfp_mask_get(), 0);
42 if (!page)
43 return -ENOMEM;
45 bio = bio_alloc(reiser4_ctx_gfp_mask_get(), 1);
46 if (bio != NULL) {
47 bio->bi_sector = block * (sb->s_blocksize >> 9);
48 bio->bi_bdev = sb->s_bdev;
49 bio->bi_io_vec[0].bv_page = page;
50 bio->bi_io_vec[0].bv_len = sb->s_blocksize;
51 bio->bi_io_vec[0].bv_offset = 0;
52 bio->bi_vcnt = 1;
53 bio->bi_size = sb->s_blocksize;
54 bio->bi_end_io = reiser4_status_endio;
55 } else {
56 __free_pages(page, 0);
57 return -ENOMEM;
59 lock_page(page);
60 submit_bio(READ, bio);
61 blk_run_address_space(reiser4_get_super_fake(sb)->i_mapping);
62 wait_on_page_locked(page);
63 if (!PageUptodate(page)) {
64 warning("green-2007",
65 "I/O error while tried to read status page\n");
66 return -EIO;
69 statuspage = (struct reiser4_status *)kmap_atomic(page, KM_USER0);
70 if (memcmp
71 (statuspage->magic, REISER4_STATUS_MAGIC,
72 sizeof(REISER4_STATUS_MAGIC))) {
73 /* Magic does not match. */
74 kunmap_atomic((char *)statuspage, KM_USER0);
75 warning("green-2008", "Wrong magic in status block\n");
76 __free_pages(page, 0);
77 bio_put(bio);
78 return -EINVAL;
80 kunmap_atomic((char *)statuspage, KM_USER0);
82 get_super_private(sb)->status_page = page;
83 get_super_private(sb)->status_bio = bio;
84 return 0;
87 /* Query the status of fs. Returns if the FS can be safely mounted.
88 Also if "status" and "extended" parameters are given, it will fill
89 actual parts of status from disk there. */
90 int reiser4_status_query(u64 * status, u64 * extended)
92 struct super_block *sb = reiser4_get_current_sb();
93 struct reiser4_status *statuspage;
94 int retval;
96 if (!get_super_private(sb)->status_page) { // No status page?
97 return REISER4_STATUS_MOUNT_UNKNOWN;
99 statuspage = (struct reiser4_status *)
100 kmap_atomic(get_super_private(sb)->status_page, KM_USER0);
101 switch ((long)le64_to_cpu(get_unaligned(&statuspage->status))) { // FIXME: this cast is a hack for 32 bit arches to work.
102 case REISER4_STATUS_OK:
103 retval = REISER4_STATUS_MOUNT_OK;
104 break;
105 case REISER4_STATUS_CORRUPTED:
106 retval = REISER4_STATUS_MOUNT_WARN;
107 break;
108 case REISER4_STATUS_DAMAGED:
109 case REISER4_STATUS_DESTROYED:
110 case REISER4_STATUS_IOERROR:
111 retval = REISER4_STATUS_MOUNT_RO;
112 break;
113 default:
114 retval = REISER4_STATUS_MOUNT_UNKNOWN;
115 break;
118 if (status)
119 *status = le64_to_cpu(get_unaligned(&statuspage->status));
120 if (extended)
121 *extended = le64_to_cpu(get_unaligned(&statuspage->extended_status));
123 kunmap_atomic((char *)statuspage, KM_USER0);
124 return retval;
127 /* This function should be called when something bad happens (e.g. from reiser4_panic).
128 It fills the status structure and tries to push it to disk. */
129 int reiser4_status_write(__u64 status, __u64 extended_status, char *message)
131 struct super_block *sb = reiser4_get_current_sb();
132 struct reiser4_status *statuspage;
133 struct bio *bio = get_super_private(sb)->status_bio;
135 if (!get_super_private(sb)->status_page) { // No status page?
136 return -1;
138 statuspage = (struct reiser4_status *)
139 kmap_atomic(get_super_private(sb)->status_page, KM_USER0);
141 put_unaligned(cpu_to_le64(status), &statuspage->status);
142 put_unaligned(cpu_to_le64(extended_status), &statuspage->extended_status);
143 strncpy(statuspage->texterror, message, REISER4_TEXTERROR_LEN);
145 kunmap_atomic((char *)statuspage, KM_USER0);
146 bio->bi_bdev = sb->s_bdev;
147 bio->bi_io_vec[0].bv_page = get_super_private(sb)->status_page;
148 bio->bi_io_vec[0].bv_len = sb->s_blocksize;
149 bio->bi_io_vec[0].bv_offset = 0;
150 bio->bi_vcnt = 1;
151 bio->bi_size = sb->s_blocksize;
152 bio->bi_end_io = reiser4_status_endio;
153 lock_page(get_super_private(sb)->status_page); // Safe as nobody should touch our page.
154 /* We can block now, but we have no other choice anyway */
155 submit_bio(WRITE, bio);
156 blk_run_address_space(reiser4_get_super_fake(sb)->i_mapping);
157 return 0; // We do not wait for io to finish.
160 /* Frees the page with status and bio structure. Should be called by disk format at umount time */
161 int reiser4_status_finish(void)
163 struct super_block *sb = reiser4_get_current_sb();
165 __free_pages(get_super_private(sb)->status_page, 0);
166 get_super_private(sb)->status_page = NULL;
167 bio_put(get_super_private(sb)->status_bio);
168 get_super_private(sb)->status_bio = NULL;
169 return 0;