Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
netfs: Perform content encryption
When dealing with an encrypted file, we gather together sufficient pages from the pagecache to constitute a logical crypto block, allocate a bounce buffer and then ask the filesystem to encrypt between the buffers. The bounce buffer is then passed to the filesystem to upload. The network filesystem must set a flag to indicate what service is desired and when the logical blocksize will be. The netfs library iterates through each block to be processed, providing a pair of scatterlists to describe the start and end buffers. Note that it should be possible in future to encrypt DIO writes also by this same mechanism. A mock-up block-encryption function for afs is included for illustration. Signed-off-by: David Howells <dhowells@redhat.com>
- Loading branch information
Showing
11 changed files
with
238 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| # SPDX-License-Identifier: GPL-2.0 | ||
|
|
||
| netfs-y := \ | ||
| crypto.o \ | ||
| direct.o \ | ||
| flush.o \ | ||
| main.o \ | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-only | ||
| /* Network filesystem content encryption support. | ||
| * | ||
| * Copyright (C) 2022 Red Hat, Inc. All Rights Reserved. | ||
| * Written by David Howells (dhowells@redhat.com) | ||
| */ | ||
|
|
||
| #include <linux/fs.h> | ||
| #include <linux/mm.h> | ||
| #include <linux/pagemap.h> | ||
| #include <linux/slab.h> | ||
| #include <linux/scatterlist.h> | ||
| #include "internal.h" | ||
|
|
||
| /* | ||
| * Allocate a bunch of pages and add them into the xarray buffer starting at | ||
| * the given index. | ||
| */ | ||
| static int netfs_alloc_buffer(struct xarray *xa, pgoff_t index, unsigned int nr_pages) | ||
| { | ||
| struct page *page; | ||
| unsigned int n; | ||
| int ret; | ||
| LIST_HEAD(list); | ||
|
|
||
| n = alloc_pages_bulk_list(GFP_NOIO, nr_pages, &list); | ||
| if (n < nr_pages) { | ||
| ret = -ENOMEM; | ||
| } | ||
|
|
||
| while ((page = list_first_entry_or_null(&list, struct page, lru))) { | ||
| list_del(&page->lru); | ||
| page->index = index; | ||
| ret = xa_insert(xa, index++, page, GFP_NOIO); | ||
| if (ret < 0) | ||
| break; | ||
| } | ||
|
|
||
| while ((page = list_first_entry_or_null(&list, struct page, lru))) { | ||
| list_del(&page->lru); | ||
| __free_page(page); | ||
| } | ||
| return ret; | ||
| } | ||
|
|
||
| /* | ||
| * Populate a scatterlist from folios in an xarray. | ||
| */ | ||
| static int netfs_xarray_to_sglist(struct xarray *xa, loff_t pos, size_t len, | ||
| struct scatterlist *sg, unsigned int n_sg) | ||
| { | ||
| struct scatterlist *p = sg; | ||
| struct folio *folio = NULL; | ||
| size_t seg, offset, skip = 0; | ||
| loff_t start = pos; | ||
| pgoff_t index = start >> PAGE_SHIFT; | ||
| int j; | ||
|
|
||
| XA_STATE(xas, xa, index); | ||
|
|
||
| sg_init_table(sg, n_sg); | ||
|
|
||
| rcu_read_lock(); | ||
|
|
||
| xas_for_each(&xas, folio, ULONG_MAX) { | ||
| if (xas_retry(&xas, folio)) | ||
| continue; | ||
| if (WARN_ON(xa_is_value(folio)) || WARN_ON(folio_test_hugetlb(folio))) | ||
| break; | ||
| for (j = (folio_index(folio) < index) ? index - folio_index(folio) : 0; | ||
| j < folio_nr_pages(folio); j++ | ||
| ) { | ||
| struct page *subpage = folio_file_page(folio, j); | ||
|
|
||
| offset = (pos + skip) & ~PAGE_MASK; | ||
| seg = min(len, PAGE_SIZE - offset); | ||
|
|
||
| sg_set_page(p++, subpage, seg, offset); | ||
|
|
||
| len -= seg; | ||
| skip += seg; | ||
| if (len == 0) | ||
| break; | ||
| } | ||
| if (len == 0) | ||
| break; | ||
| } | ||
|
|
||
| rcu_read_unlock(); | ||
| if (len > 0) { | ||
| kdebug("*** Insufficient source (%zx)", len); | ||
| //WARN_ON(len > 0); | ||
| return -EIO; | ||
| } | ||
|
|
||
| sg_mark_end(p - 1); | ||
| return p - sg; | ||
| } | ||
|
|
||
| /* | ||
| * Prepare a write request for writing. We encrypt from wback->buffer to | ||
| * wback->buffer2. | ||
| */ | ||
| bool netfs_wback_encrypt(struct netfs_writeback *wback) | ||
| { | ||
| struct netfs_i_context *ctx = netfs_i_context(wback->inode); | ||
| struct scatterlist source_sg[16], dest_sg[16]; | ||
| unsigned int n_source, n_dest; | ||
| size_t n, chunk, bsize = 1UL << ctx->crypto_bshift; | ||
| loff_t pos; | ||
| int ret; | ||
|
|
||
| _enter(""); | ||
|
|
||
| ret = netfs_alloc_buffer(&wback->buffer2, wback->first, | ||
| wback->last - wback->first + 1); | ||
| if (ret < 0) | ||
| goto error; | ||
|
|
||
| pos = wback->first * PAGE_SIZE; | ||
| n = (wback->last - wback->first + 1) * PAGE_SIZE; | ||
| _debug("ENCRYPT %llx-%llx", pos, pos + n - 1); | ||
|
|
||
| for (; n > 0; n -= chunk, pos += chunk) { | ||
| chunk = min(n, bsize); | ||
| ret = netfs_xarray_to_sglist(&wback->buffer, pos, chunk, | ||
| source_sg, ARRAY_SIZE(source_sg)); | ||
| if (ret < 0) | ||
| goto error; | ||
| n_source = ret; | ||
|
|
||
| ret = netfs_xarray_to_sglist(&wback->buffer2, pos, chunk, | ||
| dest_sg, ARRAY_SIZE(dest_sg)); | ||
| if (ret < 0) | ||
| goto error; | ||
| n_dest = ret; | ||
|
|
||
| ret = ctx->ops->encrypt_block(wback, pos, chunk, | ||
| source_sg, n_source, dest_sg, n_dest); | ||
| if (ret < 0) | ||
| goto error; | ||
| } | ||
|
|
||
| __set_bit(NETFS_WBACK_BUFFERED, &wback->flags); | ||
| return true; | ||
|
|
||
| error: | ||
| wback->error = ret; | ||
| return false; | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters