Re: Strange hardlink behavior with CIFS

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

 



On Wed, 27 Oct 2010 12:31:26 -0500
Matt Mackall <mpm@xxxxxxxxxxx> wrote:

> On Tue, 2010-10-19 at 15:13 +0530, Suresh Jayaraman wrote:
> > On 10/19/2010 12:34 AM, Matt Mackall wrote:
> > > With Linux 2.6.32-35 and either Windows or Samba in nounix mode,
> > > hardlink counts can mysteriously disappear:
> > > 
> > > - create hardlink pair foo,bar
> > > - stat foo -> nlink = 2
> > > - open foo
> > > - stat foo -> nlink = 1
> > > - close
> > > - wait or sync
> > > - ls -l -> nlink = 2
> > > 
> > > Original report is here:
> > > 
> > > http://mercurial.selenic.com/bts/issue1866
> > > 
> > 
> > A quick test on 2.6.36-rc4 kernel reveals that the problem is no longer
> > reproducible. Could you try a more recent kernel and see whether the
> > problem is reproducible?
> 
> Test continues to fail with 2.6.36.
> 
> # uname -a
> Linux calx 2.6.36 #71 SMP Tue Oct 26 02:23:34 CDT 2010 x86_64 GNU/Linux
> # mount -o nounix //localhost/stuff cifs
>            ^^^^^^
> # cd cifs
> # touch foo
> # ln foo bar
> # ./h
> file: foo nlinks 2
> file: foo nlinks 1
> file: foo nlinks 1
> 
> # cat h.c
> #include <sys/types.h>
> #include <sys/stat.h>
> #include <unistd.h>
> #include <fcntl.h>
> #include <stdio.h>
> 
> #define FPATH "foo"
> 
> int main(void)
> {
> 	int rc, fh;
> 	struct stat st;
> 
> 	rc = lstat(FPATH, &st);
> 	printf("file: %s nlinks %d\n", FPATH, st.st_nlink);
> 
> 	fh = open(FPATH, 0, O_RDONLY);
> 
> 	rc = lstat(FPATH, &st);
> 	printf("file: %s nlinks %d\n", FPATH, st.st_nlink);
> 
> 	close(fh);
> 
> 	rc = lstat(FPATH, &st);
> 	printf("file: %s nlinks %d\n", FPATH, st.st_nlink);
> 
> 	return 0;
> }
> 
> 
> 
> 

Ok, I can reproduce this too. The problem is this nastiness in CIFSSMBOpen:

        if (rc) {
                cFYI(1, "Error in Open = %d", rc);
        } else {
                *pOplock = pSMBr->OplockLevel; /* 1 byte no need to le_to_cpu */
                *netfid = pSMBr->Fid;   /* cifs fid stays in le */
                /* Let caller know file was created so we can set the mode. */
                /* Do we care about the CreateAction in any other cases? */
                if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
                        *pOplock |= CIFS_CREATE_ACTION;
                if (pfile_info) {
                        memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime,
                                36 /* CreationTime to Attributes */);
                        /* the file_info buf is endian converted by caller */
                        pfile_info->AllocationSize = pSMBr->AllocationSize;
                        pfile_info->EndOfFile = pSMBr->EndOfFile;
                        pfile_info->NumberOfLinks = cpu_to_le32(1);
                        pfile_info->DeletePending = 0;
                }
        }

In particular, the NumberOfLinks being set to 1 there. That probably
just needs to go. I'll look over it when I have time.


-- 
Jeff Layton <jlayton@xxxxxxxxxx>
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux