@@ -2632,43 +2632,56 @@ cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
2632
2632
struct TCP_Server_Info * server =
2633
2633
tlink_tcon (wdata -> cfile -> tlink )-> ses -> server ;
2634
2634
2635
- /*
2636
- * Wait for credits to resend this wdata.
2637
- * Note: we are attempting to resend the whole wdata not in segments
2638
- */
2639
2635
do {
2640
- rc = server -> ops -> wait_mtu_credits (server , wdata -> bytes , & wsize ,
2641
- & credits );
2636
+ if (wdata -> cfile -> invalidHandle ) {
2637
+ rc = cifs_reopen_file (wdata -> cfile , false);
2638
+ if (rc == - EAGAIN )
2639
+ continue ;
2640
+ else if (rc )
2641
+ break ;
2642
+ }
2642
2643
2643
- if (rc )
2644
- goto out ;
2645
2644
2646
- if (wsize < wdata -> bytes ) {
2647
- add_credits_and_wake_if (server , & credits , 0 );
2648
- msleep (1000 );
2649
- }
2650
- } while (wsize < wdata -> bytes );
2645
+ /*
2646
+ * Wait for credits to resend this wdata.
2647
+ * Note: we are attempting to resend the whole wdata not in
2648
+ * segments
2649
+ */
2650
+ do {
2651
+ rc = server -> ops -> wait_mtu_credits (server , wdata -> bytes ,
2652
+ & wsize , & credits );
2653
+ if (rc )
2654
+ goto fail ;
2655
+
2656
+ if (wsize < wdata -> bytes ) {
2657
+ add_credits_and_wake_if (server , & credits , 0 );
2658
+ msleep (1000 );
2659
+ }
2660
+ } while (wsize < wdata -> bytes );
2661
+ wdata -> credits = credits ;
2651
2662
2652
- wdata -> credits = credits ;
2653
- rc = - EAGAIN ;
2654
- while (rc == - EAGAIN ) {
2655
- rc = 0 ;
2656
- if (wdata -> cfile -> invalidHandle )
2657
- rc = cifs_reopen_file (wdata -> cfile , false);
2658
- if (!rc )
2659
- rc = server -> ops -> async_writev (wdata ,
2663
+ rc = adjust_credits (server , & wdata -> credits , wdata -> bytes );
2664
+
2665
+ if (!rc ) {
2666
+ if (wdata -> cfile -> invalidHandle )
2667
+ rc = - EAGAIN ;
2668
+ else
2669
+ rc = server -> ops -> async_writev (wdata ,
2660
2670
cifs_uncached_writedata_release );
2661
- }
2671
+ }
2662
2672
2663
- if (!rc ) {
2664
- list_add_tail (& wdata -> list , wdata_list );
2665
- return 0 ;
2666
- }
2673
+ /* If the write was successfully sent, we are done */
2674
+ if (!rc ) {
2675
+ list_add_tail (& wdata -> list , wdata_list );
2676
+ return 0 ;
2677
+ }
2667
2678
2668
- add_credits_and_wake_if ( server , & wdata -> credits , 0 );
2669
- out :
2670
- kref_put ( & wdata -> refcount , cifs_uncached_writedata_release );
2679
+ /* Roll back credits and retry if needed */
2680
+ add_credits_and_wake_if ( server , & wdata -> credits , 0 );
2681
+ } while ( rc == - EAGAIN );
2671
2682
2683
+ fail :
2684
+ kref_put (& wdata -> refcount , cifs_uncached_writedata_release );
2672
2685
return rc ;
2673
2686
}
2674
2687
@@ -2896,12 +2909,12 @@ static void collect_uncached_write_data(struct cifs_aio_ctx *ctx)
2896
2909
wdata -> bytes , & tmp_from ,
2897
2910
ctx -> cfile , cifs_sb , & tmp_list ,
2898
2911
ctx );
2912
+
2913
+ kref_put (& wdata -> refcount ,
2914
+ cifs_uncached_writedata_release );
2899
2915
}
2900
2916
2901
2917
list_splice (& tmp_list , & ctx -> list );
2902
-
2903
- kref_put (& wdata -> refcount ,
2904
- cifs_uncached_writedata_release );
2905
2918
goto restart_loop ;
2906
2919
}
2907
2920
}
@@ -3348,44 +3361,55 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata,
3348
3361
struct TCP_Server_Info * server =
3349
3362
tlink_tcon (rdata -> cfile -> tlink )-> ses -> server ;
3350
3363
3351
- /*
3352
- * Wait for credits to resend this rdata.
3353
- * Note: we are attempting to resend the whole rdata not in segments
3354
- */
3355
3364
do {
3356
- rc = server -> ops -> wait_mtu_credits (server , rdata -> bytes ,
3365
+ if (rdata -> cfile -> invalidHandle ) {
3366
+ rc = cifs_reopen_file (rdata -> cfile , true);
3367
+ if (rc == - EAGAIN )
3368
+ continue ;
3369
+ else if (rc )
3370
+ break ;
3371
+ }
3372
+
3373
+ /*
3374
+ * Wait for credits to resend this rdata.
3375
+ * Note: we are attempting to resend the whole rdata not in
3376
+ * segments
3377
+ */
3378
+ do {
3379
+ rc = server -> ops -> wait_mtu_credits (server , rdata -> bytes ,
3357
3380
& rsize , & credits );
3358
3381
3359
- if (rc )
3360
- goto out ;
3382
+ if (rc )
3383
+ goto fail ;
3361
3384
3362
- if (rsize < rdata -> bytes ) {
3363
- add_credits_and_wake_if (server , & credits , 0 );
3364
- msleep (1000 );
3365
- }
3366
- } while (rsize < rdata -> bytes );
3385
+ if (rsize < rdata -> bytes ) {
3386
+ add_credits_and_wake_if (server , & credits , 0 );
3387
+ msleep (1000 );
3388
+ }
3389
+ } while (rsize < rdata -> bytes );
3390
+ rdata -> credits = credits ;
3367
3391
3368
- rdata -> credits = credits ;
3369
- rc = - EAGAIN ;
3370
- while (rc == - EAGAIN ) {
3371
- rc = 0 ;
3372
- if (rdata -> cfile -> invalidHandle )
3373
- rc = cifs_reopen_file (rdata -> cfile , true);
3374
- if (!rc )
3375
- rc = server -> ops -> async_readv (rdata );
3376
- }
3392
+ rc = adjust_credits (server , & rdata -> credits , rdata -> bytes );
3393
+ if (!rc ) {
3394
+ if (rdata -> cfile -> invalidHandle )
3395
+ rc = - EAGAIN ;
3396
+ else
3397
+ rc = server -> ops -> async_readv (rdata );
3398
+ }
3377
3399
3378
- if (!rc ) {
3379
- /* Add to aio pending list */
3380
- list_add_tail (& rdata -> list , rdata_list );
3381
- return 0 ;
3382
- }
3400
+ /* If the read was successfully sent, we are done */
3401
+ if (!rc ) {
3402
+ /* Add to aio pending list */
3403
+ list_add_tail (& rdata -> list , rdata_list );
3404
+ return 0 ;
3405
+ }
3383
3406
3384
- add_credits_and_wake_if (server , & rdata -> credits , 0 );
3385
- out :
3386
- kref_put (& rdata -> refcount ,
3387
- cifs_uncached_readdata_release );
3407
+ /* Roll back credits and retry if needed */
3408
+ add_credits_and_wake_if (server , & rdata -> credits , 0 );
3409
+ } while (rc == - EAGAIN );
3388
3410
3411
+ fail :
3412
+ kref_put (& rdata -> refcount , cifs_uncached_readdata_release );
3389
3413
return rc ;
3390
3414
}
3391
3415
0 commit comments