mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2024-01-19 02:48:24 +00:00
ensure inodes are not duplicating unless hardlinked
This commit is contained in:
parent
de77d00c81
commit
63a9d8f01d
|
@ -31,18 +31,20 @@ func NewInodeToPath() *InodeToPath {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *InodeToPath) Lookup(path util.FullPath, mode os.FileMode, isCreate bool, possibleInode uint64, isLookup bool) uint64 {
|
func (i *InodeToPath) Lookup(path util.FullPath, mode os.FileMode, isHardlink bool, possibleInode uint64, isLookup bool) uint64 {
|
||||||
i.Lock()
|
i.Lock()
|
||||||
defer i.Unlock()
|
defer i.Unlock()
|
||||||
inode, found := i.path2inode[path]
|
inode, found := i.path2inode[path]
|
||||||
if !found {
|
if !found {
|
||||||
if possibleInode == 0 {
|
if possibleInode == 0 {
|
||||||
inode = path.AsInode(mode)
|
inode = path.AsInode(mode)
|
||||||
|
} else {
|
||||||
|
inode = possibleInode
|
||||||
|
}
|
||||||
|
if !isHardlink {
|
||||||
for _, found := i.inode2path[inode]; found; inode++ {
|
for _, found := i.inode2path[inode]; found; inode++ {
|
||||||
_, found = i.inode2path[inode]
|
_, found = i.inode2path[inode]
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
inode = possibleInode
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i.path2inode[path] = inode
|
i.path2inode[path] = inode
|
||||||
|
@ -62,6 +64,19 @@ func (i *InodeToPath) Lookup(path util.FullPath, mode os.FileMode, isCreate bool
|
||||||
return inode
|
return inode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *InodeToPath) AllocateInode(path util.FullPath, mode os.FileMode) uint64 {
|
||||||
|
if path == "/" {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
i.Lock()
|
||||||
|
defer i.Unlock()
|
||||||
|
inode := path.AsInode(mode)
|
||||||
|
for _, found := i.inode2path[inode]; found; inode++ {
|
||||||
|
_, found = i.inode2path[inode]
|
||||||
|
}
|
||||||
|
return inode
|
||||||
|
}
|
||||||
|
|
||||||
func (i *InodeToPath) GetInode(path util.FullPath) uint64 {
|
func (i *InodeToPath) GetInode(path util.FullPath) uint64 {
|
||||||
if path == "/" {
|
if path == "/" {
|
||||||
return 1
|
return 1
|
||||||
|
|
|
@ -53,7 +53,7 @@ func (wfs *WFS) Lookup(cancel <-chan struct{}, header *fuse.InHeader, name strin
|
||||||
return fuse.ENOENT
|
return fuse.ENOENT
|
||||||
}
|
}
|
||||||
|
|
||||||
inode := wfs.inodeToPath.Lookup(fullFilePath, localEntry.Mode, false, localEntry.Inode, true)
|
inode := wfs.inodeToPath.Lookup(fullFilePath, localEntry.Mode, len(localEntry.HardLinkId) > 0, localEntry.Inode, true)
|
||||||
|
|
||||||
if fh, found := wfs.fhmap.FindFileHandle(inode); found {
|
if fh, found := wfs.fhmap.FindFileHandle(inode); found {
|
||||||
glog.V(4).Infof("lookup opened file %s size %d", dirPath.Child(localEntry.Name()), filer.FileSize(fh.entry))
|
glog.V(4).Infof("lookup opened file %s size %d", dirPath.Child(localEntry.Name()), filer.FileSize(fh.entry))
|
||||||
|
|
|
@ -74,7 +74,7 @@ func (wfs *WFS) Mkdir(cancel <-chan struct{}, in *fuse.MkdirIn, name string, out
|
||||||
return fuse.EIO
|
return fuse.EIO
|
||||||
}
|
}
|
||||||
|
|
||||||
inode := wfs.inodeToPath.Lookup(entryFullPath, os.ModeDir, true, 0, true)
|
inode := wfs.inodeToPath.Lookup(entryFullPath, os.ModeDir, false, 0, true)
|
||||||
|
|
||||||
wfs.outputPbEntry(out, inode, newEntry)
|
wfs.outputPbEntry(out, inode, newEntry)
|
||||||
|
|
||||||
|
|
|
@ -162,14 +162,14 @@ func (wfs *WFS) doReadDirectory(input *fuse.ReadIn, out *fuse.DirEntryList, isPl
|
||||||
dirEntry.Name = entry.Name()
|
dirEntry.Name = entry.Name()
|
||||||
dirEntry.Mode = toSyscallMode(entry.Mode)
|
dirEntry.Mode = toSyscallMode(entry.Mode)
|
||||||
if !isPlusMode {
|
if !isPlusMode {
|
||||||
inode := wfs.inodeToPath.Lookup(dirPath.Child(dirEntry.Name), entry.Mode, false, entry.Inode, false)
|
inode := wfs.inodeToPath.Lookup(dirPath.Child(dirEntry.Name), entry.Mode, len(entry.HardLinkId) > 0, entry.Inode, false)
|
||||||
dirEntry.Ino = inode
|
dirEntry.Ino = inode
|
||||||
if !out.AddDirEntry(dirEntry) {
|
if !out.AddDirEntry(dirEntry) {
|
||||||
isEarlyTerminated = true
|
isEarlyTerminated = true
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
inode := wfs.inodeToPath.Lookup(dirPath.Child(dirEntry.Name), entry.Mode, false, entry.Inode, true)
|
inode := wfs.inodeToPath.Lookup(dirPath.Child(dirEntry.Name), entry.Mode, len(entry.HardLinkId) > 0, entry.Inode, true)
|
||||||
dirEntry.Ino = inode
|
dirEntry.Ino = inode
|
||||||
entryOut := out.AddDirLookupEntry(dirEntry)
|
entryOut := out.AddDirLookupEntry(dirEntry)
|
||||||
if entryOut == nil {
|
if entryOut == nil {
|
||||||
|
|
|
@ -46,6 +46,7 @@ func (wfs *WFS) Mknod(cancel <-chan struct{}, in *fuse.MknodIn, name string, out
|
||||||
|
|
||||||
entryFullPath := dirFullPath.Child(name)
|
entryFullPath := dirFullPath.Child(name)
|
||||||
fileMode := toOsFileMode(in.Mode)
|
fileMode := toOsFileMode(in.Mode)
|
||||||
|
inode := wfs.inodeToPath.AllocateInode(entryFullPath, fileMode)
|
||||||
|
|
||||||
newEntry := &filer_pb.Entry{
|
newEntry := &filer_pb.Entry{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -60,7 +61,7 @@ func (wfs *WFS) Mknod(cancel <-chan struct{}, in *fuse.MknodIn, name string, out
|
||||||
Replication: wfs.option.Replication,
|
Replication: wfs.option.Replication,
|
||||||
TtlSec: wfs.option.TtlSec,
|
TtlSec: wfs.option.TtlSec,
|
||||||
Rdev: in.Rdev,
|
Rdev: in.Rdev,
|
||||||
Inode: entryFullPath.AsInode(fileMode),
|
Inode: inode,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +95,8 @@ func (wfs *WFS) Mknod(cancel <-chan struct{}, in *fuse.MknodIn, name string, out
|
||||||
return fuse.EIO
|
return fuse.EIO
|
||||||
}
|
}
|
||||||
|
|
||||||
inode := wfs.inodeToPath.Lookup(entryFullPath, newEntry.FileMode(), true, 0, true)
|
// this is to increase nlookup counter
|
||||||
|
inode = wfs.inodeToPath.Lookup(entryFullPath, fileMode, false, inode, true)
|
||||||
|
|
||||||
wfs.outputPbEntry(out, inode, newEntry)
|
wfs.outputPbEntry(out, inode, newEntry)
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ func (wfs *WFS) Link(cancel <-chan struct{}, in *fuse.LinkIn, name string, out *
|
||||||
return fuse.EIO
|
return fuse.EIO
|
||||||
}
|
}
|
||||||
|
|
||||||
inode := wfs.inodeToPath.Lookup(newEntryPath, oldEntry.FileMode(), false, oldEntry.Attributes.Inode, true)
|
inode := wfs.inodeToPath.Lookup(newEntryPath, oldEntry.FileMode(), true, oldEntry.Attributes.Inode, true)
|
||||||
|
|
||||||
wfs.outputPbEntry(out, inode, request.Entry)
|
wfs.outputPbEntry(out, inode, request.Entry)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue