Blame view

drivers/md/md-bitmap.c 70 KB
457c89965   Thomas Gleixner   treewide: Add SPD...
1
  // SPDX-License-Identifier: GPL-2.0-only
32a7627cf   NeilBrown   [PATCH] md: optim...
2
3
4
5
6
7
8
9
10
  /*
   * bitmap.c two-level bitmap (C) Peter T. Breuer (ptb@ot.uc3m.es) 2003
   *
   * bitmap_create  - sets up the bitmap structure
   * bitmap_destroy - destroys the bitmap structure
   *
   * additions, Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc.:
   * - added disk storage for bitmap
   * - changes to allow various bitmap chunk sizes
32a7627cf   NeilBrown   [PATCH] md: optim...
11
12
13
14
15
16
   */
  
  /*
   * Still to do:
   *
   * flush after percent set rather than just time based. (maybe both).
32a7627cf   NeilBrown   [PATCH] md: optim...
17
   */
bff61975b   NeilBrown   md: move lots of ...
18
  #include <linux/blkdev.h>
32a7627cf   NeilBrown   [PATCH] md: optim...
19
  #include <linux/module.h>
32a7627cf   NeilBrown   [PATCH] md: optim...
20
21
22
  #include <linux/errno.h>
  #include <linux/slab.h>
  #include <linux/init.h>
32a7627cf   NeilBrown   [PATCH] md: optim...
23
24
25
26
27
28
  #include <linux/timer.h>
  #include <linux/sched.h>
  #include <linux/list.h>
  #include <linux/file.h>
  #include <linux/mount.h>
  #include <linux/buffer_head.h>
57148964d   NeilBrown   md/bitmap: move p...
29
  #include <linux/seq_file.h>
581dbd94d   NeilBrown   md/bitmap: add bl...
30
  #include <trace/events/block.h>
43b2e5d86   NeilBrown   md: move md_k.h f...
31
  #include "md.h"
935fe0983   Mike Snitzer   md: rename some d...
32
  #include "md-bitmap.h"
32a7627cf   NeilBrown   [PATCH] md: optim...
33

ac2f40be4   NeilBrown   md/bitmap: white ...
34
  static inline char *bmname(struct bitmap *bitmap)
32a7627cf   NeilBrown   [PATCH] md: optim...
35
36
37
  {
  	return bitmap->mddev ? mdname(bitmap->mddev) : "mdX";
  }
32a7627cf   NeilBrown   [PATCH] md: optim...
38
  /*
32a7627cf   NeilBrown   [PATCH] md: optim...
39
40
41
42
43
44
45
46
47
   * check a page and, if necessary, allocate it (or hijack it if the alloc fails)
   *
   * 1) check to see if this page is allocated, if it's not then try to alloc
   * 2) if the alloc fails, set the page's hijacked flag so we'll use the
   *    page pointer directly as a counter
   *
   * if we find our page, we increment the page's refcount so that it stays
   * allocated while we're using it
   */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
48
49
  static int md_bitmap_checkpage(struct bitmap_counts *bitmap,
  			       unsigned long page, int create, int no_hijack)
ee305acef   NeilBrown   md: remove sparse...
50
51
  __releases(bitmap->lock)
  __acquires(bitmap->lock)
32a7627cf   NeilBrown   [PATCH] md: optim...
52
53
54
55
  {
  	unsigned char *mappage;
  
  	if (page >= bitmap->pages) {
1187cf0a3   NeilBrown   md: Allow write-i...
56
57
58
59
  		/* This can happen if bitmap_start_sync goes beyond
  		 * End-of-device while looking for a whole page.
  		 * It is harmless.
  		 */
32a7627cf   NeilBrown   [PATCH] md: optim...
60
61
  		return -EINVAL;
  	}
32a7627cf   NeilBrown   [PATCH] md: optim...
62
63
64
65
66
67
68
69
  	if (bitmap->bp[page].hijacked) /* it's hijacked, don't try to alloc */
  		return 0;
  
  	if (bitmap->bp[page].map) /* page is already allocated, just return */
  		return 0;
  
  	if (!create)
  		return -ENOENT;
32a7627cf   NeilBrown   [PATCH] md: optim...
70
  	/* this page has not been allocated yet */
ac2f40be4   NeilBrown   md/bitmap: white ...
71
  	spin_unlock_irq(&bitmap->lock);
d95901433   NeilBrown   md/bitmap: fix a ...
72
73
74
75
76
77
78
79
80
81
82
83
84
  	/* It is possible that this is being called inside a
  	 * prepare_to_wait/finish_wait loop from raid5c:make_request().
  	 * In general it is not permitted to sleep in that context as it
  	 * can cause the loop to spin freely.
  	 * That doesn't apply here as we can only reach this point
  	 * once with any loop.
  	 * When this function completes, either bp[page].map or
  	 * bp[page].hijacked.  In either case, this function will
  	 * abort before getting to this point again.  So there is
  	 * no risk of a free-spin, and so it is safe to assert
  	 * that sleeping here is allowed.
  	 */
  	sched_annotate_sleep();
792a1d4bb   NeilBrown   md/bitmap: remove...
85
  	mappage = kzalloc(PAGE_SIZE, GFP_NOIO);
ac2f40be4   NeilBrown   md/bitmap: white ...
86
87
88
  	spin_lock_irq(&bitmap->lock);
  
  	if (mappage == NULL) {
40cffcc0e   NeilBrown   md/bitmap: create...
89
90
  		pr_debug("md/bitmap: map page allocation failed, hijacking
  ");
c9d650322   Guoqing Jiang   md-cluster: alway...
91
92
93
  		/* We don't support hijack for cluster raid */
  		if (no_hijack)
  			return -ENOMEM;
32a7627cf   NeilBrown   [PATCH] md: optim...
94
95
  		/* failed - set the hijacked flag so that we can use the
  		 * pointer as a counter */
32a7627cf   NeilBrown   [PATCH] md: optim...
96
97
  		if (!bitmap->bp[page].map)
  			bitmap->bp[page].hijacked = 1;
ac2f40be4   NeilBrown   md/bitmap: white ...
98
99
  	} else if (bitmap->bp[page].map ||
  		   bitmap->bp[page].hijacked) {
32a7627cf   NeilBrown   [PATCH] md: optim...
100
  		/* somebody beat us to getting the page */
792a1d4bb   NeilBrown   md/bitmap: remove...
101
  		kfree(mappage);
ac2f40be4   NeilBrown   md/bitmap: white ...
102
  	} else {
32a7627cf   NeilBrown   [PATCH] md: optim...
103

ac2f40be4   NeilBrown   md/bitmap: white ...
104
  		/* no page was in place and we have one, so install it */
32a7627cf   NeilBrown   [PATCH] md: optim...
105

ac2f40be4   NeilBrown   md/bitmap: white ...
106
107
108
  		bitmap->bp[page].map = mappage;
  		bitmap->missing_pages--;
  	}
32a7627cf   NeilBrown   [PATCH] md: optim...
109
110
  	return 0;
  }
32a7627cf   NeilBrown   [PATCH] md: optim...
111
112
113
  /* if page is completely empty, put it back on the free list, or dealloc it */
  /* if page was hijacked, unmark the flag so it might get alloced next time */
  /* Note: lock should be held when calling this */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
114
  static void md_bitmap_checkfree(struct bitmap_counts *bitmap, unsigned long page)
32a7627cf   NeilBrown   [PATCH] md: optim...
115
116
117
118
119
120
121
122
123
124
125
  {
  	char *ptr;
  
  	if (bitmap->bp[page].count) /* page is still busy */
  		return;
  
  	/* page is no longer in use, it can be released */
  
  	if (bitmap->bp[page].hijacked) { /* page was hijacked, undo this now */
  		bitmap->bp[page].hijacked = 0;
  		bitmap->bp[page].map = NULL;
ac2f40be4   NeilBrown   md/bitmap: white ...
126
127
128
129
130
  	} else {
  		/* normal case, free the page */
  		ptr = bitmap->bp[page].map;
  		bitmap->bp[page].map = NULL;
  		bitmap->missing_pages++;
792a1d4bb   NeilBrown   md/bitmap: remove...
131
  		kfree(ptr);
32a7627cf   NeilBrown   [PATCH] md: optim...
132
  	}
32a7627cf   NeilBrown   [PATCH] md: optim...
133
  }
32a7627cf   NeilBrown   [PATCH] md: optim...
134
135
136
  /*
   * bitmap file handling - read and write the bitmap file and its superblock
   */
32a7627cf   NeilBrown   [PATCH] md: optim...
137
138
139
  /*
   * basic page I/O operations
   */
a654b9d8f   NeilBrown   [PATCH] md: allow...
140
  /* IO operations when bitmap is stored near all superblocks */
27581e5ae   NeilBrown   md/bitmap: centra...
141
142
143
  static int read_sb_page(struct mddev *mddev, loff_t offset,
  			struct page *page,
  			unsigned long index, int size)
a654b9d8f   NeilBrown   [PATCH] md: allow...
144
145
  {
  	/* choose a good rdev and read the page from there */
3cb030020   NeilBrown   md: removing type...
146
  	struct md_rdev *rdev;
a654b9d8f   NeilBrown   [PATCH] md: allow...
147
  	sector_t target;
a654b9d8f   NeilBrown   [PATCH] md: allow...
148

dafb20fa3   NeilBrown   md: tidy up rdev_...
149
  	rdev_for_each(rdev, mddev) {
b2d444d7a   NeilBrown   [PATCH] md: conve...
150
  		if (! test_bit(In_sync, &rdev->flags)
4aaf7694f   Guoqing Jiang   md/bitmap: don't ...
151
152
  		    || test_bit(Faulty, &rdev->flags)
  		    || test_bit(Bitmap_sync, &rdev->flags))
ab904d634   NeilBrown   [PATCH] md: fix b...
153
  			continue;
ccebd4c41   Jonathan Brassow   md-new-param-to_s...
154
  		target = offset + index * (PAGE_SIZE/512);
a654b9d8f   NeilBrown   [PATCH] md: allow...
155

2b193363e   NeilBrown   md: change type o...
156
  		if (sync_page_io(rdev, target,
e1defc4ff   Martin K. Petersen   block: Do away wi...
157
  				 roundup(size, bdev_logical_block_size(rdev->bdev)),
796a5cf08   Mike Christie   md: use bio op ac...
158
  				 page, REQ_OP_READ, 0, true)) {
ab904d634   NeilBrown   [PATCH] md: fix b...
159
  			page->index = index;
27581e5ae   NeilBrown   md/bitmap: centra...
160
  			return 0;
ab904d634   NeilBrown   [PATCH] md: fix b...
161
162
  		}
  	}
27581e5ae   NeilBrown   md/bitmap: centra...
163
  	return -EIO;
a654b9d8f   NeilBrown   [PATCH] md: allow...
164
  }
fd01b88c7   NeilBrown   md: remove typede...
165
  static struct md_rdev *next_active_rdev(struct md_rdev *rdev, struct mddev *mddev)
b2d2c4cea   NeilBrown   Fix problem with ...
166
167
168
169
170
171
172
  {
  	/* Iterate the disks of an mddev, using rcu to protect access to the
  	 * linked list, and raising the refcount of devices we return to ensure
  	 * they don't disappear while in use.
  	 * As devices are only added or removed when raid_disk is < 0 and
  	 * nr_pending is 0 and In_sync is clear, the entries we return will
  	 * still be in the same position on the list when we re-enter
fd177481b   Michael Wang   raid: replace lis...
173
  	 * list_for_each_entry_continue_rcu.
8532e3439   NeilBrown   md/bitmap: remove...
174
175
176
177
178
  	 *
  	 * Note that if entered with 'rdev == NULL' to start at the
  	 * beginning, we temporarily assign 'rdev' to an address which
  	 * isn't really an rdev, but which can be used by
  	 * list_for_each_entry_continue_rcu() to find the first entry.
b2d2c4cea   NeilBrown   Fix problem with ...
179
  	 */
b2d2c4cea   NeilBrown   Fix problem with ...
180
181
182
  	rcu_read_lock();
  	if (rdev == NULL)
  		/* start at the beginning */
8532e3439   NeilBrown   md/bitmap: remove...
183
  		rdev = list_entry(&mddev->disks, struct md_rdev, same_set);
b2d2c4cea   NeilBrown   Fix problem with ...
184
185
186
  	else {
  		/* release the previous rdev and start from there. */
  		rdev_dec_pending(rdev, mddev);
b2d2c4cea   NeilBrown   Fix problem with ...
187
  	}
fd177481b   Michael Wang   raid: replace lis...
188
  	list_for_each_entry_continue_rcu(rdev, &mddev->disks, same_set) {
b2d2c4cea   NeilBrown   Fix problem with ...
189
  		if (rdev->raid_disk >= 0 &&
b2d2c4cea   NeilBrown   Fix problem with ...
190
191
192
193
194
195
196
197
198
199
  		    !test_bit(Faulty, &rdev->flags)) {
  			/* this is a usable devices */
  			atomic_inc(&rdev->nr_pending);
  			rcu_read_unlock();
  			return rdev;
  		}
  	}
  	rcu_read_unlock();
  	return NULL;
  }
ab6085c79   NeilBrown   md: don't write m...
200
  static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
a654b9d8f   NeilBrown   [PATCH] md: allow...
201
  {
46533ff7f   NeilBrown   md: Use REQ_FAILF...
202
  	struct md_rdev *rdev;
a6ff7e089   Jonathan Brassow   md: separate meta...
203
  	struct block_device *bdev;
fd01b88c7   NeilBrown   md: remove typede...
204
  	struct mddev *mddev = bitmap->mddev;
1ec885cdd   NeilBrown   md/bitmap: move s...
205
  	struct bitmap_storage *store = &bitmap->storage;
a654b9d8f   NeilBrown   [PATCH] md: allow...
206

46533ff7f   NeilBrown   md: Use REQ_FAILF...
207
208
  restart:
  	rdev = NULL;
b2d2c4cea   NeilBrown   Fix problem with ...
209
  	while ((rdev = next_active_rdev(rdev, mddev)) != NULL) {
ac2f40be4   NeilBrown   md/bitmap: white ...
210
211
  		int size = PAGE_SIZE;
  		loff_t offset = mddev->bitmap_info.offset;
a6ff7e089   Jonathan Brassow   md: separate meta...
212
213
  
  		bdev = (rdev->meta_bdev) ? rdev->meta_bdev : rdev->bdev;
9b1215c10   NeilBrown   md/bitmap: store ...
214
215
216
217
218
  		if (page->index == store->file_pages-1) {
  			int last_page_size = store->bytes & (PAGE_SIZE-1);
  			if (last_page_size == 0)
  				last_page_size = PAGE_SIZE;
  			size = roundup(last_page_size,
a6ff7e089   Jonathan Brassow   md: separate meta...
219
  				       bdev_logical_block_size(bdev));
9b1215c10   NeilBrown   md/bitmap: store ...
220
  		}
ac2f40be4   NeilBrown   md/bitmap: white ...
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
  		/* Just make sure we aren't corrupting data or
  		 * metadata
  		 */
  		if (mddev->external) {
  			/* Bitmap could be anywhere. */
  			if (rdev->sb_start + offset + (page->index
  						       * (PAGE_SIZE/512))
  			    > rdev->data_offset
  			    &&
  			    rdev->sb_start + offset
  			    < (rdev->data_offset + mddev->dev_sectors
  			     + (PAGE_SIZE/512)))
  				goto bad_alignment;
  		} else if (offset < 0) {
  			/* DATA  BITMAP METADATA  */
  			if (offset
  			    + (long)(page->index * (PAGE_SIZE/512))
  			    + size/512 > 0)
  				/* bitmap runs in to metadata */
  				goto bad_alignment;
  			if (rdev->data_offset + mddev->dev_sectors
  			    > rdev->sb_start + offset)
  				/* data runs in to bitmap */
  				goto bad_alignment;
  		} else if (rdev->sb_start < rdev->data_offset) {
  			/* METADATA BITMAP DATA */
  			if (rdev->sb_start
  			    + offset
  			    + page->index*(PAGE_SIZE/512) + size/512
  			    > rdev->data_offset)
  				/* bitmap runs in to data */
  				goto bad_alignment;
  		} else {
  			/* DATA METADATA BITMAP - no problems */
  		}
  		md_super_write(mddev, rdev,
  			       rdev->sb_start + offset
  			       + page->index * (PAGE_SIZE/512),
  			       size,
  			       page);
b2d2c4cea   NeilBrown   Fix problem with ...
261
  	}
a654b9d8f   NeilBrown   [PATCH] md: allow...
262

46533ff7f   NeilBrown   md: Use REQ_FAILF...
263
264
  	if (wait && md_super_wait(mddev) < 0)
  		goto restart;
a654b9d8f   NeilBrown   [PATCH] md: allow...
265
  	return 0;
4b80991c6   NeilBrown   md: Protect acces...
266
267
  
   bad_alignment:
4b80991c6   NeilBrown   md: Protect acces...
268
  	return -EINVAL;
a654b9d8f   NeilBrown   [PATCH] md: allow...
269
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
270
  static void md_bitmap_file_kick(struct bitmap *bitmap);
32a7627cf   NeilBrown   [PATCH] md: optim...
271
  /*
a654b9d8f   NeilBrown   [PATCH] md: allow...
272
   * write out a page to a file
32a7627cf   NeilBrown   [PATCH] md: optim...
273
   */
4ad136637   NeilBrown   md: change bitmap...
274
  static void write_page(struct bitmap *bitmap, struct page *page, int wait)
32a7627cf   NeilBrown   [PATCH] md: optim...
275
  {
d785a06a0   NeilBrown   [PATCH] md/bitmap...
276
  	struct buffer_head *bh;
32a7627cf   NeilBrown   [PATCH] md: optim...
277

1ec885cdd   NeilBrown   md/bitmap: move s...
278
  	if (bitmap->storage.file == NULL) {
f0d76d70b   NeilBrown   md: check that in...
279
280
  		switch (write_sb_page(bitmap, page, wait)) {
  		case -EINVAL:
b405fe91e   NeilBrown   md/bitmap: use se...
281
  			set_bit(BITMAP_WRITE_ERROR, &bitmap->flags);
f0d76d70b   NeilBrown   md: check that in...
282
  		}
4ad136637   NeilBrown   md: change bitmap...
283
  	} else {
a654b9d8f   NeilBrown   [PATCH] md: allow...
284

4ad136637   NeilBrown   md: change bitmap...
285
  		bh = page_buffers(page);
c708443c0   NeilBrown   [PATCH] md: make ...
286

4ad136637   NeilBrown   md: change bitmap...
287
288
289
290
  		while (bh && bh->b_blocknr) {
  			atomic_inc(&bitmap->pending_writes);
  			set_buffer_locked(bh);
  			set_buffer_mapped(bh);
2a222ca99   Mike Christie   fs: have submit_b...
291
  			submit_bh(REQ_OP_WRITE, REQ_SYNC, bh);
4ad136637   NeilBrown   md: change bitmap...
292
293
  			bh = bh->b_this_page;
  		}
d785a06a0   NeilBrown   [PATCH] md/bitmap...
294

ac2f40be4   NeilBrown   md/bitmap: white ...
295
  		if (wait)
4ad136637   NeilBrown   md: change bitmap...
296
297
  			wait_event(bitmap->write_wait,
  				   atomic_read(&bitmap->pending_writes)==0);
8a5e9cf1d   NeilBrown   [PATCH] md: make ...
298
  	}
b405fe91e   NeilBrown   md/bitmap: use se...
299
  	if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags))
e64e4018d   Andy Shevchenko   md: Avoid namespa...
300
  		md_bitmap_file_kick(bitmap);
d785a06a0   NeilBrown   [PATCH] md/bitmap...
301
302
303
304
305
  }
  
  static void end_bitmap_write(struct buffer_head *bh, int uptodate)
  {
  	struct bitmap *bitmap = bh->b_private;
32a7627cf   NeilBrown   [PATCH] md: optim...
306

b405fe91e   NeilBrown   md/bitmap: use se...
307
308
  	if (!uptodate)
  		set_bit(BITMAP_WRITE_ERROR, &bitmap->flags);
d785a06a0   NeilBrown   [PATCH] md/bitmap...
309
310
311
  	if (atomic_dec_and_test(&bitmap->pending_writes))
  		wake_up(&bitmap->write_wait);
  }
32a7627cf   NeilBrown   [PATCH] md: optim...
312

d785a06a0   NeilBrown   [PATCH] md/bitmap...
313
314
  static void free_buffers(struct page *page)
  {
27581e5ae   NeilBrown   md/bitmap: centra...
315
  	struct buffer_head *bh;
77ad4bc70   NeilBrown   [PATCH] md: enabl...
316

27581e5ae   NeilBrown   md/bitmap: centra...
317
318
319
320
  	if (!PagePrivate(page))
  		return;
  
  	bh = page_buffers(page);
d785a06a0   NeilBrown   [PATCH] md/bitmap...
321
322
323
324
  	while (bh) {
  		struct buffer_head *next = bh->b_this_page;
  		free_buffer_head(bh);
  		bh = next;
77ad4bc70   NeilBrown   [PATCH] md: enabl...
325
  	}
db2c1d86c   Guoqing Jiang   md: remove __clea...
326
  	detach_page_private(page);
d785a06a0   NeilBrown   [PATCH] md/bitmap...
327
  	put_page(page);
32a7627cf   NeilBrown   [PATCH] md: optim...
328
  }
d785a06a0   NeilBrown   [PATCH] md/bitmap...
329
330
331
332
333
334
335
  /* read a page from a file.
   * We both read the page, and attach buffers to the page to record the
   * address of each block (using bmap).  These addresses will be used
   * to write the block later, completely bypassing the filesystem.
   * This usage is similar to how swap files are handled, and allows us
   * to write to a file with no concerns of memory allocation failing.
   */
27581e5ae   NeilBrown   md/bitmap: centra...
336
337
338
339
  static int read_page(struct file *file, unsigned long index,
  		     struct bitmap *bitmap,
  		     unsigned long count,
  		     struct page *page)
32a7627cf   NeilBrown   [PATCH] md: optim...
340
  {
27581e5ae   NeilBrown   md/bitmap: centra...
341
  	int ret = 0;
496ad9aa8   Al Viro   new helper: file_...
342
  	struct inode *inode = file_inode(file);
d785a06a0   NeilBrown   [PATCH] md/bitmap...
343
  	struct buffer_head *bh;
30460e1ea   Carlos Maiolino   fs: Enable bmap()...
344
  	sector_t block, blk_cur;
313b825fa   Xianting Tian   md: only calculat...
345
  	unsigned long blocksize = i_blocksize(inode);
32a7627cf   NeilBrown   [PATCH] md: optim...
346

36a4e1fe0   NeilBrown   md: remove PRINTK...
347
348
349
  	pr_debug("read bitmap file (%dB @ %llu)
  ", (int)PAGE_SIZE,
  		 (unsigned long long)index << PAGE_SHIFT);
32a7627cf   NeilBrown   [PATCH] md: optim...
350

313b825fa   Xianting Tian   md: only calculat...
351
  	bh = alloc_page_buffers(page, blocksize, false);
d785a06a0   NeilBrown   [PATCH] md/bitmap...
352
  	if (!bh) {
27581e5ae   NeilBrown   md/bitmap: centra...
353
  		ret = -ENOMEM;
32a7627cf   NeilBrown   [PATCH] md: optim...
354
355
  		goto out;
  	}
db2c1d86c   Guoqing Jiang   md: remove __clea...
356
  	attach_page_private(page, bh);
30460e1ea   Carlos Maiolino   fs: Enable bmap()...
357
  	blk_cur = index << (PAGE_SHIFT - inode->i_blkbits);
d785a06a0   NeilBrown   [PATCH] md/bitmap...
358
  	while (bh) {
30460e1ea   Carlos Maiolino   fs: Enable bmap()...
359
  		block = blk_cur;
d785a06a0   NeilBrown   [PATCH] md/bitmap...
360
361
362
  		if (count == 0)
  			bh->b_blocknr = 0;
  		else {
30460e1ea   Carlos Maiolino   fs: Enable bmap()...
363
364
  			ret = bmap(inode, &block);
  			if (ret || !block) {
27581e5ae   NeilBrown   md/bitmap: centra...
365
  				ret = -EINVAL;
30460e1ea   Carlos Maiolino   fs: Enable bmap()...
366
  				bh->b_blocknr = 0;
d785a06a0   NeilBrown   [PATCH] md/bitmap...
367
368
  				goto out;
  			}
30460e1ea   Carlos Maiolino   fs: Enable bmap()...
369
370
  
  			bh->b_blocknr = block;
d785a06a0   NeilBrown   [PATCH] md/bitmap...
371
  			bh->b_bdev = inode->i_sb->s_bdev;
313b825fa   Xianting Tian   md: only calculat...
372
  			if (count < blocksize)
d785a06a0   NeilBrown   [PATCH] md/bitmap...
373
374
  				count = 0;
  			else
313b825fa   Xianting Tian   md: only calculat...
375
  				count -= blocksize;
d785a06a0   NeilBrown   [PATCH] md/bitmap...
376
377
378
  
  			bh->b_end_io = end_bitmap_write;
  			bh->b_private = bitmap;
ce25c31bd   NeilBrown   [PATCH] md: Chang...
379
380
381
  			atomic_inc(&bitmap->pending_writes);
  			set_buffer_locked(bh);
  			set_buffer_mapped(bh);
2a222ca99   Mike Christie   fs: have submit_b...
382
  			submit_bh(REQ_OP_READ, 0, bh);
d785a06a0   NeilBrown   [PATCH] md/bitmap...
383
  		}
30460e1ea   Carlos Maiolino   fs: Enable bmap()...
384
  		blk_cur++;
d785a06a0   NeilBrown   [PATCH] md/bitmap...
385
386
  		bh = bh->b_this_page;
  	}
d785a06a0   NeilBrown   [PATCH] md/bitmap...
387
  	page->index = index;
ce25c31bd   NeilBrown   [PATCH] md: Chang...
388
389
390
  
  	wait_event(bitmap->write_wait,
  		   atomic_read(&bitmap->pending_writes)==0);
b405fe91e   NeilBrown   md/bitmap: use se...
391
  	if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags))
27581e5ae   NeilBrown   md/bitmap: centra...
392
  		ret = -EIO;
32a7627cf   NeilBrown   [PATCH] md: optim...
393
  out:
27581e5ae   NeilBrown   md/bitmap: centra...
394
  	if (ret)
ec0cc2268   NeilBrown   md/bitmap: change...
395
396
397
398
399
  		pr_err("md: bitmap read error: (%dB @ %llu): %d
  ",
  		       (int)PAGE_SIZE,
  		       (unsigned long long)index << PAGE_SHIFT,
  		       ret);
27581e5ae   NeilBrown   md/bitmap: centra...
400
  	return ret;
32a7627cf   NeilBrown   [PATCH] md: optim...
401
402
403
404
405
  }
  
  /*
   * bitmap file superblock operations
   */
85c9ccd4f   NeilBrown   md/bitmap: Don't ...
406
  /*
e64e4018d   Andy Shevchenko   md: Avoid namespa...
407
   * md_bitmap_wait_writes() should be called before writing any bitmap
85c9ccd4f   NeilBrown   md/bitmap: Don't ...
408
   * blocks, to ensure previous writes, particularly from
e64e4018d   Andy Shevchenko   md: Avoid namespa...
409
   * md_bitmap_daemon_work(), have completed.
85c9ccd4f   NeilBrown   md/bitmap: Don't ...
410
   */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
411
  static void md_bitmap_wait_writes(struct bitmap *bitmap)
85c9ccd4f   NeilBrown   md/bitmap: Don't ...
412
413
414
415
416
  {
  	if (bitmap->storage.file)
  		wait_event(bitmap->write_wait,
  			   atomic_read(&bitmap->pending_writes)==0);
  	else
46533ff7f   NeilBrown   md: Use REQ_FAILF...
417
418
419
420
421
422
423
  		/* Note that we ignore the return value.  The writes
  		 * might have failed, but that would just mean that
  		 * some bits which should be cleared haven't been,
  		 * which is safe.  The relevant bitmap blocks will
  		 * probably get written again, but there is no great
  		 * loss if they aren't.
  		 */
85c9ccd4f   NeilBrown   md/bitmap: Don't ...
424
425
  		md_super_wait(bitmap->mddev);
  }
32a7627cf   NeilBrown   [PATCH] md: optim...
426
  /* update the event counter and sync the superblock to disk */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
427
  void md_bitmap_update_sb(struct bitmap *bitmap)
32a7627cf   NeilBrown   [PATCH] md: optim...
428
429
  {
  	bitmap_super_t *sb;
32a7627cf   NeilBrown   [PATCH] md: optim...
430
431
  
  	if (!bitmap || !bitmap->mddev) /* no bitmap for this array */
4ad136637   NeilBrown   md: change bitmap...
432
  		return;
ece5cff0d   NeilBrown   md: Support write...
433
434
  	if (bitmap->mddev->bitmap_info.external)
  		return;
1ec885cdd   NeilBrown   md/bitmap: move s...
435
  	if (!bitmap->storage.sb_page) /* no superblock */
4ad136637   NeilBrown   md: change bitmap...
436
  		return;
1ec885cdd   NeilBrown   md/bitmap: move s...
437
  	sb = kmap_atomic(bitmap->storage.sb_page);
32a7627cf   NeilBrown   [PATCH] md: optim...
438
  	sb->events = cpu_to_le64(bitmap->mddev->events);
8258c5320   NeilBrown   md/bitmap: fix sa...
439
  	if (bitmap->mddev->events < bitmap->events_cleared)
a0da84f35   Neil Brown   Improve setting o...
440
441
  		/* rocking back to read-only */
  		bitmap->events_cleared = bitmap->mddev->events;
8258c5320   NeilBrown   md/bitmap: fix sa...
442
  	sb->events_cleared = cpu_to_le64(bitmap->events_cleared);
97f0eb9f0   Hou Tao   md/bitmap: clear ...
443
444
445
446
447
  	/*
  	 * clear BITMAP_WRITE_ERROR bit to protect against the case that
  	 * a bitmap write error occurred but the later writes succeeded.
  	 */
  	sb->state = cpu_to_le32(bitmap->flags & ~BIT(BITMAP_WRITE_ERROR));
43a705076   NeilBrown   md: support updat...
448
449
450
  	/* Just in case these have been changed via sysfs: */
  	sb->daemon_sleep = cpu_to_le32(bitmap->mddev->bitmap_info.daemon_sleep/HZ);
  	sb->write_behind = cpu_to_le32(bitmap->mddev->bitmap_info.max_write_behind);
b81a04048   NeilBrown   md/bitmap: make s...
451
452
453
  	/* This might have been changed by a reshape */
  	sb->sync_size = cpu_to_le64(bitmap->mddev->resync_max_sectors);
  	sb->chunksize = cpu_to_le32(bitmap->mddev->bitmap_info.chunksize);
c4ce867fd   Goldwyn Rodrigues   Introduce md_clus...
454
  	sb->nodes = cpu_to_le32(bitmap->mddev->bitmap_info.nodes);
1dff2b87a   NeilBrown   md/bitmap: record...
455
456
  	sb->sectors_reserved = cpu_to_le32(bitmap->mddev->
  					   bitmap_info.space);
b2f46e688   Cong Wang   md: remove the se...
457
  	kunmap_atomic(sb);
1ec885cdd   NeilBrown   md/bitmap: move s...
458
  	write_page(bitmap, bitmap->storage.sb_page, 1);
32a7627cf   NeilBrown   [PATCH] md: optim...
459
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
460
  EXPORT_SYMBOL(md_bitmap_update_sb);
32a7627cf   NeilBrown   [PATCH] md: optim...
461
462
  
  /* print out the bitmap file superblock */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
463
  void md_bitmap_print_sb(struct bitmap *bitmap)
32a7627cf   NeilBrown   [PATCH] md: optim...
464
465
  {
  	bitmap_super_t *sb;
1ec885cdd   NeilBrown   md/bitmap: move s...
466
  	if (!bitmap || !bitmap->storage.sb_page)
32a7627cf   NeilBrown   [PATCH] md: optim...
467
  		return;
1ec885cdd   NeilBrown   md/bitmap: move s...
468
  	sb = kmap_atomic(bitmap->storage.sb_page);
ec0cc2268   NeilBrown   md/bitmap: change...
469
470
471
472
473
474
475
476
  	pr_debug("%s: bitmap file superblock:
  ", bmname(bitmap));
  	pr_debug("         magic: %08x
  ", le32_to_cpu(sb->magic));
  	pr_debug("       version: %d
  ", le32_to_cpu(sb->version));
  	pr_debug("          uuid: %08x.%08x.%08x.%08x
  ",
c35403f82   Christoph Hellwig   md: use correct t...
477
478
479
480
  		 le32_to_cpu(*(__le32 *)(sb->uuid+0)),
  		 le32_to_cpu(*(__le32 *)(sb->uuid+4)),
  		 le32_to_cpu(*(__le32 *)(sb->uuid+8)),
  		 le32_to_cpu(*(__le32 *)(sb->uuid+12)));
ec0cc2268   NeilBrown   md/bitmap: change...
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
  	pr_debug("        events: %llu
  ",
  		 (unsigned long long) le64_to_cpu(sb->events));
  	pr_debug("events cleared: %llu
  ",
  		 (unsigned long long) le64_to_cpu(sb->events_cleared));
  	pr_debug("         state: %08x
  ", le32_to_cpu(sb->state));
  	pr_debug("     chunksize: %d B
  ", le32_to_cpu(sb->chunksize));
  	pr_debug("  daemon sleep: %ds
  ", le32_to_cpu(sb->daemon_sleep));
  	pr_debug("     sync size: %llu KB
  ",
  		 (unsigned long long)le64_to_cpu(sb->sync_size)/2);
  	pr_debug("max write behind: %d
  ", le32_to_cpu(sb->write_behind));
b2f46e688   Cong Wang   md: remove the se...
498
  	kunmap_atomic(sb);
32a7627cf   NeilBrown   [PATCH] md: optim...
499
  }
9c81075f4   Jonathan Brassow   MD: support initi...
500
501
502
503
504
505
506
507
508
509
510
  /*
   * bitmap_new_disk_sb
   * @bitmap
   *
   * This function is somewhat the reverse of bitmap_read_sb.  bitmap_read_sb
   * reads and verifies the on-disk bitmap superblock and populates bitmap_info.
   * This function verifies 'bitmap_info' and populates the on-disk bitmap
   * structure, which is to be written to disk.
   *
   * Returns: 0 on success, -Exxx on error
   */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
511
  static int md_bitmap_new_disk_sb(struct bitmap *bitmap)
9c81075f4   Jonathan Brassow   MD: support initi...
512
513
514
  {
  	bitmap_super_t *sb;
  	unsigned long chunksize, daemon_sleep, write_behind;
9c81075f4   Jonathan Brassow   MD: support initi...
515

d3b178adb   Goldwyn Rodrigues   md: Skip cluster ...
516
  	bitmap->storage.sb_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
582e2e056   Jianpeng Ma   md/bitmap:Don't u...
517
518
  	if (bitmap->storage.sb_page == NULL)
  		return -ENOMEM;
1ec885cdd   NeilBrown   md/bitmap: move s...
519
  	bitmap->storage.sb_page->index = 0;
9c81075f4   Jonathan Brassow   MD: support initi...
520

1ec885cdd   NeilBrown   md/bitmap: move s...
521
  	sb = kmap_atomic(bitmap->storage.sb_page);
9c81075f4   Jonathan Brassow   MD: support initi...
522
523
524
525
526
527
528
  
  	sb->magic = cpu_to_le32(BITMAP_MAGIC);
  	sb->version = cpu_to_le32(BITMAP_MAJOR_HI);
  
  	chunksize = bitmap->mddev->bitmap_info.chunksize;
  	BUG_ON(!chunksize);
  	if (!is_power_of_2(chunksize)) {
b2f46e688   Cong Wang   md: remove the se...
529
  		kunmap_atomic(sb);
ec0cc2268   NeilBrown   md/bitmap: change...
530
531
  		pr_warn("bitmap chunksize not a power of 2
  ");
9c81075f4   Jonathan Brassow   MD: support initi...
532
533
534
535
536
  		return -EINVAL;
  	}
  	sb->chunksize = cpu_to_le32(chunksize);
  
  	daemon_sleep = bitmap->mddev->bitmap_info.daemon_sleep;
c97e0602b   Eric Engestrom   md/bitmap: remove...
537
  	if (!daemon_sleep || (daemon_sleep > MAX_SCHEDULE_TIMEOUT)) {
ec0cc2268   NeilBrown   md/bitmap: change...
538
539
  		pr_debug("Choosing daemon_sleep default (5 sec)
  ");
9c81075f4   Jonathan Brassow   MD: support initi...
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
  		daemon_sleep = 5 * HZ;
  	}
  	sb->daemon_sleep = cpu_to_le32(daemon_sleep);
  	bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep;
  
  	/*
  	 * FIXME: write_behind for RAID1.  If not specified, what
  	 * is a good choice?  We choose COUNTER_MAX / 2 arbitrarily.
  	 */
  	write_behind = bitmap->mddev->bitmap_info.max_write_behind;
  	if (write_behind > COUNTER_MAX)
  		write_behind = COUNTER_MAX / 2;
  	sb->write_behind = cpu_to_le32(write_behind);
  	bitmap->mddev->bitmap_info.max_write_behind = write_behind;
  
  	/* keep the array size field of the bitmap superblock up to date */
  	sb->sync_size = cpu_to_le64(bitmap->mddev->resync_max_sectors);
  
  	memcpy(sb->uuid, bitmap->mddev->uuid, 16);
b405fe91e   NeilBrown   md/bitmap: use se...
559
  	set_bit(BITMAP_STALE, &bitmap->flags);
84e923453   NeilBrown   md/bitmap: remove...
560
  	sb->state = cpu_to_le32(bitmap->flags);
9c81075f4   Jonathan Brassow   MD: support initi...
561
562
  	bitmap->events_cleared = bitmap->mddev->events;
  	sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
d3b178adb   Goldwyn Rodrigues   md: Skip cluster ...
563
  	bitmap->mddev->bitmap_info.nodes = 0;
9c81075f4   Jonathan Brassow   MD: support initi...
564

b2f46e688   Cong Wang   md: remove the se...
565
  	kunmap_atomic(sb);
9c81075f4   Jonathan Brassow   MD: support initi...
566
567
568
  
  	return 0;
  }
32a7627cf   NeilBrown   [PATCH] md: optim...
569
  /* read the superblock from the bitmap file and initialize some bitmap fields */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
570
  static int md_bitmap_read_sb(struct bitmap *bitmap)
32a7627cf   NeilBrown   [PATCH] md: optim...
571
572
573
  {
  	char *reason = NULL;
  	bitmap_super_t *sb;
4b6d287f6   NeilBrown   [PATCH] md: add w...
574
  	unsigned long chunksize, daemon_sleep, write_behind;
32a7627cf   NeilBrown   [PATCH] md: optim...
575
  	unsigned long long events;
c4ce867fd   Goldwyn Rodrigues   Introduce md_clus...
576
  	int nodes = 0;
1dff2b87a   NeilBrown   md/bitmap: record...
577
  	unsigned long sectors_reserved = 0;
32a7627cf   NeilBrown   [PATCH] md: optim...
578
  	int err = -EINVAL;
27581e5ae   NeilBrown   md/bitmap: centra...
579
  	struct page *sb_page;
33e38ac68   Goldwyn Rodrigues   md-cluster: fix b...
580
  	loff_t offset = bitmap->mddev->bitmap_info.offset;
32a7627cf   NeilBrown   [PATCH] md: optim...
581

1ec885cdd   NeilBrown   md/bitmap: move s...
582
  	if (!bitmap->storage.file && !bitmap->mddev->bitmap_info.offset) {
ef99bf480   NeilBrown   md/bitmap: allow ...
583
584
585
  		chunksize = 128 * 1024 * 1024;
  		daemon_sleep = 5 * HZ;
  		write_behind = 0;
b405fe91e   NeilBrown   md/bitmap: use se...
586
  		set_bit(BITMAP_STALE, &bitmap->flags);
ef99bf480   NeilBrown   md/bitmap: allow ...
587
588
589
  		err = 0;
  		goto out_no_sb;
  	}
32a7627cf   NeilBrown   [PATCH] md: optim...
590
  	/* page 0 is the superblock, read it... */
27581e5ae   NeilBrown   md/bitmap: centra...
591
592
593
  	sb_page = alloc_page(GFP_KERNEL);
  	if (!sb_page)
  		return -ENOMEM;
1ec885cdd   NeilBrown   md/bitmap: move s...
594
  	bitmap->storage.sb_page = sb_page;
27581e5ae   NeilBrown   md/bitmap: centra...
595

b97e92574   Goldwyn Rodrigues   Use separate bitm...
596
  re_read:
f9209a323   Goldwyn Rodrigues   bitmap_create ret...
597
598
  	/* If cluster_slot is set, the cluster is setup */
  	if (bitmap->cluster_slot >= 0) {
3b0e6aacb   Stephen Rothwell   md/bitmap: use se...
599
  		sector_t bm_blocks = bitmap->mddev->resync_max_sectors;
f9209a323   Goldwyn Rodrigues   bitmap_create ret...
600

a913096de   Zhao Heming   md/bitmap: md_bit...
601
602
  		bm_blocks = DIV_ROUND_UP_SECTOR_T(bm_blocks,
  			   (bitmap->mddev->bitmap_info.chunksize >> 9));
124eb761e   Goldwyn Rodrigues   md: Fix bitmap of...
603
604
605
  		/* bits to bytes */
  		bm_blocks = ((bm_blocks+7) >> 3) + sizeof(bitmap_super_t);
  		/* to 4k blocks */
935f3d4fc   NeilBrown   md/bitmap: fix in...
606
  		bm_blocks = DIV_ROUND_UP_SECTOR_T(bm_blocks, 4096);
33e38ac68   Goldwyn Rodrigues   md-cluster: fix b...
607
  		offset = bitmap->mddev->bitmap_info.offset + (bitmap->cluster_slot * (bm_blocks << 3));
ec0cc2268   NeilBrown   md/bitmap: change...
608
609
  		pr_debug("%s:%d bm slot: %d offset: %llu
  ", __func__, __LINE__,
33e38ac68   Goldwyn Rodrigues   md-cluster: fix b...
610
  			bitmap->cluster_slot, offset);
f9209a323   Goldwyn Rodrigues   bitmap_create ret...
611
  	}
1ec885cdd   NeilBrown   md/bitmap: move s...
612
613
  	if (bitmap->storage.file) {
  		loff_t isize = i_size_read(bitmap->storage.file->f_mapping->host);
f49d5e62d   NeilBrown   [PATCH] md: avoid...
614
  		int bytes = isize > PAGE_SIZE ? PAGE_SIZE : isize;
1ec885cdd   NeilBrown   md/bitmap: move s...
615
  		err = read_page(bitmap->storage.file, 0,
27581e5ae   NeilBrown   md/bitmap: centra...
616
  				bitmap, bytes, sb_page);
f49d5e62d   NeilBrown   [PATCH] md: avoid...
617
  	} else {
27581e5ae   NeilBrown   md/bitmap: centra...
618
  		err = read_sb_page(bitmap->mddev,
33e38ac68   Goldwyn Rodrigues   md-cluster: fix b...
619
  				   offset,
27581e5ae   NeilBrown   md/bitmap: centra...
620
  				   sb_page,
938b533d4   Shaohua Li   md/bitmap: revert...
621
  				   0, sizeof(bitmap_super_t));
a654b9d8f   NeilBrown   [PATCH] md: allow...
622
  	}
27581e5ae   NeilBrown   md/bitmap: centra...
623
  	if (err)
32a7627cf   NeilBrown   [PATCH] md: optim...
624
  		return err;
32a7627cf   NeilBrown   [PATCH] md: optim...
625

b97e92574   Goldwyn Rodrigues   Use separate bitm...
626
  	err = -EINVAL;
27581e5ae   NeilBrown   md/bitmap: centra...
627
  	sb = kmap_atomic(sb_page);
32a7627cf   NeilBrown   [PATCH] md: optim...
628

32a7627cf   NeilBrown   [PATCH] md: optim...
629
  	chunksize = le32_to_cpu(sb->chunksize);
1b04be96f   NeilBrown   md: change daemon...
630
  	daemon_sleep = le32_to_cpu(sb->daemon_sleep) * HZ;
4b6d287f6   NeilBrown   [PATCH] md: add w...
631
  	write_behind = le32_to_cpu(sb->write_behind);
1dff2b87a   NeilBrown   md/bitmap: record...
632
  	sectors_reserved = le32_to_cpu(sb->sectors_reserved);
3c462c880   Goldwyn Rodrigues   md: Increment ver...
633
634
  	/* Setup nodes/clustername only if bitmap version is
  	 * cluster-compatible
d3b178adb   Goldwyn Rodrigues   md: Skip cluster ...
635
  	 */
3c462c880   Goldwyn Rodrigues   md: Increment ver...
636
  	if (sb->version == cpu_to_le32(BITMAP_MAJOR_CLUSTERED)) {
d3b178adb   Goldwyn Rodrigues   md: Skip cluster ...
637
638
639
640
  		nodes = le32_to_cpu(sb->nodes);
  		strlcpy(bitmap->mddev->bitmap_info.cluster_name,
  				sb->cluster_name, 64);
  	}
32a7627cf   NeilBrown   [PATCH] md: optim...
641
642
643
644
  
  	/* verify that the bitmap-specific fields are valid */
  	if (sb->magic != cpu_to_le32(BITMAP_MAGIC))
  		reason = "bad magic";
bd926c63b   NeilBrown   [PATCH] md: make ...
645
  	else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO ||
3c462c880   Goldwyn Rodrigues   md: Increment ver...
646
  		 le32_to_cpu(sb->version) > BITMAP_MAJOR_CLUSTERED)
32a7627cf   NeilBrown   [PATCH] md: optim...
647
  		reason = "unrecognized superblock version";
1187cf0a3   NeilBrown   md: Allow write-i...
648
  	else if (chunksize < 512)
7dd5d34c6   NeilBrown   [PATCH] md: remov...
649
  		reason = "bitmap chunksize too small";
d744540cd   Jonathan Brassow   MD: use is_power_...
650
  	else if (!is_power_of_2(chunksize))
32a7627cf   NeilBrown   [PATCH] md: optim...
651
  		reason = "bitmap chunksize not a power of 2";
1b04be96f   NeilBrown   md: change daemon...
652
  	else if (daemon_sleep < 1 || daemon_sleep > MAX_SCHEDULE_TIMEOUT)
7dd5d34c6   NeilBrown   [PATCH] md: remov...
653
  		reason = "daemon sleep period out of range";
4b6d287f6   NeilBrown   [PATCH] md: add w...
654
655
  	else if (write_behind > COUNTER_MAX)
  		reason = "write-behind limit out of range (0 - 16383)";
32a7627cf   NeilBrown   [PATCH] md: optim...
656
  	if (reason) {
ec0cc2268   NeilBrown   md/bitmap: change...
657
658
  		pr_warn("%s: invalid bitmap file superblock: %s
  ",
32a7627cf   NeilBrown   [PATCH] md: optim...
659
660
661
662
663
664
  			bmname(bitmap), reason);
  		goto out;
  	}
  
  	/* keep the array size field of the bitmap superblock up to date */
  	sb->sync_size = cpu_to_le64(bitmap->mddev->resync_max_sectors);
278c1ca2f   NeilBrown   md/bitmap: change...
665
666
667
668
669
670
  	if (bitmap->mddev->persistent) {
  		/*
  		 * We have a persistent array superblock, so compare the
  		 * bitmap's UUID and event counter to the mddev's
  		 */
  		if (memcmp(sb->uuid, bitmap->mddev->uuid, 16)) {
ec0cc2268   NeilBrown   md/bitmap: change...
671
672
673
  			pr_warn("%s: bitmap superblock UUID mismatch
  ",
  				bmname(bitmap));
278c1ca2f   NeilBrown   md/bitmap: change...
674
675
676
  			goto out;
  		}
  		events = le64_to_cpu(sb->events);
b97e92574   Goldwyn Rodrigues   Use separate bitm...
677
  		if (!nodes && (events < bitmap->mddev->events)) {
ec0cc2268   NeilBrown   md/bitmap: change...
678
679
680
681
  			pr_warn("%s: bitmap file is out of date (%llu < %llu) -- forcing full recovery
  ",
  				bmname(bitmap), events,
  				(unsigned long long) bitmap->mddev->events);
b405fe91e   NeilBrown   md/bitmap: use se...
682
  			set_bit(BITMAP_STALE, &bitmap->flags);
278c1ca2f   NeilBrown   md/bitmap: change...
683
  		}
32a7627cf   NeilBrown   [PATCH] md: optim...
684
  	}
278c1ca2f   NeilBrown   md/bitmap: change...
685

32a7627cf   NeilBrown   [PATCH] md: optim...
686
  	/* assign fields using values from superblock */
4f2e639af   NeilBrown   [PATCH] md: endia...
687
  	bitmap->flags |= le32_to_cpu(sb->state);
bd926c63b   NeilBrown   [PATCH] md: make ...
688
  	if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN)
b405fe91e   NeilBrown   md/bitmap: use se...
689
  		set_bit(BITMAP_HOSTENDIAN, &bitmap->flags);
32a7627cf   NeilBrown   [PATCH] md: optim...
690
  	bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
cf921cc19   Goldwyn Rodrigues   Add node recovery...
691
  	strlcpy(bitmap->mddev->bitmap_info.cluster_name, sb->cluster_name, 64);
32a7627cf   NeilBrown   [PATCH] md: optim...
692
  	err = 0;
b97e92574   Goldwyn Rodrigues   Use separate bitm...
693

32a7627cf   NeilBrown   [PATCH] md: optim...
694
  out:
b2f46e688   Cong Wang   md: remove the se...
695
  	kunmap_atomic(sb);
3560741e3   Zhilong Liu   md: fix several t...
696
  	/* Assigning chunksize is required for "re_read" */
f9209a323   Goldwyn Rodrigues   bitmap_create ret...
697
  	bitmap->mddev->bitmap_info.chunksize = chunksize;
f73572731   Goldwyn Rodrigues   md: Skip cluster ...
698
  	if (err == 0 && nodes && (bitmap->cluster_slot < 0)) {
b97e92574   Goldwyn Rodrigues   Use separate bitm...
699
700
  		err = md_setup_cluster(bitmap->mddev, nodes);
  		if (err) {
ec0cc2268   NeilBrown   md/bitmap: change...
701
702
703
  			pr_warn("%s: Could not setup cluster service (%d)
  ",
  				bmname(bitmap), err);
b97e92574   Goldwyn Rodrigues   Use separate bitm...
704
705
706
  			goto out_no_sb;
  		}
  		bitmap->cluster_slot = md_cluster_ops->slot_number(bitmap->mddev);
b97e92574   Goldwyn Rodrigues   Use separate bitm...
707
708
  		goto re_read;
  	}
ef99bf480   NeilBrown   md/bitmap: allow ...
709
  out_no_sb:
b405fe91e   NeilBrown   md/bitmap: use se...
710
  	if (test_bit(BITMAP_STALE, &bitmap->flags))
ef99bf480   NeilBrown   md/bitmap: allow ...
711
712
713
714
  		bitmap->events_cleared = bitmap->mddev->events;
  	bitmap->mddev->bitmap_info.chunksize = chunksize;
  	bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep;
  	bitmap->mddev->bitmap_info.max_write_behind = write_behind;
c4ce867fd   Goldwyn Rodrigues   Introduce md_clus...
715
  	bitmap->mddev->bitmap_info.nodes = nodes;
1dff2b87a   NeilBrown   md/bitmap: record...
716
717
718
  	if (bitmap->mddev->bitmap_info.space == 0 ||
  	    bitmap->mddev->bitmap_info.space > sectors_reserved)
  		bitmap->mddev->bitmap_info.space = sectors_reserved;
b97e92574   Goldwyn Rodrigues   Use separate bitm...
719
  	if (err) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
720
  		md_bitmap_print_sb(bitmap);
f9209a323   Goldwyn Rodrigues   bitmap_create ret...
721
  		if (bitmap->cluster_slot < 0)
b97e92574   Goldwyn Rodrigues   Use separate bitm...
722
723
  			md_cluster_stop(bitmap->mddev);
  	}
32a7627cf   NeilBrown   [PATCH] md: optim...
724
725
  	return err;
  }
32a7627cf   NeilBrown   [PATCH] md: optim...
726
727
728
  /*
   * general bitmap file operations
   */
ece5cff0d   NeilBrown   md: Support write...
729
730
731
732
733
734
  /*
   * on-disk bitmap:
   *
   * Use one bit per "chunk" (block set). We do the disk I/O on the bitmap
   * file a page at a time. There's a superblock at the start of the file.
   */
32a7627cf   NeilBrown   [PATCH] md: optim...
735
  /* calculate the index of the page that contains this bit */
1ec885cdd   NeilBrown   md/bitmap: move s...
736
737
  static inline unsigned long file_page_index(struct bitmap_storage *store,
  					    unsigned long chunk)
32a7627cf   NeilBrown   [PATCH] md: optim...
738
  {
1ec885cdd   NeilBrown   md/bitmap: move s...
739
  	if (store->sb_page)
ece5cff0d   NeilBrown   md: Support write...
740
741
  		chunk += sizeof(bitmap_super_t) << 3;
  	return chunk >> PAGE_BIT_SHIFT;
32a7627cf   NeilBrown   [PATCH] md: optim...
742
743
744
  }
  
  /* calculate the (bit) offset of this bit within a page */
1ec885cdd   NeilBrown   md/bitmap: move s...
745
746
  static inline unsigned long file_page_offset(struct bitmap_storage *store,
  					     unsigned long chunk)
32a7627cf   NeilBrown   [PATCH] md: optim...
747
  {
1ec885cdd   NeilBrown   md/bitmap: move s...
748
  	if (store->sb_page)
ece5cff0d   NeilBrown   md: Support write...
749
750
  		chunk += sizeof(bitmap_super_t) << 3;
  	return chunk & (PAGE_BITS - 1);
32a7627cf   NeilBrown   [PATCH] md: optim...
751
752
753
754
755
  }
  
  /*
   * return a pointer to the page in the filemap that contains the given bit
   *
32a7627cf   NeilBrown   [PATCH] md: optim...
756
   */
1ec885cdd   NeilBrown   md/bitmap: move s...
757
  static inline struct page *filemap_get_page(struct bitmap_storage *store,
3520fa4db   Jonathan Brassow   MD bitmap: Revert...
758
  					    unsigned long chunk)
32a7627cf   NeilBrown   [PATCH] md: optim...
759
  {
1ec885cdd   NeilBrown   md/bitmap: move s...
760
  	if (file_page_index(store, chunk) >= store->file_pages)
ac2f40be4   NeilBrown   md/bitmap: white ...
761
  		return NULL;
f2e06c588   NeilBrown   md/bitmap: remove...
762
  	return store->filemap[file_page_index(store, chunk)];
32a7627cf   NeilBrown   [PATCH] md: optim...
763
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
764
765
766
  static int md_bitmap_storage_alloc(struct bitmap_storage *store,
  				   unsigned long chunks, int with_super,
  				   int slot_number)
d1244cb06   NeilBrown   md/bitmap: separa...
767
  {
b97e92574   Goldwyn Rodrigues   Use separate bitm...
768
  	int pnum, offset = 0;
d1244cb06   NeilBrown   md/bitmap: separa...
769
770
771
772
773
774
775
776
  	unsigned long num_pages;
  	unsigned long bytes;
  
  	bytes = DIV_ROUND_UP(chunks, 8);
  	if (with_super)
  		bytes += sizeof(bitmap_super_t);
  
  	num_pages = DIV_ROUND_UP(bytes, PAGE_SIZE);
7f86ffed9   Guoqing Jiang   md-cluster/bitmap...
777
  	offset = slot_number * num_pages;
d1244cb06   NeilBrown   md/bitmap: separa...
778

6da2ec560   Kees Cook   treewide: kmalloc...
779
780
  	store->filemap = kmalloc_array(num_pages, sizeof(struct page *),
  				       GFP_KERNEL);
d1244cb06   NeilBrown   md/bitmap: separa...
781
782
783
784
  	if (!store->filemap)
  		return -ENOMEM;
  
  	if (with_super && !store->sb_page) {
d60b479d1   NeilBrown   md/bitmap: add bi...
785
  		store->sb_page = alloc_page(GFP_KERNEL|__GFP_ZERO);
d1244cb06   NeilBrown   md/bitmap: separa...
786
787
  		if (store->sb_page == NULL)
  			return -ENOMEM;
d1244cb06   NeilBrown   md/bitmap: separa...
788
  	}
b97e92574   Goldwyn Rodrigues   Use separate bitm...
789

d1244cb06   NeilBrown   md/bitmap: separa...
790
791
792
793
  	pnum = 0;
  	if (store->sb_page) {
  		store->filemap[0] = store->sb_page;
  		pnum = 1;
b97e92574   Goldwyn Rodrigues   Use separate bitm...
794
  		store->sb_page->index = offset;
d1244cb06   NeilBrown   md/bitmap: separa...
795
  	}
b97e92574   Goldwyn Rodrigues   Use separate bitm...
796

d1244cb06   NeilBrown   md/bitmap: separa...
797
  	for ( ; pnum < num_pages; pnum++) {
d60b479d1   NeilBrown   md/bitmap: add bi...
798
  		store->filemap[pnum] = alloc_page(GFP_KERNEL|__GFP_ZERO);
d1244cb06   NeilBrown   md/bitmap: separa...
799
800
801
802
  		if (!store->filemap[pnum]) {
  			store->file_pages = pnum;
  			return -ENOMEM;
  		}
b97e92574   Goldwyn Rodrigues   Use separate bitm...
803
  		store->filemap[pnum]->index = pnum + offset;
d1244cb06   NeilBrown   md/bitmap: separa...
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
  	}
  	store->file_pages = pnum;
  
  	/* We need 4 bits per page, rounded up to a multiple
  	 * of sizeof(unsigned long) */
  	store->filemap_attr = kzalloc(
  		roundup(DIV_ROUND_UP(num_pages*4, 8), sizeof(unsigned long)),
  		GFP_KERNEL);
  	if (!store->filemap_attr)
  		return -ENOMEM;
  
  	store->bytes = bytes;
  
  	return 0;
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
819
  static void md_bitmap_file_unmap(struct bitmap_storage *store)
32a7627cf   NeilBrown   [PATCH] md: optim...
820
821
  {
  	struct page **map, *sb_page;
32a7627cf   NeilBrown   [PATCH] md: optim...
822
  	int pages;
fae7d326c   NeilBrown   md/bitmap: merge ...
823
  	struct file *file;
32a7627cf   NeilBrown   [PATCH] md: optim...
824

fae7d326c   NeilBrown   md/bitmap: merge ...
825
  	file = store->file;
1ec885cdd   NeilBrown   md/bitmap: move s...
826
  	map = store->filemap;
1ec885cdd   NeilBrown   md/bitmap: move s...
827
  	pages = store->file_pages;
1ec885cdd   NeilBrown   md/bitmap: move s...
828
  	sb_page = store->sb_page;
32a7627cf   NeilBrown   [PATCH] md: optim...
829
830
  
  	while (pages--)
ece5cff0d   NeilBrown   md: Support write...
831
  		if (map[pages] != sb_page) /* 0 is sb_page, release it below */
d785a06a0   NeilBrown   [PATCH] md/bitmap...
832
  			free_buffers(map[pages]);
32a7627cf   NeilBrown   [PATCH] md: optim...
833
  	kfree(map);
fae7d326c   NeilBrown   md/bitmap: merge ...
834
  	kfree(store->filemap_attr);
32a7627cf   NeilBrown   [PATCH] md: optim...
835

d785a06a0   NeilBrown   [PATCH] md/bitmap...
836
837
  	if (sb_page)
  		free_buffers(sb_page);
32a7627cf   NeilBrown   [PATCH] md: optim...
838

d785a06a0   NeilBrown   [PATCH] md/bitmap...
839
  	if (file) {
496ad9aa8   Al Viro   new helper: file_...
840
  		struct inode *inode = file_inode(file);
fc0ecff69   Andrew Morton   [PATCH] remove in...
841
  		invalidate_mapping_pages(inode->i_mapping, 0, -1);
32a7627cf   NeilBrown   [PATCH] md: optim...
842
  		fput(file);
d785a06a0   NeilBrown   [PATCH] md/bitmap...
843
  	}
32a7627cf   NeilBrown   [PATCH] md: optim...
844
  }
32a7627cf   NeilBrown   [PATCH] md: optim...
845
846
847
848
849
  /*
   * bitmap_file_kick - if an error occurs while manipulating the bitmap file
   * then it is no longer reliable, so we stop using it and we mark the file
   * as failed in the superblock
   */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
850
  static void md_bitmap_file_kick(struct bitmap *bitmap)
32a7627cf   NeilBrown   [PATCH] md: optim...
851
852
  {
  	char *path, *ptr = NULL;
b405fe91e   NeilBrown   md/bitmap: use se...
853
  	if (!test_and_set_bit(BITMAP_STALE, &bitmap->flags)) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
854
  		md_bitmap_update_sb(bitmap);
32a7627cf   NeilBrown   [PATCH] md: optim...
855

1ec885cdd   NeilBrown   md/bitmap: move s...
856
  		if (bitmap->storage.file) {
4ad136637   NeilBrown   md: change bitmap...
857
858
  			path = kmalloc(PAGE_SIZE, GFP_KERNEL);
  			if (path)
9bf39ab2a   Miklos Szeredi   vfs: add file_pat...
859
  				ptr = file_path(bitmap->storage.file,
1ec885cdd   NeilBrown   md/bitmap: move s...
860
  					     path, PAGE_SIZE);
6bcfd6018   Christoph Hellwig   md: kill file_pat...
861

ec0cc2268   NeilBrown   md/bitmap: change...
862
863
864
  			pr_warn("%s: kicking failed bitmap file %s from array!
  ",
  				bmname(bitmap), IS_ERR(ptr) ? "" : ptr);
32a7627cf   NeilBrown   [PATCH] md: optim...
865

4ad136637   NeilBrown   md: change bitmap...
866
867
  			kfree(path);
  		} else
ec0cc2268   NeilBrown   md/bitmap: change...
868
869
870
  			pr_warn("%s: disabling internal bitmap due to errors
  ",
  				bmname(bitmap));
a654b9d8f   NeilBrown   [PATCH] md: allow...
871
  	}
32a7627cf   NeilBrown   [PATCH] md: optim...
872
873
874
  }
  
  enum bitmap_page_attr {
ac2f40be4   NeilBrown   md/bitmap: white ...
875
  	BITMAP_PAGE_DIRTY = 0,     /* there are set bits that need to be synced */
5a537df44   NeilBrown   md/bitmap: rename...
876
877
  	BITMAP_PAGE_PENDING = 1,   /* there are bits that are being cleaned.
  				    * i.e. counter is 1 or 2. */
ac2f40be4   NeilBrown   md/bitmap: white ...
878
  	BITMAP_PAGE_NEEDWRITE = 2, /* there are cleared bits that need to be synced */
32a7627cf   NeilBrown   [PATCH] md: optim...
879
  };
d189122d4   NeilBrown   md/bitmap: change...
880
881
  static inline void set_page_attr(struct bitmap *bitmap, int pnum,
  				 enum bitmap_page_attr attr)
32a7627cf   NeilBrown   [PATCH] md: optim...
882
  {
bdfd11407   NeilBrown   md/bitmap: make _...
883
  	set_bit((pnum<<2) + attr, bitmap->storage.filemap_attr);
32a7627cf   NeilBrown   [PATCH] md: optim...
884
  }
d189122d4   NeilBrown   md/bitmap: change...
885
886
  static inline void clear_page_attr(struct bitmap *bitmap, int pnum,
  				   enum bitmap_page_attr attr)
32a7627cf   NeilBrown   [PATCH] md: optim...
887
  {
bdfd11407   NeilBrown   md/bitmap: make _...
888
  	clear_bit((pnum<<2) + attr, bitmap->storage.filemap_attr);
32a7627cf   NeilBrown   [PATCH] md: optim...
889
  }
bdfd11407   NeilBrown   md/bitmap: make _...
890
891
  static inline int test_page_attr(struct bitmap *bitmap, int pnum,
  				 enum bitmap_page_attr attr)
32a7627cf   NeilBrown   [PATCH] md: optim...
892
  {
1ec885cdd   NeilBrown   md/bitmap: move s...
893
  	return test_bit((pnum<<2) + attr, bitmap->storage.filemap_attr);
32a7627cf   NeilBrown   [PATCH] md: optim...
894
  }
bdfd11407   NeilBrown   md/bitmap: make _...
895
896
897
898
899
900
  static inline int test_and_clear_page_attr(struct bitmap *bitmap, int pnum,
  					   enum bitmap_page_attr attr)
  {
  	return test_and_clear_bit((pnum<<2) + attr,
  				  bitmap->storage.filemap_attr);
  }
32a7627cf   NeilBrown   [PATCH] md: optim...
901
902
903
904
905
906
907
  /*
   * bitmap_file_set_bit -- called before performing a write to the md device
   * to set (and eventually sync) a particular bit in the bitmap file
   *
   * we set the bit immediately, then we record the page number so that
   * when an unplug occurs, we can flush the dirty pages out to disk
   */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
908
  static void md_bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
32a7627cf   NeilBrown   [PATCH] md: optim...
909
910
  {
  	unsigned long bit;
3520fa4db   Jonathan Brassow   MD bitmap: Revert...
911
  	struct page *page;
32a7627cf   NeilBrown   [PATCH] md: optim...
912
  	void *kaddr;
40cffcc0e   NeilBrown   md/bitmap: create...
913
  	unsigned long chunk = block >> bitmap->counts.chunkshift;
23cea66a3   Guoqing Jiang   md-cluster/bitmap...
914
915
916
917
918
  	struct bitmap_storage *store = &bitmap->storage;
  	unsigned long node_offset = 0;
  
  	if (mddev_is_clustered(bitmap->mddev))
  		node_offset = bitmap->cluster_slot * store->file_pages;
32a7627cf   NeilBrown   [PATCH] md: optim...
919

1ec885cdd   NeilBrown   md/bitmap: move s...
920
  	page = filemap_get_page(&bitmap->storage, chunk);
3520fa4db   Jonathan Brassow   MD bitmap: Revert...
921
922
  	if (!page)
  		return;
1ec885cdd   NeilBrown   md/bitmap: move s...
923
  	bit = file_page_offset(&bitmap->storage, chunk);
32a7627cf   NeilBrown   [PATCH] md: optim...
924

3520fa4db   Jonathan Brassow   MD bitmap: Revert...
925
  	/* set the bit */
b2f46e688   Cong Wang   md: remove the se...
926
  	kaddr = kmap_atomic(page);
b405fe91e   NeilBrown   md/bitmap: use se...
927
  	if (test_bit(BITMAP_HOSTENDIAN, &bitmap->flags))
3520fa4db   Jonathan Brassow   MD bitmap: Revert...
928
929
  		set_bit(bit, kaddr);
  	else
3f810b6c4   Akinobu Mita   md: use set_bit_l...
930
  		set_bit_le(bit, kaddr);
b2f46e688   Cong Wang   md: remove the se...
931
  	kunmap_atomic(kaddr);
36a4e1fe0   NeilBrown   md: remove PRINTK...
932
933
  	pr_debug("set file bit %lu page %lu
  ", bit, page->index);
32a7627cf   NeilBrown   [PATCH] md: optim...
934
  	/* record page number so it gets flushed to disk when unplug occurs */
23cea66a3   Guoqing Jiang   md-cluster/bitmap...
935
  	set_page_attr(bitmap, page->index - node_offset, BITMAP_PAGE_DIRTY);
32a7627cf   NeilBrown   [PATCH] md: optim...
936
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
937
  static void md_bitmap_file_clear_bit(struct bitmap *bitmap, sector_t block)
ef99bf480   NeilBrown   md/bitmap: allow ...
938
939
940
941
  {
  	unsigned long bit;
  	struct page *page;
  	void *paddr;
40cffcc0e   NeilBrown   md/bitmap: create...
942
  	unsigned long chunk = block >> bitmap->counts.chunkshift;
23cea66a3   Guoqing Jiang   md-cluster/bitmap...
943
944
945
946
947
  	struct bitmap_storage *store = &bitmap->storage;
  	unsigned long node_offset = 0;
  
  	if (mddev_is_clustered(bitmap->mddev))
  		node_offset = bitmap->cluster_slot * store->file_pages;
ef99bf480   NeilBrown   md/bitmap: allow ...
948

1ec885cdd   NeilBrown   md/bitmap: move s...
949
  	page = filemap_get_page(&bitmap->storage, chunk);
ef99bf480   NeilBrown   md/bitmap: allow ...
950
951
  	if (!page)
  		return;
1ec885cdd   NeilBrown   md/bitmap: move s...
952
  	bit = file_page_offset(&bitmap->storage, chunk);
ef99bf480   NeilBrown   md/bitmap: allow ...
953
  	paddr = kmap_atomic(page);
b405fe91e   NeilBrown   md/bitmap: use se...
954
  	if (test_bit(BITMAP_HOSTENDIAN, &bitmap->flags))
ef99bf480   NeilBrown   md/bitmap: allow ...
955
956
  		clear_bit(bit, paddr);
  	else
3f810b6c4   Akinobu Mita   md: use set_bit_l...
957
  		clear_bit_le(bit, paddr);
ef99bf480   NeilBrown   md/bitmap: allow ...
958
  	kunmap_atomic(paddr);
23cea66a3   Guoqing Jiang   md-cluster/bitmap...
959
960
  	if (!test_page_attr(bitmap, page->index - node_offset, BITMAP_PAGE_NEEDWRITE)) {
  		set_page_attr(bitmap, page->index - node_offset, BITMAP_PAGE_PENDING);
ef99bf480   NeilBrown   md/bitmap: allow ...
961
962
963
  		bitmap->allclean = 0;
  	}
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
964
  static int md_bitmap_file_test_bit(struct bitmap *bitmap, sector_t block)
11dd35daa   Goldwyn Rodrigues   Copy set bits fro...
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
  {
  	unsigned long bit;
  	struct page *page;
  	void *paddr;
  	unsigned long chunk = block >> bitmap->counts.chunkshift;
  	int set = 0;
  
  	page = filemap_get_page(&bitmap->storage, chunk);
  	if (!page)
  		return -EINVAL;
  	bit = file_page_offset(&bitmap->storage, chunk);
  	paddr = kmap_atomic(page);
  	if (test_bit(BITMAP_HOSTENDIAN, &bitmap->flags))
  		set = test_bit(bit, paddr);
  	else
  		set = test_bit_le(bit, paddr);
  	kunmap_atomic(paddr);
  	return set;
  }
32a7627cf   NeilBrown   [PATCH] md: optim...
984
985
986
  /* this gets called when the md device is ready to unplug its underlying
   * (slave) device queues -- before we let any writes go down, we need to
   * sync the dirty pages of the bitmap file to disk */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
987
  void md_bitmap_unplug(struct bitmap *bitmap)
32a7627cf   NeilBrown   [PATCH] md: optim...
988
  {
746671234   NeilBrown   md/bitmap: conver...
989
  	unsigned long i;
ec7a3197f   NeilBrown   [PATCH] md/bitmap...
990
  	int dirty, need_write;
85c9ccd4f   NeilBrown   md/bitmap: Don't ...
991
  	int writing = 0;
32a7627cf   NeilBrown   [PATCH] md: optim...
992

62f82faac   NeilBrown   md/bitmap: remove...
993
994
  	if (!bitmap || !bitmap->storage.filemap ||
  	    test_bit(BITMAP_STALE, &bitmap->flags))
4ad136637   NeilBrown   md: change bitmap...
995
  		return;
32a7627cf   NeilBrown   [PATCH] md: optim...
996
997
998
  
  	/* look at each page to see if there are any set bits that need to be
  	 * flushed out to disk */
1ec885cdd   NeilBrown   md/bitmap: move s...
999
  	for (i = 0; i < bitmap->storage.file_pages; i++) {
bdfd11407   NeilBrown   md/bitmap: make _...
1000
1001
1002
1003
  		dirty = test_and_clear_page_attr(bitmap, i, BITMAP_PAGE_DIRTY);
  		need_write = test_and_clear_page_attr(bitmap, i,
  						      BITMAP_PAGE_NEEDWRITE);
  		if (dirty || need_write) {
581dbd94d   NeilBrown   md/bitmap: add bl...
1004
  			if (!writing) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1005
  				md_bitmap_wait_writes(bitmap);
581dbd94d   NeilBrown   md/bitmap: add bl...
1006
1007
1008
1009
  				if (bitmap->mddev->queue)
  					blk_add_trace_msg(bitmap->mddev->queue,
  							  "md bitmap_unplug");
  			}
d189122d4   NeilBrown   md/bitmap: change...
1010
  			clear_page_attr(bitmap, i, BITMAP_PAGE_PENDING);
bdfd11407   NeilBrown   md/bitmap: make _...
1011
  			write_page(bitmap, bitmap->storage.filemap[i], 0);
85c9ccd4f   NeilBrown   md/bitmap: Don't ...
1012
  			writing = 1;
bdfd11407   NeilBrown   md/bitmap: make _...
1013
  		}
32a7627cf   NeilBrown   [PATCH] md: optim...
1014
  	}
85c9ccd4f   NeilBrown   md/bitmap: Don't ...
1015
  	if (writing)
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1016
  		md_bitmap_wait_writes(bitmap);
4b5060dda   NeilBrown   md/bitmap: always...
1017

b405fe91e   NeilBrown   md/bitmap: use se...
1018
  	if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags))
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1019
  		md_bitmap_file_kick(bitmap);
32a7627cf   NeilBrown   [PATCH] md: optim...
1020
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1021
  EXPORT_SYMBOL(md_bitmap_unplug);
32a7627cf   NeilBrown   [PATCH] md: optim...
1022

e64e4018d   Andy Shevchenko   md: Avoid namespa...
1023
  static void md_bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed);
32a7627cf   NeilBrown   [PATCH] md: optim...
1024
1025
1026
1027
1028
1029
1030
  /* * bitmap_init_from_disk -- called at bitmap_create time to initialize
   * the in-memory bitmap from the on-disk bitmap -- also, sets up the
   * memory mapping of the bitmap file
   * Special cases:
   *   if there's no bitmap file, or if the bitmap file had been
   *   previously kicked from the array, we mark all the bits as
   *   1's in order to cause a full resync.
6a07997fc   NeilBrown   [PATCH] md: impro...
1031
1032
1033
   *
   * We ignore all bits for sectors that end earlier than 'start'.
   * This is used when reading an out-of-date bitmap...
32a7627cf   NeilBrown   [PATCH] md: optim...
1034
   */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1035
  static int md_bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
32a7627cf   NeilBrown   [PATCH] md: optim...
1036
  {
b97e92574   Goldwyn Rodrigues   Use separate bitm...
1037
  	unsigned long i, chunks, index, oldindex, bit, node_offset = 0;
27581e5ae   NeilBrown   md/bitmap: centra...
1038
  	struct page *page = NULL;
d1244cb06   NeilBrown   md/bitmap: separa...
1039
  	unsigned long bit_cnt = 0;
32a7627cf   NeilBrown   [PATCH] md: optim...
1040
  	struct file *file;
d1244cb06   NeilBrown   md/bitmap: separa...
1041
  	unsigned long offset;
32a7627cf   NeilBrown   [PATCH] md: optim...
1042
1043
  	int outofdate;
  	int ret = -ENOSPC;
ea03aff93   NeilBrown   [PATCH] md: conve...
1044
  	void *paddr;
1ec885cdd   NeilBrown   md/bitmap: move s...
1045
  	struct bitmap_storage *store = &bitmap->storage;
32a7627cf   NeilBrown   [PATCH] md: optim...
1046

40cffcc0e   NeilBrown   md/bitmap: create...
1047
  	chunks = bitmap->counts.chunks;
1ec885cdd   NeilBrown   md/bitmap: move s...
1048
  	file = store->file;
32a7627cf   NeilBrown   [PATCH] md: optim...
1049

ef99bf480   NeilBrown   md/bitmap: allow ...
1050
1051
  	if (!file && !bitmap->mddev->bitmap_info.offset) {
  		/* No permanent bitmap - fill with '1s'. */
1ec885cdd   NeilBrown   md/bitmap: move s...
1052
1053
  		store->filemap = NULL;
  		store->file_pages = 0;
ef99bf480   NeilBrown   md/bitmap: allow ...
1054
1055
  		for (i = 0; i < chunks ; i++) {
  			/* if the disk bit is set, set the memory bit */
40cffcc0e   NeilBrown   md/bitmap: create...
1056
  			int needed = ((sector_t)(i+1) << (bitmap->counts.chunkshift)
ef99bf480   NeilBrown   md/bitmap: allow ...
1057
  				      >= start);
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1058
1059
1060
  			md_bitmap_set_memory_bits(bitmap,
  						  (sector_t)i << bitmap->counts.chunkshift,
  						  needed);
ef99bf480   NeilBrown   md/bitmap: allow ...
1061
1062
1063
  		}
  		return 0;
  	}
32a7627cf   NeilBrown   [PATCH] md: optim...
1064

b405fe91e   NeilBrown   md/bitmap: use se...
1065
  	outofdate = test_bit(BITMAP_STALE, &bitmap->flags);
32a7627cf   NeilBrown   [PATCH] md: optim...
1066
  	if (outofdate)
ec0cc2268   NeilBrown   md/bitmap: change...
1067
1068
  		pr_warn("%s: bitmap file is out of date, doing full recovery
  ", bmname(bitmap));
32a7627cf   NeilBrown   [PATCH] md: optim...
1069

d1244cb06   NeilBrown   md/bitmap: separa...
1070
  	if (file && i_size_read(file->f_mapping->host) < store->bytes) {
ec0cc2268   NeilBrown   md/bitmap: change...
1071
1072
1073
1074
1075
  		pr_warn("%s: bitmap file too short %lu < %lu
  ",
  			bmname(bitmap),
  			(unsigned long) i_size_read(file->f_mapping->host),
  			store->bytes);
4ad136637   NeilBrown   md: change bitmap...
1076
  		goto err;
32a7627cf   NeilBrown   [PATCH] md: optim...
1077
  	}
bc7f77de2   NeilBrown   [PATCH] md: minor...
1078

d1244cb06   NeilBrown   md/bitmap: separa...
1079
  	oldindex = ~0L;
27581e5ae   NeilBrown   md/bitmap: centra...
1080
  	offset = 0;
d1244cb06   NeilBrown   md/bitmap: separa...
1081
  	if (!bitmap->mddev->bitmap_info.external)
27581e5ae   NeilBrown   md/bitmap: centra...
1082
  		offset = sizeof(bitmap_super_t);
32a7627cf   NeilBrown   [PATCH] md: optim...
1083

b97e92574   Goldwyn Rodrigues   Use separate bitm...
1084
1085
  	if (mddev_is_clustered(bitmap->mddev))
  		node_offset = bitmap->cluster_slot * (DIV_ROUND_UP(store->bytes, PAGE_SIZE));
32a7627cf   NeilBrown   [PATCH] md: optim...
1086
  	for (i = 0; i < chunks; i++) {
bd926c63b   NeilBrown   [PATCH] md: make ...
1087
  		int b;
1ec885cdd   NeilBrown   md/bitmap: move s...
1088
1089
  		index = file_page_index(&bitmap->storage, i);
  		bit = file_page_offset(&bitmap->storage, i);
32a7627cf   NeilBrown   [PATCH] md: optim...
1090
  		if (index != oldindex) { /* this is a new page, read it in */
d785a06a0   NeilBrown   [PATCH] md/bitmap...
1091
  			int count;
32a7627cf   NeilBrown   [PATCH] md: optim...
1092
  			/* unmap the old page, we're done with it */
d1244cb06   NeilBrown   md/bitmap: separa...
1093
1094
  			if (index == store->file_pages-1)
  				count = store->bytes - index * PAGE_SIZE;
d785a06a0   NeilBrown   [PATCH] md/bitmap...
1095
1096
  			else
  				count = PAGE_SIZE;
1ec885cdd   NeilBrown   md/bitmap: move s...
1097
  			page = store->filemap[index];
27581e5ae   NeilBrown   md/bitmap: centra...
1098
1099
1100
1101
1102
1103
1104
1105
  			if (file)
  				ret = read_page(file, index, bitmap,
  						count, page);
  			else
  				ret = read_sb_page(
  					bitmap->mddev,
  					bitmap->mddev->bitmap_info.offset,
  					page,
b97e92574   Goldwyn Rodrigues   Use separate bitm...
1106
  					index + node_offset, count);
27581e5ae   NeilBrown   md/bitmap: centra...
1107
1108
  
  			if (ret)
4ad136637   NeilBrown   md: change bitmap...
1109
  				goto err;
a654b9d8f   NeilBrown   [PATCH] md: allow...
1110

32a7627cf   NeilBrown   [PATCH] md: optim...
1111
  			oldindex = index;
32a7627cf   NeilBrown   [PATCH] md: optim...
1112
1113
1114
1115
  
  			if (outofdate) {
  				/*
  				 * if bitmap is out of date, dirty the
ac2f40be4   NeilBrown   md/bitmap: white ...
1116
  				 * whole page and write it out
32a7627cf   NeilBrown   [PATCH] md: optim...
1117
  				 */
b2f46e688   Cong Wang   md: remove the se...
1118
  				paddr = kmap_atomic(page);
ea03aff93   NeilBrown   [PATCH] md: conve...
1119
  				memset(paddr + offset, 0xff,
6a07997fc   NeilBrown   [PATCH] md: impro...
1120
  				       PAGE_SIZE - offset);
b2f46e688   Cong Wang   md: remove the se...
1121
  				kunmap_atomic(paddr);
4ad136637   NeilBrown   md: change bitmap...
1122
1123
1124
  				write_page(bitmap, page, 1);
  
  				ret = -EIO;
b405fe91e   NeilBrown   md/bitmap: use se...
1125
1126
  				if (test_bit(BITMAP_WRITE_ERROR,
  					     &bitmap->flags))
4ad136637   NeilBrown   md: change bitmap...
1127
  					goto err;
32a7627cf   NeilBrown   [PATCH] md: optim...
1128
  			}
32a7627cf   NeilBrown   [PATCH] md: optim...
1129
  		}
b2f46e688   Cong Wang   md: remove the se...
1130
  		paddr = kmap_atomic(page);
b405fe91e   NeilBrown   md/bitmap: use se...
1131
  		if (test_bit(BITMAP_HOSTENDIAN, &bitmap->flags))
ea03aff93   NeilBrown   [PATCH] md: conve...
1132
  			b = test_bit(bit, paddr);
bd926c63b   NeilBrown   [PATCH] md: make ...
1133
  		else
6b33aff36   Akinobu Mita   md: use little-en...
1134
  			b = test_bit_le(bit, paddr);
b2f46e688   Cong Wang   md: remove the se...
1135
  		kunmap_atomic(paddr);
bd926c63b   NeilBrown   [PATCH] md: make ...
1136
  		if (b) {
32a7627cf   NeilBrown   [PATCH] md: optim...
1137
  			/* if the disk bit is set, set the memory bit */
40cffcc0e   NeilBrown   md/bitmap: create...
1138
  			int needed = ((sector_t)(i+1) << bitmap->counts.chunkshift
db305e507   NeilBrown   md: fix some (mor...
1139
  				      >= start);
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1140
1141
1142
  			md_bitmap_set_memory_bits(bitmap,
  						  (sector_t)i << bitmap->counts.chunkshift,
  						  needed);
32a7627cf   NeilBrown   [PATCH] md: optim...
1143
1144
  			bit_cnt++;
  		}
27581e5ae   NeilBrown   md/bitmap: centra...
1145
  		offset = 0;
32a7627cf   NeilBrown   [PATCH] md: optim...
1146
  	}
ec0cc2268   NeilBrown   md/bitmap: change...
1147
1148
1149
1150
  	pr_debug("%s: bitmap initialized from disk: read %lu pages, set %lu of %lu bits
  ",
  		 bmname(bitmap), store->file_pages,
  		 bit_cnt, chunks);
4ad136637   NeilBrown   md: change bitmap...
1151
1152
  
  	return 0;
32a7627cf   NeilBrown   [PATCH] md: optim...
1153

4ad136637   NeilBrown   md: change bitmap...
1154
   err:
ec0cc2268   NeilBrown   md/bitmap: change...
1155
1156
1157
  	pr_warn("%s: bitmap initialisation failed: %d
  ",
  		bmname(bitmap), ret);
32a7627cf   NeilBrown   [PATCH] md: optim...
1158
1159
  	return ret;
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1160
  void md_bitmap_write_all(struct bitmap *bitmap)
a654b9d8f   NeilBrown   [PATCH] md: allow...
1161
1162
1163
1164
  {
  	/* We don't actually write all bitmap blocks here,
  	 * just flag them as needing to be written
  	 */
ec7a3197f   NeilBrown   [PATCH] md/bitmap...
1165
  	int i;
a654b9d8f   NeilBrown   [PATCH] md: allow...
1166

1ec885cdd   NeilBrown   md/bitmap: move s...
1167
  	if (!bitmap || !bitmap->storage.filemap)
ef99bf480   NeilBrown   md/bitmap: allow ...
1168
  		return;
1ec885cdd   NeilBrown   md/bitmap: move s...
1169
  	if (bitmap->storage.file)
ef99bf480   NeilBrown   md/bitmap: allow ...
1170
1171
  		/* Only one copy, so nothing needed */
  		return;
1ec885cdd   NeilBrown   md/bitmap: move s...
1172
  	for (i = 0; i < bitmap->storage.file_pages; i++)
d189122d4   NeilBrown   md/bitmap: change...
1173
  		set_page_attr(bitmap, i,
ec7a3197f   NeilBrown   [PATCH] md/bitmap...
1174
  			      BITMAP_PAGE_NEEDWRITE);
2585f3ef8   NeilBrown   md/bitmap: improv...
1175
  	bitmap->allclean = 0;
a654b9d8f   NeilBrown   [PATCH] md: allow...
1176
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1177
1178
  static void md_bitmap_count_page(struct bitmap_counts *bitmap,
  				 sector_t offset, int inc)
32a7627cf   NeilBrown   [PATCH] md: optim...
1179
  {
61a0d80ce   NeilBrown   md/bitmap: discar...
1180
  	sector_t chunk = offset >> bitmap->chunkshift;
32a7627cf   NeilBrown   [PATCH] md: optim...
1181
1182
  	unsigned long page = chunk >> PAGE_COUNTER_SHIFT;
  	bitmap->bp[page].count += inc;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1183
  	md_bitmap_checkfree(bitmap, page);
32a7627cf   NeilBrown   [PATCH] md: optim...
1184
  }
bf07bb7d5   NeilBrown   md/bitmap: disent...
1185

e64e4018d   Andy Shevchenko   md: Avoid namespa...
1186
  static void md_bitmap_set_pending(struct bitmap_counts *bitmap, sector_t offset)
bf07bb7d5   NeilBrown   md/bitmap: disent...
1187
1188
1189
1190
1191
1192
1193
1194
  {
  	sector_t chunk = offset >> bitmap->chunkshift;
  	unsigned long page = chunk >> PAGE_COUNTER_SHIFT;
  	struct bitmap_page *bp = &bitmap->bp[page];
  
  	if (!bp->pending)
  		bp->pending = 1;
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1195
1196
1197
  static bitmap_counter_t *md_bitmap_get_counter(struct bitmap_counts *bitmap,
  					       sector_t offset, sector_t *blocks,
  					       int create);
32a7627cf   NeilBrown   [PATCH] md: optim...
1198
1199
1200
1201
1202
  
  /*
   * bitmap daemon -- periodically wakes up to clean bits and flush pages
   *			out to disk
   */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1203
  void md_bitmap_daemon_work(struct mddev *mddev)
32a7627cf   NeilBrown   [PATCH] md: optim...
1204
  {
aa5cbd103   NeilBrown   md/bitmap: protec...
1205
  	struct bitmap *bitmap;
aa3163f81   NeilBrown   [PATCH] md: don't...
1206
  	unsigned long j;
bf07bb7d5   NeilBrown   md/bitmap: disent...
1207
  	unsigned long nextpage;
57dab0bdf   NeilBrown   md: use sector_t ...
1208
  	sector_t blocks;
40cffcc0e   NeilBrown   md/bitmap: create...
1209
  	struct bitmap_counts *counts;
32a7627cf   NeilBrown   [PATCH] md: optim...
1210

aa5cbd103   NeilBrown   md/bitmap: protec...
1211
1212
1213
  	/* Use a mutex to guard daemon_work against
  	 * bitmap_destroy.
  	 */
c3d9714e8   NeilBrown   md: collect bitma...
1214
  	mutex_lock(&mddev->bitmap_info.mutex);
aa5cbd103   NeilBrown   md/bitmap: protec...
1215
1216
  	bitmap = mddev->bitmap;
  	if (bitmap == NULL) {
c3d9714e8   NeilBrown   md: collect bitma...
1217
  		mutex_unlock(&mddev->bitmap_info.mutex);
4ad136637   NeilBrown   md: change bitmap...
1218
  		return;
aa5cbd103   NeilBrown   md/bitmap: protec...
1219
  	}
42a04b507   NeilBrown   md: move offset, ...
1220
  	if (time_before(jiffies, bitmap->daemon_lastrun
2e61ebbcc   NeilBrown   md/bitmap: daemon...
1221
  			+ mddev->bitmap_info.daemon_sleep))
7be3dfec4   NeilBrown   md: reduce CPU wa...
1222
  		goto done;
32a7627cf   NeilBrown   [PATCH] md: optim...
1223
  	bitmap->daemon_lastrun = jiffies;
8311c29d4   NeilBrown   md: reduce CPU wa...
1224
  	if (bitmap->allclean) {
2e61ebbcc   NeilBrown   md/bitmap: daemon...
1225
  		mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
aa5cbd103   NeilBrown   md/bitmap: protec...
1226
  		goto done;
8311c29d4   NeilBrown   md: reduce CPU wa...
1227
1228
  	}
  	bitmap->allclean = 1;
32a7627cf   NeilBrown   [PATCH] md: optim...
1229

581dbd94d   NeilBrown   md/bitmap: add bl...
1230
1231
1232
  	if (bitmap->mddev->queue)
  		blk_add_trace_msg(bitmap->mddev->queue,
  				  "md bitmap_daemon_work");
bf07bb7d5   NeilBrown   md/bitmap: disent...
1233
1234
1235
1236
  	/* Any file-page which is PENDING now needs to be written.
  	 * So set NEEDWRITE now, then after we make any last-minute changes
  	 * we will write it.
  	 */
1ec885cdd   NeilBrown   md/bitmap: move s...
1237
  	for (j = 0; j < bitmap->storage.file_pages; j++)
bdfd11407   NeilBrown   md/bitmap: make _...
1238
1239
  		if (test_and_clear_page_attr(bitmap, j,
  					     BITMAP_PAGE_PENDING))
d189122d4   NeilBrown   md/bitmap: change...
1240
  			set_page_attr(bitmap, j,
bf07bb7d5   NeilBrown   md/bitmap: disent...
1241
  				      BITMAP_PAGE_NEEDWRITE);
bf07bb7d5   NeilBrown   md/bitmap: disent...
1242
1243
1244
1245
1246
1247
1248
  
  	if (bitmap->need_sync &&
  	    mddev->bitmap_info.external == 0) {
  		/* Arrange for superblock update as well as
  		 * other changes */
  		bitmap_super_t *sb;
  		bitmap->need_sync = 0;
1ec885cdd   NeilBrown   md/bitmap: move s...
1249
1250
  		if (bitmap->storage.filemap) {
  			sb = kmap_atomic(bitmap->storage.sb_page);
ef99bf480   NeilBrown   md/bitmap: allow ...
1251
1252
1253
  			sb->events_cleared =
  				cpu_to_le64(bitmap->events_cleared);
  			kunmap_atomic(sb);
d189122d4   NeilBrown   md/bitmap: change...
1254
  			set_page_attr(bitmap, 0,
ef99bf480   NeilBrown   md/bitmap: allow ...
1255
1256
  				      BITMAP_PAGE_NEEDWRITE);
  		}
bf07bb7d5   NeilBrown   md/bitmap: disent...
1257
1258
1259
1260
  	}
  	/* Now look at the bitmap counters and if any are '2' or '1',
  	 * decrement and handle accordingly.
  	 */
40cffcc0e   NeilBrown   md/bitmap: create...
1261
1262
  	counts = &bitmap->counts;
  	spin_lock_irq(&counts->lock);
bf07bb7d5   NeilBrown   md/bitmap: disent...
1263
  	nextpage = 0;
40cffcc0e   NeilBrown   md/bitmap: create...
1264
  	for (j = 0; j < counts->chunks; j++) {
32a7627cf   NeilBrown   [PATCH] md: optim...
1265
  		bitmap_counter_t *bmc;
40cffcc0e   NeilBrown   md/bitmap: create...
1266
  		sector_t  block = (sector_t)j << counts->chunkshift;
3520fa4db   Jonathan Brassow   MD bitmap: Revert...
1267

bf07bb7d5   NeilBrown   md/bitmap: disent...
1268
1269
  		if (j == nextpage) {
  			nextpage += PAGE_COUNTER_RATIO;
40cffcc0e   NeilBrown   md/bitmap: create...
1270
  			if (!counts->bp[j >> PAGE_COUNTER_SHIFT].pending) {
bf07bb7d5   NeilBrown   md/bitmap: disent...
1271
  				j |= PAGE_COUNTER_MASK;
aa3163f81   NeilBrown   [PATCH] md: don't...
1272
1273
  				continue;
  			}
40cffcc0e   NeilBrown   md/bitmap: create...
1274
  			counts->bp[j >> PAGE_COUNTER_SHIFT].pending = 0;
32a7627cf   NeilBrown   [PATCH] md: optim...
1275
  		}
bf07bb7d5   NeilBrown   md/bitmap: disent...
1276

e64e4018d   Andy Shevchenko   md: Avoid namespa...
1277
  		bmc = md_bitmap_get_counter(counts, block, &blocks, 0);
bf07bb7d5   NeilBrown   md/bitmap: disent...
1278
  		if (!bmc) {
5a537df44   NeilBrown   md/bitmap: rename...
1279
  			j |= PAGE_COUNTER_MASK;
bf07bb7d5   NeilBrown   md/bitmap: disent...
1280
1281
1282
1283
  			continue;
  		}
  		if (*bmc == 1 && !bitmap->need_sync) {
  			/* We can clear the bit */
bf07bb7d5   NeilBrown   md/bitmap: disent...
1284
  			*bmc = 0;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1285
1286
  			md_bitmap_count_page(counts, block, -1);
  			md_bitmap_file_clear_bit(bitmap, block);
bf07bb7d5   NeilBrown   md/bitmap: disent...
1287
1288
  		} else if (*bmc && *bmc <= 2) {
  			*bmc = 1;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1289
  			md_bitmap_set_pending(counts, block);
bf07bb7d5   NeilBrown   md/bitmap: disent...
1290
  			bitmap->allclean = 0;
5a537df44   NeilBrown   md/bitmap: rename...
1291
  		}
32a7627cf   NeilBrown   [PATCH] md: optim...
1292
  	}
40cffcc0e   NeilBrown   md/bitmap: create...
1293
  	spin_unlock_irq(&counts->lock);
32a7627cf   NeilBrown   [PATCH] md: optim...
1294

e64e4018d   Andy Shevchenko   md: Avoid namespa...
1295
  	md_bitmap_wait_writes(bitmap);
bf07bb7d5   NeilBrown   md/bitmap: disent...
1296
1297
1298
1299
1300
1301
1302
1303
  	/* Now start writeout on any page in NEEDWRITE that isn't DIRTY.
  	 * DIRTY pages need to be written by bitmap_unplug so it can wait
  	 * for them.
  	 * If we find any DIRTY page we stop there and let bitmap_unplug
  	 * handle all the rest.  This is important in the case where
  	 * the first blocking holds the superblock and it has been updated.
  	 * We mustn't write any other blocks before the superblock.
  	 */
62f82faac   NeilBrown   md/bitmap: remove...
1304
1305
1306
1307
  	for (j = 0;
  	     j < bitmap->storage.file_pages
  		     && !test_bit(BITMAP_STALE, &bitmap->flags);
  	     j++) {
d189122d4   NeilBrown   md/bitmap: change...
1308
  		if (test_page_attr(bitmap, j,
bf07bb7d5   NeilBrown   md/bitmap: disent...
1309
1310
1311
  				   BITMAP_PAGE_DIRTY))
  			/* bitmap_unplug will handle the rest */
  			break;
55180498d   Zhiqiang Liu   md-bitmap: small ...
1312
1313
  		if (bitmap->storage.filemap &&
  		    test_and_clear_page_attr(bitmap, j,
bdfd11407   NeilBrown   md/bitmap: make _...
1314
  					     BITMAP_PAGE_NEEDWRITE)) {
1ec885cdd   NeilBrown   md/bitmap: move s...
1315
  			write_page(bitmap, bitmap->storage.filemap[j], 0);
32a7627cf   NeilBrown   [PATCH] md: optim...
1316
  		}
32a7627cf   NeilBrown   [PATCH] md: optim...
1317
  	}
7be3dfec4   NeilBrown   md: reduce CPU wa...
1318
   done:
8311c29d4   NeilBrown   md: reduce CPU wa...
1319
  	if (bitmap->allclean == 0)
2e61ebbcc   NeilBrown   md/bitmap: daemon...
1320
1321
  		mddev->thread->timeout =
  			mddev->bitmap_info.daemon_sleep;
c3d9714e8   NeilBrown   md: collect bitma...
1322
  	mutex_unlock(&mddev->bitmap_info.mutex);
32a7627cf   NeilBrown   [PATCH] md: optim...
1323
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1324
1325
1326
  static bitmap_counter_t *md_bitmap_get_counter(struct bitmap_counts *bitmap,
  					       sector_t offset, sector_t *blocks,
  					       int create)
ee305acef   NeilBrown   md: remove sparse...
1327
1328
  __releases(bitmap->lock)
  __acquires(bitmap->lock)
32a7627cf   NeilBrown   [PATCH] md: optim...
1329
1330
1331
1332
1333
  {
  	/* If 'create', we might release the lock and reclaim it.
  	 * The lock must have been taken with interrupts enabled.
  	 * If !create, we don't release the lock.
  	 */
61a0d80ce   NeilBrown   md/bitmap: discar...
1334
  	sector_t chunk = offset >> bitmap->chunkshift;
32a7627cf   NeilBrown   [PATCH] md: optim...
1335
1336
1337
  	unsigned long page = chunk >> PAGE_COUNTER_SHIFT;
  	unsigned long pageoff = (chunk & PAGE_COUNTER_MASK) << COUNTER_BYTE_SHIFT;
  	sector_t csize;
ef4256733   NeilBrown   md/bitmap: optimi...
1338
  	int err;
32a7627cf   NeilBrown   [PATCH] md: optim...
1339

e64e4018d   Andy Shevchenko   md: Avoid namespa...
1340
  	err = md_bitmap_checkpage(bitmap, page, create, 0);
ef4256733   NeilBrown   md/bitmap: optimi...
1341
1342
1343
  
  	if (bitmap->bp[page].hijacked ||
  	    bitmap->bp[page].map == NULL)
61a0d80ce   NeilBrown   md/bitmap: discar...
1344
  		csize = ((sector_t)1) << (bitmap->chunkshift +
d837f7277   Zhao Heming   md/bitmap: md_bit...
1345
  					  PAGE_COUNTER_SHIFT);
ef4256733   NeilBrown   md/bitmap: optimi...
1346
  	else
61a0d80ce   NeilBrown   md/bitmap: discar...
1347
  		csize = ((sector_t)1) << bitmap->chunkshift;
ef4256733   NeilBrown   md/bitmap: optimi...
1348
1349
1350
  	*blocks = csize - (offset & (csize - 1));
  
  	if (err < 0)
32a7627cf   NeilBrown   [PATCH] md: optim...
1351
  		return NULL;
ef4256733   NeilBrown   md/bitmap: optimi...
1352

32a7627cf   NeilBrown   [PATCH] md: optim...
1353
1354
1355
1356
1357
1358
  	/* now locked ... */
  
  	if (bitmap->bp[page].hijacked) { /* hijacked pointer */
  		/* should we use the first or second counter field
  		 * of the hijacked pointer? */
  		int hi = (pageoff > PAGE_COUNTER_MASK);
32a7627cf   NeilBrown   [PATCH] md: optim...
1359
1360
  		return  &((bitmap_counter_t *)
  			  &bitmap->bp[page].map)[hi];
ef4256733   NeilBrown   md/bitmap: optimi...
1361
  	} else /* page is allocated */
32a7627cf   NeilBrown   [PATCH] md: optim...
1362
1363
  		return (bitmap_counter_t *)
  			&(bitmap->bp[page].map[pageoff]);
32a7627cf   NeilBrown   [PATCH] md: optim...
1364
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1365
  int md_bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors, int behind)
32a7627cf   NeilBrown   [PATCH] md: optim...
1366
  {
ac2f40be4   NeilBrown   md/bitmap: white ...
1367
1368
  	if (!bitmap)
  		return 0;
4b6d287f6   NeilBrown   [PATCH] md: add w...
1369
1370
  
  	if (behind) {
696fcd535   Paul Clements   md: expose max va...
1371
  		int bw;
4b6d287f6   NeilBrown   [PATCH] md: add w...
1372
  		atomic_inc(&bitmap->behind_writes);
696fcd535   Paul Clements   md: expose max va...
1373
1374
1375
  		bw = atomic_read(&bitmap->behind_writes);
  		if (bw > bitmap->behind_writes_used)
  			bitmap->behind_writes_used = bw;
36a4e1fe0   NeilBrown   md: remove PRINTK...
1376
1377
1378
  		pr_debug("inc write-behind count %d/%lu
  ",
  			 bw, bitmap->mddev->bitmap_info.max_write_behind);
4b6d287f6   NeilBrown   [PATCH] md: add w...
1379
  	}
32a7627cf   NeilBrown   [PATCH] md: optim...
1380
  	while (sectors) {
57dab0bdf   NeilBrown   md: use sector_t ...
1381
  		sector_t blocks;
32a7627cf   NeilBrown   [PATCH] md: optim...
1382
  		bitmap_counter_t *bmc;
40cffcc0e   NeilBrown   md/bitmap: create...
1383
  		spin_lock_irq(&bitmap->counts.lock);
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1384
  		bmc = md_bitmap_get_counter(&bitmap->counts, offset, &blocks, 1);
32a7627cf   NeilBrown   [PATCH] md: optim...
1385
  		if (!bmc) {
40cffcc0e   NeilBrown   md/bitmap: create...
1386
  			spin_unlock_irq(&bitmap->counts.lock);
32a7627cf   NeilBrown   [PATCH] md: optim...
1387
1388
  			return 0;
  		}
27d5ea04d   Namhyung Kim   md/bitmap: use pr...
1389
  		if (unlikely(COUNTER(*bmc) == COUNTER_MAX)) {
da6e1a32f   Neil Brown   [PATCH] md: avoid...
1390
1391
1392
1393
1394
1395
1396
  			DEFINE_WAIT(__wait);
  			/* note that it is safe to do the prepare_to_wait
  			 * after the test as long as we do it before dropping
  			 * the spinlock.
  			 */
  			prepare_to_wait(&bitmap->overflow_wait, &__wait,
  					TASK_UNINTERRUPTIBLE);
40cffcc0e   NeilBrown   md/bitmap: create...
1397
  			spin_unlock_irq(&bitmap->counts.lock);
f54a9d0e5   NeilBrown   md/raid1: submit ...
1398
  			schedule();
da6e1a32f   Neil Brown   [PATCH] md: avoid...
1399
1400
1401
  			finish_wait(&bitmap->overflow_wait, &__wait);
  			continue;
  		}
ac2f40be4   NeilBrown   md/bitmap: white ...
1402
  		switch (*bmc) {
32a7627cf   NeilBrown   [PATCH] md: optim...
1403
  		case 0:
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1404
1405
  			md_bitmap_file_set_bit(bitmap, offset);
  			md_bitmap_count_page(&bitmap->counts, offset, 1);
df561f668   Gustavo A. R. Silva   treewide: Use fal...
1406
  			fallthrough;
32a7627cf   NeilBrown   [PATCH] md: optim...
1407
1408
1409
  		case 1:
  			*bmc = 2;
  		}
da6e1a32f   Neil Brown   [PATCH] md: avoid...
1410

32a7627cf   NeilBrown   [PATCH] md: optim...
1411
  		(*bmc)++;
40cffcc0e   NeilBrown   md/bitmap: create...
1412
  		spin_unlock_irq(&bitmap->counts.lock);
32a7627cf   NeilBrown   [PATCH] md: optim...
1413
1414
1415
1416
  
  		offset += blocks;
  		if (sectors > blocks)
  			sectors -= blocks;
ac2f40be4   NeilBrown   md/bitmap: white ...
1417
1418
  		else
  			sectors = 0;
32a7627cf   NeilBrown   [PATCH] md: optim...
1419
1420
1421
  	}
  	return 0;
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1422
  EXPORT_SYMBOL(md_bitmap_startwrite);
32a7627cf   NeilBrown   [PATCH] md: optim...
1423

e64e4018d   Andy Shevchenko   md: Avoid namespa...
1424
1425
  void md_bitmap_endwrite(struct bitmap *bitmap, sector_t offset,
  			unsigned long sectors, int success, int behind)
32a7627cf   NeilBrown   [PATCH] md: optim...
1426
  {
ac2f40be4   NeilBrown   md/bitmap: white ...
1427
1428
  	if (!bitmap)
  		return;
4b6d287f6   NeilBrown   [PATCH] md: add w...
1429
  	if (behind) {
e555190d8   NeilBrown   md/raid1: delay r...
1430
1431
  		if (atomic_dec_and_test(&bitmap->behind_writes))
  			wake_up(&bitmap->behind_wait);
36a4e1fe0   NeilBrown   md: remove PRINTK...
1432
1433
1434
1435
  		pr_debug("dec write-behind count %d/%lu
  ",
  			 atomic_read(&bitmap->behind_writes),
  			 bitmap->mddev->bitmap_info.max_write_behind);
4b6d287f6   NeilBrown   [PATCH] md: add w...
1436
  	}
32a7627cf   NeilBrown   [PATCH] md: optim...
1437
  	while (sectors) {
57dab0bdf   NeilBrown   md: use sector_t ...
1438
  		sector_t blocks;
32a7627cf   NeilBrown   [PATCH] md: optim...
1439
1440
  		unsigned long flags;
  		bitmap_counter_t *bmc;
40cffcc0e   NeilBrown   md/bitmap: create...
1441
  		spin_lock_irqsave(&bitmap->counts.lock, flags);
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1442
  		bmc = md_bitmap_get_counter(&bitmap->counts, offset, &blocks, 0);
32a7627cf   NeilBrown   [PATCH] md: optim...
1443
  		if (!bmc) {
40cffcc0e   NeilBrown   md/bitmap: create...
1444
  			spin_unlock_irqrestore(&bitmap->counts.lock, flags);
32a7627cf   NeilBrown   [PATCH] md: optim...
1445
1446
  			return;
  		}
961902c0f   NeilBrown   md/bitmap: It is ...
1447
  		if (success && !bitmap->mddev->degraded &&
a0da84f35   Neil Brown   Improve setting o...
1448
1449
1450
  		    bitmap->events_cleared < bitmap->mddev->events) {
  			bitmap->events_cleared = bitmap->mddev->events;
  			bitmap->need_sync = 1;
5ff5afffe   NeilBrown   md/bitmap: reduce...
1451
  			sysfs_notify_dirent_safe(bitmap->sysfs_can_clear);
a0da84f35   Neil Brown   Improve setting o...
1452
  		}
27d5ea04d   Namhyung Kim   md/bitmap: use pr...
1453
  		if (!success && !NEEDED(*bmc))
32a7627cf   NeilBrown   [PATCH] md: optim...
1454
  			*bmc |= NEEDED_MASK;
27d5ea04d   Namhyung Kim   md/bitmap: use pr...
1455
  		if (COUNTER(*bmc) == COUNTER_MAX)
da6e1a32f   Neil Brown   [PATCH] md: avoid...
1456
  			wake_up(&bitmap->overflow_wait);
32a7627cf   NeilBrown   [PATCH] md: optim...
1457
  		(*bmc)--;
2585f3ef8   NeilBrown   md/bitmap: improv...
1458
  		if (*bmc <= 2) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1459
  			md_bitmap_set_pending(&bitmap->counts, offset);
2585f3ef8   NeilBrown   md/bitmap: improv...
1460
1461
  			bitmap->allclean = 0;
  		}
40cffcc0e   NeilBrown   md/bitmap: create...
1462
  		spin_unlock_irqrestore(&bitmap->counts.lock, flags);
32a7627cf   NeilBrown   [PATCH] md: optim...
1463
1464
1465
  		offset += blocks;
  		if (sectors > blocks)
  			sectors -= blocks;
ac2f40be4   NeilBrown   md/bitmap: white ...
1466
1467
  		else
  			sectors = 0;
32a7627cf   NeilBrown   [PATCH] md: optim...
1468
1469
  	}
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1470
  EXPORT_SYMBOL(md_bitmap_endwrite);
32a7627cf   NeilBrown   [PATCH] md: optim...
1471

57dab0bdf   NeilBrown   md: use sector_t ...
1472
  static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks,
1187cf0a3   NeilBrown   md: Allow write-i...
1473
  			       int degraded)
32a7627cf   NeilBrown   [PATCH] md: optim...
1474
1475
1476
1477
1478
1479
1480
  {
  	bitmap_counter_t *bmc;
  	int rv;
  	if (bitmap == NULL) {/* FIXME or bitmap set as 'failed' */
  		*blocks = 1024;
  		return 1; /* always resync if no bitmap */
  	}
40cffcc0e   NeilBrown   md/bitmap: create...
1481
  	spin_lock_irq(&bitmap->counts.lock);
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1482
  	bmc = md_bitmap_get_counter(&bitmap->counts, offset, blocks, 0);
32a7627cf   NeilBrown   [PATCH] md: optim...
1483
1484
1485
1486
1487
1488
1489
  	rv = 0;
  	if (bmc) {
  		/* locked */
  		if (RESYNC(*bmc))
  			rv = 1;
  		else if (NEEDED(*bmc)) {
  			rv = 1;
6a806c510   NeilBrown   [PATCH] md/raid1:...
1490
1491
1492
1493
  			if (!degraded) { /* don't set/clear bits if degraded */
  				*bmc |= RESYNC_MASK;
  				*bmc &= ~NEEDED_MASK;
  			}
32a7627cf   NeilBrown   [PATCH] md: optim...
1494
1495
  		}
  	}
40cffcc0e   NeilBrown   md/bitmap: create...
1496
  	spin_unlock_irq(&bitmap->counts.lock);
32a7627cf   NeilBrown   [PATCH] md: optim...
1497
1498
  	return rv;
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1499
1500
  int md_bitmap_start_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks,
  			 int degraded)
1187cf0a3   NeilBrown   md: Allow write-i...
1501
1502
1503
1504
1505
1506
1507
1508
1509
  {
  	/* bitmap_start_sync must always report on multiples of whole
  	 * pages, otherwise resync (which is very PAGE_SIZE based) will
  	 * get confused.
  	 * So call __bitmap_start_sync repeatedly (if needed) until
  	 * At least PAGE_SIZE>>9 blocks are covered.
  	 * Return the 'or' of the result.
  	 */
  	int rv = 0;
57dab0bdf   NeilBrown   md: use sector_t ...
1510
  	sector_t blocks1;
1187cf0a3   NeilBrown   md: Allow write-i...
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
  
  	*blocks = 0;
  	while (*blocks < (PAGE_SIZE>>9)) {
  		rv |= __bitmap_start_sync(bitmap, offset,
  					  &blocks1, degraded);
  		offset += blocks1;
  		*blocks += blocks1;
  	}
  	return rv;
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1521
  EXPORT_SYMBOL(md_bitmap_start_sync);
1187cf0a3   NeilBrown   md: Allow write-i...
1522

e64e4018d   Andy Shevchenko   md: Avoid namespa...
1523
  void md_bitmap_end_sync(struct bitmap *bitmap, sector_t offset, sector_t *blocks, int aborted)
32a7627cf   NeilBrown   [PATCH] md: optim...
1524
1525
1526
  {
  	bitmap_counter_t *bmc;
  	unsigned long flags;
ac2f40be4   NeilBrown   md/bitmap: white ...
1527
1528
  
  	if (bitmap == NULL) {
32a7627cf   NeilBrown   [PATCH] md: optim...
1529
1530
1531
  		*blocks = 1024;
  		return;
  	}
40cffcc0e   NeilBrown   md/bitmap: create...
1532
  	spin_lock_irqsave(&bitmap->counts.lock, flags);
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1533
  	bmc = md_bitmap_get_counter(&bitmap->counts, offset, blocks, 0);
32a7627cf   NeilBrown   [PATCH] md: optim...
1534
1535
1536
  	if (bmc == NULL)
  		goto unlock;
  	/* locked */
32a7627cf   NeilBrown   [PATCH] md: optim...
1537
1538
1539
1540
1541
1542
  	if (RESYNC(*bmc)) {
  		*bmc &= ~RESYNC_MASK;
  
  		if (!NEEDED(*bmc) && aborted)
  			*bmc |= NEEDED_MASK;
  		else {
2585f3ef8   NeilBrown   md/bitmap: improv...
1543
  			if (*bmc <= 2) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1544
  				md_bitmap_set_pending(&bitmap->counts, offset);
2585f3ef8   NeilBrown   md/bitmap: improv...
1545
1546
  				bitmap->allclean = 0;
  			}
32a7627cf   NeilBrown   [PATCH] md: optim...
1547
1548
1549
  		}
  	}
   unlock:
40cffcc0e   NeilBrown   md/bitmap: create...
1550
  	spin_unlock_irqrestore(&bitmap->counts.lock, flags);
32a7627cf   NeilBrown   [PATCH] md: optim...
1551
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1552
  EXPORT_SYMBOL(md_bitmap_end_sync);
32a7627cf   NeilBrown   [PATCH] md: optim...
1553

e64e4018d   Andy Shevchenko   md: Avoid namespa...
1554
  void md_bitmap_close_sync(struct bitmap *bitmap)
32a7627cf   NeilBrown   [PATCH] md: optim...
1555
1556
1557
1558
1559
1560
  {
  	/* Sync has finished, and any bitmap chunks that weren't synced
  	 * properly have been aborted.  It remains to us to clear the
  	 * RESYNC bit wherever it is still on
  	 */
  	sector_t sector = 0;
57dab0bdf   NeilBrown   md: use sector_t ...
1561
  	sector_t blocks;
b47490c9b   NeilBrown   md: Update md bit...
1562
1563
  	if (!bitmap)
  		return;
32a7627cf   NeilBrown   [PATCH] md: optim...
1564
  	while (sector < bitmap->mddev->resync_max_sectors) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1565
  		md_bitmap_end_sync(bitmap, sector, &blocks, 0);
b47490c9b   NeilBrown   md: Update md bit...
1566
1567
1568
  		sector += blocks;
  	}
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1569
  EXPORT_SYMBOL(md_bitmap_close_sync);
b47490c9b   NeilBrown   md: Update md bit...
1570

e64e4018d   Andy Shevchenko   md: Avoid namespa...
1571
  void md_bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector, bool force)
b47490c9b   NeilBrown   md: Update md bit...
1572
1573
  {
  	sector_t s = 0;
57dab0bdf   NeilBrown   md: use sector_t ...
1574
  	sector_t blocks;
b47490c9b   NeilBrown   md: Update md bit...
1575
1576
1577
1578
1579
1580
1581
  
  	if (!bitmap)
  		return;
  	if (sector == 0) {
  		bitmap->last_end_sync = jiffies;
  		return;
  	}
c40f341f1   Goldwyn Rodrigues   md-cluster: Use a...
1582
  	if (!force && time_before(jiffies, (bitmap->last_end_sync
1b04be96f   NeilBrown   md: change daemon...
1583
  				  + bitmap->mddev->bitmap_info.daemon_sleep)))
b47490c9b   NeilBrown   md: Update md bit...
1584
1585
1586
  		return;
  	wait_event(bitmap->mddev->recovery_wait,
  		   atomic_read(&bitmap->mddev->recovery_active) == 0);
75d3da43c   NeilBrown   md: Don't let imp...
1587
  	bitmap->mddev->curr_resync_completed = sector;
2953079c6   Shaohua Li   md: separate flag...
1588
  	set_bit(MD_SB_CHANGE_CLEAN, &bitmap->mddev->sb_flags);
40cffcc0e   NeilBrown   md/bitmap: create...
1589
  	sector &= ~((1ULL << bitmap->counts.chunkshift) - 1);
b47490c9b   NeilBrown   md: Update md bit...
1590
1591
  	s = 0;
  	while (s < sector && s < bitmap->mddev->resync_max_sectors) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1592
  		md_bitmap_end_sync(bitmap, s, &blocks, 0);
b47490c9b   NeilBrown   md: Update md bit...
1593
  		s += blocks;
32a7627cf   NeilBrown   [PATCH] md: optim...
1594
  	}
b47490c9b   NeilBrown   md: Update md bit...
1595
  	bitmap->last_end_sync = jiffies;
e1a86dbbb   Junxiao Bi   md: fix deadlock ...
1596
  	sysfs_notify_dirent_safe(bitmap->mddev->sysfs_completed);
32a7627cf   NeilBrown   [PATCH] md: optim...
1597
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1598
  EXPORT_SYMBOL(md_bitmap_cond_end_sync);
32a7627cf   NeilBrown   [PATCH] md: optim...
1599

e64e4018d   Andy Shevchenko   md: Avoid namespa...
1600
  void md_bitmap_sync_with_cluster(struct mddev *mddev,
18c9ff7f4   Guoqing Jiang   md-cluster: sync ...
1601
1602
1603
1604
1605
1606
1607
  			      sector_t old_lo, sector_t old_hi,
  			      sector_t new_lo, sector_t new_hi)
  {
  	struct bitmap *bitmap = mddev->bitmap;
  	sector_t sector, blocks = 0;
  
  	for (sector = old_lo; sector < new_lo; ) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1608
  		md_bitmap_end_sync(bitmap, sector, &blocks, 0);
18c9ff7f4   Guoqing Jiang   md-cluster: sync ...
1609
1610
1611
1612
1613
1614
  		sector += blocks;
  	}
  	WARN((blocks > new_lo) && old_lo, "alignment is not correct for lo
  ");
  
  	for (sector = old_hi; sector < new_hi; ) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1615
  		md_bitmap_start_sync(bitmap, sector, &blocks, 0);
18c9ff7f4   Guoqing Jiang   md-cluster: sync ...
1616
1617
1618
1619
1620
  		sector += blocks;
  	}
  	WARN((blocks > new_hi) && old_hi, "alignment is not correct for hi
  ");
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1621
  EXPORT_SYMBOL(md_bitmap_sync_with_cluster);
18c9ff7f4   Guoqing Jiang   md-cluster: sync ...
1622

e64e4018d   Andy Shevchenko   md: Avoid namespa...
1623
  static void md_bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed)
32a7627cf   NeilBrown   [PATCH] md: optim...
1624
1625
  {
  	/* For each chunk covered by any of these sectors, set the
ef99bf480   NeilBrown   md/bitmap: allow ...
1626
  	 * counter to 2 and possibly set resync_needed.  They should all
32a7627cf   NeilBrown   [PATCH] md: optim...
1627
1628
  	 * be 0 at this point
  	 */
193f1c931   NeilBrown   [PATCH] md: alway...
1629

57dab0bdf   NeilBrown   md: use sector_t ...
1630
  	sector_t secs;
193f1c931   NeilBrown   [PATCH] md: alway...
1631
  	bitmap_counter_t *bmc;
40cffcc0e   NeilBrown   md/bitmap: create...
1632
  	spin_lock_irq(&bitmap->counts.lock);
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1633
  	bmc = md_bitmap_get_counter(&bitmap->counts, offset, &secs, 1);
193f1c931   NeilBrown   [PATCH] md: alway...
1634
  	if (!bmc) {
40cffcc0e   NeilBrown   md/bitmap: create...
1635
  		spin_unlock_irq(&bitmap->counts.lock);
193f1c931   NeilBrown   [PATCH] md: alway...
1636
  		return;
32a7627cf   NeilBrown   [PATCH] md: optim...
1637
  	}
ac2f40be4   NeilBrown   md/bitmap: white ...
1638
  	if (!*bmc) {
11dd35daa   Goldwyn Rodrigues   Copy set bits fro...
1639
  		*bmc = 2;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1640
1641
  		md_bitmap_count_page(&bitmap->counts, offset, 1);
  		md_bitmap_set_pending(&bitmap->counts, offset);
2585f3ef8   NeilBrown   md/bitmap: improv...
1642
  		bitmap->allclean = 0;
193f1c931   NeilBrown   [PATCH] md: alway...
1643
  	}
11dd35daa   Goldwyn Rodrigues   Copy set bits fro...
1644
1645
  	if (needed)
  		*bmc |= NEEDED_MASK;
40cffcc0e   NeilBrown   md/bitmap: create...
1646
  	spin_unlock_irq(&bitmap->counts.lock);
32a7627cf   NeilBrown   [PATCH] md: optim...
1647
  }
9b1d1dac1   Paul Clements   [PATCH] md: new s...
1648
  /* dirty the memory and file bits for bitmap chunks "s" to "e" */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1649
  void md_bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e)
9b1d1dac1   Paul Clements   [PATCH] md: new s...
1650
1651
1652
1653
  {
  	unsigned long chunk;
  
  	for (chunk = s; chunk <= e; chunk++) {
40cffcc0e   NeilBrown   md/bitmap: create...
1654
  		sector_t sec = (sector_t)chunk << bitmap->counts.chunkshift;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1655
1656
  		md_bitmap_set_memory_bits(bitmap, sec, 1);
  		md_bitmap_file_set_bit(bitmap, sec);
ffa23322b   NeilBrown   md/bitmap: update...
1657
1658
1659
1660
1661
1662
  		if (sec < bitmap->mddev->recovery_cp)
  			/* We are asserting that the array is dirty,
  			 * so move the recovery_cp address back so
  			 * that it is obvious that it is dirty
  			 */
  			bitmap->mddev->recovery_cp = sec;
9b1d1dac1   Paul Clements   [PATCH] md: new s...
1663
1664
  	}
  }
32a7627cf   NeilBrown   [PATCH] md: optim...
1665
  /*
6b8b3e8a8   NeilBrown   [PATCH] md: make ...
1666
1667
   * flush out any pending updates
   */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1668
  void md_bitmap_flush(struct mddev *mddev)
6b8b3e8a8   NeilBrown   [PATCH] md: make ...
1669
1670
  {
  	struct bitmap *bitmap = mddev->bitmap;
42a04b507   NeilBrown   md: move offset, ...
1671
  	long sleep;
6b8b3e8a8   NeilBrown   [PATCH] md: make ...
1672
1673
1674
1675
1676
1677
1678
  
  	if (!bitmap) /* there was no bitmap */
  		return;
  
  	/* run the daemon_work three time to ensure everything is flushed
  	 * that can be
  	 */
1b04be96f   NeilBrown   md: change daemon...
1679
  	sleep = mddev->bitmap_info.daemon_sleep * 2;
42a04b507   NeilBrown   md: move offset, ...
1680
  	bitmap->daemon_lastrun -= sleep;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1681
  	md_bitmap_daemon_work(mddev);
42a04b507   NeilBrown   md: move offset, ...
1682
  	bitmap->daemon_lastrun -= sleep;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1683
  	md_bitmap_daemon_work(mddev);
42a04b507   NeilBrown   md: move offset, ...
1684
  	bitmap->daemon_lastrun -= sleep;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1685
1686
  	md_bitmap_daemon_work(mddev);
  	md_bitmap_update_sb(bitmap);
6b8b3e8a8   NeilBrown   [PATCH] md: make ...
1687
1688
1689
  }
  
  /*
32a7627cf   NeilBrown   [PATCH] md: optim...
1690
1691
   * free memory that was allocated
   */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1692
  void md_bitmap_free(struct bitmap *bitmap)
32a7627cf   NeilBrown   [PATCH] md: optim...
1693
1694
1695
  {
  	unsigned long k, pages;
  	struct bitmap_page *bp;
32a7627cf   NeilBrown   [PATCH] md: optim...
1696
1697
1698
  
  	if (!bitmap) /* there was no bitmap */
  		return;
f9a67b118   Guoqing Jiang   md/bitmap: clear ...
1699
1700
  	if (bitmap->sysfs_can_clear)
  		sysfs_put(bitmap->sysfs_can_clear);
f9209a323   Goldwyn Rodrigues   bitmap_create ret...
1701
1702
  	if (mddev_is_clustered(bitmap->mddev) && bitmap->mddev->cluster_info &&
  		bitmap->cluster_slot == md_cluster_ops->slot_number(bitmap->mddev))
b97e92574   Goldwyn Rodrigues   Use separate bitm...
1703
  		md_cluster_stop(bitmap->mddev);
fae7d326c   NeilBrown   md/bitmap: merge ...
1704
1705
1706
1707
1708
  	/* Shouldn't be needed - but just in case.... */
  	wait_event(bitmap->write_wait,
  		   atomic_read(&bitmap->pending_writes) == 0);
  
  	/* release the bitmap file  */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1709
  	md_bitmap_file_unmap(&bitmap->storage);
32a7627cf   NeilBrown   [PATCH] md: optim...
1710

40cffcc0e   NeilBrown   md/bitmap: create...
1711
1712
  	bp = bitmap->counts.bp;
  	pages = bitmap->counts.pages;
32a7627cf   NeilBrown   [PATCH] md: optim...
1713
1714
  
  	/* free all allocated memory */
32a7627cf   NeilBrown   [PATCH] md: optim...
1715
1716
1717
1718
1719
1720
1721
  	if (bp) /* deallocate the page memory */
  		for (k = 0; k < pages; k++)
  			if (bp[k].map && !bp[k].hijacked)
  				kfree(bp[k].map);
  	kfree(bp);
  	kfree(bitmap);
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1722
  EXPORT_SYMBOL(md_bitmap_free);
aa5cbd103   NeilBrown   md/bitmap: protec...
1723

e64e4018d   Andy Shevchenko   md: Avoid namespa...
1724
  void md_bitmap_wait_behind_writes(struct mddev *mddev)
48df498da   Guoqing Jiang   md: move bitmap_d...
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
  {
  	struct bitmap *bitmap = mddev->bitmap;
  
  	/* wait for behind writes to complete */
  	if (bitmap && atomic_read(&bitmap->behind_writes) > 0) {
  		pr_debug("md:%s: behind writes in progress - waiting to stop.
  ",
  			 mdname(mddev));
  		/* need to kick something here to make sure I/O goes? */
  		wait_event(bitmap->behind_wait,
  			   atomic_read(&bitmap->behind_writes) == 0);
  	}
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1738
  void md_bitmap_destroy(struct mddev *mddev)
3178b0dbd   NeilBrown   [PATCH] md: do no...
1739
1740
1741
1742
1743
  {
  	struct bitmap *bitmap = mddev->bitmap;
  
  	if (!bitmap) /* there was no bitmap */
  		return;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1744
  	md_bitmap_wait_behind_writes(mddev);
69b00b5bb   Guoqing Jiang   md: introduce a n...
1745
1746
  	if (!mddev->serialize_policy)
  		mddev_destroy_serial_pool(mddev, NULL, true);
48df498da   Guoqing Jiang   md: move bitmap_d...
1747

c3d9714e8   NeilBrown   md: collect bitma...
1748
  	mutex_lock(&mddev->bitmap_info.mutex);
978a7a47c   NeilBrown   md/bitmap: protec...
1749
  	spin_lock(&mddev->lock);
3178b0dbd   NeilBrown   [PATCH] md: do no...
1750
  	mddev->bitmap = NULL; /* disconnect from the md device */
978a7a47c   NeilBrown   md/bitmap: protec...
1751
  	spin_unlock(&mddev->lock);
c3d9714e8   NeilBrown   md: collect bitma...
1752
  	mutex_unlock(&mddev->bitmap_info.mutex);
b15c2e57f   NeilBrown   [PATCH] md: move ...
1753
1754
  	if (mddev->thread)
  		mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
3178b0dbd   NeilBrown   [PATCH] md: do no...
1755

e64e4018d   Andy Shevchenko   md: Avoid namespa...
1756
  	md_bitmap_free(bitmap);
3178b0dbd   NeilBrown   [PATCH] md: do no...
1757
  }
32a7627cf   NeilBrown   [PATCH] md: optim...
1758
1759
1760
1761
  
  /*
   * initialize the bitmap structure
   * if this returns an error, bitmap_destroy must be called to do clean up
f9a67b118   Guoqing Jiang   md/bitmap: clear ...
1762
   * once mddev->bitmap is set
32a7627cf   NeilBrown   [PATCH] md: optim...
1763
   */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1764
  struct bitmap *md_bitmap_create(struct mddev *mddev, int slot)
32a7627cf   NeilBrown   [PATCH] md: optim...
1765
1766
  {
  	struct bitmap *bitmap;
1f5939033   NeilBrown   md: support bitma...
1767
  	sector_t blocks = mddev->resync_max_sectors;
c3d9714e8   NeilBrown   md: collect bitma...
1768
  	struct file *file = mddev->bitmap_info.file;
32a7627cf   NeilBrown   [PATCH] md: optim...
1769
  	int err;
324a56e16   Tejun Heo   kernfs: s/sysfs_d...
1770
  	struct kernfs_node *bm = NULL;
32a7627cf   NeilBrown   [PATCH] md: optim...
1771

5f6e3c836   Alexey Dobriyan   [PATCH] md: use B...
1772
  	BUILD_BUG_ON(sizeof(bitmap_super_t) != 256);
32a7627cf   NeilBrown   [PATCH] md: optim...
1773

c3d9714e8   NeilBrown   md: collect bitma...
1774
  	BUG_ON(file && mddev->bitmap_info.offset);
a654b9d8f   NeilBrown   [PATCH] md: allow...
1775

230b55fa8   NeilBrown   md: forbid a RAID...
1776
1777
1778
1779
1780
1781
  	if (test_bit(MD_HAS_JOURNAL, &mddev->flags)) {
  		pr_notice("md/raid:%s: array with journal cannot have bitmap
  ",
  			  mdname(mddev));
  		return ERR_PTR(-EBUSY);
  	}
9ffae0cf3   NeilBrown   [PATCH] md: conve...
1782
  	bitmap = kzalloc(sizeof(*bitmap), GFP_KERNEL);
32a7627cf   NeilBrown   [PATCH] md: optim...
1783
  	if (!bitmap)
f9209a323   Goldwyn Rodrigues   bitmap_create ret...
1784
  		return ERR_PTR(-ENOMEM);
32a7627cf   NeilBrown   [PATCH] md: optim...
1785

40cffcc0e   NeilBrown   md/bitmap: create...
1786
  	spin_lock_init(&bitmap->counts.lock);
ce25c31bd   NeilBrown   [PATCH] md: Chang...
1787
1788
  	atomic_set(&bitmap->pending_writes, 0);
  	init_waitqueue_head(&bitmap->write_wait);
da6e1a32f   Neil Brown   [PATCH] md: avoid...
1789
  	init_waitqueue_head(&bitmap->overflow_wait);
e555190d8   NeilBrown   md/raid1: delay r...
1790
  	init_waitqueue_head(&bitmap->behind_wait);
ce25c31bd   NeilBrown   [PATCH] md: Chang...
1791

32a7627cf   NeilBrown   [PATCH] md: optim...
1792
  	bitmap->mddev = mddev;
f9209a323   Goldwyn Rodrigues   bitmap_create ret...
1793
  	bitmap->cluster_slot = slot;
32a7627cf   NeilBrown   [PATCH] md: optim...
1794

5ff5afffe   NeilBrown   md/bitmap: reduce...
1795
  	if (mddev->kobj.sd)
388975ccc   Tejun Heo   sysfs: clean up s...
1796
  		bm = sysfs_get_dirent(mddev->kobj.sd, "bitmap");
ece5cff0d   NeilBrown   md: Support write...
1797
  	if (bm) {
388975ccc   Tejun Heo   sysfs: clean up s...
1798
  		bitmap->sysfs_can_clear = sysfs_get_dirent(bm, "can_clear");
ece5cff0d   NeilBrown   md: Support write...
1799
1800
1801
  		sysfs_put(bm);
  	} else
  		bitmap->sysfs_can_clear = NULL;
1ec885cdd   NeilBrown   md/bitmap: move s...
1802
  	bitmap->storage.file = file;
ce25c31bd   NeilBrown   [PATCH] md: Chang...
1803
1804
  	if (file) {
  		get_file(file);
ae8fa2831   NeilBrown   md: remove clumsy...
1805
1806
1807
1808
  		/* As future accesses to this file will use bmap,
  		 * and bypass the page cache, we must sync the file
  		 * first.
  		 */
8018ab057   Christoph Hellwig   sanitize vfs_fsyn...
1809
  		vfs_fsync(file, 1);
ce25c31bd   NeilBrown   [PATCH] md: Chang...
1810
  	}
42a04b507   NeilBrown   md: move offset, ...
1811
  	/* read superblock from bitmap file (this sets mddev->bitmap_info.chunksize) */
9c81075f4   Jonathan Brassow   MD: support initi...
1812
1813
1814
1815
1816
1817
  	if (!mddev->bitmap_info.external) {
  		/*
  		 * If 'MD_ARRAY_FIRST_USE' is set, then device-mapper is
  		 * instructing us to create a new on-disk bitmap instance.
  		 */
  		if (test_and_clear_bit(MD_ARRAY_FIRST_USE, &mddev->flags))
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1818
  			err = md_bitmap_new_disk_sb(bitmap);
9c81075f4   Jonathan Brassow   MD: support initi...
1819
  		else
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1820
  			err = md_bitmap_read_sb(bitmap);
9c81075f4   Jonathan Brassow   MD: support initi...
1821
  	} else {
ece5cff0d   NeilBrown   md: Support write...
1822
1823
1824
1825
1826
1827
1828
  		err = 0;
  		if (mddev->bitmap_info.chunksize == 0 ||
  		    mddev->bitmap_info.daemon_sleep == 0)
  			/* chunksize and time_base need to be
  			 * set first. */
  			err = -EINVAL;
  	}
32a7627cf   NeilBrown   [PATCH] md: optim...
1829
  	if (err)
3178b0dbd   NeilBrown   [PATCH] md: do no...
1830
  		goto error;
32a7627cf   NeilBrown   [PATCH] md: optim...
1831

624ce4f56   NeilBrown   md/bitmap: move s...
1832
  	bitmap->daemon_lastrun = jiffies;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1833
  	err = md_bitmap_resize(bitmap, blocks, mddev->bitmap_info.chunksize, 1);
d60b479d1   NeilBrown   md/bitmap: add bi...
1834
  	if (err)
3178b0dbd   NeilBrown   [PATCH] md: do no...
1835
  		goto error;
32a7627cf   NeilBrown   [PATCH] md: optim...
1836

ec0cc2268   NeilBrown   md/bitmap: change...
1837
1838
1839
  	pr_debug("created bitmap (%lu pages) for device %s
  ",
  		 bitmap->counts.pages, bmname(bitmap));
69e51b449   NeilBrown   md/bitmap: separ...
1840

f9209a323   Goldwyn Rodrigues   bitmap_create ret...
1841
1842
1843
  	err = test_bit(BITMAP_WRITE_ERROR, &bitmap->flags) ? -EIO : 0;
  	if (err)
  		goto error;
69e51b449   NeilBrown   md/bitmap: separ...
1844

f9209a323   Goldwyn Rodrigues   bitmap_create ret...
1845
  	return bitmap;
69e51b449   NeilBrown   md/bitmap: separ...
1846
   error:
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1847
  	md_bitmap_free(bitmap);
f9209a323   Goldwyn Rodrigues   bitmap_create ret...
1848
  	return ERR_PTR(err);
69e51b449   NeilBrown   md/bitmap: separ...
1849
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1850
  int md_bitmap_load(struct mddev *mddev)
69e51b449   NeilBrown   md/bitmap: separ...
1851
1852
  {
  	int err = 0;
3520fa4db   Jonathan Brassow   MD bitmap: Revert...
1853
  	sector_t start = 0;
69e51b449   NeilBrown   md/bitmap: separ...
1854
1855
  	sector_t sector = 0;
  	struct bitmap *bitmap = mddev->bitmap;
617b194a1   Guoqing Jiang   md-bitmap: create...
1856
  	struct md_rdev *rdev;
69e51b449   NeilBrown   md/bitmap: separ...
1857
1858
1859
  
  	if (!bitmap)
  		goto out;
617b194a1   Guoqing Jiang   md-bitmap: create...
1860
  	rdev_for_each(rdev, mddev)
404659cf1   Guoqing Jiang   md: rename wb stuffs
1861
  		mddev_create_serial_pool(mddev, rdev, true);
617b194a1   Guoqing Jiang   md-bitmap: create...
1862

51e453aec   Guoqing Jiang   md-cluster: gathe...
1863
1864
  	if (mddev_is_clustered(mddev))
  		md_cluster_ops->load_bitmaps(mddev, mddev->bitmap_info.nodes);
69e51b449   NeilBrown   md/bitmap: separ...
1865
1866
1867
1868
1869
1870
  	/* Clear out old bitmap info first:  Either there is none, or we
  	 * are resuming after someone else has possibly changed things,
  	 * so we should forget old cached info.
  	 * All chunks should be clean, but some might need_sync.
  	 */
  	while (sector < mddev->resync_max_sectors) {
57dab0bdf   NeilBrown   md: use sector_t ...
1871
  		sector_t blocks;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1872
  		md_bitmap_start_sync(bitmap, sector, &blocks, 0);
69e51b449   NeilBrown   md/bitmap: separ...
1873
1874
  		sector += blocks;
  	}
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1875
  	md_bitmap_close_sync(bitmap);
69e51b449   NeilBrown   md/bitmap: separ...
1876

3520fa4db   Jonathan Brassow   MD bitmap: Revert...
1877
1878
1879
1880
1881
  	if (mddev->degraded == 0
  	    || bitmap->events_cleared == mddev->events)
  		/* no need to keep dirty bits to optimise a
  		 * re-add of a missing device */
  		start = mddev->recovery_cp;
afbaa90b8   NeilBrown   md/bitmap: preven...
1882
  	mutex_lock(&mddev->bitmap_info.mutex);
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1883
  	err = md_bitmap_init_from_disk(bitmap, start);
afbaa90b8   NeilBrown   md/bitmap: preven...
1884
  	mutex_unlock(&mddev->bitmap_info.mutex);
3520fa4db   Jonathan Brassow   MD bitmap: Revert...
1885

32a7627cf   NeilBrown   [PATCH] md: optim...
1886
  	if (err)
69e51b449   NeilBrown   md/bitmap: separ...
1887
  		goto out;
b405fe91e   NeilBrown   md/bitmap: use se...
1888
  	clear_bit(BITMAP_STALE, &bitmap->flags);
ef99bf480   NeilBrown   md/bitmap: allow ...
1889
1890
1891
  
  	/* Kick recovery in case any bits were set */
  	set_bit(MD_RECOVERY_NEEDED, &bitmap->mddev->recovery);
3178b0dbd   NeilBrown   [PATCH] md: do no...
1892

1b04be96f   NeilBrown   md: change daemon...
1893
  	mddev->thread->timeout = mddev->bitmap_info.daemon_sleep;
9cd30fdc3   NeilBrown   md: remove needle...
1894
  	md_wakeup_thread(mddev->thread);
b15c2e57f   NeilBrown   [PATCH] md: move ...
1895

e64e4018d   Andy Shevchenko   md: Avoid namespa...
1896
  	md_bitmap_update_sb(bitmap);
4ad136637   NeilBrown   md: change bitmap...
1897

b405fe91e   NeilBrown   md/bitmap: use se...
1898
  	if (test_bit(BITMAP_WRITE_ERROR, &bitmap->flags))
69e51b449   NeilBrown   md/bitmap: separ...
1899
1900
  		err = -EIO;
  out:
3178b0dbd   NeilBrown   [PATCH] md: do no...
1901
  	return err;
32a7627cf   NeilBrown   [PATCH] md: optim...
1902
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1903
  EXPORT_SYMBOL_GPL(md_bitmap_load);
32a7627cf   NeilBrown   [PATCH] md: optim...
1904

1383b347a   Zhao Heming   md/bitmap: fix me...
1905
  /* caller need to free returned bitmap with md_bitmap_free() */
b98938d16   Guoqing Jiang   md-cluster: intro...
1906
1907
1908
1909
  struct bitmap *get_bitmap_from_slot(struct mddev *mddev, int slot)
  {
  	int rv = 0;
  	struct bitmap *bitmap;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1910
  	bitmap = md_bitmap_create(mddev, slot);
b98938d16   Guoqing Jiang   md-cluster: intro...
1911
1912
1913
1914
  	if (IS_ERR(bitmap)) {
  		rv = PTR_ERR(bitmap);
  		return ERR_PTR(rv);
  	}
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1915
  	rv = md_bitmap_init_from_disk(bitmap, 0);
b98938d16   Guoqing Jiang   md-cluster: intro...
1916
  	if (rv) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1917
  		md_bitmap_free(bitmap);
b98938d16   Guoqing Jiang   md-cluster: intro...
1918
1919
1920
1921
1922
1923
  		return ERR_PTR(rv);
  	}
  
  	return bitmap;
  }
  EXPORT_SYMBOL(get_bitmap_from_slot);
11dd35daa   Goldwyn Rodrigues   Copy set bits fro...
1924
1925
1926
  /* Loads the bitmap associated with slot and copies the resync information
   * to our bitmap
   */
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1927
  int md_bitmap_copy_from_slot(struct mddev *mddev, int slot,
97f6cd39d   Goldwyn Rodrigues   md-cluster: re-ad...
1928
  		sector_t *low, sector_t *high, bool clear_bits)
11dd35daa   Goldwyn Rodrigues   Copy set bits fro...
1929
1930
1931
1932
  {
  	int rv = 0, i, j;
  	sector_t block, lo = 0, hi = 0;
  	struct bitmap_counts *counts;
b98938d16   Guoqing Jiang   md-cluster: intro...
1933
  	struct bitmap *bitmap;
11dd35daa   Goldwyn Rodrigues   Copy set bits fro...
1934

b98938d16   Guoqing Jiang   md-cluster: intro...
1935
1936
1937
1938
1939
1940
  	bitmap = get_bitmap_from_slot(mddev, slot);
  	if (IS_ERR(bitmap)) {
  		pr_err("%s can't get bitmap from slot %d
  ", __func__, slot);
  		return -1;
  	}
11dd35daa   Goldwyn Rodrigues   Copy set bits fro...
1941
1942
1943
1944
  
  	counts = &bitmap->counts;
  	for (j = 0; j < counts->chunks; j++) {
  		block = (sector_t)j << counts->chunkshift;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1945
  		if (md_bitmap_file_test_bit(bitmap, block)) {
11dd35daa   Goldwyn Rodrigues   Copy set bits fro...
1946
1947
1948
  			if (!lo)
  				lo = block;
  			hi = block;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1949
1950
1951
  			md_bitmap_file_clear_bit(bitmap, block);
  			md_bitmap_set_memory_bits(mddev->bitmap, block, 1);
  			md_bitmap_file_set_bit(mddev->bitmap, block);
11dd35daa   Goldwyn Rodrigues   Copy set bits fro...
1952
1953
  		}
  	}
97f6cd39d   Goldwyn Rodrigues   md-cluster: re-ad...
1954
  	if (clear_bits) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1955
  		md_bitmap_update_sb(bitmap);
c84400c89   Guoqing Jiang   md-cluster/bitmap...
1956
1957
  		/* BITMAP_PAGE_PENDING is set, but bitmap_unplug needs
  		 * BITMAP_PAGE_DIRTY or _NEEDWRITE to write ... */
97f6cd39d   Goldwyn Rodrigues   md-cluster: re-ad...
1958
  		for (i = 0; i < bitmap->storage.file_pages; i++)
c84400c89   Guoqing Jiang   md-cluster/bitmap...
1959
1960
  			if (test_page_attr(bitmap, i, BITMAP_PAGE_PENDING))
  				set_page_attr(bitmap, i, BITMAP_PAGE_NEEDWRITE);
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1961
  		md_bitmap_unplug(bitmap);
97f6cd39d   Goldwyn Rodrigues   md-cluster: re-ad...
1962
  	}
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1963
  	md_bitmap_unplug(mddev->bitmap);
11dd35daa   Goldwyn Rodrigues   Copy set bits fro...
1964
1965
  	*low = lo;
  	*high = hi;
1383b347a   Zhao Heming   md/bitmap: fix me...
1966
  	md_bitmap_free(bitmap);
b98938d16   Guoqing Jiang   md-cluster: intro...
1967

11dd35daa   Goldwyn Rodrigues   Copy set bits fro...
1968
1969
  	return rv;
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1970
  EXPORT_SYMBOL_GPL(md_bitmap_copy_from_slot);
11dd35daa   Goldwyn Rodrigues   Copy set bits fro...
1971

e64e4018d   Andy Shevchenko   md: Avoid namespa...
1972
  void md_bitmap_status(struct seq_file *seq, struct bitmap *bitmap)
57148964d   NeilBrown   md/bitmap: move p...
1973
1974
  {
  	unsigned long chunk_kb;
40cffcc0e   NeilBrown   md/bitmap: create...
1975
  	struct bitmap_counts *counts;
57148964d   NeilBrown   md/bitmap: move p...
1976
1977
1978
  
  	if (!bitmap)
  		return;
40cffcc0e   NeilBrown   md/bitmap: create...
1979
  	counts = &bitmap->counts;
57148964d   NeilBrown   md/bitmap: move p...
1980
1981
1982
  	chunk_kb = bitmap->mddev->bitmap_info.chunksize >> 10;
  	seq_printf(seq, "bitmap: %lu/%lu pages [%luKB], "
  		   "%lu%s chunk",
40cffcc0e   NeilBrown   md/bitmap: create...
1983
1984
1985
  		   counts->pages - counts->missing_pages,
  		   counts->pages,
  		   (counts->pages - counts->missing_pages)
57148964d   NeilBrown   md/bitmap: move p...
1986
1987
1988
  		   << (PAGE_SHIFT - 10),
  		   chunk_kb ? chunk_kb : bitmap->mddev->bitmap_info.chunksize,
  		   chunk_kb ? "KB" : "B");
1ec885cdd   NeilBrown   md/bitmap: move s...
1989
  	if (bitmap->storage.file) {
57148964d   NeilBrown   md/bitmap: move p...
1990
  		seq_printf(seq, ", file: ");
2726d5662   Miklos Szeredi   vfs: add seq_file...
1991
1992
  		seq_file_path(seq, bitmap->storage.file, " \t
  ");
57148964d   NeilBrown   md/bitmap: move p...
1993
1994
1995
1996
  	}
  
  	seq_printf(seq, "
  ");
57148964d   NeilBrown   md/bitmap: move p...
1997
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
1998
  int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
d60b479d1   NeilBrown   md/bitmap: add bi...
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
  		  int chunksize, int init)
  {
  	/* If chunk_size is 0, choose an appropriate chunk size.
  	 * Then possibly allocate new storage space.
  	 * Then quiesce, copy bits, replace bitmap, and re-start
  	 *
  	 * This function is called both to set up the initial bitmap
  	 * and to resize the bitmap while the array is active.
  	 * If this happens as a result of the array being resized,
  	 * chunksize will be zero, and we need to choose a suitable
  	 * chunksize, otherwise we use what we are given.
  	 */
  	struct bitmap_storage store;
  	struct bitmap_counts old_counts;
  	unsigned long chunks;
  	sector_t block;
  	sector_t old_blocks, new_blocks;
  	int chunkshift;
  	int ret = 0;
  	long pages;
  	struct bitmap_page *new_bp;
e8a27f836   NeilBrown   md/bitmap: disabl...
2020
2021
2022
2023
2024
  	if (bitmap->storage.file && !init) {
  		pr_info("md: cannot resize file-based bitmap
  ");
  		return -EINVAL;
  	}
d60b479d1   NeilBrown   md/bitmap: add bi...
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
  	if (chunksize == 0) {
  		/* If there is enough space, leave the chunk size unchanged,
  		 * else increase by factor of two until there is enough space.
  		 */
  		long bytes;
  		long space = bitmap->mddev->bitmap_info.space;
  
  		if (space == 0) {
  			/* We don't know how much space there is, so limit
  			 * to current size - in sectors.
  			 */
  			bytes = DIV_ROUND_UP(bitmap->counts.chunks, 8);
  			if (!bitmap->mddev->bitmap_info.external)
  				bytes += sizeof(bitmap_super_t);
  			space = DIV_ROUND_UP(bytes, 512);
  			bitmap->mddev->bitmap_info.space = space;
  		}
  		chunkshift = bitmap->counts.chunkshift;
  		chunkshift--;
  		do {
  			/* 'chunkshift' is shift from block size to chunk size */
  			chunkshift++;
  			chunks = DIV_ROUND_UP_SECTOR_T(blocks, 1 << chunkshift);
  			bytes = DIV_ROUND_UP(chunks, 8);
  			if (!bitmap->mddev->bitmap_info.external)
  				bytes += sizeof(bitmap_super_t);
  		} while (bytes > (space << 9));
  	} else
  		chunkshift = ffz(~chunksize) - BITMAP_BLOCK_SHIFT;
  
  	chunks = DIV_ROUND_UP_SECTOR_T(blocks, 1 << chunkshift);
  	memset(&store, 0, sizeof(store));
  	if (bitmap->mddev->bitmap_info.offset || bitmap->mddev->bitmap_info.file)
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2058
2059
2060
2061
  		ret = md_bitmap_storage_alloc(&store, chunks,
  					      !bitmap->mddev->bitmap_info.external,
  					      mddev_is_clustered(bitmap->mddev)
  					      ? bitmap->cluster_slot : 0);
cbb387323   Guoqing Jiang   md/bitmap: call b...
2062
  	if (ret) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2063
  		md_bitmap_file_unmap(&store);
d60b479d1   NeilBrown   md/bitmap: add bi...
2064
  		goto err;
cbb387323   Guoqing Jiang   md/bitmap: call b...
2065
  	}
d60b479d1   NeilBrown   md/bitmap: add bi...
2066
2067
  
  	pages = DIV_ROUND_UP(chunks, PAGE_COUNTER_RATIO);
6396bb221   Kees Cook   treewide: kzalloc...
2068
  	new_bp = kcalloc(pages, sizeof(*new_bp), GFP_KERNEL);
d60b479d1   NeilBrown   md/bitmap: add bi...
2069
2070
  	ret = -ENOMEM;
  	if (!new_bp) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2071
  		md_bitmap_file_unmap(&store);
d60b479d1   NeilBrown   md/bitmap: add bi...
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
  		goto err;
  	}
  
  	if (!init)
  		bitmap->mddev->pers->quiesce(bitmap->mddev, 1);
  
  	store.file = bitmap->storage.file;
  	bitmap->storage.file = NULL;
  
  	if (store.sb_page && bitmap->storage.sb_page)
  		memcpy(page_address(store.sb_page),
  		       page_address(bitmap->storage.sb_page),
938b533d4   Shaohua Li   md/bitmap: revert...
2084
  		       sizeof(bitmap_super_t));
fadcbd290   Guoqing Jiang   md/bitmap: avoid ...
2085
  	spin_lock_irq(&bitmap->counts.lock);
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2086
  	md_bitmap_file_unmap(&bitmap->storage);
d60b479d1   NeilBrown   md/bitmap: add bi...
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
  	bitmap->storage = store;
  
  	old_counts = bitmap->counts;
  	bitmap->counts.bp = new_bp;
  	bitmap->counts.pages = pages;
  	bitmap->counts.missing_pages = pages;
  	bitmap->counts.chunkshift = chunkshift;
  	bitmap->counts.chunks = chunks;
  	bitmap->mddev->bitmap_info.chunksize = 1 << (chunkshift +
  						     BITMAP_BLOCK_SHIFT);
  
  	blocks = min(old_counts.chunks << old_counts.chunkshift,
  		     chunks << chunkshift);
c9d650322   Guoqing Jiang   md-cluster: alway...
2100
2101
2102
2103
  	/* For cluster raid, need to pre-allocate bitmap */
  	if (mddev_is_clustered(bitmap->mddev)) {
  		unsigned long page;
  		for (page = 0; page < pages; page++) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2104
  			ret = md_bitmap_checkpage(&bitmap->counts, page, 1, 1);
c9d650322   Guoqing Jiang   md-cluster: alway...
2105
2106
2107
2108
2109
  			if (ret) {
  				unsigned long k;
  
  				/* deallocate the page memory */
  				for (k = 0; k < page; k++) {
bc47e8425   kbuild test robot   md-cluster: fix i...
2110
  					kfree(new_bp[k].map);
c9d650322   Guoqing Jiang   md-cluster: alway...
2111
  				}
0868b99c2   Zdenek Kabelac   md: free unused m...
2112
  				kfree(new_bp);
c9d650322   Guoqing Jiang   md-cluster: alway...
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
  
  				/* restore some fields from old_counts */
  				bitmap->counts.bp = old_counts.bp;
  				bitmap->counts.pages = old_counts.pages;
  				bitmap->counts.missing_pages = old_counts.pages;
  				bitmap->counts.chunkshift = old_counts.chunkshift;
  				bitmap->counts.chunks = old_counts.chunks;
  				bitmap->mddev->bitmap_info.chunksize = 1 << (old_counts.chunkshift +
  									     BITMAP_BLOCK_SHIFT);
  				blocks = old_counts.chunks << old_counts.chunkshift;
ec0cc2268   NeilBrown   md/bitmap: change...
2123
2124
  				pr_warn("Could not pre-allocate in-memory bitmap for cluster raid
  ");
c9d650322   Guoqing Jiang   md-cluster: alway...
2125
2126
2127
2128
2129
  				break;
  			} else
  				bitmap->counts.bp[page].count += 1;
  		}
  	}
d60b479d1   NeilBrown   md/bitmap: add bi...
2130
2131
2132
  	for (block = 0; block < blocks; ) {
  		bitmap_counter_t *bmc_old, *bmc_new;
  		int set;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2133
  		bmc_old = md_bitmap_get_counter(&old_counts, block, &old_blocks, 0);
d60b479d1   NeilBrown   md/bitmap: add bi...
2134
2135
2136
  		set = bmc_old && NEEDED(*bmc_old);
  
  		if (set) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2137
  			bmc_new = md_bitmap_get_counter(&bitmap->counts, block, &new_blocks, 1);
d60b479d1   NeilBrown   md/bitmap: add bi...
2138
2139
2140
2141
2142
2143
  			if (*bmc_new == 0) {
  				/* need to set on-disk bits too. */
  				sector_t end = block + new_blocks;
  				sector_t start = block >> chunkshift;
  				start <<= chunkshift;
  				while (start < end) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2144
  					md_bitmap_file_set_bit(bitmap, block);
d60b479d1   NeilBrown   md/bitmap: add bi...
2145
2146
2147
  					start += 1 << chunkshift;
  				}
  				*bmc_new = 2;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2148
2149
  				md_bitmap_count_page(&bitmap->counts, block, 1);
  				md_bitmap_set_pending(&bitmap->counts, block);
d60b479d1   NeilBrown   md/bitmap: add bi...
2150
2151
2152
2153
2154
2155
2156
  			}
  			*bmc_new |= NEEDED_MASK;
  			if (new_blocks < old_blocks)
  				old_blocks = new_blocks;
  		}
  		block += old_blocks;
  	}
0868b99c2   Zdenek Kabelac   md: free unused m...
2157
2158
2159
2160
2161
2162
2163
  	if (bitmap->counts.bp != old_counts.bp) {
  		unsigned long k;
  		for (k = 0; k < old_counts.pages; k++)
  			if (!old_counts.bp[k].hijacked)
  				kfree(old_counts.bp[k].map);
  		kfree(old_counts.bp);
  	}
d60b479d1   NeilBrown   md/bitmap: add bi...
2164
2165
2166
2167
  	if (!init) {
  		int i;
  		while (block < (chunks << chunkshift)) {
  			bitmap_counter_t *bmc;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2168
  			bmc = md_bitmap_get_counter(&bitmap->counts, block, &new_blocks, 1);
d60b479d1   NeilBrown   md/bitmap: add bi...
2169
2170
2171
2172
2173
2174
  			if (bmc) {
  				/* new space.  It needs to be resynced, so
  				 * we set NEEDED_MASK.
  				 */
  				if (*bmc == 0) {
  					*bmc = NEEDED_MASK | 2;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2175
2176
  					md_bitmap_count_page(&bitmap->counts, block, 1);
  					md_bitmap_set_pending(&bitmap->counts, block);
d60b479d1   NeilBrown   md/bitmap: add bi...
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
  				}
  			}
  			block += new_blocks;
  		}
  		for (i = 0; i < bitmap->storage.file_pages; i++)
  			set_page_attr(bitmap, i, BITMAP_PAGE_DIRTY);
  	}
  	spin_unlock_irq(&bitmap->counts.lock);
  
  	if (!init) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2187
  		md_bitmap_unplug(bitmap);
d60b479d1   NeilBrown   md/bitmap: add bi...
2188
2189
2190
2191
2192
2193
  		bitmap->mddev->pers->quiesce(bitmap->mddev, 0);
  	}
  	ret = 0;
  err:
  	return ret;
  }
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2194
  EXPORT_SYMBOL_GPL(md_bitmap_resize);
d60b479d1   NeilBrown   md/bitmap: add bi...
2195

43a705076   NeilBrown   md: support updat...
2196
  static ssize_t
fd01b88c7   NeilBrown   md: remove typede...
2197
  location_show(struct mddev *mddev, char *page)
43a705076   NeilBrown   md: support updat...
2198
2199
  {
  	ssize_t len;
ac2f40be4   NeilBrown   md/bitmap: white ...
2200
  	if (mddev->bitmap_info.file)
43a705076   NeilBrown   md: support updat...
2201
  		len = sprintf(page, "file");
ac2f40be4   NeilBrown   md/bitmap: white ...
2202
  	else if (mddev->bitmap_info.offset)
43a705076   NeilBrown   md: support updat...
2203
  		len = sprintf(page, "%+lld", (long long)mddev->bitmap_info.offset);
ac2f40be4   NeilBrown   md/bitmap: white ...
2204
  	else
43a705076   NeilBrown   md: support updat...
2205
2206
2207
2208
2209
2210
2211
  		len = sprintf(page, "none");
  	len += sprintf(page+len, "
  ");
  	return len;
  }
  
  static ssize_t
fd01b88c7   NeilBrown   md: remove typede...
2212
  location_store(struct mddev *mddev, const char *buf, size_t len)
43a705076   NeilBrown   md: support updat...
2213
  {
d9dd26b20   Shaohua Li   MD: hold mddev lo...
2214
  	int rv;
43a705076   NeilBrown   md: support updat...
2215

d9dd26b20   Shaohua Li   MD: hold mddev lo...
2216
2217
2218
  	rv = mddev_lock(mddev);
  	if (rv)
  		return rv;
43a705076   NeilBrown   md: support updat...
2219
  	if (mddev->pers) {
d9dd26b20   Shaohua Li   MD: hold mddev lo...
2220
2221
2222
2223
2224
2225
2226
2227
  		if (!mddev->pers->quiesce) {
  			rv = -EBUSY;
  			goto out;
  		}
  		if (mddev->recovery || mddev->sync_thread) {
  			rv = -EBUSY;
  			goto out;
  		}
43a705076   NeilBrown   md: support updat...
2228
2229
2230
2231
2232
  	}
  
  	if (mddev->bitmap || mddev->bitmap_info.file ||
  	    mddev->bitmap_info.offset) {
  		/* bitmap already configured.  Only option is to clear it */
d9dd26b20   Shaohua Li   MD: hold mddev lo...
2233
2234
2235
2236
  		if (strncmp(buf, "none", 4) != 0) {
  			rv = -EBUSY;
  			goto out;
  		}
43a705076   NeilBrown   md: support updat...
2237
  		if (mddev->pers) {
f8f83d8ff   Jack Wang   md/bitmap: use md...
2238
  			mddev_suspend(mddev);
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2239
  			md_bitmap_destroy(mddev);
f8f83d8ff   Jack Wang   md/bitmap: use md...
2240
  			mddev_resume(mddev);
43a705076   NeilBrown   md: support updat...
2241
2242
2243
2244
2245
  		}
  		mddev->bitmap_info.offset = 0;
  		if (mddev->bitmap_info.file) {
  			struct file *f = mddev->bitmap_info.file;
  			mddev->bitmap_info.file = NULL;
43a705076   NeilBrown   md: support updat...
2246
2247
2248
2249
2250
2251
2252
2253
2254
  			fput(f);
  		}
  	} else {
  		/* No bitmap, OK to set a location */
  		long long offset;
  		if (strncmp(buf, "none", 4) == 0)
  			/* nothing to be done */;
  		else if (strncmp(buf, "file:", 5) == 0) {
  			/* Not supported yet */
d9dd26b20   Shaohua Li   MD: hold mddev lo...
2255
2256
  			rv = -EINVAL;
  			goto out;
43a705076   NeilBrown   md: support updat...
2257
  		} else {
43a705076   NeilBrown   md: support updat...
2258
  			if (buf[0] == '+')
b29bebd66   Jingoo Han   md: replace stric...
2259
  				rv = kstrtoll(buf+1, 10, &offset);
43a705076   NeilBrown   md: support updat...
2260
  			else
b29bebd66   Jingoo Han   md: replace stric...
2261
  				rv = kstrtoll(buf, 10, &offset);
43a705076   NeilBrown   md: support updat...
2262
  			if (rv)
d9dd26b20   Shaohua Li   MD: hold mddev lo...
2263
2264
2265
2266
2267
  				goto out;
  			if (offset == 0) {
  				rv = -EINVAL;
  				goto out;
  			}
ece5cff0d   NeilBrown   md: Support write...
2268
2269
  			if (mddev->bitmap_info.external == 0 &&
  			    mddev->major_version == 0 &&
d9dd26b20   Shaohua Li   MD: hold mddev lo...
2270
2271
2272
2273
  			    offset != mddev->bitmap_info.default_offset) {
  				rv = -EINVAL;
  				goto out;
  			}
43a705076   NeilBrown   md: support updat...
2274
2275
  			mddev->bitmap_info.offset = offset;
  			if (mddev->pers) {
f9209a323   Goldwyn Rodrigues   bitmap_create ret...
2276
  				struct bitmap *bitmap;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2277
  				bitmap = md_bitmap_create(mddev, -1);
f8f83d8ff   Jack Wang   md/bitmap: use md...
2278
  				mddev_suspend(mddev);
f9209a323   Goldwyn Rodrigues   bitmap_create ret...
2279
2280
2281
2282
  				if (IS_ERR(bitmap))
  					rv = PTR_ERR(bitmap);
  				else {
  					mddev->bitmap = bitmap;
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2283
  					rv = md_bitmap_load(mddev);
f9a67b118   Guoqing Jiang   md/bitmap: clear ...
2284
  					if (rv)
f9209a323   Goldwyn Rodrigues   bitmap_create ret...
2285
  						mddev->bitmap_info.offset = 0;
43a705076   NeilBrown   md: support updat...
2286
  				}
f9a67b118   Guoqing Jiang   md/bitmap: clear ...
2287
  				if (rv) {
e64e4018d   Andy Shevchenko   md: Avoid namespa...
2288
  					md_bitmap_destroy(mddev);
f8f83d8ff   Jack Wang   md/bitmap: use md...
2289
  					mddev_resume(mddev);
d9dd26b20   Shaohua Li   MD: hold mddev lo...
2290
  					goto out;
f9a67b118   Guoqing Jiang   md/bitmap: clear ...
2291
  				}
f8f83d8ff   Jack Wang   md/bitmap: use md...
2292
  				mddev_resume(mddev);
43a705076   NeilBrown   md: support updat...
2293
2294
2295
2296
2297
2298
2299
  			}
  		}
  	}
  	if (!mddev->external) {
  		/* Ensure new bitmap info is stored in
  		 * metadata promptly.
  		 */
2953079c6   Shaohua Li   md: separate flag...
2300
  		set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags);
43a705076   NeilBrown   md: support updat...
2301
2302
  		md_wakeup_thread(mddev->thread);
  	}
d9dd26b20   Shaohua Li   MD: hold mddev lo...
2303
2304
2305
2306
2307
  	rv = 0;
  out:
  	mddev_unlock(mddev);
  	if (rv)
  		return rv;
43a705076   NeilBrown   md: support updat...
2308
2309
2310
2311
2312
  	return len;
  }
  
  static struct md_sysfs_entry bitmap_location =
  __ATTR(location, S_IRUGO|S_IWUSR, location_show, location_store);
6409bb05a   NeilBrown   md/bitmap: add ne...
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
  /* 'bitmap/space' is the space available at 'location' for the
   * bitmap.  This allows the kernel to know when it is safe to
   * resize the bitmap to match a resized array.
   */
  static ssize_t
  space_show(struct mddev *mddev, char *page)
  {
  	return sprintf(page, "%lu
  ", mddev->bitmap_info.space);
  }
  
  static ssize_t
  space_store(struct mddev *mddev, const char *buf, size_t len)
  {
  	unsigned long sectors;
  	int rv;
  
  	rv = kstrtoul(buf, 10, &sectors);
  	if (rv)
  		return rv;
  
  	if (sectors == 0)
  		return -EINVAL;
  
  	if (mddev->bitmap &&
9b1215c10   NeilBrown   md/bitmap: store ...
2338
  	    sectors < (mddev->bitmap->storage.bytes + 511) >> 9)
6409bb05a   NeilBrown   md/bitmap: add ne...
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
  		return -EFBIG; /* Bitmap is too big for this small space */
  
  	/* could make sure it isn't too big, but that isn't really
  	 * needed - user-space should be careful.
  	 */
  	mddev->bitmap_info.space = sectors;
  	return len;
  }
  
  static struct md_sysfs_entry bitmap_space =
  __ATTR(space, S_IRUGO|S_IWUSR, space_show, space_store);
43a705076   NeilBrown   md: support updat...
2350
  static ssize_t
fd01b88c7   NeilBrown   md: remove typede...
2351
  timeout_show(struct mddev *mddev, char *page)
43a705076   NeilBrown   md: support updat...
2352
2353
2354
2355
  {
  	ssize_t len;
  	unsigned long secs = mddev->bitmap_info.daemon_sleep / HZ;
  	unsigned long jifs = mddev->bitmap_info.daemon_sleep % HZ;
ac2f40be4   NeilBrown   md/bitmap: white ...
2356

43a705076   NeilBrown   md: support updat...
2357
2358
2359
2360
2361
2362
2363
2364
2365
  	len = sprintf(page, "%lu", secs);
  	if (jifs)
  		len += sprintf(page+len, ".%03u", jiffies_to_msecs(jifs));
  	len += sprintf(page+len, "
  ");
  	return len;
  }
  
  static ssize_t
fd01b88c7   NeilBrown   md: remove typede...
2366
  timeout_store(struct mddev *mddev, const char *buf, size_t len)
43a705076   NeilBrown   md: support updat...
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
  {
  	/* timeout can be set at any time */
  	unsigned long timeout;
  	int rv = strict_strtoul_scaled(buf, &timeout, 4);
  	if (rv)
  		return rv;
  
  	/* just to make sure we don't overflow... */
  	if (timeout >= LONG_MAX / HZ)
  		return -EINVAL;
  
  	timeout = timeout * HZ / 10000;
  
  	if (timeout >= MAX_SCHEDULE_TIMEOUT)
  		timeout = MAX_SCHEDULE_TIMEOUT-1;
  	if (timeout < 1)
  		timeout = 1;
  	mddev->bitmap_info.daemon_sleep = timeout;
  	if (mddev->thread) {
  		/* if thread->timeout is MAX_SCHEDULE_TIMEOUT, then
  		 * the bitmap is all clean and we don't need to
  		 * adjust the timeout right now
  		 */
  		if (mddev->thread->timeout < MAX_SCHEDULE_TIMEOUT) {
  			mddev->thread->timeout = timeout;
  			md_wakeup_thread(mddev->thread);
  		}
  	}
  	return len;
  }
  
  static struct md_sysfs_entry bitmap_timeout =
  __ATTR(time_base, S_IRUGO|S_IWUSR, timeout_show, timeout_store);
  
  static ssize_t
fd01b88c7   NeilBrown   md: remove typede...
2402
  backlog_show(struct mddev *mddev, char *page)
43a705076   NeilBrown   md: support updat...
2403
2404
2405
2406
2407
2408
  {
  	return sprintf(page, "%lu
  ", mddev->bitmap_info.max_write_behind);
  }
  
  static ssize_t
fd01b88c7   NeilBrown   md: remove typede...
2409
  backlog_store(struct mddev *mddev, const char *buf, size_t len)
43a705076   NeilBrown   md: support updat...
2410
2411
  {
  	unsigned long backlog;
10c92fca6   Guoqing Jiang   md-bitmap: create...
2412
  	unsigned long old_mwb = mddev->bitmap_info.max_write_behind;
b29bebd66   Jingoo Han   md: replace stric...
2413
  	int rv = kstrtoul(buf, 10, &backlog);
43a705076   NeilBrown   md: support updat...
2414
2415
2416
2417
2418
  	if (rv)
  		return rv;
  	if (backlog > COUNTER_MAX)
  		return -EINVAL;
  	mddev->bitmap_info.max_write_behind = backlog;
404659cf1   Guoqing Jiang   md: rename wb stuffs
2419
2420
  	if (!backlog && mddev->serial_info_pool) {
  		/* serial_info_pool is not needed if backlog is zero */
69b00b5bb   Guoqing Jiang   md: introduce a n...
2421
2422
  		if (!mddev->serialize_policy)
  			mddev_destroy_serial_pool(mddev, NULL, false);
404659cf1   Guoqing Jiang   md: rename wb stuffs
2423
2424
  	} else if (backlog && !mddev->serial_info_pool) {
  		/* serial_info_pool is needed since backlog is not zero */
10c92fca6   Guoqing Jiang   md-bitmap: create...
2425
2426
2427
  		struct md_rdev *rdev;
  
  		rdev_for_each(rdev, mddev)
404659cf1   Guoqing Jiang   md: rename wb stuffs
2428
  			mddev_create_serial_pool(mddev, rdev, false);
10c92fca6   Guoqing Jiang   md-bitmap: create...
2429
2430
2431
  	}
  	if (old_mwb != backlog)
  		md_bitmap_update_sb(mddev->bitmap);
43a705076   NeilBrown   md: support updat...
2432
2433
2434
2435
2436
2437
2438
  	return len;
  }
  
  static struct md_sysfs_entry bitmap_backlog =
  __ATTR(backlog, S_IRUGO|S_IWUSR, backlog_show, backlog_store);
  
  static ssize_t
fd01b88c7   NeilBrown   md: remove typede...
2439
  chunksize_show(struct mddev *mddev, char *page)
43a705076   NeilBrown   md: support updat...
2440
2441
2442
2443
2444
2445
  {
  	return sprintf(page, "%lu
  ", mddev->bitmap_info.chunksize);
  }
  
  static ssize_t
fd01b88c7   NeilBrown   md: remove typede...
2446
  chunksize_store(struct mddev *mddev, const char *buf, size_t len)
43a705076   NeilBrown   md: support updat...
2447
2448
2449
2450
2451
2452
  {
  	/* Can only be changed when no bitmap is active */
  	int rv;
  	unsigned long csize;
  	if (mddev->bitmap)
  		return -EBUSY;
b29bebd66   Jingoo Han   md: replace stric...
2453
  	rv = kstrtoul(buf, 10, &csize);
43a705076   NeilBrown   md: support updat...
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
  	if (rv)
  		return rv;
  	if (csize < 512 ||
  	    !is_power_of_2(csize))
  		return -EINVAL;
  	mddev->bitmap_info.chunksize = csize;
  	return len;
  }
  
  static struct md_sysfs_entry bitmap_chunksize =
  __ATTR(chunksize, S_IRUGO|S_IWUSR, chunksize_show, chunksize_store);
fd01b88c7   NeilBrown   md: remove typede...
2465
  static ssize_t metadata_show(struct mddev *mddev, char *page)
ece5cff0d   NeilBrown   md: Support write...
2466
  {
c4ce867fd   Goldwyn Rodrigues   Introduce md_clus...
2467
2468
2469
  	if (mddev_is_clustered(mddev))
  		return sprintf(page, "clustered
  ");
ece5cff0d   NeilBrown   md: Support write...
2470
2471
2472
2473
  	return sprintf(page, "%s
  ", (mddev->bitmap_info.external
  				      ? "external" : "internal"));
  }
fd01b88c7   NeilBrown   md: remove typede...
2474
  static ssize_t metadata_store(struct mddev *mddev, const char *buf, size_t len)
ece5cff0d   NeilBrown   md: Support write...
2475
2476
2477
2478
2479
2480
2481
  {
  	if (mddev->bitmap ||
  	    mddev->bitmap_info.file ||
  	    mddev->bitmap_info.offset)
  		return -EBUSY;
  	if (strncmp(buf, "external", 8) == 0)
  		mddev->bitmap_info.external = 1;
c4ce867fd   Goldwyn Rodrigues   Introduce md_clus...
2482
2483
  	else if ((strncmp(buf, "internal", 8) == 0) ||
  			(strncmp(buf, "clustered", 9) == 0))
ece5cff0d   NeilBrown   md: Support write...
2484
2485
2486
2487
2488
2489
2490
2491
  		mddev->bitmap_info.external = 0;
  	else
  		return -EINVAL;
  	return len;
  }
  
  static struct md_sysfs_entry bitmap_metadata =
  __ATTR(metadata, S_IRUGO|S_IWUSR, metadata_show, metadata_store);
fd01b88c7   NeilBrown   md: remove typede...
2492
  static ssize_t can_clear_show(struct mddev *mddev, char *page)
ece5cff0d   NeilBrown   md: Support write...
2493
2494
  {
  	int len;
b7b17c9b6   NeilBrown   md: remove mddev_...
2495
  	spin_lock(&mddev->lock);
ece5cff0d   NeilBrown   md: Support write...
2496
2497
2498
2499
2500
2501
2502
  	if (mddev->bitmap)
  		len = sprintf(page, "%s
  ", (mddev->bitmap->need_sync ?
  					     "false" : "true"));
  	else
  		len = sprintf(page, "
  ");
b7b17c9b6   NeilBrown   md: remove mddev_...
2503
  	spin_unlock(&mddev->lock);
ece5cff0d   NeilBrown   md: Support write...
2504
2505
  	return len;
  }
fd01b88c7   NeilBrown   md: remove typede...
2506
  static ssize_t can_clear_store(struct mddev *mddev, const char *buf, size_t len)
ece5cff0d   NeilBrown   md: Support write...
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
  {
  	if (mddev->bitmap == NULL)
  		return -ENOENT;
  	if (strncmp(buf, "false", 5) == 0)
  		mddev->bitmap->need_sync = 1;
  	else if (strncmp(buf, "true", 4) == 0) {
  		if (mddev->degraded)
  			return -EBUSY;
  		mddev->bitmap->need_sync = 0;
  	} else
  		return -EINVAL;
  	return len;
  }
  
  static struct md_sysfs_entry bitmap_can_clear =
  __ATTR(can_clear, S_IRUGO|S_IWUSR, can_clear_show, can_clear_store);
696fcd535   Paul Clements   md: expose max va...
2523
  static ssize_t
fd01b88c7   NeilBrown   md: remove typede...
2524
  behind_writes_used_show(struct mddev *mddev, char *page)
696fcd535   Paul Clements   md: expose max va...
2525
  {
b7b17c9b6   NeilBrown   md: remove mddev_...
2526
2527
  	ssize_t ret;
  	spin_lock(&mddev->lock);
696fcd535   Paul Clements   md: expose max va...
2528
  	if (mddev->bitmap == NULL)
b7b17c9b6   NeilBrown   md: remove mddev_...
2529
2530
2531
2532
2533
2534
2535
2536
  		ret = sprintf(page, "0
  ");
  	else
  		ret = sprintf(page, "%lu
  ",
  			      mddev->bitmap->behind_writes_used);
  	spin_unlock(&mddev->lock);
  	return ret;
696fcd535   Paul Clements   md: expose max va...
2537
2538
2539
  }
  
  static ssize_t
fd01b88c7   NeilBrown   md: remove typede...
2540
  behind_writes_used_reset(struct mddev *mddev, const char *buf, size_t len)
696fcd535   Paul Clements   md: expose max va...
2541
2542
2543
2544
2545
2546
2547
2548
2549
  {
  	if (mddev->bitmap)
  		mddev->bitmap->behind_writes_used = 0;
  	return len;
  }
  
  static struct md_sysfs_entry max_backlog_used =
  __ATTR(max_backlog_used, S_IRUGO | S_IWUSR,
         behind_writes_used_show, behind_writes_used_reset);
43a705076   NeilBrown   md: support updat...
2550
2551
  static struct attribute *md_bitmap_attrs[] = {
  	&bitmap_location.attr,
6409bb05a   NeilBrown   md/bitmap: add ne...
2552
  	&bitmap_space.attr,
43a705076   NeilBrown   md: support updat...
2553
2554
2555
  	&bitmap_timeout.attr,
  	&bitmap_backlog.attr,
  	&bitmap_chunksize.attr,
ece5cff0d   NeilBrown   md: Support write...
2556
2557
  	&bitmap_metadata.attr,
  	&bitmap_can_clear.attr,
696fcd535   Paul Clements   md: expose max va...
2558
  	&max_backlog_used.attr,
43a705076   NeilBrown   md: support updat...
2559
2560
2561
2562
2563
2564
  	NULL
  };
  struct attribute_group md_bitmap_group = {
  	.name = "bitmap",
  	.attrs = md_bitmap_attrs,
  };