Re: [PATCH 2/4] pnfs_submit: Only update stateid if it is more recent than current

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Oct 7, 2010 at 10:06 PM, Benny Halevy <bhalevy@xxxxxxxxxxx> wrote:
> On 2010-10-07 10:01, Fred Isaman wrote:
>> On Thu, Oct 7, 2010 at 9:34 AM, Benny Halevy <bhalevy@xxxxxxxxxxx> wrote:
>>> On 2010-10-06 16:35, Fred Isaman wrote:
>>>> Right now, when we set the stateid, we blindly overwrite the current
>>>> one, allowing the seqid to incorrectly roll backward.
>>>>
>>>> Signed-off-by: Fred Isaman <iisaman@xxxxxxxxxx>
>>>> ---
>>>> Âfs/nfs/pnfs.c | Â 38 ++++++++++++++++++++++++++++++++------
>>>> Â1 files changed, 32 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
>>>> index 39bce9b..555955b 100644
>>>> --- a/fs/nfs/pnfs.c
>>>> +++ b/fs/nfs/pnfs.c
>>>> @@ -459,16 +459,42 @@ pnfs_destroy_all_layouts(struct nfs_client *clp)
>>>> Â Â Â }
>>>> Â}
>>>>
>>>> +/* update lo->stateid with new if is more recent
>>>> + *
>>>> + * lo->stateid could be the open stateid, in which case we just use what given.
>>>> + */
>>>> Âstatic void
>>>> Âpnfs_set_layout_stateid(struct pnfs_layout_hdr *lo,
>>>> - Â Â Â Â Â Â Â Â Â Â const nfs4_stateid *stateid)
>>>> + Â Â Â Â Â Â Â Â Â Â const nfs4_stateid *new)
>>>> Â{
>>>> - Â Â /* TODO - should enforce that embedded seqid, in the case
>>>> - Â Â Â* that the two stateid.others are equal, Âonly increases.
>>>> - Â Â Â* Complicated by wrap-around.
>>>> - Â Â Â*/
>>>> + Â Â nfs4_stateid *old = &lo->stateid;
>>>> + Â Â bool overwrite = false;
>>>> +
>>>> Â Â Â write_seqlock(&lo->seqlock);
>>>> - Â Â memcpy(lo->stateid.data, stateid->data, sizeof(lo->stateid.data));
>>>> + Â Â if (!test_bit(NFS_LAYOUT_STATEID_SET, &lo->state) ||
>>>> + Â Â Â Â memcmp(old->stateid.other, new->stateid.other, sizeof(new->stateid.other)))
>>>> + Â Â Â Â Â Â overwrite = true;
>>>> + Â Â else {
>>>> + Â Â Â Â Â Â u32 oldseq, newseq, limit;
>>>> +
>>>> + Â Â Â Â Â Â oldseq = be32_to_cpu(old->stateid.seqid);
>>>> + Â Â Â Â Â Â newseq = be32_to_cpu(new->stateid.seqid);
>>>> + Â Â Â Â Â Â /* There are no good bounds on window size, so just
>>>> + Â Â Â Â Â Â Â* use a ridiculously large window of 2^31.
>>>> + Â Â Â Â Â Â Â*/
>>>> + Â Â Â Â Â Â limit = oldseq + (1 << 31);
>>>> + Â Â Â Â Â Â if (oldseq < limit) {
>>>> + Â Â Â Â Â Â Â Â Â Â /* The easy, non-wraparound case */
>>>> + Â Â Â Â Â Â Â Â Â Â if (oldseq < newseq && newseq < limit)
>>>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â overwrite = true;
>>>> + Â Â Â Â Â Â } else {
>>>> + Â Â Â Â Â Â Â Â Â Â /* Near wraparound edge */
>>>> + Â Â Â Â Â Â Â Â Â Â if (oldseq < newseq || newseq < limit)
>>>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â overwrite = true;
>>>> + Â Â Â Â Â Â }
>>>
>>> Wouldn't it be simpler to just look at (int32_t)(newseq - oldseq)?
>>>
>>
>> Why yes it would. ÂI'll send a new version of this patch shortly.
>>
>
> No need :)
> I'll just change this as follows:
>
> + Â Â Â else {
> + Â Â Â Â Â Â Â u32 oldseq, newseq, limit;
> +
> + Â Â Â Â Â Â Â oldseq = be32_to_cpu(old->stateid.seqid);
> + Â Â Â Â Â Â Â newseq = be32_to_cpu(new->stateid.seqid);
> + Â Â Â Â Â Â Â if ((int)(newseq - oldseq) > 0)
> + Â Â Â Â Â Â Â Â Â Â Â overwrite = true;
Do we also need to verify the other field of the stateid? Will there
be situations that server change the other field and reset the seqid?

Thanks,
Shelley
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux