@@ -333,3 +333,86 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
333333 goto out ;
334334}
335335EXPORT_SYMBOL (netfs_perform_write );
336+
337+ /**
338+ * netfs_buffered_write_iter_locked - write data to a file
339+ * @iocb: IO state structure (file, offset, etc.)
340+ * @from: iov_iter with data to write
341+ * @netfs_group: Grouping for dirty pages (eg. ceph snaps).
342+ *
343+ * This function does all the work needed for actually writing data to a
344+ * file. It does all basic checks, removes SUID from the file, updates
345+ * modification times and calls proper subroutines depending on whether we
346+ * do direct IO or a standard buffered write.
347+ *
348+ * The caller must hold appropriate locks around this function and have called
349+ * generic_write_checks() already. The caller is also responsible for doing
350+ * any necessary syncing afterwards.
351+ *
352+ * This function does *not* take care of syncing data in case of O_SYNC write.
353+ * A caller has to handle it. This is mainly due to the fact that we want to
354+ * avoid syncing under i_rwsem.
355+ *
356+ * Return:
357+ * * number of bytes written, even for truncated writes
358+ * * negative error code if no data has been written at all
359+ */
360+ ssize_t netfs_buffered_write_iter_locked (struct kiocb * iocb , struct iov_iter * from ,
361+ struct netfs_group * netfs_group )
362+ {
363+ struct file * file = iocb -> ki_filp ;
364+ ssize_t ret ;
365+
366+ trace_netfs_write_iter (iocb , from );
367+
368+ ret = file_remove_privs (file );
369+ if (ret )
370+ return ret ;
371+
372+ ret = file_update_time (file );
373+ if (ret )
374+ return ret ;
375+
376+ return netfs_perform_write (iocb , from , netfs_group );
377+ }
378+ EXPORT_SYMBOL (netfs_buffered_write_iter_locked );
379+
380+ /**
381+ * netfs_file_write_iter - write data to a file
382+ * @iocb: IO state structure
383+ * @from: iov_iter with data to write
384+ *
385+ * Perform a write to a file, writing into the pagecache if possible and doing
386+ * an unbuffered write instead if not.
387+ *
388+ * Return:
389+ * * Negative error code if no data has been written at all of
390+ * vfs_fsync_range() failed for a synchronous write
391+ * * Number of bytes written, even for truncated writes
392+ */
393+ ssize_t netfs_file_write_iter (struct kiocb * iocb , struct iov_iter * from )
394+ {
395+ struct file * file = iocb -> ki_filp ;
396+ struct inode * inode = file -> f_mapping -> host ;
397+ struct netfs_inode * ictx = netfs_inode (inode );
398+ ssize_t ret ;
399+
400+ _enter ("%llx,%zx,%llx" , iocb -> ki_pos , iov_iter_count (from ), i_size_read (inode ));
401+
402+ if ((iocb -> ki_flags & IOCB_DIRECT ) ||
403+ test_bit (NETFS_ICTX_UNBUFFERED , & ictx -> flags ))
404+ return netfs_unbuffered_write_iter (iocb , from );
405+
406+ ret = netfs_start_io_write (inode );
407+ if (ret < 0 )
408+ return ret ;
409+
410+ ret = generic_write_checks (iocb , from );
411+ if (ret > 0 )
412+ ret = netfs_buffered_write_iter_locked (iocb , from , NULL );
413+ netfs_end_io_write (inode );
414+ if (ret > 0 )
415+ ret = generic_write_sync (iocb , ret );
416+ return ret ;
417+ }
418+ EXPORT_SYMBOL (netfs_file_write_iter );
0 commit comments