@@ -41,51 +41,101 @@ void fscrypt_decrypt_bio(struct bio *bio)
41
41
}
42
42
EXPORT_SYMBOL (fscrypt_decrypt_bio );
43
43
44
+ /**
45
+ * fscrypt_zeroout_range() - zero out a range of blocks in an encrypted file
46
+ * @inode: the file's inode
47
+ * @lblk: the first file logical block to zero out
48
+ * @pblk: the first filesystem physical block to zero out
49
+ * @len: number of blocks to zero out
50
+ *
51
+ * Zero out filesystem blocks in an encrypted regular file on-disk, i.e. write
52
+ * ciphertext blocks which decrypt to the all-zeroes block. The blocks must be
53
+ * both logically and physically contiguous. It's also assumed that the
54
+ * filesystem only uses a single block device, ->s_bdev.
55
+ *
56
+ * Note that since each block uses a different IV, this involves writing a
57
+ * different ciphertext to each block; we can't simply reuse the same one.
58
+ *
59
+ * Return: 0 on success; -errno on failure.
60
+ */
44
61
int fscrypt_zeroout_range (const struct inode * inode , pgoff_t lblk ,
45
- sector_t pblk , unsigned int len )
62
+ sector_t pblk , unsigned int len )
46
63
{
47
64
const unsigned int blockbits = inode -> i_blkbits ;
48
65
const unsigned int blocksize = 1 << blockbits ;
49
- struct page * ciphertext_page ;
66
+ const unsigned int blocks_per_page_bits = PAGE_SHIFT - blockbits ;
67
+ const unsigned int blocks_per_page = 1 << blocks_per_page_bits ;
68
+ struct page * pages [16 ]; /* write up to 16 pages at a time */
69
+ unsigned int nr_pages ;
70
+ unsigned int i ;
71
+ unsigned int offset ;
50
72
struct bio * bio ;
51
- int ret , err = 0 ;
73
+ int ret , err ;
52
74
53
- ciphertext_page = fscrypt_alloc_bounce_page (GFP_NOWAIT );
54
- if (!ciphertext_page )
55
- return - ENOMEM ;
75
+ if (len == 0 )
76
+ return 0 ;
56
77
57
- while (len -- ) {
58
- err = fscrypt_crypt_block (inode , FS_ENCRYPT , lblk ,
59
- ZERO_PAGE (0 ), ciphertext_page ,
60
- blocksize , 0 , GFP_NOFS );
61
- if (err )
62
- goto errout ;
78
+ BUILD_BUG_ON (ARRAY_SIZE (pages ) > BIO_MAX_PAGES );
79
+ nr_pages = min_t (unsigned int , ARRAY_SIZE (pages ),
80
+ (len + blocks_per_page - 1 ) >> blocks_per_page_bits );
63
81
64
- bio = bio_alloc (GFP_NOWAIT , 1 );
65
- if (!bio ) {
66
- err = - ENOMEM ;
67
- goto errout ;
68
- }
82
+ /*
83
+ * We need at least one page for ciphertext. Allocate the first one
84
+ * from a mempool, with __GFP_DIRECT_RECLAIM set so that it can't fail.
85
+ *
86
+ * Any additional page allocations are allowed to fail, as they only
87
+ * help performance, and waiting on the mempool for them could deadlock.
88
+ */
89
+ for (i = 0 ; i < nr_pages ; i ++ ) {
90
+ pages [i ] = fscrypt_alloc_bounce_page (i == 0 ? GFP_NOFS :
91
+ GFP_NOWAIT | __GFP_NOWARN );
92
+ if (!pages [i ])
93
+ break ;
94
+ }
95
+ nr_pages = i ;
96
+ if (WARN_ON (nr_pages <= 0 ))
97
+ return - EINVAL ;
98
+
99
+ /* This always succeeds since __GFP_DIRECT_RECLAIM is set. */
100
+ bio = bio_alloc (GFP_NOFS , nr_pages );
101
+
102
+ do {
69
103
bio_set_dev (bio , inode -> i_sb -> s_bdev );
70
104
bio -> bi_iter .bi_sector = pblk << (blockbits - 9 );
71
105
bio_set_op_attrs (bio , REQ_OP_WRITE , 0 );
72
- ret = bio_add_page (bio , ciphertext_page , blocksize , 0 );
73
- if (WARN_ON (ret != blocksize )) {
74
- /* should never happen! */
75
- bio_put (bio );
76
- err = - EIO ;
77
- goto errout ;
78
- }
106
+
107
+ i = 0 ;
108
+ offset = 0 ;
109
+ do {
110
+ err = fscrypt_crypt_block (inode , FS_ENCRYPT , lblk ,
111
+ ZERO_PAGE (0 ), pages [i ],
112
+ blocksize , offset , GFP_NOFS );
113
+ if (err )
114
+ goto out ;
115
+ lblk ++ ;
116
+ pblk ++ ;
117
+ len -- ;
118
+ offset += blocksize ;
119
+ if (offset == PAGE_SIZE || len == 0 ) {
120
+ ret = bio_add_page (bio , pages [i ++ ], offset , 0 );
121
+ if (WARN_ON (ret != offset )) {
122
+ err = - EIO ;
123
+ goto out ;
124
+ }
125
+ offset = 0 ;
126
+ }
127
+ } while (i != nr_pages && len != 0 );
128
+
79
129
err = submit_bio_wait (bio );
80
- bio_put (bio );
81
130
if (err )
82
- goto errout ;
83
- lblk ++ ;
84
- pblk ++ ;
85
- }
131
+ goto out ;
132
+ bio_reset (bio );
133
+ } while (len != 0 );
86
134
err = 0 ;
87
- errout :
88
- fscrypt_free_bounce_page (ciphertext_page );
135
+ out :
136
+ bio_put (bio );
137
+ for (i = 0 ; i < nr_pages ; i ++ )
138
+ fscrypt_free_bounce_page (pages [i ]);
89
139
return err ;
90
140
}
91
141
EXPORT_SYMBOL (fscrypt_zeroout_range );
0 commit comments