/* Bring in the user pages that we will copy from _first_ lest *wehitanastydeadlockoncopyingfromthesamepageas *we'rewritingto,withoutitbeingmarkeduptodate. * *Notonlyisthisanoptimisation,butitisalsorequiredto *checkthattheaddressisactuallyvalid,whenatomic *usercopiesareusedbelow. * *WerelyonthepagebeingheldontolongenoughbytheLRU *thatwecangrabitbelowifthiscausesittoberead.
*/
ret = -EFAULT; if (unlikely(fault_in_iov_iter_readable(iter, part) == part)) break;
folio = netfs_grab_folio_for_write(mapping, pos, part); if (IS_ERR(folio)) {
ret = PTR_ERR(folio); break;
}
/* Wait for writeback to complete. The writeback engine owns *theinfoinfolio->privateandmaychangeituntilit *removestheWBmark.
*/ if (folio_get_private(folio) &&
folio_wait_writeback_killable(folio)) {
ret = written ? -EINTR : -ERESTARTSYS; goto error_folio_unlock;
}
if (signal_pending(current)) {
ret = written ? -EINTR : -ERESTARTSYS; goto error_folio_unlock;
}
/* Decide how we should modify a folio. We might be attempting *todowrite-streaming,inwhichcasewedon'twanttoa *localRMWcycleifwecanavoidit.Ifwe'redoinglocal *cachingorcontentcrypto,weawardthatpriorityover *avoidingRMW.Ifthefileisopenreadably,thenwealso *assumethatwemaywanttoreadwhatwewrote.
*/
finfo = netfs_folio_info(folio);
group = netfs_folio_group(folio);
if (unlikely(group != netfs_group) &&
group != NETFS_FOLIO_COPY_TO_CACHE) goto flush_content;
if (folio_test_uptodate(folio)) { if (mapping_writably_mapped(mapping))
flush_dcache_folio(folio);
copied = copy_folio_from_iter_atomic(folio, offset, part, iter); if (unlikely(copied == 0)) goto copy_failed;
netfs_set_group(folio, netfs_group);
trace_netfs_folio(folio, netfs_folio_is_uptodate); goto copied;
}
/* If the page is above the zero-point then we assume that the *serverwouldjustreturnablockofzerosorashortreadif *wetrytoreadit.
*/ if (fpos >= ctx->zero_point) {
folio_zero_segment(folio, 0, offset);
copied = copy_folio_from_iter_atomic(folio, offset, part, iter); if (unlikely(copied == 0)) goto copy_failed;
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); goto copied;
}
/* See if we can write a whole folio in one go. */ if (!maybe_trouble && offset == 0 && part >= flen) {
copied = copy_folio_from_iter_atomic(folio, offset, part, iter); if (unlikely(copied == 0)) goto copy_failed; if (unlikely(copied < part)) {
maybe_trouble = true;
iov_iter_revert(iter, copied);
copied = 0;
folio_unlock(folio); goto retry;
}
__netfs_set_group(folio, netfs_group);
folio_mark_uptodate(folio);
trace_netfs_folio(folio, netfs_whole_folio_modify); goto copied;
}
/* We don't want to do a streaming write on a file that loses *cachingservicetemporarilybecausethebackingstoregot *culledandwedon'treallywanttogetastreamingwriteon *afilethat'sopenforreadingas->read_folio()thenhasto *beabletoflushit.
*/ if ((file->f_mode & FMODE_READ) ||
netfs_is_cache_enabled(ctx)) { if (finfo) {
netfs_stat(&netfs_n_wh_wstream_conflict); goto flush_content;
}
ret = netfs_prefetch_for_write(file, folio, offset, part); if (ret < 0) {
_debug("prefetch = %zd", ret); goto error_folio_unlock;
} /* Note that copy-to-cache may have been set. */
ret = balance_dirty_pages_ratelimited_flags(mapping, bdp_flags); if (unlikely(ret < 0)) break;
cond_resched();
} while (iov_iter_count(iter));
out: if (likely(written)) { /* Set indication that ctime and mtime got updated in case *closeisdeferred.
*/
set_bit(NETFS_ICTX_MODIFIED_ATTR, &ctx->flags); if (unlikely(ctx->ops->post_modify))
ctx->ops->post_modify(inode);
}
if (unlikely(wreq)) {
ret2 = netfs_end_writethrough(wreq, &wbc, writethrough);
wbc_detach_inode(&wbc); if (ret2 == -EIOCBQUEUED) return ret2; if (ret == 0 && ret2 < 0)
ret = ret2;
}
iocb->ki_pos += written;
_leave(" = %zd [%zd]", written, ret); return written ? written : ret;
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.