~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/block/blk-lib.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /block/blk-lib.c (Version linux-6.11.5) and /block/blk-lib.c (Version linux-6.7.12)


  1 // SPDX-License-Identifier: GPL-2.0                 1 // SPDX-License-Identifier: GPL-2.0
  2 /*                                                  2 /*
  3  * Functions related to generic helpers functi      3  * Functions related to generic helpers functions
  4  */                                                 4  */
  5 #include <linux/kernel.h>                           5 #include <linux/kernel.h>
  6 #include <linux/module.h>                           6 #include <linux/module.h>
  7 #include <linux/bio.h>                              7 #include <linux/bio.h>
  8 #include <linux/blkdev.h>                           8 #include <linux/blkdev.h>
  9 #include <linux/scatterlist.h>                      9 #include <linux/scatterlist.h>
 10                                                    10 
 11 #include "blk.h"                                   11 #include "blk.h"
 12                                                    12 
 13 static sector_t bio_discard_limit(struct block     13 static sector_t bio_discard_limit(struct block_device *bdev, sector_t sector)
 14 {                                                  14 {
 15         unsigned int discard_granularity = bde     15         unsigned int discard_granularity = bdev_discard_granularity(bdev);
 16         sector_t granularity_aligned_sector;       16         sector_t granularity_aligned_sector;
 17                                                    17 
 18         if (bdev_is_partition(bdev))               18         if (bdev_is_partition(bdev))
 19                 sector += bdev->bd_start_sect;     19                 sector += bdev->bd_start_sect;
 20                                                    20 
 21         granularity_aligned_sector =               21         granularity_aligned_sector =
 22                 round_up(sector, discard_granu     22                 round_up(sector, discard_granularity >> SECTOR_SHIFT);
 23                                                    23 
 24         /*                                         24         /*
 25          * Make sure subsequent bios start ali     25          * Make sure subsequent bios start aligned to the discard granularity if
 26          * it needs to be split.                   26          * it needs to be split.
 27          */                                        27          */
 28         if (granularity_aligned_sector != sect     28         if (granularity_aligned_sector != sector)
 29                 return granularity_aligned_sec     29                 return granularity_aligned_sector - sector;
 30                                                    30 
 31         /*                                         31         /*
 32          * Align the bio size to the discard g     32          * Align the bio size to the discard granularity to make splitting the bio
 33          * at discard granularity boundaries e     33          * at discard granularity boundaries easier in the driver if needed.
 34          */                                        34          */
 35         return round_down(UINT_MAX, discard_gr     35         return round_down(UINT_MAX, discard_granularity) >> SECTOR_SHIFT;
 36 }                                                  36 }
 37                                                    37 
 38 struct bio *blk_alloc_discard_bio(struct block !!  38 int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
 39                 sector_t *sector, sector_t *nr !!  39                 sector_t nr_sects, gfp_t gfp_mask, struct bio **biop)
 40 {                                                  40 {
 41         sector_t bio_sects = min(*nr_sects, bi !!  41         struct bio *bio = *biop;
 42         struct bio *bio;                       !!  42         sector_t bs_mask;
 43                                                    43 
 44         if (!bio_sects)                        !!  44         if (bdev_read_only(bdev))
 45                 return NULL;                   !!  45                 return -EPERM;
                                                   >>  46         if (!bdev_max_discard_sectors(bdev))
                                                   >>  47                 return -EOPNOTSUPP;
 46                                                    48 
 47         bio = bio_alloc(bdev, 0, REQ_OP_DISCAR !!  49         /* In case the discard granularity isn't set by buggy device driver */
 48         if (!bio)                              !!  50         if (WARN_ON_ONCE(!bdev_discard_granularity(bdev))) {
 49                 return NULL;                   !!  51                 pr_err_ratelimited("%pg: Error: discard_granularity is 0.\n",
 50         bio->bi_iter.bi_sector = *sector;      !!  52                                    bdev);
 51         bio->bi_iter.bi_size = bio_sects << SE !!  53                 return -EOPNOTSUPP;
 52         *sector += bio_sects;                  !!  54         }
 53         *nr_sects -= bio_sects;                << 
 54         /*                                     << 
 55          * We can loop for a long time in here << 
 56          * discards (like mkfs).  Be nice and  << 
 57          * softlocking if preempt is disabled. << 
 58          */                                    << 
 59         cond_resched();                        << 
 60         return bio;                            << 
 61 }                                              << 
 62                                                    55 
 63 int __blkdev_issue_discard(struct block_device !!  56         bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1;
 64                 sector_t nr_sects, gfp_t gfp_m !!  57         if ((sector | nr_sects) & bs_mask)
 65 {                                              !!  58                 return -EINVAL;
 66         struct bio *bio;                       << 
 67                                                    59 
 68         while ((bio = blk_alloc_discard_bio(bd !!  60         if (!nr_sects)
 69                         gfp_mask)))            !!  61                 return -EINVAL;
 70                 *biop = bio_chain_and_submit(* !!  62 
                                                   >>  63         while (nr_sects) {
                                                   >>  64                 sector_t req_sects =
                                                   >>  65                         min(nr_sects, bio_discard_limit(bdev, sector));
                                                   >>  66 
                                                   >>  67                 bio = blk_next_bio(bio, bdev, 0, REQ_OP_DISCARD, gfp_mask);
                                                   >>  68                 bio->bi_iter.bi_sector = sector;
                                                   >>  69                 bio->bi_iter.bi_size = req_sects << 9;
                                                   >>  70                 sector += req_sects;
                                                   >>  71                 nr_sects -= req_sects;
                                                   >>  72 
                                                   >>  73                 /*
                                                   >>  74                  * We can loop for a long time in here, if someone does
                                                   >>  75                  * full device discards (like mkfs). Be nice and allow
                                                   >>  76                  * us to schedule out to avoid softlocking if preempt
                                                   >>  77                  * is disabled.
                                                   >>  78                  */
                                                   >>  79                 cond_resched();
                                                   >>  80         }
                                                   >>  81 
                                                   >>  82         *biop = bio;
 71         return 0;                                  83         return 0;
 72 }                                                  84 }
 73 EXPORT_SYMBOL(__blkdev_issue_discard);             85 EXPORT_SYMBOL(__blkdev_issue_discard);
 74                                                    86 
 75 /**                                                87 /**
 76  * blkdev_issue_discard - queue a discard          88  * blkdev_issue_discard - queue a discard
 77  * @bdev:       blockdev to issue discard for      89  * @bdev:       blockdev to issue discard for
 78  * @sector:     start sector                       90  * @sector:     start sector
 79  * @nr_sects:   number of sectors to discard       91  * @nr_sects:   number of sectors to discard
 80  * @gfp_mask:   memory allocation flags (for b     92  * @gfp_mask:   memory allocation flags (for bio_alloc)
 81  *                                                 93  *
 82  * Description:                                    94  * Description:
 83  *    Issue a discard request for the sectors      95  *    Issue a discard request for the sectors in question.
 84  */                                                96  */
 85 int blkdev_issue_discard(struct block_device *     97 int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
 86                 sector_t nr_sects, gfp_t gfp_m     98                 sector_t nr_sects, gfp_t gfp_mask)
 87 {                                                  99 {
 88         struct bio *bio = NULL;                   100         struct bio *bio = NULL;
 89         struct blk_plug plug;                     101         struct blk_plug plug;
 90         int ret;                                  102         int ret;
 91                                                   103 
 92         blk_start_plug(&plug);                    104         blk_start_plug(&plug);
 93         ret = __blkdev_issue_discard(bdev, sec    105         ret = __blkdev_issue_discard(bdev, sector, nr_sects, gfp_mask, &bio);
 94         if (!ret && bio) {                        106         if (!ret && bio) {
 95                 ret = submit_bio_wait(bio);       107                 ret = submit_bio_wait(bio);
 96                 if (ret == -EOPNOTSUPP)           108                 if (ret == -EOPNOTSUPP)
 97                         ret = 0;                  109                         ret = 0;
 98                 bio_put(bio);                     110                 bio_put(bio);
 99         }                                         111         }
100         blk_finish_plug(&plug);                   112         blk_finish_plug(&plug);
101                                                   113 
102         return ret;                               114         return ret;
103 }                                                 115 }
104 EXPORT_SYMBOL(blkdev_issue_discard);              116 EXPORT_SYMBOL(blkdev_issue_discard);
105                                                   117 
106 static sector_t bio_write_zeroes_limit(struct  !! 118 static int __blkdev_issue_write_zeroes(struct block_device *bdev,
107 {                                              << 
108         sector_t bs_mask = (bdev_logical_block << 
109                                                << 
110         return min(bdev_write_zeroes_sectors(b << 
111                 (UINT_MAX >> SECTOR_SHIFT) & ~ << 
112 }                                              << 
113                                                << 
114 /*                                             << 
115  * There is no reliable way for the SCSI subsy << 
116  * device supports a WRITE SAME operation with << 
117  * to media. As a result, write_zeroes is enab << 
118  * disabled if a zeroing operation subsequentl << 
119  * queue limit is likely to change at runtime. << 
120  */                                            << 
121 static void __blkdev_issue_write_zeroes(struct << 
122                 sector_t sector, sector_t nr_s    119                 sector_t sector, sector_t nr_sects, gfp_t gfp_mask,
123                 struct bio **biop, unsigned fl !! 120                 struct bio **biop, unsigned flags)
124 {                                                 121 {
                                                   >> 122         struct bio *bio = *biop;
                                                   >> 123         unsigned int max_write_zeroes_sectors;
125                                                   124 
126         while (nr_sects) {                     !! 125         if (bdev_read_only(bdev))
127                 unsigned int len = min(nr_sect !! 126                 return -EPERM;
128                 struct bio *bio;               << 
129                                                   127 
130                 if ((flags & BLKDEV_ZERO_KILLA !! 128         /* Ensure that max_write_zeroes_sectors doesn't overflow bi_size */
131                     fatal_signal_pending(curre !! 129         max_write_zeroes_sectors = bdev_write_zeroes_sectors(bdev);
132                         break;                 !! 130 
                                                   >> 131         if (max_write_zeroes_sectors == 0)
                                                   >> 132                 return -EOPNOTSUPP;
133                                                   133 
134                 bio = bio_alloc(bdev, 0, REQ_O !! 134         while (nr_sects) {
                                                   >> 135                 bio = blk_next_bio(bio, bdev, 0, REQ_OP_WRITE_ZEROES, gfp_mask);
135                 bio->bi_iter.bi_sector = secto    136                 bio->bi_iter.bi_sector = sector;
136                 if (flags & BLKDEV_ZERO_NOUNMA    137                 if (flags & BLKDEV_ZERO_NOUNMAP)
137                         bio->bi_opf |= REQ_NOU    138                         bio->bi_opf |= REQ_NOUNMAP;
138                                                   139 
139                 bio->bi_iter.bi_size = len <<  !! 140                 if (nr_sects > max_write_zeroes_sectors) {
140                 *biop = bio_chain_and_submit(* !! 141                         bio->bi_iter.bi_size = max_write_zeroes_sectors << 9;
141                                                !! 142                         nr_sects -= max_write_zeroes_sectors;
142                 nr_sects -= len;               !! 143                         sector += max_write_zeroes_sectors;
143                 sector += len;                 !! 144                 } else {
144                 cond_resched();                !! 145                         bio->bi_iter.bi_size = nr_sects << 9;
145         }                                      !! 146                         nr_sects = 0;
146 }                                              << 
147                                                << 
148 static int blkdev_issue_write_zeroes(struct bl << 
149                 sector_t nr_sects, gfp_t gfp,  << 
150 {                                              << 
151         sector_t limit = bio_write_zeroes_limi << 
152         struct bio *bio = NULL;                << 
153         struct blk_plug plug;                  << 
154         int ret = 0;                           << 
155                                                << 
156         blk_start_plug(&plug);                 << 
157         __blkdev_issue_write_zeroes(bdev, sect << 
158                         flags, limit);         << 
159         if (bio) {                             << 
160                 if ((flags & BLKDEV_ZERO_KILLA << 
161                     fatal_signal_pending(curre << 
162                         bio_await_chain(bio);  << 
163                         blk_finish_plug(&plug) << 
164                         return -EINTR;         << 
165                 }                                 147                 }
166                 ret = submit_bio_wait(bio);    !! 148                 cond_resched();
167                 bio_put(bio);                  << 
168         }                                         149         }
169         blk_finish_plug(&plug);                << 
170                                                   150 
171         /*                                     !! 151         *biop = bio;
172          * For some devices there is no non-de !! 152         return 0;
173          * WRITE ZEROES is actually supported. << 
174          * on an I/O error, in which case we'l << 
175          * "not supported" here.               << 
176          */                                    << 
177         if (ret && !bdev_write_zeroes_sectors( << 
178                 return -EOPNOTSUPP;            << 
179         return ret;                            << 
180 }                                                 153 }
181                                                   154 
182 /*                                                155 /*
183  * Convert a number of 512B sectors to a numbe    156  * Convert a number of 512B sectors to a number of pages.
184  * The result is limited to a number of pages     157  * The result is limited to a number of pages that can fit into a BIO.
185  * Also make sure that the result is always at    158  * Also make sure that the result is always at least 1 (page) for the cases
186  * where nr_sects is lower than the number of     159  * where nr_sects is lower than the number of sectors in a page.
187  */                                               160  */
188 static unsigned int __blkdev_sectors_to_bio_pa    161 static unsigned int __blkdev_sectors_to_bio_pages(sector_t nr_sects)
189 {                                                 162 {
190         sector_t pages = DIV_ROUND_UP_SECTOR_T    163         sector_t pages = DIV_ROUND_UP_SECTOR_T(nr_sects, PAGE_SIZE / 512);
191                                                   164 
192         return min(pages, (sector_t)BIO_MAX_VE    165         return min(pages, (sector_t)BIO_MAX_VECS);
193 }                                                 166 }
194                                                   167 
195 static void __blkdev_issue_zero_pages(struct b !! 168 static int __blkdev_issue_zero_pages(struct block_device *bdev,
196                 sector_t sector, sector_t nr_s    169                 sector_t sector, sector_t nr_sects, gfp_t gfp_mask,
197                 struct bio **biop, unsigned in !! 170                 struct bio **biop)
198 {                                                 171 {
199         while (nr_sects) {                     !! 172         struct bio *bio = *biop;
200                 unsigned int nr_vecs = __blkde !! 173         int bi_size = 0;
201                 struct bio *bio;               !! 174         unsigned int sz;
202                                                << 
203                 bio = bio_alloc(bdev, nr_vecs, << 
204                 bio->bi_iter.bi_sector = secto << 
205                                                   175 
206                 if ((flags & BLKDEV_ZERO_KILLA !! 176         if (bdev_read_only(bdev))
207                     fatal_signal_pending(curre !! 177                 return -EPERM;
208                         break;                 << 
209                                                   178 
210                 do {                           !! 179         while (nr_sects != 0) {
211                         unsigned int len, adde !! 180                 bio = blk_next_bio(bio, bdev, __blkdev_sectors_to_bio_pages(nr_sects),
                                                   >> 181                                    REQ_OP_WRITE, gfp_mask);
                                                   >> 182                 bio->bi_iter.bi_sector = sector;
212                                                   183 
213                         len = min_t(sector_t,  !! 184                 while (nr_sects != 0) {
214                                 PAGE_SIZE, nr_ !! 185                         sz = min((sector_t) PAGE_SIZE, nr_sects << 9);
215                         added = bio_add_page(b !! 186                         bi_size = bio_add_page(bio, ZERO_PAGE(0), sz, 0);
216                         if (added < len)       !! 187                         nr_sects -= bi_size >> 9;
                                                   >> 188                         sector += bi_size >> 9;
                                                   >> 189                         if (bi_size < sz)
217                                 break;            190                                 break;
218                         nr_sects -= added >> S << 
219                         sector += added >> SEC << 
220                 } while (nr_sects);            << 
221                                                << 
222                 *biop = bio_chain_and_submit(* << 
223                 cond_resched();                << 
224         }                                      << 
225 }                                              << 
226                                                << 
227 static int blkdev_issue_zero_pages(struct bloc << 
228                 sector_t nr_sects, gfp_t gfp,  << 
229 {                                              << 
230         struct bio *bio = NULL;                << 
231         struct blk_plug plug;                  << 
232         int ret = 0;                           << 
233                                                << 
234         if (flags & BLKDEV_ZERO_NOFALLBACK)    << 
235                 return -EOPNOTSUPP;            << 
236                                                << 
237         blk_start_plug(&plug);                 << 
238         __blkdev_issue_zero_pages(bdev, sector << 
239         if (bio) {                             << 
240                 if ((flags & BLKDEV_ZERO_KILLA << 
241                     fatal_signal_pending(curre << 
242                         bio_await_chain(bio);  << 
243                         blk_finish_plug(&plug) << 
244                         return -EINTR;         << 
245                 }                                 191                 }
246                 ret = submit_bio_wait(bio);    !! 192                 cond_resched();
247                 bio_put(bio);                  << 
248         }                                         193         }
249         blk_finish_plug(&plug);                << 
250                                                   194 
251         return ret;                            !! 195         *biop = bio;
                                                   >> 196         return 0;
252 }                                                 197 }
253                                                   198 
254 /**                                               199 /**
255  * __blkdev_issue_zeroout - generate number of    200  * __blkdev_issue_zeroout - generate number of zero filed write bios
256  * @bdev:       blockdev to issue                 201  * @bdev:       blockdev to issue
257  * @sector:     start sector                      202  * @sector:     start sector
258  * @nr_sects:   number of sectors to write        203  * @nr_sects:   number of sectors to write
259  * @gfp_mask:   memory allocation flags (for b    204  * @gfp_mask:   memory allocation flags (for bio_alloc)
260  * @biop:       pointer to anchor bio             205  * @biop:       pointer to anchor bio
261  * @flags:      controls detailed behavior        206  * @flags:      controls detailed behavior
262  *                                                207  *
263  * Description:                                   208  * Description:
264  *  Zero-fill a block range, either using hard    209  *  Zero-fill a block range, either using hardware offload or by explicitly
265  *  writing zeroes to the device.                 210  *  writing zeroes to the device.
266  *                                                211  *
267  *  If a device is using logical block provisi    212  *  If a device is using logical block provisioning, the underlying space will
268  *  not be released if %flags contains BLKDEV_    213  *  not be released if %flags contains BLKDEV_ZERO_NOUNMAP.
269  *                                                214  *
270  *  If %flags contains BLKDEV_ZERO_NOFALLBACK,    215  *  If %flags contains BLKDEV_ZERO_NOFALLBACK, the function will return
271  *  -EOPNOTSUPP if no explicit hardware offloa    216  *  -EOPNOTSUPP if no explicit hardware offload for zeroing is provided.
272  */                                               217  */
273 int __blkdev_issue_zeroout(struct block_device    218 int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
274                 sector_t nr_sects, gfp_t gfp_m    219                 sector_t nr_sects, gfp_t gfp_mask, struct bio **biop,
275                 unsigned flags)                   220                 unsigned flags)
276 {                                                 221 {
277         sector_t limit = bio_write_zeroes_limi !! 222         int ret;
                                                   >> 223         sector_t bs_mask;
278                                                   224 
279         if (bdev_read_only(bdev))              !! 225         bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1;
280                 return -EPERM;                 !! 226         if ((sector | nr_sects) & bs_mask)
                                                   >> 227                 return -EINVAL;
281                                                   228 
282         if (limit) {                           !! 229         ret = __blkdev_issue_write_zeroes(bdev, sector, nr_sects, gfp_mask,
283                 __blkdev_issue_write_zeroes(bd !! 230                         biop, flags);
284                                 gfp_mask, biop !! 231         if (ret != -EOPNOTSUPP || (flags & BLKDEV_ZERO_NOFALLBACK))
285         } else {                               !! 232                 return ret;
286                 if (flags & BLKDEV_ZERO_NOFALL !! 233 
287                         return -EOPNOTSUPP;    !! 234         return __blkdev_issue_zero_pages(bdev, sector, nr_sects, gfp_mask,
288                 __blkdev_issue_zero_pages(bdev !! 235                                          biop);
289                                 biop, flags);  << 
290         }                                      << 
291         return 0;                              << 
292 }                                                 236 }
293 EXPORT_SYMBOL(__blkdev_issue_zeroout);            237 EXPORT_SYMBOL(__blkdev_issue_zeroout);
294                                                   238 
295 /**                                               239 /**
296  * blkdev_issue_zeroout - zero-fill a block ra    240  * blkdev_issue_zeroout - zero-fill a block range
297  * @bdev:       blockdev to write                 241  * @bdev:       blockdev to write
298  * @sector:     start sector                      242  * @sector:     start sector
299  * @nr_sects:   number of sectors to write        243  * @nr_sects:   number of sectors to write
300  * @gfp_mask:   memory allocation flags (for b    244  * @gfp_mask:   memory allocation flags (for bio_alloc)
301  * @flags:      controls detailed behavior        245  * @flags:      controls detailed behavior
302  *                                                246  *
303  * Description:                                   247  * Description:
304  *  Zero-fill a block range, either using hard    248  *  Zero-fill a block range, either using hardware offload or by explicitly
305  *  writing zeroes to the device.  See __blkde    249  *  writing zeroes to the device.  See __blkdev_issue_zeroout() for the
306  *  valid values for %flags.                      250  *  valid values for %flags.
307  */                                               251  */
308 int blkdev_issue_zeroout(struct block_device *    252 int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
309                 sector_t nr_sects, gfp_t gfp_m    253                 sector_t nr_sects, gfp_t gfp_mask, unsigned flags)
310 {                                                 254 {
311         int ret;                               !! 255         int ret = 0;
                                                   >> 256         sector_t bs_mask;
                                                   >> 257         struct bio *bio;
                                                   >> 258         struct blk_plug plug;
                                                   >> 259         bool try_write_zeroes = !!bdev_write_zeroes_sectors(bdev);
312                                                   260 
313         if ((sector | nr_sects) & ((bdev_logic !! 261         bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1;
                                                   >> 262         if ((sector | nr_sects) & bs_mask)
314                 return -EINVAL;                   263                 return -EINVAL;
315         if (bdev_read_only(bdev))              << 
316                 return -EPERM;                 << 
317                                                   264 
318         if (bdev_write_zeroes_sectors(bdev)) { !! 265 retry:
319                 ret = blkdev_issue_write_zeroe !! 266         bio = NULL;
320                                 gfp_mask, flag !! 267         blk_start_plug(&plug);
321                 if (ret != -EOPNOTSUPP)        !! 268         if (try_write_zeroes) {
322                         return ret;            !! 269                 ret = __blkdev_issue_write_zeroes(bdev, sector, nr_sects,
                                                   >> 270                                                   gfp_mask, &bio, flags);
                                                   >> 271         } else if (!(flags & BLKDEV_ZERO_NOFALLBACK)) {
                                                   >> 272                 ret = __blkdev_issue_zero_pages(bdev, sector, nr_sects,
                                                   >> 273                                                 gfp_mask, &bio);
                                                   >> 274         } else {
                                                   >> 275                 /* No zeroing offload support */
                                                   >> 276                 ret = -EOPNOTSUPP;
                                                   >> 277         }
                                                   >> 278         if (ret == 0 && bio) {
                                                   >> 279                 ret = submit_bio_wait(bio);
                                                   >> 280                 bio_put(bio);
                                                   >> 281         }
                                                   >> 282         blk_finish_plug(&plug);
                                                   >> 283         if (ret && try_write_zeroes) {
                                                   >> 284                 if (!(flags & BLKDEV_ZERO_NOFALLBACK)) {
                                                   >> 285                         try_write_zeroes = false;
                                                   >> 286                         goto retry;
                                                   >> 287                 }
                                                   >> 288                 if (!bdev_write_zeroes_sectors(bdev)) {
                                                   >> 289                         /*
                                                   >> 290                          * Zeroing offload support was indicated, but the
                                                   >> 291                          * device reported ILLEGAL REQUEST (for some devices
                                                   >> 292                          * there is no non-destructive way to verify whether
                                                   >> 293                          * WRITE ZEROES is actually supported).
                                                   >> 294                          */
                                                   >> 295                         ret = -EOPNOTSUPP;
                                                   >> 296                 }
323         }                                         297         }
324                                                   298 
325         return blkdev_issue_zero_pages(bdev, s !! 299         return ret;
326 }                                                 300 }
327 EXPORT_SYMBOL(blkdev_issue_zeroout);              301 EXPORT_SYMBOL(blkdev_issue_zeroout);
328                                                   302 
329 int blkdev_issue_secure_erase(struct block_dev    303 int blkdev_issue_secure_erase(struct block_device *bdev, sector_t sector,
330                 sector_t nr_sects, gfp_t gfp)     304                 sector_t nr_sects, gfp_t gfp)
331 {                                                 305 {
332         sector_t bs_mask = (bdev_logical_block    306         sector_t bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1;
333         unsigned int max_sectors = bdev_max_se    307         unsigned int max_sectors = bdev_max_secure_erase_sectors(bdev);
334         struct bio *bio = NULL;                   308         struct bio *bio = NULL;
335         struct blk_plug plug;                     309         struct blk_plug plug;
336         int ret = 0;                              310         int ret = 0;
337                                                   311 
338         /* make sure that "len << SECTOR_SHIFT    312         /* make sure that "len << SECTOR_SHIFT" doesn't overflow */
339         if (max_sectors > UINT_MAX >> SECTOR_S    313         if (max_sectors > UINT_MAX >> SECTOR_SHIFT)
340                 max_sectors = UINT_MAX >> SECT    314                 max_sectors = UINT_MAX >> SECTOR_SHIFT;
341         max_sectors &= ~bs_mask;                  315         max_sectors &= ~bs_mask;
342                                                   316 
343         if (max_sectors == 0)                     317         if (max_sectors == 0)
344                 return -EOPNOTSUPP;               318                 return -EOPNOTSUPP;
345         if ((sector | nr_sects) & bs_mask)        319         if ((sector | nr_sects) & bs_mask)
346                 return -EINVAL;                   320                 return -EINVAL;
347         if (bdev_read_only(bdev))                 321         if (bdev_read_only(bdev))
348                 return -EPERM;                    322                 return -EPERM;
349                                                   323 
350         blk_start_plug(&plug);                    324         blk_start_plug(&plug);
351         while (nr_sects) {                     !! 325         for (;;) {
352                 unsigned int len = min_t(secto    326                 unsigned int len = min_t(sector_t, nr_sects, max_sectors);
353                                                   327 
354                 bio = blk_next_bio(bio, bdev,     328                 bio = blk_next_bio(bio, bdev, 0, REQ_OP_SECURE_ERASE, gfp);
355                 bio->bi_iter.bi_sector = secto    329                 bio->bi_iter.bi_sector = sector;
356                 bio->bi_iter.bi_size = len <<     330                 bio->bi_iter.bi_size = len << SECTOR_SHIFT;
357                                                   331 
358                 sector += len;                    332                 sector += len;
359                 nr_sects -= len;                  333                 nr_sects -= len;
                                                   >> 334                 if (!nr_sects) {
                                                   >> 335                         ret = submit_bio_wait(bio);
                                                   >> 336                         bio_put(bio);
                                                   >> 337                         break;
                                                   >> 338                 }
360                 cond_resched();                   339                 cond_resched();
361         }                                      << 
362         if (bio) {                             << 
363                 ret = submit_bio_wait(bio);    << 
364                 bio_put(bio);                  << 
365         }                                         340         }
366         blk_finish_plug(&plug);                   341         blk_finish_plug(&plug);
367                                                   342 
368         return ret;                               343         return ret;
369 }                                                 344 }
370 EXPORT_SYMBOL(blkdev_issue_secure_erase);         345 EXPORT_SYMBOL(blkdev_issue_secure_erase);
371                                                   346 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php