mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 20:51:44 +00:00
vfs-6.13.netfs
-----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCZzcUoQAKCRCRxhvAZXjc omxAAP9WE8zSxeu7Foa6+OmLO62mYdB8rRrQ4OjzX+zunL0UnAD9FAHPsB4amWm4 /zK3Nf7ipijop5+RgSJTgURffASKOgI= =ifkk -----END PGP SIGNATURE----- Merge tag 'vfs-6.13.netfs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull netfs updates from Christian Brauner: "Various fixes for the netfs library and related infrastructure: cachefiles: - Fix a dentry leak in cachefiles_open_file() - Fix incorrect length return value in cachefiles_ondemand_fd_write_iter() - Fix missing pos updates in cachefiles_ondemand_fd_write_iter() - Clean up in cachefiles_commit_tmpfile() - Fix NULL pointer dereference in object->file - Add a memory barrier for FSCACHE_VOLUME_CREATING netfs: - Remove call to folio_index() - Fix a few minor bugs in netfs_page_mkwrite() - Remove unnecessary references to pages" * tag 'vfs-6.13.netfs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: netfs/fscache: Add a memory barrier for FSCACHE_VOLUME_CREATING cachefiles: Fix NULL pointer dereference in object->file cachefiles: Clean up in cachefiles_commit_tmpfile() cachefiles: Fix missing pos updates in cachefiles_ondemand_fd_write_iter() cachefiles: Fix incorrect length return value in cachefiles_ondemand_fd_write_iter() netfs: Remove unnecessary references to pages netfs: Fix a few minor bugs in netfs_page_mkwrite() netfs: Remove call to folio_index()
This commit is contained in:
commit
8dcf44fcad
@ -327,6 +327,8 @@ static void cachefiles_commit_object(struct cachefiles_object *object,
|
||||
static void cachefiles_clean_up_object(struct cachefiles_object *object,
|
||||
struct cachefiles_cache *cache)
|
||||
{
|
||||
struct file *file;
|
||||
|
||||
if (test_bit(FSCACHE_COOKIE_RETIRED, &object->cookie->flags)) {
|
||||
if (!test_bit(CACHEFILES_OBJECT_USING_TMPFILE, &object->flags)) {
|
||||
cachefiles_see_object(object, cachefiles_obj_see_clean_delete);
|
||||
@ -342,10 +344,14 @@ static void cachefiles_clean_up_object(struct cachefiles_object *object,
|
||||
}
|
||||
|
||||
cachefiles_unmark_inode_in_use(object, object->file);
|
||||
if (object->file) {
|
||||
fput(object->file);
|
||||
object->file = NULL;
|
||||
}
|
||||
|
||||
spin_lock(&object->lock);
|
||||
file = object->file;
|
||||
object->file = NULL;
|
||||
spin_unlock(&object->lock);
|
||||
|
||||
if (file)
|
||||
fput(file);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -691,11 +691,6 @@ bool cachefiles_commit_tmpfile(struct cachefiles_cache *cache,
|
||||
}
|
||||
|
||||
if (!d_is_negative(dentry)) {
|
||||
if (d_backing_inode(dentry) == file_inode(object->file)) {
|
||||
success = true;
|
||||
goto out_dput;
|
||||
}
|
||||
|
||||
ret = cachefiles_unlink(volume->cache, object, fan, dentry,
|
||||
FSCACHE_OBJECT_IS_STALE);
|
||||
if (ret < 0)
|
||||
|
@ -60,26 +60,36 @@ static ssize_t cachefiles_ondemand_fd_write_iter(struct kiocb *kiocb,
|
||||
{
|
||||
struct cachefiles_object *object = kiocb->ki_filp->private_data;
|
||||
struct cachefiles_cache *cache = object->volume->cache;
|
||||
struct file *file = object->file;
|
||||
size_t len = iter->count;
|
||||
struct file *file;
|
||||
size_t len = iter->count, aligned_len = len;
|
||||
loff_t pos = kiocb->ki_pos;
|
||||
const struct cred *saved_cred;
|
||||
int ret;
|
||||
|
||||
if (!file)
|
||||
spin_lock(&object->lock);
|
||||
file = object->file;
|
||||
if (!file) {
|
||||
spin_unlock(&object->lock);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
get_file(file);
|
||||
spin_unlock(&object->lock);
|
||||
|
||||
cachefiles_begin_secure(cache, &saved_cred);
|
||||
ret = __cachefiles_prepare_write(object, file, &pos, &len, len, true);
|
||||
ret = __cachefiles_prepare_write(object, file, &pos, &aligned_len, len, true);
|
||||
cachefiles_end_secure(cache, saved_cred);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
trace_cachefiles_ondemand_fd_write(object, file_inode(file), pos, len);
|
||||
ret = __cachefiles_write(object, file, pos, iter, NULL, NULL);
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
ret = len;
|
||||
kiocb->ki_pos += ret;
|
||||
}
|
||||
|
||||
out:
|
||||
fput(file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -87,12 +97,22 @@ static loff_t cachefiles_ondemand_fd_llseek(struct file *filp, loff_t pos,
|
||||
int whence)
|
||||
{
|
||||
struct cachefiles_object *object = filp->private_data;
|
||||
struct file *file = object->file;
|
||||
struct file *file;
|
||||
loff_t ret;
|
||||
|
||||
if (!file)
|
||||
spin_lock(&object->lock);
|
||||
file = object->file;
|
||||
if (!file) {
|
||||
spin_unlock(&object->lock);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
get_file(file);
|
||||
spin_unlock(&object->lock);
|
||||
|
||||
return vfs_llseek(file, pos, whence);
|
||||
ret = vfs_llseek(file, pos, whence);
|
||||
fput(file);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl,
|
||||
|
@ -627,7 +627,7 @@ static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len,
|
||||
if (unlikely(always_fill)) {
|
||||
if (pos - offset + len <= i_size)
|
||||
return false; /* Page entirely before EOF */
|
||||
zero_user_segment(&folio->page, 0, plen);
|
||||
folio_zero_segment(folio, 0, plen);
|
||||
folio_mark_uptodate(folio);
|
||||
return true;
|
||||
}
|
||||
@ -646,7 +646,7 @@ static bool netfs_skip_folio_read(struct folio *folio, loff_t pos, size_t len,
|
||||
|
||||
return false;
|
||||
zero_out:
|
||||
zero_user_segments(&folio->page, 0, offset, offset + len, plen);
|
||||
folio_zero_segments(folio, 0, offset, offset + len, plen);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -713,7 +713,7 @@ retry:
|
||||
if (folio_test_uptodate(folio))
|
||||
goto have_folio;
|
||||
|
||||
/* If the page is beyond the EOF, we want to clear it - unless it's
|
||||
/* If the folio is beyond the EOF, we want to clear it - unless it's
|
||||
* within the cache granule containing the EOF, in which case we need
|
||||
* to preload the granule.
|
||||
*/
|
||||
@ -773,7 +773,7 @@ error:
|
||||
EXPORT_SYMBOL(netfs_write_begin);
|
||||
|
||||
/*
|
||||
* Preload the data into a page we're proposing to write into.
|
||||
* Preload the data into a folio we're proposing to write into.
|
||||
*/
|
||||
int netfs_prefetch_for_write(struct file *file, struct folio *folio,
|
||||
size_t offset, size_t len)
|
||||
|
@ -83,13 +83,13 @@ static void netfs_update_i_size(struct netfs_inode *ctx, struct inode *inode,
|
||||
* netfs_perform_write - Copy data into the pagecache.
|
||||
* @iocb: The operation parameters
|
||||
* @iter: The source buffer
|
||||
* @netfs_group: Grouping for dirty pages (eg. ceph snaps).
|
||||
* @netfs_group: Grouping for dirty folios (eg. ceph snaps).
|
||||
*
|
||||
* Copy data into pagecache pages attached to the inode specified by @iocb.
|
||||
* Copy data into pagecache folios attached to the inode specified by @iocb.
|
||||
* The caller must hold appropriate inode locks.
|
||||
*
|
||||
* Dirty pages are tagged with a netfs_folio struct if they're not up to date
|
||||
* to indicate the range modified. Dirty pages may also be tagged with a
|
||||
* Dirty folios are tagged with a netfs_folio struct if they're not up to date
|
||||
* to indicate the range modified. Dirty folios may also be tagged with a
|
||||
* netfs-specific grouping such that data from an old group gets flushed before
|
||||
* a new one is started.
|
||||
*/
|
||||
@ -223,11 +223,11 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
|
||||
* we try to read it.
|
||||
*/
|
||||
if (fpos >= ctx->zero_point) {
|
||||
zero_user_segment(&folio->page, 0, offset);
|
||||
folio_zero_segment(folio, 0, offset);
|
||||
copied = copy_folio_from_iter_atomic(folio, offset, part, iter);
|
||||
if (unlikely(copied == 0))
|
||||
goto copy_failed;
|
||||
zero_user_segment(&folio->page, offset + copied, flen);
|
||||
folio_zero_segment(folio, offset + copied, flen);
|
||||
__netfs_set_group(folio, netfs_group);
|
||||
folio_mark_uptodate(folio);
|
||||
trace_netfs_folio(folio, netfs_modify_and_clear);
|
||||
@ -407,7 +407,7 @@ EXPORT_SYMBOL(netfs_perform_write);
|
||||
* netfs_buffered_write_iter_locked - write data to a file
|
||||
* @iocb: IO state structure (file, offset, etc.)
|
||||
* @from: iov_iter with data to write
|
||||
* @netfs_group: Grouping for dirty pages (eg. ceph snaps).
|
||||
* @netfs_group: Grouping for dirty folios (eg. ceph snaps).
|
||||
*
|
||||
* This function does all the work needed for actually writing data to a
|
||||
* file. It does all basic checks, removes SUID from the file, updates
|
||||
@ -491,7 +491,9 @@ EXPORT_SYMBOL(netfs_file_write_iter);
|
||||
|
||||
/*
|
||||
* Notification that a previously read-only page is about to become writable.
|
||||
* Note that the caller indicates a single page of a multipage folio.
|
||||
* The caller indicates the precise page that needs to be written to, but
|
||||
* we only track group on a per-folio basis, so we block more often than
|
||||
* we might otherwise.
|
||||
*/
|
||||
vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_group)
|
||||
{
|
||||
@ -501,7 +503,7 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr
|
||||
struct address_space *mapping = file->f_mapping;
|
||||
struct inode *inode = file_inode(file);
|
||||
struct netfs_inode *ictx = netfs_inode(inode);
|
||||
vm_fault_t ret = VM_FAULT_RETRY;
|
||||
vm_fault_t ret = VM_FAULT_NOPAGE;
|
||||
int err;
|
||||
|
||||
_enter("%lx", folio->index);
|
||||
@ -510,21 +512,15 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr
|
||||
|
||||
if (folio_lock_killable(folio) < 0)
|
||||
goto out;
|
||||
if (folio->mapping != mapping) {
|
||||
folio_unlock(folio);
|
||||
ret = VM_FAULT_NOPAGE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (folio_wait_writeback_killable(folio)) {
|
||||
ret = VM_FAULT_LOCKED;
|
||||
goto out;
|
||||
}
|
||||
if (folio->mapping != mapping)
|
||||
goto unlock;
|
||||
if (folio_wait_writeback_killable(folio) < 0)
|
||||
goto unlock;
|
||||
|
||||
/* Can we see a streaming write here? */
|
||||
if (WARN_ON(!folio_test_uptodate(folio))) {
|
||||
ret = VM_FAULT_SIGBUS | VM_FAULT_LOCKED;
|
||||
goto out;
|
||||
ret = VM_FAULT_SIGBUS;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
group = netfs_folio_group(folio);
|
||||
@ -559,5 +555,8 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr
|
||||
out:
|
||||
sb_end_pagefault(inode->i_sb);
|
||||
return ret;
|
||||
unlock:
|
||||
folio_unlock(folio);
|
||||
goto out;
|
||||
}
|
||||
EXPORT_SYMBOL(netfs_page_mkwrite);
|
||||
|
@ -322,8 +322,7 @@ maybe_wait:
|
||||
}
|
||||
return;
|
||||
no_wait:
|
||||
clear_bit_unlock(FSCACHE_VOLUME_CREATING, &volume->flags);
|
||||
wake_up_bit(&volume->flags, FSCACHE_VOLUME_CREATING);
|
||||
clear_and_wake_up_bit(FSCACHE_VOLUME_CREATING, &volume->flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -450,7 +450,7 @@ TRACE_EVENT(netfs_folio,
|
||||
struct address_space *__m = READ_ONCE(folio->mapping);
|
||||
__entry->ino = __m ? __m->host->i_ino : 0;
|
||||
__entry->why = why;
|
||||
__entry->index = folio_index(folio);
|
||||
__entry->index = folio->index;
|
||||
__entry->nr = folio_nr_pages(folio);
|
||||
),
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user