@@ -333,3 +333,86 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
333
333
goto out ;
334
334
}
335
335
EXPORT_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