diff options
Diffstat (limited to 'fs/nfs/flexfilelayout/flexfilelayout.c')
| -rw-r--r-- | fs/nfs/flexfilelayout/flexfilelayout.c | 45 | 
1 files changed, 22 insertions, 23 deletions
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index e6206eaf2bdf..51b51369704c 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -37,6 +37,7 @@ ff_layout_alloc_layout_hdr(struct inode *inode, gfp_t gfp_flags)  	if (ffl) {  		INIT_LIST_HEAD(&ffl->error_list);  		INIT_LIST_HEAD(&ffl->mirrors); +		ffl->last_report_time = ktime_get();  		return &ffl->generic_hdr;  	} else  		return NULL; @@ -640,19 +641,18 @@ nfs4_ff_layoutstat_start_io(struct nfs4_ff_layout_mirror *mirror,  {  	static const ktime_t notime = {0};  	s64 report_interval = FF_LAYOUTSTATS_REPORT_INTERVAL; +	struct nfs4_flexfile_layout *ffl = FF_LAYOUT_FROM_HDR(mirror->layout);  	nfs4_ff_start_busy_timer(&layoutstat->busy_timer, now);  	if (ktime_equal(mirror->start_time, notime))  		mirror->start_time = now; -	if (ktime_equal(mirror->last_report_time, notime)) -		mirror->last_report_time = now;  	if (mirror->report_interval != 0)  		report_interval = (s64)mirror->report_interval * 1000LL;  	else if (layoutstats_timer != 0)  		report_interval = (s64)layoutstats_timer * 1000LL; -	if (ktime_to_ms(ktime_sub(now, mirror->last_report_time)) >= +	if (ktime_to_ms(ktime_sub(now, ffl->last_report_time)) >=  			report_interval) { -		mirror->last_report_time = now; +		ffl->last_report_time = now;  		return true;  	} @@ -806,11 +806,14 @@ ff_layout_choose_best_ds_for_read(struct pnfs_layout_segment *lseg,  {  	struct nfs4_ff_layout_segment *fls = FF_LAYOUT_LSEG(lseg);  	struct nfs4_pnfs_ds *ds; +	bool fail_return = false;  	int idx;  	/* mirrors are sorted by efficiency */  	for (idx = start_idx; idx < fls->mirror_array_cnt; idx++) { -		ds = nfs4_ff_layout_prepare_ds(lseg, idx, false); +		if (idx+1 == fls->mirror_array_cnt) +			fail_return = true; +		ds = nfs4_ff_layout_prepare_ds(lseg, idx, fail_return);  		if (ds) {  			*best_idx = idx;  			return ds; @@ -859,6 +862,7 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,  	struct nfs4_pnfs_ds *ds;  	int ds_idx; +retry:  	/* Use full layout for now */  	if (!pgio->pg_lseg)  		ff_layout_pg_get_read(pgio, req, false); @@ -871,10 +875,13 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,  	ds = ff_layout_choose_best_ds_for_read(pgio->pg_lseg, 0, &ds_idx);  	if (!ds) { -		if (ff_layout_no_fallback_to_mds(pgio->pg_lseg)) -			goto out_pnfs; -		else +		if (!ff_layout_no_fallback_to_mds(pgio->pg_lseg))  			goto out_mds; +		pnfs_put_lseg(pgio->pg_lseg); +		pgio->pg_lseg = NULL; +		/* Sleep for 1 second before retrying */ +		ssleep(1); +		goto retry;  	}  	mirror = FF_LAYOUT_COMP(pgio->pg_lseg, ds_idx); @@ -890,12 +897,6 @@ out_mds:  	pnfs_put_lseg(pgio->pg_lseg);  	pgio->pg_lseg = NULL;  	nfs_pageio_reset_read_mds(pgio); -	return; - -out_pnfs: -	pnfs_set_lo_fail(pgio->pg_lseg); -	pnfs_put_lseg(pgio->pg_lseg); -	pgio->pg_lseg = NULL;  }  static void @@ -909,6 +910,7 @@ ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio,  	int i;  	int status; +retry:  	if (!pgio->pg_lseg) {  		pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,  						   req->wb_context, @@ -940,10 +942,13 @@ ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio,  	for (i = 0; i < pgio->pg_mirror_count; i++) {  		ds = nfs4_ff_layout_prepare_ds(pgio->pg_lseg, i, true);  		if (!ds) { -			if (ff_layout_no_fallback_to_mds(pgio->pg_lseg)) -				goto out_pnfs; -			else +			if (!ff_layout_no_fallback_to_mds(pgio->pg_lseg))  				goto out_mds; +			pnfs_put_lseg(pgio->pg_lseg); +			pgio->pg_lseg = NULL; +			/* Sleep for 1 second before retrying */ +			ssleep(1); +			goto retry;  		}  		pgm = &pgio->pg_mirrors[i];  		mirror = FF_LAYOUT_COMP(pgio->pg_lseg, i); @@ -956,12 +961,6 @@ out_mds:  	pnfs_put_lseg(pgio->pg_lseg);  	pgio->pg_lseg = NULL;  	nfs_pageio_reset_write_mds(pgio); -	return; - -out_pnfs: -	pnfs_set_lo_fail(pgio->pg_lseg); -	pnfs_put_lseg(pgio->pg_lseg); -	pgio->pg_lseg = NULL;  }  static unsigned int  |