@@ -363,7 +363,7 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
363
363
void fuse_read_fill (struct fuse_req * req , struct file * file ,
364
364
struct inode * inode , loff_t pos , size_t count , int opcode )
365
365
{
366
- struct fuse_read_in * inarg = & req -> misc .read_in ;
366
+ struct fuse_read_in * inarg = & req -> misc .read . in ;
367
367
struct fuse_file * ff = file -> private_data ;
368
368
369
369
inarg -> fh = ff -> fh ;
@@ -389,7 +389,7 @@ static size_t fuse_send_read(struct fuse_req *req, struct file *file,
389
389
390
390
fuse_read_fill (req , file , inode , pos , count , FUSE_READ );
391
391
if (owner != NULL ) {
392
- struct fuse_read_in * inarg = & req -> misc .read_in ;
392
+ struct fuse_read_in * inarg = & req -> misc .read . in ;
393
393
394
394
inarg -> read_flags |= FUSE_READ_LOCKOWNER ;
395
395
inarg -> lock_owner = fuse_lock_owner_id (fc , owner );
@@ -398,11 +398,29 @@ static size_t fuse_send_read(struct fuse_req *req, struct file *file,
398
398
return req -> out .args [0 ].size ;
399
399
}
400
400
401
+ static void fuse_read_update_size (struct inode * inode , loff_t size ,
402
+ u64 attr_ver )
403
+ {
404
+ struct fuse_conn * fc = get_fuse_conn (inode );
405
+ struct fuse_inode * fi = get_fuse_inode (inode );
406
+
407
+ spin_lock (& fc -> lock );
408
+ if (attr_ver == fi -> attr_version && size < inode -> i_size ) {
409
+ fi -> attr_version = ++ fc -> attr_version ;
410
+ i_size_write (inode , size );
411
+ }
412
+ spin_unlock (& fc -> lock );
413
+ }
414
+
401
415
static int fuse_readpage (struct file * file , struct page * page )
402
416
{
403
417
struct inode * inode = page -> mapping -> host ;
404
418
struct fuse_conn * fc = get_fuse_conn (inode );
405
419
struct fuse_req * req ;
420
+ size_t num_read ;
421
+ loff_t pos = page_offset (page );
422
+ size_t count = PAGE_CACHE_SIZE ;
423
+ u64 attr_ver ;
406
424
int err ;
407
425
408
426
err = - EIO ;
@@ -421,15 +439,25 @@ static int fuse_readpage(struct file *file, struct page *page)
421
439
if (IS_ERR (req ))
422
440
goto out ;
423
441
442
+ attr_ver = fuse_get_attr_version (fc );
443
+
424
444
req -> out .page_zeroing = 1 ;
425
445
req -> num_pages = 1 ;
426
446
req -> pages [0 ] = page ;
427
- fuse_send_read (req , file , inode , page_offset (page ), PAGE_CACHE_SIZE ,
428
- NULL );
447
+ num_read = fuse_send_read (req , file , inode , pos , count , NULL );
429
448
err = req -> out .h .error ;
430
449
fuse_put_request (fc , req );
431
- if (!err )
450
+
451
+ if (!err ) {
452
+ /*
453
+ * Short read means EOF. If file size is larger, truncate it
454
+ */
455
+ if (num_read < count )
456
+ fuse_read_update_size (inode , pos + num_read , attr_ver );
457
+
432
458
SetPageUptodate (page );
459
+ }
460
+
433
461
fuse_invalidate_attr (inode ); /* atime changed */
434
462
out :
435
463
unlock_page (page );
@@ -439,8 +467,19 @@ static int fuse_readpage(struct file *file, struct page *page)
439
467
static void fuse_readpages_end (struct fuse_conn * fc , struct fuse_req * req )
440
468
{
441
469
int i ;
470
+ size_t count = req -> misc .read .in .size ;
471
+ size_t num_read = req -> out .args [0 ].size ;
472
+ struct inode * inode = req -> pages [0 ]-> mapping -> host ;
442
473
443
- fuse_invalidate_attr (req -> pages [0 ]-> mapping -> host ); /* atime changed */
474
+ /*
475
+ * Short read means EOF. If file size is larger, truncate it
476
+ */
477
+ if (!req -> out .h .error && num_read < count ) {
478
+ loff_t pos = page_offset (req -> pages [0 ]) + num_read ;
479
+ fuse_read_update_size (inode , pos , req -> misc .read .attr_ver );
480
+ }
481
+
482
+ fuse_invalidate_attr (inode ); /* atime changed */
444
483
445
484
for (i = 0 ; i < req -> num_pages ; i ++ ) {
446
485
struct page * page = req -> pages [i ];
@@ -463,6 +502,7 @@ static void fuse_send_readpages(struct fuse_req *req, struct file *file,
463
502
size_t count = req -> num_pages << PAGE_CACHE_SHIFT ;
464
503
req -> out .page_zeroing = 1 ;
465
504
fuse_read_fill (req , file , inode , pos , count , FUSE_READ );
505
+ req -> misc .read .attr_ver = fuse_get_attr_version (fc );
466
506
if (fc -> async_read ) {
467
507
struct fuse_file * ff = file -> private_data ;
468
508
req -> ff = fuse_file_get (ff );
0 commit comments