@@ -546,7 +546,6 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
546
546
int written = 0 ;
547
547
int flags ;
548
548
int check_caps = 0 ;
549
- int page_align ;
550
549
int ret ;
551
550
struct timespec mtime = CURRENT_TIME ;
552
551
loff_t pos = iocb -> ki_pos ;
@@ -575,10 +574,9 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
575
574
iov_iter_init (& i , WRITE , iov , nr_segs , count );
576
575
577
576
while (iov_iter_count (& i ) > 0 ) {
578
- void __user * data = i .iov -> iov_base + i .iov_offset ;
579
- u64 len = i .iov -> iov_len - i .iov_offset ;
580
-
581
- page_align = (unsigned long )data & ~PAGE_MASK ;
577
+ u64 len = iov_iter_single_seg_count (& i );
578
+ size_t start ;
579
+ ssize_t n ;
582
580
583
581
snapc = ci -> i_snap_realm -> cached_context ;
584
582
vino = ceph_vino (inode );
@@ -594,20 +592,21 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
594
592
break ;
595
593
}
596
594
597
- num_pages = calc_pages_for ( page_align , len );
598
- pages = ceph_get_direct_page_vector ( data , num_pages , false);
599
- if ( IS_ERR ( pages )) {
600
- ret = PTR_ERR ( pages );
601
- goto out ;
595
+ n = iov_iter_get_pages_alloc ( & i , & pages , len , & start );
596
+ if ( unlikely ( n < 0 )) {
597
+ ret = n ;
598
+ ceph_osdc_put_request ( req );
599
+ break ;
602
600
}
603
601
602
+ num_pages = (n + start + PAGE_SIZE - 1 ) / PAGE_SIZE ;
604
603
/*
605
604
* throw out any page cache pages in this range. this
606
605
* may block.
607
606
*/
608
607
truncate_inode_pages_range (inode -> i_mapping , pos ,
609
- (pos + len ) | (PAGE_CACHE_SIZE - 1 ));
610
- osd_req_op_extent_osd_data_pages (req , 0 , pages , len , page_align ,
608
+ (pos + n ) | (PAGE_CACHE_SIZE - 1 ));
609
+ osd_req_op_extent_osd_data_pages (req , 0 , pages , n , start ,
611
610
false, false);
612
611
613
612
/* BUG_ON(vino.snap != CEPH_NOSNAP); */
@@ -619,22 +618,20 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
619
618
620
619
ceph_put_page_vector (pages , num_pages , false);
621
620
622
- out :
623
621
ceph_osdc_put_request (req );
624
- if (ret == 0 ) {
625
- pos += len ;
626
- written += len ;
627
- iov_iter_advance (& i , (size_t )len );
628
-
629
- if (pos > i_size_read (inode )) {
630
- check_caps = ceph_inode_set_size (inode , pos );
631
- if (check_caps )
632
- ceph_check_caps (ceph_inode (inode ),
633
- CHECK_CAPS_AUTHONLY ,
634
- NULL );
635
- }
636
- } else
622
+ if (ret )
637
623
break ;
624
+ pos += n ;
625
+ written += n ;
626
+ iov_iter_advance (& i , n );
627
+
628
+ if (pos > i_size_read (inode )) {
629
+ check_caps = ceph_inode_set_size (inode , pos );
630
+ if (check_caps )
631
+ ceph_check_caps (ceph_inode (inode ),
632
+ CHECK_CAPS_AUTHONLY ,
633
+ NULL );
634
+ }
638
635
}
639
636
640
637
if (ret != - EOLDSNAPC && written > 0 ) {
0 commit comments