Whamcloud - gitweb
LU-14075 kernel: kernel update RHEL8.2 [4.18.0-193.28.1.el8_2]
[fs/lustre-release.git] / lustre / kernel_patches / patches / block-integrity-allow-optional-integrity-functions-rhel7.patch
1 This adds optional integrity functions for given bio, they are
2 passsed to bio_integrity_prep and initialized in
3 bio_integrity_payload.
4 The optional integrity generate/verify functions take priority
5 over the ones registered on the block device.
6
7 It brings flexibility to bio integrity handling. e.g. a network
8 filesystem with integrity support would have integrity
9 generation happen on the clients, and send them over the wire.
10 On the server side once we receive the integrity bits and pass
11 the network layer checksums we would merely pass it on to the
12 block devices have integrity support, so we don't have to
13 calculate the integrity again.
14 Verification shares the same principle: on the server we just
15 copy the integrity bits from the device and send them through
16 the wire, then the verification happens on the clients.
17
18 Index: linux-3.10.0-862.9.1.el7/fs/bio-integrity.c
19 ===================================================================
20 --- linux-3.10.0-862.9.1.el7.orig/fs/bio-integrity.c
21 +++ linux-3.10.0-862.9.1.el7/fs/bio-integrity.c
22 @@ -38,7 +38,7 @@ void blk_flush_integrity(void)
23  }
24  
25  /**
26 - * bio_integrity_alloc - Allocate integrity payload and attach it to bio
27 + * bio_integrity_alloc_fn - Allocate integrity payload and attach it to bio
28   * @bio:       bio to attach integrity metadata to
29   * @gfp_mask:  Memory allocation mask
30   * @nr_vecs:   Number of integrity metadata scatter-gather elements
31 @@ -47,9 +47,11 @@ void blk_flush_integrity(void)
32   * metadata.  nr_vecs specifies the maximum number of pages containing
33   * integrity metadata that can be attached.
34   */
35 -struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio,
36 -                                                 gfp_t gfp_mask,
37 -                                                 unsigned int nr_vecs)
38 +struct bio_integrity_payload *bio_integrity_alloc_fn(struct bio *bio,
39 +                                                    gfp_t gfp_mask,
40 +                                                    unsigned int nr_vecs,
41 +                                                    integrity_gen_fn *generate_fn,
42 +                                                    integrity_vrfy_fn *verify_fn)
43  {
44         struct bio_integrity_payload *bip;
45         struct bio_set *bs = bio->bi_pool;
46 @@ -81,6 +83,8 @@ struct bio_integrity_payload *bio_integr
47  
48         bip->bip_slab = idx;
49         bip->bip_bio = bio;
50 +       bip->bip_generate_fn = generate_fn;
51 +       bip->bip_verify_fn = verify_fn;
52         bio->bi_integrity = bip;
53  
54         return bip;
55 @@ -88,6 +92,13 @@ err:
56         mempool_free(bip, bs->bio_integrity_pool);
57         return NULL;
58  }
59 +EXPORT_SYMBOL(bio_integrity_alloc_fn);
60 +
61 +struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, gfp_t gfp,
62 +                                                 unsigned int nr)
63 +{
64 +       return bio_integrity_alloc_fn(bio, gfp, nr, NULL, NULL);
65 +}
66  EXPORT_SYMBOL(bio_integrity_alloc);
67  
68  /**
69 @@ -312,10 +323,12 @@ static void bio_integrity_generate(struc
70  {
71         struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
72         struct blk_integrity_exchg bix;
73 +       struct bio_integrity_payload *bip = bio->bi_integrity;
74         struct bio_vec *bv;
75         sector_t sector = bio->bi_sector;
76         unsigned int i, sectors, total;
77         void *prot_buf = bio->bi_integrity->bip_buf;
78 +       integrity_gen_fn *generate_fn = bip->bip_generate_fn ?: bi->generate_fn;
79  
80         total = 0;
81         bix.disk_name = bio->bi_bdev->bd_disk->disk_name;
82 @@ -328,7 +341,7 @@ static void bio_integrity_generate(struc
83                 bix.prot_buf = prot_buf;
84                 bix.sector = sector;
85  
86 -               bi->generate_fn(&bix);
87 +               generate_fn(&bix);
88  
89                 sectors = bv->bv_len / bi->sector_size;
90                 sector += sectors;
91 @@ -349,7 +362,7 @@ static inline unsigned short blk_integri
92  }
93  
94  /**
95 - * bio_integrity_prep - Prepare bio for integrity I/O
96 + * bio_integrity_prep_fn - Prepare bio for integrity I/O
97   * @bio:       bio to prepare
98   *
99   * Description: Allocates a buffer for integrity metadata, maps the
100 @@ -359,7 +372,8 @@ static inline unsigned short blk_integri
101   * block device's integrity function.  In the READ case, the buffer
102   * will be prepared for DMA and a suitable end_io handler set up.
103   */
104 -int bio_integrity_prep(struct bio *bio)
105 +int bio_integrity_prep_fn(struct bio *bio, integrity_gen_fn *generate_fn,
106 +                         integrity_vrfy_fn *verify_fn)
107  {
108         struct bio_integrity_payload *bip;
109         struct blk_integrity *bi;
110 @@ -390,7 +404,8 @@ int bio_integrity_prep(struct bio *bio)
111         nr_pages = end - start;
112  
113         /* Allocate bio integrity payload and integrity vectors */
114 -       bip = bio_integrity_alloc(bio, GFP_NOIO, nr_pages);
115 +       bip = bio_integrity_alloc_fn(bio, GFP_NOIO, nr_pages,
116 +                                    generate_fn, verify_fn);
117         if (unlikely(bip == NULL)) {
118                 printk(KERN_ERR "could not allocate data integrity bioset\n");
119                 kfree(buf);
120 @@ -440,6 +455,12 @@ int bio_integrity_prep(struct bio *bio)
121  
122         return 0;
123  }
124 +EXPORT_SYMBOL(bio_integrity_prep_fn);
125 +
126 +int bio_integrity_prep(struct bio *bio)
127 +{
128 +       return bio_integrity_prep_fn(bio, NULL, NULL);
129 +}
130  EXPORT_SYMBOL(bio_integrity_prep);
131  
132  /**
133 @@ -454,10 +475,13 @@ static int bio_integrity_verify(struct b
134  {
135         struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
136         struct blk_integrity_exchg bix;
137 +       struct bio_integrity_payload *bip = bio->bi_integrity;
138         struct bio_vec *bv;
139         sector_t sector = bio->bi_integrity->bip_sector;
140         unsigned int i, sectors, total, ret;
141         void *prot_buf = bio->bi_integrity->bip_buf;
142 +       integrity_vrfy_fn *verify_fn = bip->bip_verify_fn ?:
143 +                                       bi->verify_fn;
144  
145         ret = total = 0;
146         bix.disk_name = bio->bi_bdev->bd_disk->disk_name;
147 @@ -474,7 +498,7 @@ static int bio_integrity_verify(struct b
148                 bix.prot_buf = prot_buf;
149                 bix.sector = sector;
150  
151 -               ret = bi->verify_fn(&bix);
152 +               ret = verify_fn(&bix);
153  
154                 if (ret) {
155                         kunmap_atomic(kaddr);
156 @@ -711,7 +735,9 @@ int bio_integrity_clone(struct bio *bio,
157  
158         BUG_ON(bip_src == NULL);
159  
160 -       bip = bio_integrity_alloc(bio, gfp_mask, bip_src->bip_vcnt);
161 +       bip = bio_integrity_alloc_fn(bio, gfp_mask, bip_src->bip_vcnt,
162 +                                    bip_src->bip_generate_fn,
163 +                                    bip_src->bip_verify_fn);
164  
165         if (bip == NULL)
166                 return -EIO;
167 Index: linux-3.10.0-862.9.1.el7/include/linux/bio.h
168 ===================================================================
169 --- linux-3.10.0-862.9.1.el7.orig/include/linux/bio.h
170 +++ linux-3.10.0-862.9.1.el7/include/linux/bio.h
171 @@ -195,6 +195,11 @@ struct bio_integrity_payload {
172         struct work_struct      bip_work;       /* I/O completion */
173  
174         struct bio_vec          *bip_vec;
175 +
176 +       /* put after bip_vec as that is last externally-accessed bip_ field */
177 +       integrity_gen_fn        *bip_generate_fn;
178 +       integrity_vrfy_fn       *bip_verify_fn;
179
180         struct bio_vec          bip_inline_vecs[0];/* embedded bvec array */
181  };
182  #endif /* CONFIG_BLK_DEV_INTEGRITY */
183 @@ -618,6 +623,11 @@ struct biovec_slab {
184  #define bio_integrity(bio) (bio->bi_integrity != NULL)
185  
186  extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int);
187 +extern struct bio_integrity_payload *bio_integrity_alloc_fn(struct bio *bio,
188 +                                               gfp_t gfp_mask,
189 +                                               unsigned int nr_vecs,
190 +                                               integrity_gen_fn *generate_fn,
191 +                                               integrity_vrfy_fn *verify_fn);
192  extern void bio_integrity_free(struct bio *);
193  extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int);
194  extern int bio_integrity_enabled(struct bio *bio);
195 @@ -624,6 +634,9 @@ struct biovec_slab {
196  extern int bio_integrity_set_tag(struct bio *, void *, unsigned int);
197  extern int bio_integrity_get_tag(struct bio *, void *, unsigned int);
198  extern int bio_integrity_prep(struct bio *);
199 +extern int bio_integrity_prep_fn(struct bio *bio,
200 +                                integrity_gen_fn *generate_fn,
201 +                                integrity_vrfy_fn *verify_fn);
202  extern void bio_integrity_endio(struct bio *, int);
203  extern void bio_integrity_advance(struct bio *, unsigned int);
204  extern void bio_integrity_trim(struct bio *, unsigned int, unsigned int);
205 Index: linux-3.10.0-862.9.1.el7/include/linux/blk_types.h
206 ===================================================================
207 --- linux-3.10.0-862.9.1.el7.orig/include/linux/blk_types.h
208 +++ linux-3.10.0-862.9.1.el7/include/linux/blk_types.h
209 @@ -16,8 +16,11 @@ struct page;
210  struct block_device;
211  struct io_context;
212  struct cgroup_subsys_state;
213 +struct blk_integrity_exchg;
214  typedef void (bio_end_io_t) (struct bio *, int);
215  typedef void (bio_destructor_t) (struct bio *);
216 +typedef void (integrity_gen_fn) (struct blk_integrity_exchg *bix);
217 +typedef int (integrity_vrfy_fn) (struct blk_integrity_exchg *bix);
218  
219  /*
220   * was unsigned short, but we might as well be ready for > 64kB I/O pages
221 Index: linux-3.10.0-862.9.1.el7/include/linux/blkdev.h
222 ===================================================================
223 --- linux-3.10.0-862.9.1.el7.orig/include/linux/blkdev.h
224 +++ linux-3.10.0-862.9.1.el7/include/linux/blkdev.h
225 @@ -1702,8 +1702,6 @@ struct blk_integrity_exchg {
226         const char              *disk_name;
227  };
228  
229 -typedef void (integrity_gen_fn) (struct blk_integrity_exchg *);
230 -typedef int (integrity_vrfy_fn) (struct blk_integrity_exchg *);
231  typedef void (integrity_set_tag_fn) (void *, void *, unsigned int);
232  typedef void (integrity_get_tag_fn) (void *, void *, unsigned int);
233