Whamcloud - gitweb
LU-17744 ldiskfs: mballoc stats fixes
[fs/lustre-release.git] / lustre / kernel_patches / patches / block-integrity-allow-optional-integrity-functions-rhel8.patch
1 This adds optional integrity functions for given bio, they are
2 passed 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-4.18.0-80.11.2.el8_0/block/bio-integrity.c
19 ===================================================================
20 --- linux-4.18.0-80.11.2.el8_0.orig/block/bio-integrity.c
21 +++ linux-4.18.0-80.11.2.el8_0/block/bio-integrity.c
22 @@ -39,7 +39,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 @@ -48,9 +48,10 @@ 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_processing_fn *verify_fn)
42  {
43         struct bio_integrity_payload *bip;
44         struct bio_set *bs = bio->bi_pool;
45 @@ -85,6 +86,7 @@ struct bio_integrity_payload *bio_integr
46         }
47  
48         bip->bip_bio = bio;
49 +       bip->bip_verify_fn = verify_fn;
50         bio->bi_integrity = bip;
51         bio->bi_opf |= REQ_INTEGRITY;
52  
53 @@ -93,6 +95,14 @@ err:
54         mempool_free(bip, &bs->bio_integrity_pool);
55         return ERR_PTR(-ENOMEM);
56  }
57 +EXPORT_SYMBOL(bio_integrity_alloc_fn);
58 +
59 +struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio,
60 +                                                 gfp_t gfp_mask,
61 +                                                 unsigned int nr_vecs)
62 +{
63 +       return bio_integrity_alloc_fn(bio, gfp_mask, nr_vecs, NULL);
64 +}
65  EXPORT_SYMBOL(bio_integrity_alloc);
66  
67  /**
68 @@ -200,7 +210,7 @@ static blk_status_t bio_integrity_proces
69  }
70  
71  /**
72 - * bio_integrity_prep - Prepare bio for integrity I/O
73 + * bio_integrity_prep_fn - Prepare bio for integrity I/O
74   * @bio:       bio to prepare
75   *
76   * Description:  Checks if the bio already has an integrity payload attached.
77 @@ -211,7 +221,9 @@ static blk_status_t bio_integrity_proces
78   * the block device's integrity function.  In the READ case, the buffer
79   * will be prepared for DMA and a suitable end_io handler set up.
80   */
81 -bool bio_integrity_prep(struct bio *bio)
82 +bool bio_integrity_prep_fn(struct bio *bio,
83 +                          integrity_processing_fn *generate_fn,
84 +                          integrity_processing_fn *verify_fn)
85  {
86         struct bio_integrity_payload *bip;
87         struct blk_integrity *bi = blk_get_integrity(bio->bi_disk);
88 @@ -261,7 +273,7 @@ bool bio_integrity_prep(struct bio *bio)
89         nr_pages = end - start;
90  
91         /* Allocate bio integrity payload and integrity vectors */
92 -       bip = bio_integrity_alloc(bio, GFP_NOIO, nr_pages);
93 +       bip = bio_integrity_alloc_fn(bio, GFP_NOIO, nr_pages, verify_fn);
94         if (IS_ERR(bip)) {
95                 printk(KERN_ERR "could not allocate data integrity bioset\n");
96                 kfree(buf);
97 @@ -305,7 +317,7 @@ bool bio_integrity_prep(struct bio *bio)
98         /* Auto-generate integrity metadata if this is a write */
99         if (bio_data_dir(bio) == WRITE) {
100                 bio_integrity_process(bio, &bio->bi_iter,
101 -                                     bi->profile->generate_fn);
102 +                                     generate_fn ?: bi->profile->generate_fn);
103         } else {
104                 bip->bio_iter = bio->bi_iter;
105         }
106 @@ -317,6 +329,12 @@ err_end_io:
107         return false;
108  
109  }
110 +EXPORT_SYMBOL(bio_integrity_prep_fn);
111 +
112 +bool bio_integrity_prep(struct bio *bio)
113 +{
114 +       return bio_integrity_prep_fn(bio, NULL, NULL);
115 +}
116  EXPORT_SYMBOL(bio_integrity_prep);
117  
118  /**
119 @@ -340,7 +358,7 @@ static void bio_integrity_verify_fn(stru
120          * it's original position.
121          */
122         bio->bi_status = bio_integrity_process(bio, &bip->bio_iter,
123 -                                               bi->profile->verify_fn);
124 +                                       bip->bip_verify_fn ?: bi->profile->verify_fn);
125         bio_integrity_free(bio);
126         bio_endio(bio);
127  }
128 @@ -423,7 +441,8 @@ int bio_integrity_clone(struct bio *bio,
129  
130         BUG_ON(bip_src == NULL);
131  
132 -       bip = bio_integrity_alloc(bio, gfp_mask, bip_src->bip_vcnt);
133 +       bip = bio_integrity_alloc_fn(bio, gfp_mask, bip_src->bip_vcnt,
134 +                                    bip_src->bip_verify_fn);
135         if (IS_ERR(bip))
136                 return PTR_ERR(bip);
137  
138 Index: linux-4.18.0-80.11.2.el8_0/include/linux/bio.h
139 ===================================================================
140 --- linux-4.18.0-80.11.2.el8_0.orig/include/linux/bio.h
141 +++ linux-4.18.0-80.11.2.el8_0/include/linux/bio.h
142 @@ -313,7 +313,8 @@ struct bio_integrity_payload {
143  
144         struct bio_vec          *bip_vec;
145  
146 -       RH_KABI_RESERVE(1)
147 +       /* put after bip_vec as that is last externally-accessed bip_ field */
148 +       RH_KABI_USE(1, integrity_processing_fn *bip_verify_fn)
149         RH_KABI_RESERVE(2)
150  
151         struct bio_vec          bip_inline_vecs[0];/* embedded bvec array */
152 @@ -760,8 +761,15 @@ static inline bool bioset_initialized(st
153                 bip_for_each_vec(_bvl, _bio->bi_integrity, _iter)
154  
155  extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int);
156 +extern struct bio_integrity_payload *bio_integrity_alloc_fn(struct bio *bio,
157 +                                                       gfp_t gfp_mask,
158 +                                                       unsigned int nr_vecs,
159 +                                                       integrity_processing_fn *verify_fn);
160  extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int);
161  extern bool bio_integrity_prep(struct bio *);
162 +extern bool bio_integrity_prep_fn(struct bio *bio,
163 +                               integrity_processing_fn *generate_fn,
164 +                               integrity_processing_fn *verify_fn);
165  extern void bio_integrity_advance(struct bio *, unsigned int);
166  extern void bio_integrity_trim(struct bio *);
167  extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t);
168 Index: linux-4.18.0-80.11.2.el8_0/include/linux/blk_types.h
169 ===================================================================
170 --- linux-4.18.0-80.11.2.el8_0.orig/include/linux/blk_types.h
171 +++ linux-4.18.0-80.11.2.el8_0/include/linux/blk_types.h
172 @@ -18,6 +18,7 @@ struct page;
173  struct block_device;
174  struct io_context;
175  struct cgroup_subsys_state;
176 +struct blk_integrity_iter;
177  typedef void (bio_end_io_t) (struct bio *);
178  
179  /*
180 @@ -41,6 +42,8 @@ typedef u8 __bitwise blk_status_t;
181  #define BLK_STS_RESOURCE       ((__force blk_status_t)9)
182  #define BLK_STS_IOERR          ((__force blk_status_t)10)
183  
184 +typedef blk_status_t (integrity_processing_fn) (struct blk_integrity_iter *);
185 +
186  /* hack for device mapper, don't use elsewhere: */
187  #define BLK_STS_DM_REQUEUE    ((__force blk_status_t)11)
188  
189 Index: linux-4.18.0-80.11.2.el8_0/include/linux/blkdev.h
190 ===================================================================
191 --- linux-4.18.0-80.11.2.el8_0.orig/include/linux/blkdev.h
192 +++ linux-4.18.0-80.11.2.el8_0/include/linux/blkdev.h
193 @@ -1505,8 +1505,6 @@ struct blk_integrity_iter {
194         const char              *disk_name;
195  };
196  
197 -typedef blk_status_t (integrity_processing_fn) (struct blk_integrity_iter *);
198 -
199  struct blk_integrity_profile {
200         integrity_processing_fn         *generate_fn;
201         integrity_processing_fn         *verify_fn;