1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by
4 /* Functions that deal with reiser4 status block, query status and update it,
8 #include <linux/highmem.h>
10 #include <linux/blkdev.h>
13 #include "status_flags.h"
16 /* This is our end I/O handler that marks page uptodate if IO was successful.
17 It also unconditionally unlocks the page, so we can see that io was done.
18 We do not free bio, because we hope to reuse that. */
19 static void reiser4_status_endio(struct bio
*bio
, int err
)
21 if (test_bit(BIO_UPTODATE
, &bio
->bi_flags
)) {
22 SetPageUptodate(bio
->bi_io_vec
->bv_page
);
24 ClearPageUptodate(bio
->bi_io_vec
->bv_page
);
25 SetPageError(bio
->bi_io_vec
->bv_page
);
27 unlock_page(bio
->bi_io_vec
->bv_page
);
30 /* Initialise status code. This is expected to be called from the disk format
31 code. block paremeter is where status block lives. */
32 int reiser4_status_init(reiser4_block_nr block
)
34 struct super_block
*sb
= reiser4_get_current_sb();
35 struct reiser4_status
*statuspage
;
39 get_super_private(sb
)->status_page
= NULL
;
40 get_super_private(sb
)->status_bio
= NULL
;
42 page
= alloc_pages(reiser4_ctx_gfp_mask_get(), 0);
46 bio
= bio_alloc(reiser4_ctx_gfp_mask_get(), 1);
48 bio
->bi_sector
= block
* (sb
->s_blocksize
>> 9);
49 bio
->bi_bdev
= sb
->s_bdev
;
50 bio
->bi_io_vec
[0].bv_page
= page
;
51 bio
->bi_io_vec
[0].bv_len
= sb
->s_blocksize
;
52 bio
->bi_io_vec
[0].bv_offset
= 0;
54 bio
->bi_size
= sb
->s_blocksize
;
55 bio
->bi_end_io
= reiser4_status_endio
;
57 __free_pages(page
, 0);
61 submit_bio(READ
, bio
);
62 blk_run_address_space(reiser4_get_super_fake(sb
)->i_mapping
);
63 wait_on_page_locked(page
);
64 if (!PageUptodate(page
)) {
66 "I/O error while tried to read status page\n");
70 statuspage
= (struct reiser4_status
*)kmap_atomic(page
, KM_USER0
);
72 (statuspage
->magic
, REISER4_STATUS_MAGIC
,
73 sizeof(REISER4_STATUS_MAGIC
))) {
74 /* Magic does not match. */
75 kunmap_atomic((char *)statuspage
, KM_USER0
);
76 warning("green-2008", "Wrong magic in status block\n");
77 __free_pages(page
, 0);
81 kunmap_atomic((char *)statuspage
, KM_USER0
);
83 get_super_private(sb
)->status_page
= page
;
84 get_super_private(sb
)->status_bio
= bio
;
88 /* Query the status of fs. Returns if the FS can be safely mounted.
89 Also if "status" and "extended" parameters are given, it will fill
90 actual parts of status from disk there. */
91 int reiser4_status_query(u64
*status
, u64
*extended
)
93 struct super_block
*sb
= reiser4_get_current_sb();
94 struct reiser4_status
*statuspage
;
97 if (!get_super_private(sb
)->status_page
)
99 return REISER4_STATUS_MOUNT_UNKNOWN
;
100 statuspage
= (struct reiser4_status
*)
101 kmap_atomic(get_super_private(sb
)->status_page
, KM_USER0
);
102 switch ((long)le64_to_cpu(get_unaligned(&statuspage
->status
))) {
103 /* FIXME: this cast is a hack for 32 bit arches to work. */
104 case REISER4_STATUS_OK
:
105 retval
= REISER4_STATUS_MOUNT_OK
;
107 case REISER4_STATUS_CORRUPTED
:
108 retval
= REISER4_STATUS_MOUNT_WARN
;
110 case REISER4_STATUS_DAMAGED
:
111 case REISER4_STATUS_DESTROYED
:
112 case REISER4_STATUS_IOERROR
:
113 retval
= REISER4_STATUS_MOUNT_RO
;
116 retval
= REISER4_STATUS_MOUNT_UNKNOWN
;
121 *status
= le64_to_cpu(get_unaligned(&statuspage
->status
));
123 *extended
= le64_to_cpu(get_unaligned(&statuspage
->extended_status
));
125 kunmap_atomic((char *)statuspage
, KM_USER0
);
129 /* This function should be called when something bad happens (e.g. from
130 reiser4_panic). It fills the status structure and tries to push it to disk.*/
131 int reiser4_status_write(__u64 status
, __u64 extended_status
, char *message
)
133 struct super_block
*sb
= reiser4_get_current_sb();
134 struct reiser4_status
*statuspage
;
135 struct bio
*bio
= get_super_private(sb
)->status_bio
;
137 if (!get_super_private(sb
)->status_page
)
138 /* No status page? */
140 statuspage
= (struct reiser4_status
*)
141 kmap_atomic(get_super_private(sb
)->status_page
, KM_USER0
);
143 put_unaligned(cpu_to_le64(status
), &statuspage
->status
);
144 put_unaligned(cpu_to_le64(extended_status
), &statuspage
->extended_status
);
145 strncpy(statuspage
->texterror
, message
, REISER4_TEXTERROR_LEN
);
147 kunmap_atomic((char *)statuspage
, KM_USER0
);
148 bio
->bi_bdev
= sb
->s_bdev
;
149 bio
->bi_io_vec
[0].bv_page
= get_super_private(sb
)->status_page
;
150 bio
->bi_io_vec
[0].bv_len
= sb
->s_blocksize
;
151 bio
->bi_io_vec
[0].bv_offset
= 0;
153 bio
->bi_size
= sb
->s_blocksize
;
154 bio
->bi_end_io
= reiser4_status_endio
;
155 lock_page(get_super_private(sb
)->status_page
); /* Safe as nobody should
157 /* We can block now, but we have no other choice anyway */
158 submit_bio(WRITE
, bio
);
159 blk_run_address_space(reiser4_get_super_fake(sb
)->i_mapping
);
160 return 0; /* We do not wait for io to finish. */
163 /* Frees the page with status and bio structure. Should be called by disk format
165 int reiser4_status_finish(void)
167 struct super_block
*sb
= reiser4_get_current_sb();
169 __free_pages(get_super_private(sb
)->status_page
, 0);
170 get_super_private(sb
)->status_page
= NULL
;
171 bio_put(get_super_private(sb
)->status_bio
);
172 get_super_private(sb
)->status_bio
= NULL
;