// SPDX-License-Identifier: GPL-2.0-or-later /* * mmap.c * * Code to deal with the mess that is clustered mmap. * * Copyright (C) 2002, 2004 Oracle. All rights reserved.
*/
/* * There are cases that lead to the page no longer belonging to the * mapping. * 1) pagecache truncates locally due to memory pressure. * 2) pagecache truncates when another is taking EX lock against * inode lock. see ocfs2_data_convert_worker. * * The i_size check doesn't catch the case where nodes truncated and * then re-extended the file. We'll re-check the page mapping after * taking the page lock inside of ocfs2_write_begin_nolock(). * * Let VM retry with these cases.
*/ if ((folio->mapping != inode->i_mapping) ||
!folio_test_uptodate(folio) ||
(pos >= size)) goto out;
/* * Call ocfs2_write_begin() and ocfs2_write_end() to take * advantage of the allocation code there. We pass a write * length of the whole page (chopped to i_size) to make sure * the whole thing is allocated. * * Since we know the page is up to date, we don't have to * worry about ocfs2_write_begin() skipping some buffer reads * because the "write" would invalidate their data.
*/ if (folio->index == last_index)
len = ((size - 1) & ~PAGE_MASK) + 1;
err = ocfs2_write_begin_nolock(mapping, pos, len, OCFS2_WRITE_MMAP,
&locked_folio, &fsdata, di_bh, folio); if (err) { if (err != -ENOSPC)
mlog_errno(err);
ret = vmf_error(err); goto out;
}
if (!locked_folio) {
ret = VM_FAULT_NOPAGE; goto out;
}
err = ocfs2_write_end_nolock(mapping, pos, len, len, fsdata);
BUG_ON(err != len);
ret = VM_FAULT_LOCKED;
out: return ret;
}
/* * The cluster locks taken will block a truncate from another * node. Taking the data lock will also ensure that we don't * attempt page truncation as part of a downconvert.
*/
err = ocfs2_inode_lock(inode, &di_bh, 1); if (err < 0) {
mlog_errno(err);
ret = vmf_error(err); goto out;
}
/* * The alloc sem should be enough to serialize with * ocfs2_truncate_file() changing i_size as well as any thread * modifying the inode btree.
*/
down_write(&OCFS2_I(inode)->ip_alloc_sem);
ret = __ocfs2_page_mkwrite(vmf->vma->vm_file, di_bh, folio);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.