diff mbox

cifs: When "refer file directly", make new inode cache if "uniqueid is different"

Message ID 549A249A.3080000@nttcom.co.jp (mailing list archive)
State New, archived
Headers show

Commit Message

Nakajima Akira Dec. 24, 2014, 2:27 a.m. UTC
When refer file "directly" (e.g. ls -li <filename>),
 if file is same name, old inode cache is used.
This causes that client shows wrong(old) inode number.
So this patch is that if uniqueid is different, return error.

## But this patch is applicable to when Server is UNIX.
## When Server is Windows, we need another new patch.


Reproducible sample :
1. create file 'a' at cifs client.
2. rm 'a' and touch 'b a' at server.
3. ls -li 'a' at client, then client shows wrong(old) inode number.

Bug link:
https://bugzilla.kernel.org/show_bug.cgi?id=90021



Signed-off-by: Nakajima Akira <nakajima.akira@nttcom.co.jp>
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Shirish Pargaonkar Jan. 4, 2015, 5:34 a.m. UTC | #1
Looks correct.

Reviewed-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>


On Tue, Dec 23, 2014 at 8:27 PM, Nakajima Akira
<nakajima.akira@nttcom.co.jp> wrote:
> When refer file "directly" (e.g. ls -li <filename>),
>  if file is same name, old inode cache is used.
> This causes that client shows wrong(old) inode number.
> So this patch is that if uniqueid is different, return error.
>
> ## But this patch is applicable to when Server is UNIX.
> ## When Server is Windows, we need another new patch.
>
>
> Reproducible sample :
> 1. create file 'a' at cifs client.
> 2. rm 'a' and touch 'b a' at server.
> 3. ls -li 'a' at client, then client shows wrong(old) inode number.
>
> Bug link:
> https://bugzilla.kernel.org/show_bug.cgi?id=90021
>
>
>
> Signed-off-by: Nakajima Akira <nakajima.akira@nttcom.co.jp>
> diff -uprN -X linux-3.18-vanilla/Documentation/dontdiff linux-3.18-vanilla/fs/cifs/inode.c linux-3.18/fs/cifs/inode.c
> --- linux-3.18-vanilla/fs/cifs/inode.c  2014-12-08 07:21:05.000000000 +0900
> +++ linux-3.18/fs/cifs/inode.c  2014-12-19 11:07:59.127000000 +0900
> @@ -402,9 +402,18 @@ int cifs_get_inode_info_unix(struct inod
>                         rc = -ENOMEM;
>         } else {
>                 /* we already have inode, update it */
> +
> +               /* if uniqueid is different, return error */
> +               if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM &&
> +                   CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) {
> +                       rc = -ENOENT;
> +                       goto cgiiu_exit;
> +               }
> +
>                 cifs_fattr_to_inode(*pinode, &fattr);
>         }
>
> +cgiiu_exit:
>         return rc;
>  }
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jeff Layton April 7, 2015, 10:45 a.m. UTC | #2
On Wed, 24 Dec 2014 11:27:38 +0900
Nakajima Akira <nakajima.akira@nttcom.co.jp> wrote:

> When refer file "directly" (e.g. ls -li <filename>),
>  if file is same name, old inode cache is used.
> This causes that client shows wrong(old) inode number.
> So this patch is that if uniqueid is different, return error.
> 
> ## But this patch is applicable to when Server is UNIX.
> ## When Server is Windows, we need another new patch.
> 
> 
> Reproducible sample :
> 1. create file 'a' at cifs client.
> 2. rm 'a' and touch 'b a' at server.
> 3. ls -li 'a' at client, then client shows wrong(old) inode number.
> 
> Bug link:
> https://bugzilla.kernel.org/show_bug.cgi?id=90021
> 
> 
> 
> Signed-off-by: Nakajima Akira <nakajima.akira@nttcom.co.jp>
> diff -uprN -X linux-3.18-vanilla/Documentation/dontdiff linux-3.18-vanilla/fs/cifs/inode.c linux-3.18/fs/cifs/inode.c
> --- linux-3.18-vanilla/fs/cifs/inode.c	2014-12-08 07:21:05.000000000 +0900
> +++ linux-3.18/fs/cifs/inode.c	2014-12-19 11:07:59.127000000 +0900
> @@ -402,9 +402,18 @@ int cifs_get_inode_info_unix(struct inod
>  			rc = -ENOMEM;
>  	} else {
>  		/* we already have inode, update it */
> +
> +		/* if uniqueid is different, return error */
> +		if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM &&
> +		    CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) {
> +			rc = -ENOENT;
> +			goto cgiiu_exit;
> +		}
> +
>  		cifs_fattr_to_inode(*pinode, &fattr);
>  	}
>  
> +cgiiu_exit:
>  	return rc;
>  }
>  

Returning ENOENT here seems like the wrong error to me. That path does
exist, it just no longer refers to the same file as before.

Maybe ESTALE would be better as it would allow the VFS layer
to revalidate the dcache and invalidate the old dentry?
Steve French April 7, 2015, 2:39 p.m. UTC | #3
On Tue, Apr 7, 2015 at 5:45 AM, Jeff Layton <jlayton@samba.org> wrote:
> On Wed, 24 Dec 2014 11:27:38 +0900
> Nakajima Akira <nakajima.akira@nttcom.co.jp> wrote:
>
>> When refer file "directly" (e.g. ls -li <filename>),
>>  if file is same name, old inode cache is used.
>> This causes that client shows wrong(old) inode number.
>> So this patch is that if uniqueid is different, return error.
>>
>> ## But this patch is applicable to when Server is UNIX.
>> ## When Server is Windows, we need another new patch.
>>
>>
>> Reproducible sample :
>> 1. create file 'a' at cifs client.
>> 2. rm 'a' and touch 'b a' at server.
>> 3. ls -li 'a' at client, then client shows wrong(old) inode number.
>>
>> Bug link:
>> https://bugzilla.kernel.org/show_bug.cgi?id=90021
>>
>>
>>
>> Signed-off-by: Nakajima Akira <nakajima.akira@nttcom.co.jp>
>> diff -uprN -X linux-3.18-vanilla/Documentation/dontdiff linux-3.18-vanilla/fs/cifs/inode.c linux-3.18/fs/cifs/inode.c
>> --- linux-3.18-vanilla/fs/cifs/inode.c        2014-12-08 07:21:05.000000000 +0900
>> +++ linux-3.18/fs/cifs/inode.c        2014-12-19 11:07:59.127000000 +0900
>> @@ -402,9 +402,18 @@ int cifs_get_inode_info_unix(struct inod
>>                       rc = -ENOMEM;
>>       } else {
>>               /* we already have inode, update it */
>> +
>> +             /* if uniqueid is different, return error */
>> +             if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM &&
>> +                 CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) {
>> +                     rc = -ENOENT;
>> +                     goto cgiiu_exit;
>> +             }
>> +
>>               cifs_fattr_to_inode(*pinode, &fattr);
>>       }
>>
>> +cgiiu_exit:
>>       return rc;
>>  }
>>
>
> Returning ENOENT here seems like the wrong error to me. That path does
> exist, it just no longer refers to the same file as before.
>
> Maybe ESTALE would be better as it would allow the VFS layer
> to revalidate the dcache and invalidate the old dentry?
>
> --
> Jeff Layton <jlayton@samba.org>

Similar to what Jeff mentioned, isn't the nfs_relavidate_inode path
roughly equivalent to what we want here (where nfs.ko returns ESTALE
on various cases where we detect an inode that doesn't match what we
expect)?
Nakajima Akira April 9, 2015, 8:07 a.m. UTC | #4
On 2015/04/07 23:39, Steve French wrote:
> On Tue, Apr 7, 2015 at 5:45 AM, Jeff Layton <jlayton@samba.org> wrote:
>> On Wed, 24 Dec 2014 11:27:38 +0900
>> Nakajima Akira <nakajima.akira@nttcom.co.jp> wrote:
>>
>>> When refer file "directly" (e.g. ls -li <filename>),
>>>  if file is same name, old inode cache is used.
>>> This causes that client shows wrong(old) inode number.
>>> So this patch is that if uniqueid is different, return error.
>>>
>>> ## But this patch is applicable to when Server is UNIX.
>>> ## When Server is Windows, we need another new patch.
>>>
>>>
>>> Reproducible sample :
>>> 1. create file 'a' at cifs client.
>>> 2. rm 'a' and touch 'b a' at server.
>>> 3. ls -li 'a' at client, then client shows wrong(old) inode number.
>>>
>>> Bug link:
>>> https://bugzilla.kernel.org/show_bug.cgi?id=90021
>>>
>>>
>>>
>>> Signed-off-by: Nakajima Akira <nakajima.akira@nttcom.co.jp>
>>> diff -uprN -X linux-3.18-vanilla/Documentation/dontdiff linux-3.18-vanilla/fs/cifs/inode.c linux-3.18/fs/cifs/inode.c
>>> --- linux-3.18-vanilla/fs/cifs/inode.c        2014-12-08 07:21:05.000000000 +0900
>>> +++ linux-3.18/fs/cifs/inode.c        2014-12-19 11:07:59.127000000 +0900
>>> @@ -402,9 +402,18 @@ int cifs_get_inode_info_unix(struct inod
>>>                       rc = -ENOMEM;
>>>       } else {
>>>               /* we already have inode, update it */
>>> +
>>> +             /* if uniqueid is different, return error */
>>> +             if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM &&
>>> +                 CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) {
>>> +                     rc = -ENOENT;
>>> +                     goto cgiiu_exit;
>>> +             }
>>> +
>>>               cifs_fattr_to_inode(*pinode, &fattr);
>>>       }
>>>
>>> +cgiiu_exit:
>>>       return rc;
>>>  }
>>>
>>
>> Returning ENOENT here seems like the wrong error to me. That path does
>> exist, it just no longer refers to the same file as before.
>>
>> Maybe ESTALE would be better as it would allow the VFS layer
>> to revalidate the dcache and invalidate the old dentry?
>>
>> --
>> Jeff Layton <jlayton@samba.org>
> 
> Similar to what Jeff mentioned, isn't the nfs_relavidate_inode path
> roughly equivalent to what we want here (where nfs.ko returns ESTALE
> on various cases where we detect an inode that doesn't match what we
> expect)?

If uniqueid is different, return -ESTALE.
If filetype is different, return -ENOENT.
That's right?

+		/* if filetype is different, return error */
+		if (unlikely(((*pinode)->i_mode & S_IFMT) !=
+		    (fattr.cf_mode & S_IFMT))) {
+			rc = -ENOENT;
+			goto cgiiu_exit;
+		}

--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jeff Layton April 10, 2015, 1:16 p.m. UTC | #5
On Thu, 9 Apr 2015 17:07:56 +0900
Nakajima Akira <nakajima.akira@nttcom.co.jp> wrote:

> On 2015/04/07 23:39, Steve French wrote:
> > On Tue, Apr 7, 2015 at 5:45 AM, Jeff Layton <jlayton@samba.org> wrote:
> >> On Wed, 24 Dec 2014 11:27:38 +0900
> >> Nakajima Akira <nakajima.akira@nttcom.co.jp> wrote:
> >>
> >>> When refer file "directly" (e.g. ls -li <filename>),
> >>>  if file is same name, old inode cache is used.
> >>> This causes that client shows wrong(old) inode number.
> >>> So this patch is that if uniqueid is different, return error.
> >>>
> >>> ## But this patch is applicable to when Server is UNIX.
> >>> ## When Server is Windows, we need another new patch.
> >>>
> >>>
> >>> Reproducible sample :
> >>> 1. create file 'a' at cifs client.
> >>> 2. rm 'a' and touch 'b a' at server.
> >>> 3. ls -li 'a' at client, then client shows wrong(old) inode number.
> >>>
> >>> Bug link:
> >>> https://bugzilla.kernel.org/show_bug.cgi?id=90021
> >>>
> >>>
> >>>
> >>> Signed-off-by: Nakajima Akira <nakajima.akira@nttcom.co.jp>
> >>> diff -uprN -X linux-3.18-vanilla/Documentation/dontdiff linux-3.18-vanilla/fs/cifs/inode.c linux-3.18/fs/cifs/inode.c
> >>> --- linux-3.18-vanilla/fs/cifs/inode.c        2014-12-08 07:21:05.000000000 +0900
> >>> +++ linux-3.18/fs/cifs/inode.c        2014-12-19 11:07:59.127000000 +0900
> >>> @@ -402,9 +402,18 @@ int cifs_get_inode_info_unix(struct inod
> >>>                       rc = -ENOMEM;
> >>>       } else {
> >>>               /* we already have inode, update it */
> >>> +
> >>> +             /* if uniqueid is different, return error */
> >>> +             if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM &&
> >>> +                 CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) {
> >>> +                     rc = -ENOENT;
> >>> +                     goto cgiiu_exit;
> >>> +             }
> >>> +
> >>>               cifs_fattr_to_inode(*pinode, &fattr);
> >>>       }
> >>>
> >>> +cgiiu_exit:
> >>>       return rc;
> >>>  }
> >>>
> >>
> >> Returning ENOENT here seems like the wrong error to me. That path does
> >> exist, it just no longer refers to the same file as before.
> >>
> >> Maybe ESTALE would be better as it would allow the VFS layer
> >> to revalidate the dcache and invalidate the old dentry?
> >>
> >> --
> >> Jeff Layton <jlayton@samba.org>
> > 
> > Similar to what Jeff mentioned, isn't the nfs_relavidate_inode path
> > roughly equivalent to what we want here (where nfs.ko returns ESTALE
> > on various cases where we detect an inode that doesn't match what we
> > expect)?
> 
> If uniqueid is different, return -ESTALE.
> If filetype is different, return -ENOENT.
> That's right?
> 
> +		/* if filetype is different, return error */
> +		if (unlikely(((*pinode)->i_mode & S_IFMT) !=
> +		    (fattr.cf_mode & S_IFMT))) {
> +			rc = -ENOENT;
> +			goto cgiiu_exit;
> +		}
> 

No, I don't think so. In both cases, the dcache is wrong and the dentry
should be dropped and reinstantiated to point to a new inode. An ESTALE
return is the trigger for that to occur. An ENOENT return is going to
mean a stat() failure in your testcase, I think.

So I think you want to return ESTALE in both cases. That said, please
do test it and ensure that it does the right thing.
Shirish Pargaonkar April 13, 2015, 4:24 a.m. UTC | #6
I am not sure if ESTALE or ENOENT would have an effect on a dcache entry.
A dcache entry and dentry are two different things, as I understand.
In this case, dcache entry has not changed, what has changed is the dentry,
specifically the inode it points to, so there is really no reason to purge
and reinstate a dcache entry.

On Fri, Apr 10, 2015 at 8:16 AM, Jeff Layton <jlayton@samba.org> wrote:
> On Thu, 9 Apr 2015 17:07:56 +0900
> Nakajima Akira <nakajima.akira@nttcom.co.jp> wrote:
>
>> On 2015/04/07 23:39, Steve French wrote:
>> > On Tue, Apr 7, 2015 at 5:45 AM, Jeff Layton <jlayton@samba.org> wrote:
>> >> On Wed, 24 Dec 2014 11:27:38 +0900
>> >> Nakajima Akira <nakajima.akira@nttcom.co.jp> wrote:
>> >>
>> >>> When refer file "directly" (e.g. ls -li <filename>),
>> >>>  if file is same name, old inode cache is used.
>> >>> This causes that client shows wrong(old) inode number.
>> >>> So this patch is that if uniqueid is different, return error.
>> >>>
>> >>> ## But this patch is applicable to when Server is UNIX.
>> >>> ## When Server is Windows, we need another new patch.
>> >>>
>> >>>
>> >>> Reproducible sample :
>> >>> 1. create file 'a' at cifs client.
>> >>> 2. rm 'a' and touch 'b a' at server.
>> >>> 3. ls -li 'a' at client, then client shows wrong(old) inode number.
>> >>>
>> >>> Bug link:
>> >>> https://bugzilla.kernel.org/show_bug.cgi?id=90021
>> >>>
>> >>>
>> >>>
>> >>> Signed-off-by: Nakajima Akira <nakajima.akira@nttcom.co.jp>
>> >>> diff -uprN -X linux-3.18-vanilla/Documentation/dontdiff linux-3.18-vanilla/fs/cifs/inode.c linux-3.18/fs/cifs/inode.c
>> >>> --- linux-3.18-vanilla/fs/cifs/inode.c        2014-12-08 07:21:05.000000000 +0900
>> >>> +++ linux-3.18/fs/cifs/inode.c        2014-12-19 11:07:59.127000000 +0900
>> >>> @@ -402,9 +402,18 @@ int cifs_get_inode_info_unix(struct inod
>> >>>                       rc = -ENOMEM;
>> >>>       } else {
>> >>>               /* we already have inode, update it */
>> >>> +
>> >>> +             /* if uniqueid is different, return error */
>> >>> +             if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM &&
>> >>> +                 CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) {
>> >>> +                     rc = -ENOENT;
>> >>> +                     goto cgiiu_exit;
>> >>> +             }
>> >>> +
>> >>>               cifs_fattr_to_inode(*pinode, &fattr);
>> >>>       }
>> >>>
>> >>> +cgiiu_exit:
>> >>>       return rc;
>> >>>  }
>> >>>
>> >>
>> >> Returning ENOENT here seems like the wrong error to me. That path does
>> >> exist, it just no longer refers to the same file as before.
>> >>
>> >> Maybe ESTALE would be better as it would allow the VFS layer
>> >> to revalidate the dcache and invalidate the old dentry?
>> >>
>> >> --
>> >> Jeff Layton <jlayton@samba.org>
>> >
>> > Similar to what Jeff mentioned, isn't the nfs_relavidate_inode path
>> > roughly equivalent to what we want here (where nfs.ko returns ESTALE
>> > on various cases where we detect an inode that doesn't match what we
>> > expect)?
>>
>> If uniqueid is different, return -ESTALE.
>> If filetype is different, return -ENOENT.
>> That's right?
>>
>> +             /* if filetype is different, return error */
>> +             if (unlikely(((*pinode)->i_mode & S_IFMT) !=
>> +                 (fattr.cf_mode & S_IFMT))) {
>> +                     rc = -ENOENT;
>> +                     goto cgiiu_exit;
>> +             }
>>
>
> No, I don't think so. In both cases, the dcache is wrong and the dentry
> should be dropped and reinstantiated to point to a new inode. An ESTALE
> return is the trigger for that to occur. An ENOENT return is going to
> mean a stat() failure in your testcase, I think.
>
> So I think you want to return ESTALE in both cases. That said, please
> do test it and ensure that it does the right thing.
>
> --
> Jeff Layton <jlayton@samba.org>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jeff Layton April 13, 2015, 8:42 p.m. UTC | #7
On Sun, 12 Apr 2015 23:24:59 -0500
Shirish Pargaonkar <shirishpargaonkar@gmail.com> wrote:

> I am not sure if ESTALE or ENOENT would have an effect on a dcache entry.
> A dcache entry and dentry are two different things, as I understand.

Oh, in this case I was specifically referring to the kernel's cache of
dentries as the dcache.

> In this case, dcache entry has not changed, what has changed is the dentry,
> specifically the inode it points to, so there is really no reason to purge
> and reinstate a dcache entry.
> 

No, the dentry has changed. We did an operation against the server and
found that the underlying inode type is different.

In practical terms, the Linux dcache should handle that by dropping the
old dentry and instantiating a new one. So, I think that returning
ESTALE is a better error there since it should trigger the upper VFS
layers to do just that.

> On Fri, Apr 10, 2015 at 8:16 AM, Jeff Layton <jlayton@samba.org> wrote:
> > On Thu, 9 Apr 2015 17:07:56 +0900
> > Nakajima Akira <nakajima.akira@nttcom.co.jp> wrote:
> >
> >> On 2015/04/07 23:39, Steve French wrote:
> >> > On Tue, Apr 7, 2015 at 5:45 AM, Jeff Layton <jlayton@samba.org> wrote:
> >> >> On Wed, 24 Dec 2014 11:27:38 +0900
> >> >> Nakajima Akira <nakajima.akira@nttcom.co.jp> wrote:
> >> >>
> >> >>> When refer file "directly" (e.g. ls -li <filename>),
> >> >>>  if file is same name, old inode cache is used.
> >> >>> This causes that client shows wrong(old) inode number.
> >> >>> So this patch is that if uniqueid is different, return error.
> >> >>>
> >> >>> ## But this patch is applicable to when Server is UNIX.
> >> >>> ## When Server is Windows, we need another new patch.
> >> >>>
> >> >>>
> >> >>> Reproducible sample :
> >> >>> 1. create file 'a' at cifs client.
> >> >>> 2. rm 'a' and touch 'b a' at server.
> >> >>> 3. ls -li 'a' at client, then client shows wrong(old) inode number.
> >> >>>
> >> >>> Bug link:
> >> >>> https://bugzilla.kernel.org/show_bug.cgi?id=90021
> >> >>>
> >> >>>
> >> >>>
> >> >>> Signed-off-by: Nakajima Akira <nakajima.akira@nttcom.co.jp>
> >> >>> diff -uprN -X linux-3.18-vanilla/Documentation/dontdiff linux-3.18-vanilla/fs/cifs/inode.c linux-3.18/fs/cifs/inode.c
> >> >>> --- linux-3.18-vanilla/fs/cifs/inode.c        2014-12-08 07:21:05.000000000 +0900
> >> >>> +++ linux-3.18/fs/cifs/inode.c        2014-12-19 11:07:59.127000000 +0900
> >> >>> @@ -402,9 +402,18 @@ int cifs_get_inode_info_unix(struct inod
> >> >>>                       rc = -ENOMEM;
> >> >>>       } else {
> >> >>>               /* we already have inode, update it */
> >> >>> +
> >> >>> +             /* if uniqueid is different, return error */
> >> >>> +             if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM &&
> >> >>> +                 CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) {
> >> >>> +                     rc = -ENOENT;
> >> >>> +                     goto cgiiu_exit;
> >> >>> +             }
> >> >>> +
> >> >>>               cifs_fattr_to_inode(*pinode, &fattr);
> >> >>>       }
> >> >>>
> >> >>> +cgiiu_exit:
> >> >>>       return rc;
> >> >>>  }
> >> >>>
> >> >>
> >> >> Returning ENOENT here seems like the wrong error to me. That path does
> >> >> exist, it just no longer refers to the same file as before.
> >> >>
> >> >> Maybe ESTALE would be better as it would allow the VFS layer
> >> >> to revalidate the dcache and invalidate the old dentry?
> >> >>
> >> >> --
> >> >> Jeff Layton <jlayton@samba.org>
> >> >
> >> > Similar to what Jeff mentioned, isn't the nfs_relavidate_inode path
> >> > roughly equivalent to what we want here (where nfs.ko returns ESTALE
> >> > on various cases where we detect an inode that doesn't match what we
> >> > expect)?
> >>
> >> If uniqueid is different, return -ESTALE.
> >> If filetype is different, return -ENOENT.
> >> That's right?
> >>
> >> +             /* if filetype is different, return error */
> >> +             if (unlikely(((*pinode)->i_mode & S_IFMT) !=
> >> +                 (fattr.cf_mode & S_IFMT))) {
> >> +                     rc = -ENOENT;
> >> +                     goto cgiiu_exit;
> >> +             }
> >>
> >
> > No, I don't think so. In both cases, the dcache is wrong and the dentry
> > should be dropped and reinstantiated to point to a new inode. An ESTALE
> > return is the trigger for that to occur. An ENOENT return is going to
> > mean a stat() failure in your testcase, I think.
> >
> > So I think you want to return ESTALE in both cases. That said, please
> > do test it and ensure that it does the right thing.
> >
> > --
> > Jeff Layton <jlayton@samba.org>
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff -uprN -X linux-3.18-vanilla/Documentation/dontdiff linux-3.18-vanilla/fs/cifs/inode.c linux-3.18/fs/cifs/inode.c
--- linux-3.18-vanilla/fs/cifs/inode.c	2014-12-08 07:21:05.000000000 +0900
+++ linux-3.18/fs/cifs/inode.c	2014-12-19 11:07:59.127000000 +0900
@@ -402,9 +402,18 @@  int cifs_get_inode_info_unix(struct inod
 			rc = -ENOMEM;
 	} else {
 		/* we already have inode, update it */
+
+		/* if uniqueid is different, return error */
+		if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM &&
+		    CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) {
+			rc = -ENOENT;
+			goto cgiiu_exit;
+		}
+
 		cifs_fattr_to_inode(*pinode, &fattr);
 	}
 
+cgiiu_exit:
 	return rc;
 }