[pnfs] [PATCH 21/38] [v1] pnfs: client layout cache: {get_lock, put_unlock}_current_layout

Benny Halevy bhalevy at panasas.com
Tue Jan 8 02:18:56 EST 2008


On Jan. 08, 2008, 1:57 +0200, Dean Hildebrand <seattleplus at gmail.com> wrote:
> 
> Benny Halevy wrote:
>>  
>>  /*
>> - * get, possibly allocate current_layout
>> + * get, possibly allocate, and lock current_layout
>>   
> What I wouldn't mind here is a comment saying something to the effect of:
> "Grab's lock on layout.  If successful, caller must unlock current_layout
> by  ___fill in how layout lock is released____"
> 
> I think this will help future developers figure out the start and end 
> points for the layout lock.
> Thanks for re-sending the patches btw.

Sore, no problem, and thanks for the feedback!

Benny

> Dean
>>   */
>>  static struct pnfs_layout_type *
>>  get_alloc_layout(struct inode *ino,
>> @@ -467,7 +509,7 @@ get_alloc_layout(struct inode *ino,
>>  
>>  	dprintk("%s Begin\n", __FUNCTION__);
>>  
>> -	while ((lo = nfsi->current_layout) == NULL) {
>> +	while ((lo = get_lock_current_layout(nfsi)) == NULL) {
>>  		/* Compete against other threads on who's doing the allocation,
>>  		 * wait until bit is cleared if we lost this race.
>>  		 */
>> @@ -480,22 +522,22 @@ get_alloc_layout(struct inode *ino,
>>  		}
>>  
>>  		/* Was current_layout already allocated while we slept?
>> -		 * If not, allocate it.
>> +		 * If so, retry get_lock'ing it. Otherwise, allocate it.
>>  		 */
>> -		lo = nfsi->current_layout;
>> -		if (!lo)
>> -			lo = nfsi->current_layout =
>> -				alloc_init_layout(ino, io_ops);
>> +		if (nfsi->current_layout)
>> +			continue;
>> +
>> +		lo = alloc_init_layout(ino, io_ops);
>> +		if (lo) {
>> +			/* must grab the layout lock */
>> +			spin_lock(&nfsi->lo_lock);
>>   
>> +			nfsi->current_layout = lo;
>> +		} else
>> +			lo = ERR_PTR(-ENOMEM);
>>  
>>  		/* release the NFS_INO_LAYOUT_ALLOC bit and wake up waiters */
>>  		clear_bit_unlock(NFS_INO_LAYOUT_ALLOC, &nfsi->pnfs_layout_state);
>>  		wake_up_bit(&nfsi->pnfs_layout_state, NFS_INO_LAYOUT_ALLOC);
>> -
>> -		/* we're done here.
>> -		 * just check whether alloc_init_layout succeeded.
>> -		 */
>> -		if (!lo)
>> -			lo = ERR_PTR(-ENOMEM);
>>  		break;
>>  	}
>>  
>> @@ -505,7 +547,6 @@ get_alloc_layout(struct inode *ino,
>>  	else
>>  		dprintk("%s Return error %ld\n", __FUNCTION__, PTR_ERR(lo));
>>  #endif
>> -	return lo;
>>  }
>>  
>>  /* Update the file's layout for the given range and iomode.
>> @@ -631,6 +672,7 @@ out:
>>  
>>  	/* res.layout.buf kalloc'ed by the xdr decoder? */
>>  	kfree(res.layout.buf);
>> +	put_unlock_current_layout(nfsi, layout_new);
>>  ret:
>>  	dprintk("%s end (err:%d) state 0x%lx\n",
>>  		__FUNCTION__, result, nfsi->pnfs_layout_state);
>> @@ -721,9 +763,11 @@ pnfs_getboundary(struct inode *inode)
>>  		goto out;
>>  
>>  	nfsi = NFS_I(inode);
>> -	lo = nfsi->current_layout;
>> -	if (lo)
>> +	lo = get_lock_current_layout(nfsi);;
>> +	if (lo) {
>>  		stripe_size = policy_ops->get_stripesize(lo);
>> +		put_unlock_current_layout(nfsi, lo);
>> +	}
>>  out:
>>  	return stripe_size;
>>  }
>> diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
>> index 1a093b1..99dfe9c 100644
>> --- a/include/linux/nfs_fs.h
>> +++ b/include/linux/nfs_fs.h
>> @@ -181,6 +181,7 @@ struct nfs_inode {
>>  #define NFS_INO_LAYOUT_ALLOC	0x0002	/* get layout failed, stop trying */
>>  	time_t pnfs_layout_suspend;
>>  	wait_queue_head_t lo_waitq;
>> +	spinlock_t lo_lock;
>>  	struct pnfs_layout_type *current_layout;
>>  	/* use rpc_creds in this open_context to send LAYOUTCOMMIT to MDS */
>>  	struct nfs_open_context *layoutcommit_ctx;
>>   
> _______________________________________________
> pNFS mailing list
> pNFS at linux-nfs.org
> http://linux-nfs.org/cgi-bin/mailman/listinfo/pnfs
> 



More information about the pNFS mailing list