aboutsummaryrefslogtreecommitdiffstats
path: root/arch/score
Commit message (Expand)AuthorAge
* Merge branch 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmare...Linus Torvalds2010-10-28
|\
| * Merge branch 'kbuild/rc-fixes' into kbuild/kconfigMichal Marek2010-10-12
| |\
| * | kbuild: migrate all arch to the kconfig mainmenu upgradeArnaud Lacombe2010-09-19
* | | ptrace: cleanup arch_ptrace() on scoreNamhyung Kim2010-10-27
* | | ptrace: change signature of arch_ptrace()Namhyung Kim2010-10-27
* | | mm: remove pte_*map_nested()Peter Zijlstra2010-10-26
* | | Fix IRQ flag handling namingDavid Howells2010-10-07
* | | Make do_execve() take a const filename pointerDavid Howells2010-08-17
| |/ |/|
* | defconfig reductionSam Ravnborg2010-08-14
* | score: fix dereference of NULL pointer in local_flush_tlb_page()Roel Kluin2010-08-12
* | Merge branch 'for-2.6.36' of git://git.kernel.dk/linux-2.6-blockLinus Torvalds2010-08-10
|\ \
| * | remove needless ISA_DMA_THRESHOLDFUJITA Tomonori2010-08-07
| |/
* | Merge branch 'timers-timekeeping-for-linus' of git://git.kernel.org/pub/scm/l...Linus Torvalds2010-08-06
|\ \
| * | time: Kill off CONFIG_GENERIC_TIMEJohn Stultz2010-07-27
| |/
* | Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kern...Linus Torvalds2010-08-06
|\ \
| * | arch: Implement local64_tPeter Zijlstra2010-06-09
| |/
* | Merge commit 'v2.6.35' into kbuild/kbuildMichal Marek2010-08-04
|\|
| * asm-generic: remove ISA_DMA_THRESHOLD in scatterlist.hFUJITA Tomonori2010-05-27
| * add descriptive comment for TIF_MEMDIE task flag declaration.Andreas Dilger2010-05-14
| * include cleanup: Update gfp.h and slab.h includes to prepare for breaking imp...Tejun Heo2010-03-30
| * ptrace: move user_enable_single_step & co prototypes to linux/ptrace.hChristoph Hellwig2010-03-12
| * Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-armLinus Torvalds2010-03-01
| |\
| | * MM: Pass a PTE pointer to update_mmu_cache() rather than the PTE itselfRussell King2010-02-20
| * | Merge branch 'linus' into x86/mmThomas Gleixner2010-02-17
| |\|
| * | resources: introduce generic page_is_ram()Wu Fengguang2010-02-01
* | | kbuild: allow assignment to {A,C,LD}FLAGS_MODULE on the command lineSam Ravnborg2010-08-03
| |/ |/|
* | mm: make totalhigh_pages unsigned longAndreas Fenkart2010-01-11
* | Merge branch 'for-linus' of git://gitserver.sunplusct.com/linux-2.6-scoreLinus Torvalds2009-12-17
|\ \
| * | score: include asm-generic/param.h in asm/delay.h.Chen Liqin2009-12-17
| * | score: fixed pfn_valid define.Chen Liqin2009-12-17
| * | score: add flush_dcahce_page and PG_dcache_dirty defineChen Liqin2009-12-17
* | | Merge branch 'for-33' of git://repo.or.cz/linux-kbuildLinus Torvalds2009-12-17
|\ \ \ | |/ / |/| |
| * | score: add asm/asm-offsets.h wrapperMichal Marek2009-12-12
* | | elf: kill USE_ELF_CORE_DUMPChristoph Hellwig2009-12-16
|/ /
* | Add missing alignment check in arch/score sys_mmap()Al Viro2009-12-11
* | Unify sys_mmap*Al Viro2009-12-11
* | block: add helpers to run flush_dcache_page() against a bio and a request's p...Ilya Loginov2009-11-26
|/
* Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-nextLinus Torvalds2009-09-23
|\
| * Use new __init_task_data macro in arch init_task.c files.Joe Perches2009-09-21
* | score: Cleanup linker script using new macros.Tim Abbott2009-09-23
* | score: Make THREAD_SIZE available to assembly files.Tim Abbott2009-09-23
* | score: Make PAGE_SIZE available to assembly.Tim Abbott2009-09-23
|/
* score: add TIF_NOTIFY_RESUME define in asm/thread_info.hChen Liqin2009-09-17
* score: make init_thread_union align to THREAD_SIZEChen Liqin2009-08-30
* score: update files according to review comments.Chen Liqin2009-08-30
* score: add old syscall supportChen Liqin2009-08-30
* score: add MEMORY_START and MEMORY_SIZE define, to make the code clearChen Liqin2009-08-30
* score: update inconsistent declare after .c was changedChen Liqin2009-08-30
* score: remove unused code, add include files in .cChen Liqin2009-08-30
* score: clean up mm/init.cArnd Bergmann2009-06-27
ref='/cgit/cgit.cgi/litmus-rt.git/commit/block/blk-integrity.c?h=v2015.1&id=7ba1ba12eeef0aa7113beb16410ef8b7c748e18b'>7ba1ba12eeef
13f05c8d8e98

































7ba1ba12eeef
















b984679efe1a


7ba1ba12eeef



































b24498d477a1
7ba1ba12eeef
b24498d477a1
7ba1ba12eeef





b24498d477a1
7ba1ba12eeef








b24498d477a1
7ba1ba12eeef
b24498d477a1
7ba1ba12eeef





b24498d477a1
7ba1ba12eeef































52cf25d0ab7f
7ba1ba12eeef





























322316385dde
7ba1ba12eeef




322316385dde

7ba1ba12eeef





7ba1ba12eeef

b984679efe1a
322316385dde
7ba1ba12eeef



ed9e1982347b

7ba1ba12eeef





b24498d477a1
e1defc4ff0cf
7ba1ba12eeef




322316385dde









7ba1ba12eeef






















3839e4b29b43
0c032ab889e7
7ba1ba12eeef

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
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
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
























                                                                      
                       





                                                                             
                                                    
                                                            
                                                                
   
                                                                       
 


                                          
 
                                                
 







                                                                              
 

                                               
                                   
                                              








                                                                      
                                                    




                                                               
                                                                     
 


                                          
 
                                                



                                                              




                                                                                























                                                                                

                                                                 


                                                                    
                                                                 
                                
                                                                   
 
                                                  
 
                         
                       
                          

                                                                           
                                                      




                                                                          
                                                      




                                                                             
                                                      




                                                                      
                                                      






                                           
































                                                                         















                                                                                

                                                                             


































                                                                            
                                                 
            
                                                  




                                                                        
                                                                             







                                                                    
                                                  
            
                                                   




                                                                         
                                                                              






























                                                                        
                                               




























                                                                          
                                                      



                                                                     
                                                                  




                                                                                
                                      
                                                       
                                                               


                                                                     
                                                                  




                                                              
                                                                        
                                                                        



                                                  








                                                        





















                                                                
                               
                               
                                        
/*
 * blk-integrity.c - Block layer data integrity extensions
 *
 * Copyright (C) 2007, 2008 Oracle Corporation
 * Written by: Martin K. Petersen <martin.petersen@oracle.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 as published by the Free Software Foundation.
 *
 * This program 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 this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
 * USA.
 *
 */

#include <linux/blkdev.h>
#include <linux/mempool.h>
#include <linux/bio.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>

#include "blk.h"

static struct kmem_cache *integrity_cachep;

/**
 * blk_rq_count_integrity_sg - Count number of integrity scatterlist elements
 * @q:		request queue
 * @bio:	bio with integrity metadata attached
 *
 * Description: Returns the number of elements required in a
 * scatterlist corresponding to the integrity metadata in a bio.
 */
int blk_rq_count_integrity_sg(struct request_queue *q, struct bio *bio)
{
	struct bio_vec *iv, *ivprv = NULL;
	unsigned int segments = 0;
	unsigned int seg_size = 0;
	unsigned int i = 0;

	bio_for_each_integrity_vec(iv, bio, i) {

		if (ivprv) {
			if (!BIOVEC_PHYS_MERGEABLE(ivprv, iv))
				goto new_segment;

			if (!BIOVEC_SEG_BOUNDARY(q, ivprv, iv))
				goto new_segment;

			if (seg_size + iv->bv_len > queue_max_segment_size(q))
				goto new_segment;

			seg_size += iv->bv_len;
		} else {
new_segment:
			segments++;
			seg_size = iv->bv_len;
		}

		ivprv = iv;
	}

	return segments;
}
EXPORT_SYMBOL(blk_rq_count_integrity_sg);

/**
 * blk_rq_map_integrity_sg - Map integrity metadata into a scatterlist
 * @q:		request queue
 * @bio:	bio with integrity metadata attached
 * @sglist:	target scatterlist
 *
 * Description: Map the integrity vectors in request into a
 * scatterlist.  The scatterlist must be big enough to hold all
 * elements.  I.e. sized using blk_rq_count_integrity_sg().
 */
int blk_rq_map_integrity_sg(struct request_queue *q, struct bio *bio,
			    struct scatterlist *sglist)
{
	struct bio_vec *iv, *ivprv = NULL;
	struct scatterlist *sg = NULL;
	unsigned int segments = 0;
	unsigned int i = 0;

	bio_for_each_integrity_vec(iv, bio, i) {

		if (ivprv) {
			if (!BIOVEC_PHYS_MERGEABLE(ivprv, iv))
				goto new_segment;

			if (!BIOVEC_SEG_BOUNDARY(q, ivprv, iv))
				goto new_segment;

			if (sg->length + iv->bv_len > queue_max_segment_size(q))
				goto new_segment;

			sg->length += iv->bv_len;
		} else {
new_segment:
			if (!sg)
				sg = sglist;
			else {
				sg->page_link &= ~0x02;
				sg = sg_next(sg);
			}

			sg_set_page(sg, iv->bv_page, iv->bv_len, iv->bv_offset);
			segments++;
		}

		ivprv = iv;
	}

	if (sg)
		sg_mark_end(sg);

	return segments;
}
EXPORT_SYMBOL(blk_rq_map_integrity_sg);

/**
 * blk_integrity_compare - Compare integrity profile of two disks
 * @gd1:	Disk to compare
 * @gd2:	Disk to compare
 *
 * Description: Meta-devices like DM and MD need to verify that all
 * sub-devices use the same integrity format before advertising to
 * upper layers that they can send/receive integrity metadata.  This
 * function can be used to check whether two gendisk devices have
 * compatible integrity formats.
 */
int blk_integrity_compare(struct gendisk *gd1, struct gendisk *gd2)
{
	struct blk_integrity *b1 = gd1->integrity;
	struct blk_integrity *b2 = gd2->integrity;

	if (!b1 && !b2)
		return 0;

	if (!b1 || !b2)
		return -1;

	if (b1->sector_size != b2->sector_size) {
		printk(KERN_ERR "%s: %s/%s sector sz %u != %u\n", __func__,
		       gd1->disk_name, gd2->disk_name,
		       b1->sector_size, b2->sector_size);
		return -1;
	}

	if (b1->tuple_size != b2->tuple_size) {
		printk(KERN_ERR "%s: %s/%s tuple sz %u != %u\n", __func__,
		       gd1->disk_name, gd2->disk_name,
		       b1->tuple_size, b2->tuple_size);
		return -1;
	}

	if (b1->tag_size && b2->tag_size && (b1->tag_size != b2->tag_size)) {
		printk(KERN_ERR "%s: %s/%s tag sz %u != %u\n", __func__,
		       gd1->disk_name, gd2->disk_name,
		       b1->tag_size, b2->tag_size);
		return -1;
	}

	if (strcmp(b1->name, b2->name)) {
		printk(KERN_ERR "%s: %s/%s type %s != %s\n", __func__,
		       gd1->disk_name, gd2->disk_name,
		       b1->name, b2->name);
		return -1;
	}

	return 0;
}
EXPORT_SYMBOL(blk_integrity_compare);

int blk_integrity_merge_rq(struct request_queue *q, struct request *req,
			   struct request *next)
{
	if (blk_integrity_rq(req) != blk_integrity_rq(next))
		return -1;

	if (req->nr_integrity_segments + next->nr_integrity_segments >
	    q->limits.max_integrity_segments)
		return -1;

	return 0;
}
EXPORT_SYMBOL(blk_integrity_merge_rq);

int blk_integrity_merge_bio(struct request_queue *q, struct request *req,
			    struct bio *bio)
{
	int nr_integrity_segs;
	struct bio *next = bio->bi_next;

	bio->bi_next = NULL;
	nr_integrity_segs = blk_rq_count_integrity_sg(q, bio);
	bio->bi_next = next;

	if (req->nr_integrity_segments + nr_integrity_segs >
	    q->limits.max_integrity_segments)
		return -1;

	req->nr_integrity_segments += nr_integrity_segs;

	return 0;
}
EXPORT_SYMBOL(blk_integrity_merge_bio);

struct integrity_sysfs_entry {
	struct attribute attr;
	ssize_t (*show)(struct blk_integrity *, char *);
	ssize_t (*store)(struct blk_integrity *, const char *, size_t);
};

static ssize_t integrity_attr_show(struct kobject *kobj, struct attribute *attr,
				   char *page)
{
	struct blk_integrity *bi =
		container_of(kobj, struct blk_integrity, kobj);
	struct integrity_sysfs_entry *entry =
		container_of(attr, struct integrity_sysfs_entry, attr);

	return entry->show(bi, page);
}

static ssize_t integrity_attr_store(struct kobject *kobj,
				    struct attribute *attr, const char *page,
				    size_t count)
{
	struct blk_integrity *bi =
		container_of(kobj, struct blk_integrity, kobj);
	struct integrity_sysfs_entry *entry =
		container_of(attr, struct integrity_sysfs_entry, attr);
	ssize_t ret = 0;

	if (entry->store)
		ret = entry->store(bi, page, count);

	return ret;
}

static ssize_t integrity_format_show(struct blk_integrity *bi, char *page)
{
	if (bi != NULL && bi->name != NULL)
		return sprintf(page, "%s\n", bi->name);
	else
		return sprintf(page, "none\n");
}

static ssize_t integrity_tag_size_show(struct blk_integrity *bi, char *page)
{
	if (bi != NULL)
		return sprintf(page, "%u\n", bi->tag_size);
	else
		return sprintf(page, "0\n");
}

static ssize_t integrity_read_store(struct blk_integrity *bi,
				    const char *page, size_t count)
{
	char *p = (char *) page;
	unsigned long val = simple_strtoul(p, &p, 10);

	if (val)
		bi->flags |= INTEGRITY_FLAG_READ;
	else
		bi->flags &= ~INTEGRITY_FLAG_READ;

	return count;
}

static ssize_t integrity_read_show(struct blk_integrity *bi, char *page)
{
	return sprintf(page, "%d\n", (bi->flags & INTEGRITY_FLAG_READ) != 0);
}

static ssize_t integrity_write_store(struct blk_integrity *bi,
				     const char *page, size_t count)
{
	char *p = (char *) page;
	unsigned long val = simple_strtoul(p, &p, 10);

	if (val)
		bi->flags |= INTEGRITY_FLAG_WRITE;
	else
		bi->flags &= ~INTEGRITY_FLAG_WRITE;

	return count;
}

static ssize_t integrity_write_show(struct blk_integrity *bi, char *page)
{
	return sprintf(page, "%d\n", (bi->flags & INTEGRITY_FLAG_WRITE) != 0);
}

static struct integrity_sysfs_entry integrity_format_entry = {
	.attr = { .name = "format", .mode = S_IRUGO },
	.show = integrity_format_show,
};

static struct integrity_sysfs_entry integrity_tag_size_entry = {
	.attr = { .name = "tag_size", .mode = S_IRUGO },
	.show = integrity_tag_size_show,
};

static struct integrity_sysfs_entry integrity_read_entry = {
	.attr = { .name = "read_verify", .mode = S_IRUGO | S_IWUSR },
	.show = integrity_read_show,
	.store = integrity_read_store,
};

static struct integrity_sysfs_entry integrity_write_entry = {
	.attr = { .name = "write_generate", .mode = S_IRUGO | S_IWUSR },
	.show = integrity_write_show,
	.store = integrity_write_store,
};

static struct attribute *integrity_attrs[] = {
	&integrity_format_entry.attr,
	&integrity_tag_size_entry.attr,
	&integrity_read_entry.attr,
	&integrity_write_entry.attr,
	NULL,
};

static const struct sysfs_ops integrity_ops = {
	.show	= &integrity_attr_show,
	.store	= &integrity_attr_store,
};

static int __init blk_dev_integrity_init(void)
{
	integrity_cachep = kmem_cache_create("blkdev_integrity",
					     sizeof(struct blk_integrity),
					     0, SLAB_PANIC, NULL);
	return 0;
}
subsys_initcall(blk_dev_integrity_init);

static void blk_integrity_release(struct kobject *kobj)
{
	struct blk_integrity *bi =
		container_of(kobj, struct blk_integrity, kobj);

	kmem_cache_free(integrity_cachep, bi);
}

static struct kobj_type integrity_ktype = {
	.default_attrs	= integrity_attrs,
	.sysfs_ops	= &integrity_ops,
	.release	= blk_integrity_release,
};

/**
 * blk_integrity_register - Register a gendisk as being integrity-capable
 * @disk:	struct gendisk pointer to make integrity-aware
 * @template:	optional integrity profile to register
 *
 * Description: When a device needs to advertise itself as being able
 * to send/receive integrity metadata it must use this function to
 * register the capability with the block layer.  The template is a
 * blk_integrity struct with values appropriate for the underlying
 * hardware.  If template is NULL the new profile is allocated but
 * not filled out. See Documentation/block/data-integrity.txt.
 */
int blk_integrity_register(struct gendisk *disk, struct blk_integrity *template)
{
	struct blk_integrity *bi;

	BUG_ON(disk == NULL);

	if (disk->integrity == NULL) {
		bi = kmem_cache_alloc(integrity_cachep,
				      GFP_KERNEL | __GFP_ZERO);
		if (!bi)
			return -1;

		if (kobject_init_and_add(&bi->kobj, &integrity_ktype,
					 &disk_to_dev(disk)->kobj,
					 "%s", "integrity")) {
			kmem_cache_free(integrity_cachep, bi);
			return -1;
		}

		kobject_uevent(&bi->kobj, KOBJ_ADD);

		bi->flags |= INTEGRITY_FLAG_READ | INTEGRITY_FLAG_WRITE;
		bi->sector_size = queue_logical_block_size(disk->queue);
		disk->integrity = bi;
	} else
		bi = disk->integrity;

	/* Use the provided profile as template */
	if (template != NULL) {
		bi->name = template->name;
		bi->generate_fn = template->generate_fn;
		bi->verify_fn = template->verify_fn;
		bi->tuple_size = template->tuple_size;
		bi->set_tag_fn = template->set_tag_fn;
		bi->get_tag_fn = template->get_tag_fn;
		bi->tag_size = template->tag_size;
	} else
		bi->name = "unsupported";

	return 0;
}
EXPORT_SYMBOL(blk_integrity_register);

/**
 * blk_integrity_unregister - Remove block integrity profile
 * @disk:	disk whose integrity profile to deallocate
 *
 * Description: This function frees all memory used by the block
 * integrity profile.  To be called at device teardown.
 */
void blk_integrity_unregister(struct gendisk *disk)
{
	struct blk_integrity *bi;

	if (!disk || !disk->integrity)
		return;

	bi = disk->integrity;

	kobject_uevent(&bi->kobj, KOBJ_REMOVE);
	kobject_del(&bi->kobj);
	kobject_put(&bi->kobj);
	disk->integrity = NULL;
}
EXPORT_SYMBOL(blk_integrity_unregister);