Blame view

fs/exofs/ore.c 30.1 KB
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
1
2
  /*
   * Copyright (C) 2005, 2006
27d2e1491   Boaz Harrosh   exofs: Remove IBM...
3
   * Avishay Traeger (avishay@gmail.com)
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
4
   * Copyright (C) 2008, 2009
aa281ac63   Boaz Harrosh   Boaz Harrosh - Fi...
5
   * Boaz Harrosh <ooo@electrozaur.com>
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
   *
   * This file is part of exofs.
   *
   * exofs is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation.  Since it is based on ext2, and the only
   * valid version of GPL for the Linux kernel is version 2, the only valid
   * version of GPL for exofs is version 2.
   *
   * exofs is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with exofs; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   */
5a0e3ad6a   Tejun Heo   include cleanup: ...
24
  #include <linux/slab.h>
143cb494c   Paul Gortmaker   fs: add module.h ...
25
  #include <linux/module.h>
5d952b839   Boaz Harrosh   exofs: RAID0 support
26
  #include <asm/div64.h>
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
27
  #include <linux/lcm.h>
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
28

a1fec1dbb   Boaz Harrosh   ore: RAID5 read
29
  #include "ore_raid.h"
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
30

aa281ac63   Boaz Harrosh   Boaz Harrosh - Fi...
31
  MODULE_AUTHOR("Boaz Harrosh <ooo@electrozaur.com>");
cf283ade0   Boaz Harrosh   ore: Make ore its...
32
33
  MODULE_DESCRIPTION("Objects Raid Engine ore.ko");
  MODULE_LICENSE("GPL");
5a51c0c7e   Boaz Harrosh   ore/exofs: Define...
34
35
36
37
38
39
40
41
42
  /* ore_verify_layout does a couple of things:
   * 1. Given a minimum number of needed parameters fixes up the rest of the
   *    members to be operatonals for the ore. The needed parameters are those
   *    that are defined by the pnfs-objects layout STD.
   * 2. Check to see if the current ore code actually supports these parameters
   *    for example stripe_unit must be a multple of the system PAGE_SIZE,
   *    and etc...
   * 3. Cache some havily used calculations that will be needed by users.
   */
5a51c0c7e   Boaz Harrosh   ore/exofs: Define...
43
44
45
46
47
48
  enum { BIO_MAX_PAGES_KMALLOC =
  		(PAGE_SIZE - sizeof(struct bio)) / sizeof(struct bio_vec),};
  
  int ore_verify_layout(unsigned total_comps, struct ore_layout *layout)
  {
  	u64 stripe_length;
44231e686   Boaz Harrosh   ore: Enable RAID5...
49
50
51
52
53
54
55
56
  	switch (layout->raid_algorithm) {
  	case PNFS_OSD_RAID_0:
  		layout->parity = 0;
  		break;
  	case PNFS_OSD_RAID_5:
  		layout->parity = 1;
  		break;
  	case PNFS_OSD_RAID_PQ:
ce5d36aac   Boaz Harrosh   ore: Support for ...
57
58
  		layout->parity = 2;
  		break;
44231e686   Boaz Harrosh   ore: Enable RAID5...
59
60
  	case PNFS_OSD_RAID_4:
  	default:
ce5d36aac   Boaz Harrosh   ore: Support for ...
61
62
63
  		ORE_ERR("Only RAID_0/5/6 for now received-enum=%d
  ",
  			layout->raid_algorithm);
5a51c0c7e   Boaz Harrosh   ore/exofs: Define...
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  		return -EINVAL;
  	}
  	if (0 != (layout->stripe_unit & ~PAGE_MASK)) {
  		ORE_ERR("Stripe Unit(0x%llx)"
  			  " must be Multples of PAGE_SIZE(0x%lx)
  ",
  			  _LLU(layout->stripe_unit), PAGE_SIZE);
  		return -EINVAL;
  	}
  	if (layout->group_width) {
  		if (!layout->group_depth) {
  			ORE_ERR("group_depth == 0 && group_width != 0
  ");
  			return -EINVAL;
  		}
  		if (total_comps < (layout->group_width * layout->mirrors_p1)) {
  			ORE_ERR("Data Map wrong, "
  				"numdevs=%d < group_width=%d * mirrors=%d
  ",
  				total_comps, layout->group_width,
  				layout->mirrors_p1);
  			return -EINVAL;
  		}
  		layout->group_count = total_comps / layout->mirrors_p1 /
  						layout->group_width;
  	} else {
  		if (layout->group_depth) {
  			printk(KERN_NOTICE "Warning: group_depth ignored "
  				"group_width == 0 && group_depth == %lld
  ",
  				_LLU(layout->group_depth));
  		}
  		layout->group_width = total_comps / layout->mirrors_p1;
  		layout->group_depth = -1;
  		layout->group_count = 1;
  	}
  
  	stripe_length = (u64)layout->group_width * layout->stripe_unit;
  	if (stripe_length >= (1ULL << 32)) {
  		ORE_ERR("Stripe_length(0x%llx) >= 32bit is not supported
  ",
  			_LLU(stripe_length));
  		return -EINVAL;
  	}
  
  	layout->max_io_length =
  		(BIO_MAX_PAGES_KMALLOC * PAGE_SIZE - layout->stripe_unit) *
aad560b7f   Boaz Harrosh   ore: Fix wrong ma...
111
  					(layout->group_width - layout->parity);
769ba8d92   Boaz Harrosh   ore: RAID5 Write
112
113
114
115
116
117
118
119
  	if (layout->parity) {
  		unsigned stripe_length =
  				(layout->group_width - layout->parity) *
  				layout->stripe_unit;
  
  		layout->max_io_length /= stripe_length;
  		layout->max_io_length *= stripe_length;
  	}
ce5d36aac   Boaz Harrosh   ore: Support for ...
120
121
  	ORE_DBGMSG("max_io_length=0x%lx
  ", layout->max_io_length);
5a51c0c7e   Boaz Harrosh   ore/exofs: Define...
122
123
124
  	return 0;
  }
  EXPORT_SYMBOL(ore_verify_layout);
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
125
  static u8 *_ios_cred(struct ore_io_state *ios, unsigned index)
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
126
  {
5bf696dad   Boaz Harrosh   exofs: Rename str...
127
  	return ios->oc->comps[index & ios->oc->single_comp].cred;
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
128
  }
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
129
  static struct osd_obj_id *_ios_obj(struct ore_io_state *ios, unsigned index)
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
130
  {
5bf696dad   Boaz Harrosh   exofs: Rename str...
131
  	return &ios->oc->comps[index & ios->oc->single_comp].obj;
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
132
  }
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
133
  static struct osd_dev *_ios_od(struct ore_io_state *ios, unsigned index)
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
134
  {
3bd985685   Boaz Harrosh   ore: Support for ...
135
136
137
138
  	ORE_DBGMSG2("oc->first_dev=%d oc->numdevs=%d i=%d oc->ods=%p
  ",
  		    ios->oc->first_dev, ios->oc->numdevs, index,
  		    ios->oc->ods);
d866d875f   Boaz Harrosh   ore/exofs: Change...
139
  	return ore_comp_dev(ios->oc, index);
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
140
  }
769ba8d92   Boaz Harrosh   ore: RAID5 Write
141
  int  _ore_get_io_state(struct ore_layout *layout,
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
142
143
144
  			struct ore_components *oc, unsigned numdevs,
  			unsigned sgs_per_dev, unsigned num_par_pages,
  			struct ore_io_state **pios)
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
145
  {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
146
  	struct ore_io_state *ios;
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
  	struct page **pages;
  	struct osd_sg_entry *sgilist;
  	struct __alloc_all_io_state {
  		struct ore_io_state ios;
  		struct ore_per_dev_state per_dev[numdevs];
  		union {
  			struct osd_sg_entry sglist[sgs_per_dev * numdevs];
  			struct page *pages[num_par_pages];
  		};
  	} *_aios;
  
  	if (likely(sizeof(*_aios) <= PAGE_SIZE)) {
  		_aios = kzalloc(sizeof(*_aios), GFP_KERNEL);
  		if (unlikely(!_aios)) {
  			ORE_DBGMSG("Failed kzalloc bytes=%zd
  ",
  				   sizeof(*_aios));
  			*pios = NULL;
  			return -ENOMEM;
  		}
  		pages = num_par_pages ? _aios->pages : NULL;
  		sgilist = sgs_per_dev ? _aios->sglist : NULL;
  		ios = &_aios->ios;
  	} else {
  		struct __alloc_small_io_state {
  			struct ore_io_state ios;
  			struct ore_per_dev_state per_dev[numdevs];
  		} *_aio_small;
  		union __extra_part {
  			struct osd_sg_entry sglist[sgs_per_dev * numdevs];
  			struct page *pages[num_par_pages];
  		} *extra_part;
  
  		_aio_small = kzalloc(sizeof(*_aio_small), GFP_KERNEL);
  		if (unlikely(!_aio_small)) {
  			ORE_DBGMSG("Failed alloc first part bytes=%zd
  ",
  				   sizeof(*_aio_small));
  			*pios = NULL;
  			return -ENOMEM;
  		}
  		extra_part = kzalloc(sizeof(*extra_part), GFP_KERNEL);
  		if (unlikely(!extra_part)) {
  			ORE_DBGMSG("Failed alloc second part bytes=%zd
  ",
  				   sizeof(*extra_part));
  			kfree(_aio_small);
  			*pios = NULL;
  			return -ENOMEM;
  		}
06886a5a3   Boaz Harrosh   exofs: Move all o...
197

a1fec1dbb   Boaz Harrosh   ore: RAID5 read
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
  		pages = num_par_pages ? extra_part->pages : NULL;
  		sgilist = sgs_per_dev ? extra_part->sglist : NULL;
  		/* In this case the per_dev[0].sgilist holds the pointer to
  		 * be freed
  		 */
  		ios = &_aio_small->ios;
  		ios->extra_part_alloc = true;
  	}
  
  	if (pages) {
  		ios->parity_pages = pages;
  		ios->max_par_pages = num_par_pages;
  	}
  	if (sgilist) {
  		unsigned d;
  
  		for (d = 0; d < numdevs; ++d) {
  			ios->per_dev[d].sglist = sgilist;
  			sgilist += sgs_per_dev;
  		}
  		ios->sgs_per_dev = sgs_per_dev;
06886a5a3   Boaz Harrosh   exofs: Move all o...
219
  	}
45d3abcb1   Boaz Harrosh   exofs: Move layou...
220
  	ios->layout = layout;
5bf696dad   Boaz Harrosh   exofs: Rename str...
221
  	ios->oc = oc;
b916c5cd4   Boaz Harrosh   ore: Only IO one ...
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
  	*pios = ios;
  	return 0;
  }
  
  /* Allocate an io_state for only a single group of devices
   *
   * If a user needs to call ore_read/write() this version must be used becase it
   * allocates extra stuff for striping and raid.
   * The ore might decide to only IO less then @length bytes do to alignmets
   * and constrains as follows:
   * - The IO cannot cross group boundary.
   * - In raid5/6 The end of the IO must align at end of a stripe eg.
   *   (@offset + @length) % strip_size == 0. Or the complete range is within a
   *   single stripe.
   * - Memory condition only permitted a shorter IO. (A user can use @length=~0
   *   And check the returned ios->length for max_io_size.)
   *
   * The caller must check returned ios->length (and/or ios->nr_pages) and
   * re-issue these pages that fall outside of ios->length
   */
  int  ore_get_rw_state(struct ore_layout *layout, struct ore_components *oc,
  		      bool is_reading, u64 offset, u64 length,
  		      struct ore_io_state **pios)
  {
  	struct ore_io_state *ios;
  	unsigned numdevs = layout->group_width * layout->mirrors_p1;
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
248
  	unsigned sgs_per_dev = 0, max_par_pages = 0;
b916c5cd4   Boaz Harrosh   ore: Only IO one ...
249
  	int ret;
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
  	if (layout->parity && length) {
  		unsigned data_devs = layout->group_width - layout->parity;
  		unsigned stripe_size = layout->stripe_unit * data_devs;
  		unsigned pages_in_unit = layout->stripe_unit / PAGE_SIZE;
  		u32 remainder;
  		u64 num_stripes;
  		u64 num_raid_units;
  
  		num_stripes = div_u64_rem(length, stripe_size, &remainder);
  		if (remainder)
  			++num_stripes;
  
  		num_raid_units =  num_stripes * layout->parity;
  
  		if (is_reading) {
  			/* For reads add per_dev sglist array */
  			/* TODO: Raid 6 we need twice more. Actually:
  			*         num_stripes / LCMdP(W,P);
  			*         if (W%P != 0) num_stripes *= parity;
  			*/
  
  			/* first/last seg is split */
  			num_raid_units += layout->group_width;
361aba569   Boaz Harrosh   ore: fix BUG_ON, ...
273
  			sgs_per_dev = div_u64(num_raid_units, data_devs) + 2;
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
274
275
276
277
278
279
280
281
282
  		} else {
  			/* For Writes add parity pages array. */
  			max_par_pages = num_raid_units * pages_in_unit *
  						sizeof(struct page *);
  		}
  	}
  
  	ret = _ore_get_io_state(layout, oc, numdevs, sgs_per_dev, max_par_pages,
  				pios);
b916c5cd4   Boaz Harrosh   ore: Only IO one ...
283
284
285
286
  	if (unlikely(ret))
  		return ret;
  
  	ios = *pios;
e1042ba09   Boaz Harrosh   exofs: Add offset...
287
  	ios->reading = is_reading;
b916c5cd4   Boaz Harrosh   ore: Only IO one ...
288
289
290
  	ios->offset = offset;
  
  	if (length) {
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
291
292
  		ore_calc_stripe_info(layout, offset, length, &ios->si);
  		ios->length = ios->si.length;
aad560b7f   Boaz Harrosh   ore: Fix wrong ma...
293
294
  		ios->nr_pages = ((ios->offset & (PAGE_SIZE - 1)) +
  				 ios->length + PAGE_SIZE - 1) / PAGE_SIZE;
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
295
296
  		if (layout->parity)
  			_ore_post_alloc_raid_stuff(ios);
b916c5cd4   Boaz Harrosh   ore: Only IO one ...
297
  	}
e1042ba09   Boaz Harrosh   exofs: Add offset...
298

06886a5a3   Boaz Harrosh   exofs: Move all o...
299
  	return 0;
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
300
  }
cf283ade0   Boaz Harrosh   ore: Make ore its...
301
  EXPORT_SYMBOL(ore_get_rw_state);
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
302

b916c5cd4   Boaz Harrosh   ore: Only IO one ...
303
304
305
306
307
308
309
  /* Allocate an io_state for all the devices in the comps array
   *
   * This version of io_state allocation is used mostly by create/remove
   * and trunc where we currently need all the devices. The only wastful
   * bit is the read/write_attributes with no IO. Those sites should
   * be converted to use ore_get_rw_state() with length=0
   */
5bf696dad   Boaz Harrosh   exofs: Rename str...
310
  int  ore_get_io_state(struct ore_layout *layout, struct ore_components *oc,
b916c5cd4   Boaz Harrosh   ore: Only IO one ...
311
  		      struct ore_io_state **pios)
e1042ba09   Boaz Harrosh   exofs: Add offset...
312
  {
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
313
  	return _ore_get_io_state(layout, oc, oc->numdevs, 0, 0, pios);
e1042ba09   Boaz Harrosh   exofs: Add offset...
314
  }
cf283ade0   Boaz Harrosh   ore: Make ore its...
315
  EXPORT_SYMBOL(ore_get_io_state);
e1042ba09   Boaz Harrosh   exofs: Add offset...
316

8ff660ab8   Boaz Harrosh   exofs: Rename rai...
317
  void ore_put_io_state(struct ore_io_state *ios)
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
318
  {
06886a5a3   Boaz Harrosh   exofs: Move all o...
319
320
  	if (ios) {
  		unsigned i;
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
321

06886a5a3   Boaz Harrosh   exofs: Move all o...
322
  		for (i = 0; i < ios->numdevs; i++) {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
323
  			struct ore_per_dev_state *per_dev = &ios->per_dev[i];
06886a5a3   Boaz Harrosh   exofs: Move all o...
324
325
326
327
328
329
  
  			if (per_dev->or)
  				osd_end_request(per_dev->or);
  			if (per_dev->bio)
  				bio_put(per_dev->bio);
  		}
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
330
  		_ore_free_raid_stuff(ios);
06886a5a3   Boaz Harrosh   exofs: Move all o...
331
  		kfree(ios);
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
332
  	}
06886a5a3   Boaz Harrosh   exofs: Move all o...
333
  }
cf283ade0   Boaz Harrosh   ore: Make ore its...
334
  EXPORT_SYMBOL(ore_put_io_state);
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
335

8ff660ab8   Boaz Harrosh   exofs: Rename rai...
336
  static void _sync_done(struct ore_io_state *ios, void *p)
06886a5a3   Boaz Harrosh   exofs: Move all o...
337
338
  {
  	struct completion *waiting = p;
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
339

06886a5a3   Boaz Harrosh   exofs: Move all o...
340
341
342
343
344
  	complete(waiting);
  }
  
  static void _last_io(struct kref *kref)
  {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
345
346
  	struct ore_io_state *ios = container_of(
  					kref, struct ore_io_state, kref);
06886a5a3   Boaz Harrosh   exofs: Move all o...
347
348
349
350
351
352
  
  	ios->done(ios, ios->private);
  }
  
  static void _done_io(struct osd_request *or, void *p)
  {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
353
  	struct ore_io_state *ios = p;
06886a5a3   Boaz Harrosh   exofs: Move all o...
354
355
356
  
  	kref_put(&ios->kref, _last_io);
  }
769ba8d92   Boaz Harrosh   ore: RAID5 Write
357
  int ore_io_execute(struct ore_io_state *ios)
06886a5a3   Boaz Harrosh   exofs: Move all o...
358
359
360
361
362
363
364
365
366
367
368
369
370
371
  {
  	DECLARE_COMPLETION_ONSTACK(wait);
  	bool sync = (ios->done == NULL);
  	int i, ret;
  
  	if (sync) {
  		ios->done = _sync_done;
  		ios->private = &wait;
  	}
  
  	for (i = 0; i < ios->numdevs; i++) {
  		struct osd_request *or = ios->per_dev[i].or;
  		if (unlikely(!or))
  			continue;
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
372
  		ret = osd_finalize_request(or, 0, _ios_cred(ios, i), NULL);
06886a5a3   Boaz Harrosh   exofs: Move all o...
373
  		if (unlikely(ret)) {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
374
375
  			ORE_DBGMSG("Failed to osd_finalize_request() => %d
  ",
06886a5a3   Boaz Harrosh   exofs: Move all o...
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
  				     ret);
  			return ret;
  		}
  	}
  
  	kref_init(&ios->kref);
  
  	for (i = 0; i < ios->numdevs; i++) {
  		struct osd_request *or = ios->per_dev[i].or;
  		if (unlikely(!or))
  			continue;
  
  		kref_get(&ios->kref);
  		osd_execute_request_async(or, _done_io, ios);
  	}
  
  	kref_put(&ios->kref, _last_io);
  	ret = 0;
  
  	if (sync) {
  		wait_for_completion(&wait);
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
397
  		ret = ore_check_io(ios, NULL);
06886a5a3   Boaz Harrosh   exofs: Move all o...
398
  	}
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
399
400
  	return ret;
  }
22ddc5563   Boaz Harrosh   exofs: Recover in...
401
402
403
404
  static void _clear_bio(struct bio *bio)
  {
  	struct bio_vec *bv;
  	unsigned i;
d74c6d514   Kent Overstreet   block: Add bio_fo...
405
  	bio_for_each_segment_all(bv, bio, i) {
22ddc5563   Boaz Harrosh   exofs: Recover in...
406
407
408
409
410
411
412
413
  		unsigned this_count = bv->bv_len;
  
  		if (likely(PAGE_SIZE == this_count))
  			clear_highpage(bv->bv_page);
  		else
  			zero_user(bv->bv_page, bv->bv_offset, this_count);
  	}
  }
4b46c9f5c   Boaz Harrosh   ore/exofs: Change...
414
  int ore_check_io(struct ore_io_state *ios, ore_on_dev_error on_dev_error)
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
415
  {
06886a5a3   Boaz Harrosh   exofs: Move all o...
416
417
418
  	enum osd_err_priority acumulated_osd_err = 0;
  	int acumulated_lin_err = 0;
  	int i;
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
419

06886a5a3   Boaz Harrosh   exofs: Move all o...
420
421
  	for (i = 0; i < ios->numdevs; i++) {
  		struct osd_sense_info osi;
4b46c9f5c   Boaz Harrosh   ore/exofs: Change...
422
423
  		struct ore_per_dev_state *per_dev = &ios->per_dev[i];
  		struct osd_request *or = per_dev->or;
22ddc5563   Boaz Harrosh   exofs: Recover in...
424
425
426
427
  		int ret;
  
  		if (unlikely(!or))
  			continue;
06886a5a3   Boaz Harrosh   exofs: Move all o...
428

22ddc5563   Boaz Harrosh   exofs: Recover in...
429
  		ret = osd_req_decode_sense(or, &osi);
06886a5a3   Boaz Harrosh   exofs: Move all o...
430
431
  		if (likely(!ret))
  			continue;
2deb76db0   Boaz Harrosh   ore: Don't crash ...
432
433
434
435
436
437
  		if ((OSD_ERR_PRI_CLEAR_PAGES == osi.osd_err_pri) &&
  		    per_dev->bio) {
  			/* start read offset passed endof file.
  			 * Note: if we do not have bio it means read-attributes
  			 * In this case we should return error to caller.
  			 */
4b46c9f5c   Boaz Harrosh   ore/exofs: Change...
438
  			_clear_bio(per_dev->bio);
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
439
  			ORE_DBGMSG("start read offset passed end of file "
22ddc5563   Boaz Harrosh   exofs: Recover in...
440
441
  				"offset=0x%llx, length=0x%llx
  ",
4b46c9f5c   Boaz Harrosh   ore/exofs: Change...
442
443
  				_LLU(per_dev->offset),
  				_LLU(per_dev->length));
22ddc5563   Boaz Harrosh   exofs: Recover in...
444
445
  
  			continue; /* we recovered */
06886a5a3   Boaz Harrosh   exofs: Move all o...
446
  		}
4b46c9f5c   Boaz Harrosh   ore/exofs: Change...
447
448
449
450
  		if (on_dev_error) {
  			u64 residual = ios->reading ?
  					or->in.residual : or->out.residual;
  			u64 offset = (ios->offset + ios->length) - residual;
ffefb8eaa   Boaz Harrosh   ore: Fix crash in...
451
452
  			unsigned dev = per_dev->dev - ios->oc->first_dev;
  			struct ore_dev *od = ios->oc->ods[dev];
4b46c9f5c   Boaz Harrosh   ore/exofs: Change...
453

ffefb8eaa   Boaz Harrosh   ore: Fix crash in...
454
  			on_dev_error(ios, od, dev, osi.osd_err_pri,
4b46c9f5c   Boaz Harrosh   ore/exofs: Change...
455
456
  				     offset, residual);
  		}
06886a5a3   Boaz Harrosh   exofs: Move all o...
457
458
459
460
461
  		if (osi.osd_err_pri >= acumulated_osd_err) {
  			acumulated_osd_err = osi.osd_err_pri;
  			acumulated_lin_err = ret;
  		}
  	}
06886a5a3   Boaz Harrosh   exofs: Move all o...
462
463
  	return acumulated_lin_err;
  }
cf283ade0   Boaz Harrosh   ore: Make ore its...
464
  EXPORT_SYMBOL(ore_check_io);
06886a5a3   Boaz Harrosh   exofs: Move all o...
465

b367e78bd   Boaz Harrosh   exofs: Prepare fo...
466
467
468
  /*
   * L - logical offset into the file
   *
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
469
470
   * D - number of Data devices
   *	D = group_width - parity
b367e78bd   Boaz Harrosh   exofs: Prepare fo...
471
   *
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
472
473
   * U - The number of bytes in a stripe within a group
   *	U =  stripe_unit * D
b367e78bd   Boaz Harrosh   exofs: Prepare fo...
474
   *
50a76fd3c   Boaz Harrosh   exofs: groups sup...
475
476
   * T - The number of bytes striped within a group of component objects
   *     (before advancing to the next group)
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
477
   *	T = U * group_depth
50a76fd3c   Boaz Harrosh   exofs: groups sup...
478
479
480
   *
   * S - The number of bytes striped across all component objects
   *     before the pattern repeats
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
481
   *	S = T * group_count
50a76fd3c   Boaz Harrosh   exofs: groups sup...
482
   *
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
483
   * M - The "major" (i.e., across all components) cycle number
50a76fd3c   Boaz Harrosh   exofs: groups sup...
484
485
   *	M = L / S
   *
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
486
   * G - Counts the groups from the beginning of the major cycle
50a76fd3c   Boaz Harrosh   exofs: groups sup...
487
488
489
   *	G = (L - (M * S)) / T	[or (L % S) / T]
   *
   * H - The byte offset within the group
50a76fd3c   Boaz Harrosh   exofs: groups sup...
490
491
492
   *	H = (L - (M * S)) % T	[or (L % S) % T]
   *
   * N - The "minor" (i.e., across the group) stripe number
50a76fd3c   Boaz Harrosh   exofs: groups sup...
493
   *	N = H / U
b367e78bd   Boaz Harrosh   exofs: Prepare fo...
494
495
496
   *
   * C - The component index coresponding to L
   *
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
497
498
   *	C = (H - (N * U)) / stripe_unit + G * D
   *	[or (L % U) / stripe_unit + G * D]
b367e78bd   Boaz Harrosh   exofs: Prepare fo...
499
500
   *
   * O - The component offset coresponding to L
50a76fd3c   Boaz Harrosh   exofs: groups sup...
501
   *	O = L % stripe_unit + N * stripe_unit + M * group_depth * stripe_unit
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
   *
   * LCMdP – Parity cycle: Lowest Common Multiple of group_width, parity
   *          divide by parity
   *	LCMdP = lcm(group_width, parity) / parity
   *
   * R - The parity Rotation stripe
   *     (Note parity cycle always starts at a group's boundary)
   *	R = N % LCMdP
   *
   * I = the first parity device index
   *	I = (group_width + group_width - R*parity - parity) % group_width
   *
   * Craid - The component index Rotated
   *	Craid = (group_width + C - R*parity) % group_width
   *      (We add the group_width to avoid negative numbers modulo math)
b367e78bd   Boaz Harrosh   exofs: Prepare fo...
517
   */
611d7a5dc   Boaz Harrosh   ore: Make ore_cal...
518
  void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset,
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
519
  			  u64 length, struct ore_striping_info *si)
5d952b839   Boaz Harrosh   exofs: RAID0 support
520
  {
16f75bb35   Boaz Harrosh   exofs: Fix trunca...
521
522
523
  	u32	stripe_unit = layout->stripe_unit;
  	u32	group_width = layout->group_width;
  	u64	group_depth = layout->group_depth;
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
524
  	u32	parity      = layout->parity;
50a76fd3c   Boaz Harrosh   exofs: groups sup...
525

a1fec1dbb   Boaz Harrosh   ore: RAID5 read
526
527
  	u32	D = group_width - parity;
  	u32	U = D * stripe_unit;
50a76fd3c   Boaz Harrosh   exofs: groups sup...
528
  	u64	T = U * group_depth;
16f75bb35   Boaz Harrosh   exofs: Fix trunca...
529
  	u64	S = T * layout->group_count;
50a76fd3c   Boaz Harrosh   exofs: groups sup...
530
531
532
533
534
535
536
537
538
539
540
  	u64	M = div64_u64(file_offset, S);
  
  	/*
  	G = (L - (M * S)) / T
  	H = (L - (M * S)) % T
  	*/
  	u64	LmodS = file_offset - M * S;
  	u32	G = div64_u64(LmodS, T);
  	u64	H = LmodS - G * T;
  
  	u32	N = div_u64(H, U);
aad560b7f   Boaz Harrosh   ore: Fix wrong ma...
541
  	u32	Nlast;
50a76fd3c   Boaz Harrosh   exofs: groups sup...
542
543
  
  	/* "H - (N * U)" is just "H % U" so it's bound to u32 */
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
544
  	u32	C = (u32)(H - (N * U)) / stripe_unit + G * group_width;
455682ce5   Boaz Harrosh   ore: Remove redun...
545
  	u32 first_dev = C - C % group_width;
b367e78bd   Boaz Harrosh   exofs: Prepare fo...
546

50a76fd3c   Boaz Harrosh   exofs: groups sup...
547
  	div_u64_rem(file_offset, stripe_unit, &si->unit_off);
5d952b839   Boaz Harrosh   exofs: RAID0 support
548

50a76fd3c   Boaz Harrosh   exofs: groups sup...
549
550
  	si->obj_offset = si->unit_off + (N * stripe_unit) +
  				  (M * group_depth * stripe_unit);
455682ce5   Boaz Harrosh   ore: Remove redun...
551
552
  	si->cur_comp = C - first_dev;
  	si->cur_pg = si->unit_off / PAGE_SIZE;
50a76fd3c   Boaz Harrosh   exofs: groups sup...
553

a1fec1dbb   Boaz Harrosh   ore: RAID5 read
554
555
556
557
  	if (parity) {
  		u32 LCMdP = lcm(group_width, parity) / parity;
  		/* R     = N % LCMdP; */
  		u32 RxP   = (N % LCMdP) * parity;
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
558
559
560
  
  		si->par_dev = (group_width + group_width - parity - RxP) %
  			      group_width + first_dev;
ce5d36aac   Boaz Harrosh   ore: Support for ...
561
562
  		si->dev = (group_width + group_width + C - RxP) %
  			  group_width + first_dev;
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
563
564
565
566
567
568
569
570
571
572
573
574
575
576
  		si->bytes_in_stripe = U;
  		si->first_stripe_start = M * S + G * T + N * U;
  	} else {
  		/* Make the math correct see _prepare_one_group */
  		si->par_dev = group_width;
  		si->dev = C;
  	}
  
  	si->dev *= layout->mirrors_p1;
  	si->par_dev *= layout->mirrors_p1;
  	si->offset = file_offset;
  	si->length = T - H;
  	if (si->length > length)
  		si->length = length;
aad560b7f   Boaz Harrosh   ore: Fix wrong ma...
577
578
579
  
  	Nlast = div_u64(H + si->length + U - 1, U);
  	si->maxdevUnits = Nlast - N;
16f75bb35   Boaz Harrosh   exofs: Fix trunca...
580
  	si->M = M;
5d952b839   Boaz Harrosh   exofs: RAID0 support
581
  }
611d7a5dc   Boaz Harrosh   ore: Make ore_cal...
582
  EXPORT_SYMBOL(ore_calc_stripe_info);
5d952b839   Boaz Harrosh   exofs: RAID0 support
583

a1fec1dbb   Boaz Harrosh   ore: RAID5 read
584
585
586
  int _ore_add_stripe_unit(struct ore_io_state *ios,  unsigned *cur_pg,
  			 unsigned pgbase, struct page **pages,
  			 struct ore_per_dev_state *per_dev, int cur_len)
5d952b839   Boaz Harrosh   exofs: RAID0 support
587
  {
86093aaff   Boaz Harrosh   exofs: convert io...
588
  	unsigned pg = *cur_pg;
5d952b839   Boaz Harrosh   exofs: RAID0 support
589
  	struct request_queue *q =
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
590
  			osd_request_queue(_ios_od(ios, per_dev->dev));
bbf9a31bb   Boaz Harrosh   ore: Support for ...
591
592
  	unsigned len = cur_len;
  	int ret;
5d952b839   Boaz Harrosh   exofs: RAID0 support
593
594
  
  	if (per_dev->bio == NULL) {
aad560b7f   Boaz Harrosh   ore: Fix wrong ma...
595
596
597
598
599
600
601
602
603
604
  		unsigned bio_size;
  
  		if (!ios->reading) {
  			bio_size = ios->si.maxdevUnits;
  		} else {
  			bio_size = (ios->si.maxdevUnits + 1) *
  			     (ios->layout->group_width - ios->layout->parity) /
  			     ios->layout->group_width;
  		}
  		bio_size *= (ios->layout->stripe_unit / PAGE_SIZE);
5d952b839   Boaz Harrosh   exofs: RAID0 support
605
606
607
  
  		per_dev->bio = bio_kmalloc(GFP_KERNEL, bio_size);
  		if (unlikely(!per_dev->bio)) {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
608
609
  			ORE_DBGMSG("Failed to allocate BIO size=%u
  ",
5d952b839   Boaz Harrosh   exofs: RAID0 support
610
  				     bio_size);
bbf9a31bb   Boaz Harrosh   ore: Support for ...
611
612
  			ret = -ENOMEM;
  			goto out;
5d952b839   Boaz Harrosh   exofs: RAID0 support
613
614
615
616
  		}
  	}
  
  	while (cur_len > 0) {
86093aaff   Boaz Harrosh   exofs: convert io...
617
618
  		unsigned pglen = min_t(unsigned, PAGE_SIZE - pgbase, cur_len);
  		unsigned added_len;
5d952b839   Boaz Harrosh   exofs: RAID0 support
619

86093aaff   Boaz Harrosh   exofs: convert io...
620
  		cur_len -= pglen;
5d952b839   Boaz Harrosh   exofs: RAID0 support
621

a1fec1dbb   Boaz Harrosh   ore: RAID5 read
622
  		added_len = bio_add_pc_page(q, per_dev->bio, pages[pg],
86093aaff   Boaz Harrosh   exofs: convert io...
623
  					    pglen, pgbase);
bbf9a31bb   Boaz Harrosh   ore: Support for ...
624
  		if (unlikely(pglen != added_len)) {
aad560b7f   Boaz Harrosh   ore: Fix wrong ma...
625
626
627
628
629
630
631
  			/* If bi_vcnt == bi_max then this is a SW BUG */
  			ORE_DBGMSG("Failed bio_add_pc_page bi_vcnt=0x%x "
  				   "bi_max=0x%x BIO_MAX=0x%x cur_len=0x%x
  ",
  				   per_dev->bio->bi_vcnt,
  				   per_dev->bio->bi_max_vecs,
  				   BIO_MAX_PAGES_KMALLOC, cur_len);
bbf9a31bb   Boaz Harrosh   ore: Support for ...
632
633
634
  			ret = -ENOMEM;
  			goto out;
  		}
769ba8d92   Boaz Harrosh   ore: RAID5 Write
635
  		_add_stripe_page(ios->sp2d, &ios->si, pages[pg]);
86093aaff   Boaz Harrosh   exofs: convert io...
636
637
  		pgbase = 0;
  		++pg;
5d952b839   Boaz Harrosh   exofs: RAID0 support
638
639
  	}
  	BUG_ON(cur_len);
bbf9a31bb   Boaz Harrosh   ore: Support for ...
640
  	per_dev->length += len;
86093aaff   Boaz Harrosh   exofs: convert io...
641
  	*cur_pg = pg;
bbf9a31bb   Boaz Harrosh   ore: Support for ...
642
643
644
645
646
647
648
  	ret = 0;
  out:	/* we fail the complete unit on an error eg don't advance
  	 * per_dev->length and cur_pg. This means that we might have a bigger
  	 * bio than the CDB requested length (per_dev->length). That's fine
  	 * only the oposite is fatal.
  	 */
  	return ret;
5d952b839   Boaz Harrosh   exofs: RAID0 support
649
  }
ce5d36aac   Boaz Harrosh   ore: Support for ...
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
  static int _add_parity_units(struct ore_io_state *ios,
  			     struct ore_striping_info *si,
  			     unsigned dev, unsigned first_dev,
  			     unsigned mirrors_p1, unsigned devs_in_group,
  			     unsigned cur_len)
  {
  	unsigned do_parity;
  	int ret = 0;
  
  	for (do_parity = ios->layout->parity; do_parity; --do_parity) {
  		struct ore_per_dev_state *per_dev;
  
  		per_dev = &ios->per_dev[dev - first_dev];
  		if (!per_dev->length && !per_dev->offset) {
  			/* Only/always the parity unit of the first
  			 * stripe will be empty. So this is a chance to
  			 * initialize the per_dev info.
  			 */
  			per_dev->dev = dev;
  			per_dev->offset = si->obj_offset - si->unit_off;
  		}
  
  		ret = _ore_add_parity_unit(ios, si, per_dev, cur_len,
  					   do_parity == 1);
  		if (unlikely(ret))
  				break;
  
  		if (do_parity != 1) {
  			dev = ((dev + mirrors_p1) % devs_in_group) + first_dev;
  			si->cur_comp = (si->cur_comp + 1) %
  						       ios->layout->group_width;
  		}
  	}
  
  	return ret;
  }
982607540   Boaz Harrosh   ore: cleanup: Emb...
686
  static int _prepare_for_striping(struct ore_io_state *ios)
5d952b839   Boaz Harrosh   exofs: RAID0 support
687
  {
982607540   Boaz Harrosh   ore: cleanup: Emb...
688
  	struct ore_striping_info *si = &ios->si;
5d952b839   Boaz Harrosh   exofs: RAID0 support
689
  	unsigned stripe_unit = ios->layout->stripe_unit;
b367e78bd   Boaz Harrosh   exofs: Prepare fo...
690
  	unsigned mirrors_p1 = ios->layout->mirrors_p1;
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
691
692
  	unsigned group_width = ios->layout->group_width;
  	unsigned devs_in_group = group_width * mirrors_p1;
b367e78bd   Boaz Harrosh   exofs: Prepare fo...
693
  	unsigned dev = si->dev;
50a76fd3c   Boaz Harrosh   exofs: groups sup...
694
  	unsigned first_dev = dev - (dev % devs_in_group);
50a76fd3c   Boaz Harrosh   exofs: groups sup...
695
  	unsigned cur_pg = ios->pages_consumed;
982607540   Boaz Harrosh   ore: cleanup: Emb...
696
  	u64 length = ios->length;
86093aaff   Boaz Harrosh   exofs: convert io...
697
  	int ret = 0;
5d952b839   Boaz Harrosh   exofs: RAID0 support
698

982607540   Boaz Harrosh   ore: cleanup: Emb...
699
  	if (!ios->pages) {
982607540   Boaz Harrosh   ore: cleanup: Emb...
700
701
702
  		ios->numdevs = ios->layout->mirrors_p1;
  		return 0;
  	}
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
703
  	BUG_ON(length > si->length);
5d952b839   Boaz Harrosh   exofs: RAID0 support
704
  	while (length) {
101a64278   Boaz Harrosh   ore: (trivial) re...
705
706
  		struct ore_per_dev_state *per_dev =
  						&ios->per_dev[dev - first_dev];
b367e78bd   Boaz Harrosh   exofs: Prepare fo...
707
  		unsigned cur_len, page_off = 0;
5d952b839   Boaz Harrosh   exofs: RAID0 support
708

ce5d36aac   Boaz Harrosh   ore: Support for ...
709
710
  		if (!per_dev->length && !per_dev->offset) {
  			/* First time initialize the per_dev info. */
b367e78bd   Boaz Harrosh   exofs: Prepare fo...
711
  			per_dev->dev = dev;
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
712
713
  			if (dev == si->dev) {
  				WARN_ON(dev == si->par_dev);
b367e78bd   Boaz Harrosh   exofs: Prepare fo...
714
715
716
717
  				per_dev->offset = si->obj_offset;
  				cur_len = stripe_unit - si->unit_off;
  				page_off = si->unit_off & ~PAGE_MASK;
  				BUG_ON(page_off && (page_off != ios->pgbase));
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
718
  			} else {
ce5d36aac   Boaz Harrosh   ore: Support for ...
719
  				per_dev->offset = si->obj_offset - si->unit_off;
b367e78bd   Boaz Harrosh   exofs: Prepare fo...
720
721
  				cur_len = stripe_unit;
  			}
5d952b839   Boaz Harrosh   exofs: RAID0 support
722
  		} else {
b367e78bd   Boaz Harrosh   exofs: Prepare fo...
723
  			cur_len = stripe_unit;
5d952b839   Boaz Harrosh   exofs: RAID0 support
724
  		}
b367e78bd   Boaz Harrosh   exofs: Prepare fo...
725
726
  		if (cur_len >= length)
  			cur_len = length;
5d952b839   Boaz Harrosh   exofs: RAID0 support
727

a1fec1dbb   Boaz Harrosh   ore: RAID5 read
728
729
  		ret = _ore_add_stripe_unit(ios, &cur_pg, page_off, ios->pages,
  					   per_dev, cur_len);
5d952b839   Boaz Harrosh   exofs: RAID0 support
730
731
  		if (unlikely(ret))
  			goto out;
5d952b839   Boaz Harrosh   exofs: RAID0 support
732
  		length -= cur_len;
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
733

101a64278   Boaz Harrosh   ore: (trivial) re...
734
  		dev = ((dev + mirrors_p1) % devs_in_group) + first_dev;
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
735
  		si->cur_comp = (si->cur_comp + 1) % group_width;
769ba8d92   Boaz Harrosh   ore: RAID5 Write
736
737
  		if (unlikely((dev == si->par_dev) || (!length && ios->sp2d))) {
  			if (!length && ios->sp2d) {
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
738
739
740
741
  				/* If we are writing and this is the very last
  				 * stripe. then operate on parity dev.
  				 */
  				dev = si->par_dev;
455682ce5   Boaz Harrosh   ore: Remove redun...
742
743
  				/* If last stripe operate on parity comp */
  				si->cur_comp = group_width - ios->layout->parity;
769ba8d92   Boaz Harrosh   ore: RAID5 Write
744
  			}
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
745

101a64278   Boaz Harrosh   ore: (trivial) re...
746
747
748
  			/* In writes cur_len just means if it's the
  			 * last one. See _ore_add_parity_unit.
  			 */
ce5d36aac   Boaz Harrosh   ore: Support for ...
749
750
  			ret = _add_parity_units(ios, si, dev, first_dev,
  						mirrors_p1, devs_in_group,
101a64278   Boaz Harrosh   ore: (trivial) re...
751
  						ios->sp2d ? length : cur_len);
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
752
753
754
755
756
757
758
759
760
  			if (unlikely(ret))
  					goto out;
  
  			/* Rotate next par_dev backwards with wraping */
  			si->par_dev = (devs_in_group + si->par_dev -
  				       ios->layout->parity * mirrors_p1) %
  				      devs_in_group + first_dev;
  			/* Next stripe, start fresh */
  			si->cur_comp = 0;
769ba8d92   Boaz Harrosh   ore: RAID5 Write
761
  			si->cur_pg = 0;
ce5d36aac   Boaz Harrosh   ore: Support for ...
762
763
  			si->obj_offset += cur_len;
  			si->unit_off = 0;
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
764
  		}
5d952b839   Boaz Harrosh   exofs: RAID0 support
765
766
  	}
  out:
b916c5cd4   Boaz Harrosh   ore: Only IO one ...
767
  	ios->numdevs = devs_in_group;
50a76fd3c   Boaz Harrosh   exofs: groups sup...
768
  	ios->pages_consumed = cur_pg;
62b62ad87   Boaz Harrosh   ore: Remove suppo...
769
  	return ret;
5d952b839   Boaz Harrosh   exofs: RAID0 support
770
  }
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
771
  int ore_create(struct ore_io_state *ios)
06886a5a3   Boaz Harrosh   exofs: Move all o...
772
773
  {
  	int i, ret;
5bf696dad   Boaz Harrosh   exofs: Rename str...
774
  	for (i = 0; i < ios->oc->numdevs; i++) {
06886a5a3   Boaz Harrosh   exofs: Move all o...
775
  		struct osd_request *or;
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
776
  		or = osd_start_request(_ios_od(ios, i), GFP_KERNEL);
06886a5a3   Boaz Harrosh   exofs: Move all o...
777
  		if (unlikely(!or)) {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
778
779
  			ORE_ERR("%s: osd_start_request failed
  ", __func__);
06886a5a3   Boaz Harrosh   exofs: Move all o...
780
781
782
783
784
  			ret = -ENOMEM;
  			goto out;
  		}
  		ios->per_dev[i].or = or;
  		ios->numdevs++;
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
785
  		osd_req_create_object(or, _ios_obj(ios, i));
06886a5a3   Boaz Harrosh   exofs: Move all o...
786
  	}
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
787
  	ret = ore_io_execute(ios);
06886a5a3   Boaz Harrosh   exofs: Move all o...
788
789
790
791
  
  out:
  	return ret;
  }
cf283ade0   Boaz Harrosh   ore: Make ore its...
792
  EXPORT_SYMBOL(ore_create);
06886a5a3   Boaz Harrosh   exofs: Move all o...
793

8ff660ab8   Boaz Harrosh   exofs: Rename rai...
794
  int ore_remove(struct ore_io_state *ios)
06886a5a3   Boaz Harrosh   exofs: Move all o...
795
796
  {
  	int i, ret;
5bf696dad   Boaz Harrosh   exofs: Rename str...
797
  	for (i = 0; i < ios->oc->numdevs; i++) {
06886a5a3   Boaz Harrosh   exofs: Move all o...
798
  		struct osd_request *or;
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
799
  		or = osd_start_request(_ios_od(ios, i), GFP_KERNEL);
06886a5a3   Boaz Harrosh   exofs: Move all o...
800
  		if (unlikely(!or)) {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
801
802
  			ORE_ERR("%s: osd_start_request failed
  ", __func__);
06886a5a3   Boaz Harrosh   exofs: Move all o...
803
804
805
806
807
  			ret = -ENOMEM;
  			goto out;
  		}
  		ios->per_dev[i].or = or;
  		ios->numdevs++;
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
808
  		osd_req_remove_object(or, _ios_obj(ios, i));
06886a5a3   Boaz Harrosh   exofs: Move all o...
809
  	}
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
810
  	ret = ore_io_execute(ios);
06886a5a3   Boaz Harrosh   exofs: Move all o...
811
812
813
814
  
  out:
  	return ret;
  }
cf283ade0   Boaz Harrosh   ore: Make ore its...
815
  EXPORT_SYMBOL(ore_remove);
06886a5a3   Boaz Harrosh   exofs: Move all o...
816

8ff660ab8   Boaz Harrosh   exofs: Rename rai...
817
  static int _write_mirror(struct ore_io_state *ios, int cur_comp)
06886a5a3   Boaz Harrosh   exofs: Move all o...
818
  {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
819
  	struct ore_per_dev_state *master_dev = &ios->per_dev[cur_comp];
5d952b839   Boaz Harrosh   exofs: RAID0 support
820
821
822
  	unsigned dev = ios->per_dev[cur_comp].dev;
  	unsigned last_comp = cur_comp + ios->layout->mirrors_p1;
  	int ret = 0;
06886a5a3   Boaz Harrosh   exofs: Move all o...
823

50a76fd3c   Boaz Harrosh   exofs: groups sup...
824
825
  	if (ios->pages && !master_dev->length)
  		return 0; /* Just an empty slot */
5d952b839   Boaz Harrosh   exofs: RAID0 support
826
  	for (; cur_comp < last_comp; ++cur_comp, ++dev) {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
827
  		struct ore_per_dev_state *per_dev = &ios->per_dev[cur_comp];
06886a5a3   Boaz Harrosh   exofs: Move all o...
828
  		struct osd_request *or;
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
829
  		or = osd_start_request(_ios_od(ios, dev), GFP_KERNEL);
06886a5a3   Boaz Harrosh   exofs: Move all o...
830
  		if (unlikely(!or)) {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
831
832
  			ORE_ERR("%s: osd_start_request failed
  ", __func__);
06886a5a3   Boaz Harrosh   exofs: Move all o...
833
834
835
  			ret = -ENOMEM;
  			goto out;
  		}
5d952b839   Boaz Harrosh   exofs: RAID0 support
836
  		per_dev->or = or;
06886a5a3   Boaz Harrosh   exofs: Move all o...
837

86093aaff   Boaz Harrosh   exofs: convert io...
838
  		if (ios->pages) {
06886a5a3   Boaz Harrosh   exofs: Move all o...
839
  			struct bio *bio;
5d952b839   Boaz Harrosh   exofs: RAID0 support
840
  			if (per_dev != master_dev) {
bf800ef18   Kent Overstreet   block: Add bio_cl...
841
842
  				bio = bio_clone_kmalloc(master_dev->bio,
  							GFP_KERNEL);
04dc1e88a   Boaz Harrosh   exofs: Multi-devi...
843
  				if (unlikely(!bio)) {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
844
  					ORE_DBGMSG(
426d31071   Paul Bolle   fix printk typo '...
845
846
  					      "Failed to allocate BIO size=%u
  ",
5d952b839   Boaz Harrosh   exofs: RAID0 support
847
  					      master_dev->bio->bi_max_vecs);
04dc1e88a   Boaz Harrosh   exofs: Multi-devi...
848
849
850
  					ret = -ENOMEM;
  					goto out;
  				}
74d46992e   Christoph Hellwig   block: replace bi...
851
  				bio->bi_disk = NULL;
04dc1e88a   Boaz Harrosh   exofs: Multi-devi...
852
  				bio->bi_next = NULL;
6851a5e5c   Boaz Harrosh   ore: Remove check...
853
  				per_dev->offset = master_dev->offset;
5d952b839   Boaz Harrosh   exofs: RAID0 support
854
855
856
  				per_dev->length = master_dev->length;
  				per_dev->bio =  bio;
  				per_dev->dev = dev;
04dc1e88a   Boaz Harrosh   exofs: Multi-devi...
857
  			} else {
5d952b839   Boaz Harrosh   exofs: RAID0 support
858
859
  				bio = master_dev->bio;
  				/* FIXME: bio_set_dir() */
95fe6c1a2   Mike Christie   block, fs, mm, dr...
860
  				bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
04dc1e88a   Boaz Harrosh   exofs: Multi-devi...
861
  			}
06886a5a3   Boaz Harrosh   exofs: Move all o...
862

9e62bb445   Boaz Harrosh   ore: Fix out-of-b...
863
864
  			osd_req_write(or, _ios_obj(ios, cur_comp),
  				      per_dev->offset, bio, per_dev->length);
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
865
  			ORE_DBGMSG("write(0x%llx) offset=0x%llx "
34ce4e7c2   Boaz Harrosh   exofs: debug prin...
866
867
  				      "length=0x%llx dev=%d
  ",
9e62bb445   Boaz Harrosh   ore: Fix out-of-b...
868
  				     _LLU(_ios_obj(ios, cur_comp)->id),
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
869
  				     _LLU(per_dev->offset),
5d952b839   Boaz Harrosh   exofs: RAID0 support
870
  				     _LLU(per_dev->length), dev);
06886a5a3   Boaz Harrosh   exofs: Move all o...
871
  		} else if (ios->kern_buff) {
6851a5e5c   Boaz Harrosh   ore: Remove check...
872
873
874
875
876
877
878
  			per_dev->offset = ios->si.obj_offset;
  			per_dev->dev = ios->si.dev + dev;
  
  			/* no cross device without page array */
  			BUG_ON((ios->layout->group_width > 1) &&
  			       (ios->si.unit_off + ios->length >
  				ios->layout->stripe_unit));
9e62bb445   Boaz Harrosh   ore: Fix out-of-b...
879
  			ret = osd_req_write_kern(or, _ios_obj(ios, cur_comp),
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
880
881
  						 per_dev->offset,
  						 ios->kern_buff, ios->length);
5d952b839   Boaz Harrosh   exofs: RAID0 support
882
883
  			if (unlikely(ret))
  				goto out;
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
884
  			ORE_DBGMSG2("write_kern(0x%llx) offset=0x%llx "
34ce4e7c2   Boaz Harrosh   exofs: debug prin...
885
886
  				      "length=0x%llx dev=%d
  ",
9e62bb445   Boaz Harrosh   ore: Fix out-of-b...
887
  				     _LLU(_ios_obj(ios, cur_comp)->id),
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
888
  				     _LLU(per_dev->offset),
6851a5e5c   Boaz Harrosh   ore: Remove check...
889
  				     _LLU(ios->length), per_dev->dev);
06886a5a3   Boaz Harrosh   exofs: Move all o...
890
  		} else {
9e62bb445   Boaz Harrosh   ore: Fix out-of-b...
891
  			osd_req_set_attributes(or, _ios_obj(ios, cur_comp));
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
892
893
  			ORE_DBGMSG2("obj(0x%llx) set_attributes=%d dev=%d
  ",
9e62bb445   Boaz Harrosh   ore: Fix out-of-b...
894
  				     _LLU(_ios_obj(ios, cur_comp)->id),
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
895
  				     ios->out_attr_len, dev);
06886a5a3   Boaz Harrosh   exofs: Move all o...
896
897
898
899
900
901
902
903
904
  		}
  
  		if (ios->out_attr)
  			osd_req_add_set_attr_list(or, ios->out_attr,
  						  ios->out_attr_len);
  
  		if (ios->in_attr)
  			osd_req_add_get_attr_list(or, ios->in_attr,
  						  ios->in_attr_len);
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
905
  	}
06886a5a3   Boaz Harrosh   exofs: Move all o...
906
907
908
909
  
  out:
  	return ret;
  }
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
910
  int ore_write(struct ore_io_state *ios)
5d952b839   Boaz Harrosh   exofs: RAID0 support
911
912
913
  {
  	int i;
  	int ret;
769ba8d92   Boaz Harrosh   ore: RAID5 Write
914
915
916
917
918
919
920
  	if (unlikely(ios->sp2d && !ios->r4w)) {
  		/* A library is attempting a RAID-write without providing
  		 * a pages lock interface.
  		 */
  		WARN_ON_ONCE(1);
  		return -ENOTSUPP;
  	}
5d952b839   Boaz Harrosh   exofs: RAID0 support
921
922
923
924
925
  	ret = _prepare_for_striping(ios);
  	if (unlikely(ret))
  		return ret;
  
  	for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
926
  		ret = _write_mirror(ios, i);
5d952b839   Boaz Harrosh   exofs: RAID0 support
927
928
929
  		if (unlikely(ret))
  			return ret;
  	}
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
930
  	ret = ore_io_execute(ios);
5d952b839   Boaz Harrosh   exofs: RAID0 support
931
932
  	return ret;
  }
cf283ade0   Boaz Harrosh   ore: Make ore its...
933
  EXPORT_SYMBOL(ore_write);
5d952b839   Boaz Harrosh   exofs: RAID0 support
934

769ba8d92   Boaz Harrosh   ore: RAID5 Write
935
  int _ore_read_mirror(struct ore_io_state *ios, unsigned cur_comp)
06886a5a3   Boaz Harrosh   exofs: Move all o...
936
  {
46f4d973f   Boaz Harrosh   exofs: unindent e...
937
  	struct osd_request *or;
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
938
  	struct ore_per_dev_state *per_dev = &ios->per_dev[cur_comp];
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
939
940
  	struct osd_obj_id *obj = _ios_obj(ios, cur_comp);
  	unsigned first_dev = (unsigned)obj->id;
06886a5a3   Boaz Harrosh   exofs: Move all o...
941

50a76fd3c   Boaz Harrosh   exofs: groups sup...
942
943
  	if (ios->pages && !per_dev->length)
  		return 0; /* Just an empty slot */
5d952b839   Boaz Harrosh   exofs: RAID0 support
944
  	first_dev = per_dev->dev + first_dev % ios->layout->mirrors_p1;
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
945
  	or = osd_start_request(_ios_od(ios, first_dev), GFP_KERNEL);
46f4d973f   Boaz Harrosh   exofs: unindent e...
946
  	if (unlikely(!or)) {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
947
948
  		ORE_ERR("%s: osd_start_request failed
  ", __func__);
46f4d973f   Boaz Harrosh   exofs: unindent e...
949
950
951
  		return -ENOMEM;
  	}
  	per_dev->or = or;
46f4d973f   Boaz Harrosh   exofs: unindent e...
952

86093aaff   Boaz Harrosh   exofs: convert io...
953
  	if (ios->pages) {
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
954
955
956
957
958
959
960
961
962
963
964
965
966
  		if (per_dev->cur_sg) {
  			/* finalize the last sg_entry */
  			_ore_add_sg_seg(per_dev, 0, false);
  			if (unlikely(!per_dev->cur_sg))
  				return 0; /* Skip parity only device */
  
  			osd_req_read_sg(or, obj, per_dev->bio,
  					per_dev->sglist, per_dev->cur_sg);
  		} else {
  			/* The no raid case */
  			osd_req_read(or, obj, per_dev->offset,
  				     per_dev->bio, per_dev->length);
  		}
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
967
  		ORE_DBGMSG("read(0x%llx) offset=0x%llx length=0x%llx"
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
968
969
  			     " dev=%d sg_len=%d
  ", _LLU(obj->id),
5d952b839   Boaz Harrosh   exofs: RAID0 support
970
  			     _LLU(per_dev->offset), _LLU(per_dev->length),
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
971
  			     first_dev, per_dev->cur_sg);
46f4d973f   Boaz Harrosh   exofs: unindent e...
972
  	} else {
6851a5e5c   Boaz Harrosh   ore: Remove check...
973
  		BUG_ON(ios->kern_buff);
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
974
  		osd_req_get_attributes(or, obj);
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
975
976
  		ORE_DBGMSG2("obj(0x%llx) get_attributes=%d dev=%d
  ",
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
977
978
  			      _LLU(obj->id),
  			      ios->in_attr_len, first_dev);
46f4d973f   Boaz Harrosh   exofs: unindent e...
979
  	}
46f4d973f   Boaz Harrosh   exofs: unindent e...
980
981
  	if (ios->out_attr)
  		osd_req_add_set_attr_list(or, ios->out_attr, ios->out_attr_len);
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
982

46f4d973f   Boaz Harrosh   exofs: unindent e...
983
984
  	if (ios->in_attr)
  		osd_req_add_get_attr_list(or, ios->in_attr, ios->in_attr_len);
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
985

5d952b839   Boaz Harrosh   exofs: RAID0 support
986
987
  	return 0;
  }
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
988
  int ore_read(struct ore_io_state *ios)
5d952b839   Boaz Harrosh   exofs: RAID0 support
989
990
991
992
993
994
995
996
997
  {
  	int i;
  	int ret;
  
  	ret = _prepare_for_striping(ios);
  	if (unlikely(ret))
  		return ret;
  
  	for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) {
769ba8d92   Boaz Harrosh   ore: RAID5 Write
998
  		ret = _ore_read_mirror(ios, i);
5d952b839   Boaz Harrosh   exofs: RAID0 support
999
1000
1001
  		if (unlikely(ret))
  			return ret;
  	}
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
1002
  	ret = ore_io_execute(ios);
5d952b839   Boaz Harrosh   exofs: RAID0 support
1003
  	return ret;
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
1004
  }
cf283ade0   Boaz Harrosh   ore: Make ore its...
1005
  EXPORT_SYMBOL(ore_read);
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
1006

8ff660ab8   Boaz Harrosh   exofs: Rename rai...
1007
  int extract_attr_from_ios(struct ore_io_state *ios, struct osd_attr *attr)
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
1008
1009
1010
1011
1012
1013
1014
  {
  	struct osd_attr cur_attr = {.attr_page = 0}; /* start with zeros */
  	void *iter = NULL;
  	int nelem;
  
  	do {
  		nelem = 1;
06886a5a3   Boaz Harrosh   exofs: Move all o...
1015
1016
  		osd_req_decode_get_attr_list(ios->per_dev[0].or,
  					     &cur_attr, &nelem, &iter);
b14f8ab28   Boaz Harrosh   exofs: Kbuild, He...
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
  		if ((cur_attr.attr_page == attr->attr_page) &&
  		    (cur_attr.attr_id == attr->attr_id)) {
  			attr->len = cur_attr.len;
  			attr->val_ptr = cur_attr.val_ptr;
  			return 0;
  		}
  	} while (iter);
  
  	return -EIO;
  }
cf283ade0   Boaz Harrosh   ore: Make ore its...
1027
  EXPORT_SYMBOL(extract_attr_from_ios);
06886a5a3   Boaz Harrosh   exofs: Move all o...
1028

8ff660ab8   Boaz Harrosh   exofs: Rename rai...
1029
  static int _truncate_mirrors(struct ore_io_state *ios, unsigned cur_comp,
5d952b839   Boaz Harrosh   exofs: RAID0 support
1030
1031
1032
1033
1034
  			     struct osd_attr *attr)
  {
  	int last_comp = cur_comp + ios->layout->mirrors_p1;
  
  	for (; cur_comp < last_comp; ++cur_comp) {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
1035
  		struct ore_per_dev_state *per_dev = &ios->per_dev[cur_comp];
5d952b839   Boaz Harrosh   exofs: RAID0 support
1036
  		struct osd_request *or;
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
1037
  		or = osd_start_request(_ios_od(ios, cur_comp), GFP_KERNEL);
5d952b839   Boaz Harrosh   exofs: RAID0 support
1038
  		if (unlikely(!or)) {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
1039
1040
  			ORE_ERR("%s: osd_start_request failed
  ", __func__);
5d952b839   Boaz Harrosh   exofs: RAID0 support
1041
1042
1043
  			return -ENOMEM;
  		}
  		per_dev->or = or;
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
1044
  		osd_req_set_attributes(or, _ios_obj(ios, cur_comp));
5d952b839   Boaz Harrosh   exofs: RAID0 support
1045
1046
1047
1048
1049
  		osd_req_add_set_attr_list(or, attr, 1);
  	}
  
  	return 0;
  }
16f75bb35   Boaz Harrosh   exofs: Fix trunca...
1050
  struct _trunc_info {
eb507bc18   Boaz Harrosh   ore: Make ore_str...
1051
  	struct ore_striping_info si;
16f75bb35   Boaz Harrosh   exofs: Fix trunca...
1052
1053
1054
1055
1056
  	u64 prev_group_obj_off;
  	u64 next_group_obj_off;
  
  	unsigned first_group_dev;
  	unsigned nex_group_dev;
16f75bb35   Boaz Harrosh   exofs: Fix trunca...
1057
  };
1958c7c28   H Hartley Sweeten   exofs/ore.c: loca...
1058
1059
  static void _calc_trunk_info(struct ore_layout *layout, u64 file_offset,
  			     struct _trunc_info *ti)
16f75bb35   Boaz Harrosh   exofs: Fix trunca...
1060
1061
  {
  	unsigned stripe_unit = layout->stripe_unit;
a1fec1dbb   Boaz Harrosh   ore: RAID5 read
1062
  	ore_calc_stripe_info(layout, file_offset, 0, &ti->si);
16f75bb35   Boaz Harrosh   exofs: Fix trunca...
1063
1064
1065
1066
1067
1068
  
  	ti->prev_group_obj_off = ti->si.M * stripe_unit;
  	ti->next_group_obj_off = ti->si.M ? (ti->si.M - 1) * stripe_unit : 0;
  
  	ti->first_group_dev = ti->si.dev - (ti->si.dev % layout->group_width);
  	ti->nex_group_dev = ti->first_group_dev + layout->group_width;
16f75bb35   Boaz Harrosh   exofs: Fix trunca...
1069
  }
5bf696dad   Boaz Harrosh   exofs: Rename str...
1070
  int ore_truncate(struct ore_layout *layout, struct ore_components *oc,
9e9db4564   Boaz Harrosh   exofs: ios: Move ...
1071
  		   u64 size)
06886a5a3   Boaz Harrosh   exofs: Move all o...
1072
  {
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
1073
  	struct ore_io_state *ios;
5d952b839   Boaz Harrosh   exofs: RAID0 support
1074
1075
1076
1077
  	struct exofs_trunc_attr {
  		struct osd_attr attr;
  		__be64 newsize;
  	} *size_attrs;
16f75bb35   Boaz Harrosh   exofs: Fix trunca...
1078
  	struct _trunc_info ti;
06886a5a3   Boaz Harrosh   exofs: Move all o...
1079
  	int i, ret;
5bf696dad   Boaz Harrosh   exofs: Rename str...
1080
  	ret = ore_get_io_state(layout, oc, &ios);
5d952b839   Boaz Harrosh   exofs: RAID0 support
1081
1082
  	if (unlikely(ret))
  		return ret;
16f75bb35   Boaz Harrosh   exofs: Fix trunca...
1083
  	_calc_trunk_info(ios->layout, size, &ti);
b916c5cd4   Boaz Harrosh   ore: Only IO one ...
1084
  	size_attrs = kcalloc(ios->oc->numdevs, sizeof(*size_attrs),
5d952b839   Boaz Harrosh   exofs: RAID0 support
1085
1086
1087
1088
1089
  			     GFP_KERNEL);
  	if (unlikely(!size_attrs)) {
  		ret = -ENOMEM;
  		goto out;
  	}
06886a5a3   Boaz Harrosh   exofs: Move all o...
1090

5bf696dad   Boaz Harrosh   exofs: Rename str...
1091
  	ios->numdevs = ios->oc->numdevs;
06886a5a3   Boaz Harrosh   exofs: Move all o...
1092

b916c5cd4   Boaz Harrosh   ore: Only IO one ...
1093
  	for (i = 0; i < ios->numdevs; ++i) {
5d952b839   Boaz Harrosh   exofs: RAID0 support
1094
1095
  		struct exofs_trunc_attr *size_attr = &size_attrs[i];
  		u64 obj_size;
06886a5a3   Boaz Harrosh   exofs: Move all o...
1096

16f75bb35   Boaz Harrosh   exofs: Fix trunca...
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
  		if (i < ti.first_group_dev)
  			obj_size = ti.prev_group_obj_off;
  		else if (i >= ti.nex_group_dev)
  			obj_size = ti.next_group_obj_off;
  		else if (i < ti.si.dev) /* dev within this group */
  			obj_size = ti.si.obj_offset +
  				      ios->layout->stripe_unit - ti.si.unit_off;
  		else if (i == ti.si.dev)
  			obj_size = ti.si.obj_offset;
  		else /* i > ti.dev */
  			obj_size = ti.si.obj_offset - ti.si.unit_off;
06886a5a3   Boaz Harrosh   exofs: Move all o...
1108

5d952b839   Boaz Harrosh   exofs: RAID0 support
1109
1110
1111
  		size_attr->newsize = cpu_to_be64(obj_size);
  		size_attr->attr = g_attr_logical_length;
  		size_attr->attr.val_ptr = &size_attr->newsize;
aad560b7f   Boaz Harrosh   ore: Fix wrong ma...
1112
1113
  		ORE_DBGMSG2("trunc(0x%llx) obj_offset=0x%llx dev=%d
  ",
5bf696dad   Boaz Harrosh   exofs: Rename str...
1114
  			     _LLU(oc->comps->obj.id), _LLU(obj_size), i);
5d952b839   Boaz Harrosh   exofs: RAID0 support
1115
1116
1117
1118
  		ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1,
  					&size_attr->attr);
  		if (unlikely(ret))
  			goto out;
06886a5a3   Boaz Harrosh   exofs: Move all o...
1119
  	}
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
1120
  	ret = ore_io_execute(ios);
06886a5a3   Boaz Harrosh   exofs: Move all o...
1121
1122
  
  out:
5d952b839   Boaz Harrosh   exofs: RAID0 support
1123
  	kfree(size_attrs);
8ff660ab8   Boaz Harrosh   exofs: Rename rai...
1124
  	ore_put_io_state(ios);
06886a5a3   Boaz Harrosh   exofs: Move all o...
1125
1126
  	return ret;
  }
cf283ade0   Boaz Harrosh   ore: Make ore its...
1127
  EXPORT_SYMBOL(ore_truncate);
85e44df47   Boaz Harrosh   exofs: Move exofs...
1128
1129
1130
  
  const struct osd_attr g_attr_logical_length = ATTR_DEF(
  	OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8);
cf283ade0   Boaz Harrosh   ore: Make ore its...
1131
  EXPORT_SYMBOL(g_attr_logical_length);