Skip to content

Commit

Permalink
meta: track atime for ReadLink as well
Browse files Browse the repository at this point in the history
  • Loading branch information
SandyXSD committed May 11, 2023
1 parent d002ef5 commit cdc9658
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 16 deletions.
29 changes: 24 additions & 5 deletions pkg/meta/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package meta

import (
"encoding/binary"
"encoding/json"
"fmt"
"os"
Expand Down Expand Up @@ -89,7 +90,7 @@ type engine interface {
doLink(ctx Context, inode, parent Ino, name string, attr *Attr) syscall.Errno
doUnlink(ctx Context, parent Ino, name string, attr *Attr, skipCheckTrash ...bool) syscall.Errno
doRmdir(ctx Context, parent Ino, name string, inode *Ino, skipCheckTrash ...bool) syscall.Errno
doReadlink(ctx Context, inode Ino) ([]byte, error)
doReadlink(ctx Context, inode Ino, noatime bool) (int64, []byte, error)
doReaddir(ctx Context, inode Ino, plus uint8, entries *[]*Entry, limit int) syscall.Errno
doRename(ctx Context, parentSrc Ino, nameSrc string, parentDst Ino, nameDst string, flags uint32, inode, tinode *Ino, attr, tattr *Attr) syscall.Errno
doSetXattr(ctx Context, inode Ino, name string, value []byte, flags uint32) syscall.Errno
Expand Down Expand Up @@ -1320,20 +1321,38 @@ func (m *baseMeta) Link(ctx Context, inode, parent Ino, name string, attr *Attr)
}

func (m *baseMeta) ReadLink(ctx Context, inode Ino, path *[]byte) syscall.Errno {
noatime := m.conf.AtimeMode == NoAtime || m.conf.ReadOnly
if target, ok := m.symlinks.Load(inode); ok {
*path = target.([]byte)
return 0
if noatime {
*path = target.([]byte)
return 0
} else {
buf := target.([]byte)
// ctime and mtime are ignored since symlink can't be modified
attr := &Attr{Atime: int64(binary.BigEndian.Uint64(buf[:8]))}
if !m.atimeNeedsUpdate(attr, time.Now()) {
*path = buf[8:]
return 0
}
}
}
defer m.timeit("ReadLink", time.Now())
target, err := m.en.doReadlink(ctx, inode)
atime, target, err := m.en.doReadlink(ctx, inode, noatime)
if err != nil {
return errno(err)
}
if len(target) == 0 {
return syscall.ENOENT
}
*path = target
m.symlinks.Store(inode, target)
if noatime {
m.symlinks.Store(inode, target)
} else {
buf := make([]byte, 8+len(target))
binary.BigEndian.PutUint64(buf[:8], uint64(atime))
copy(buf[8:], target)
m.symlinks.Store(inode, buf)
}
return 0
}

Expand Down
29 changes: 27 additions & 2 deletions pkg/meta/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -1169,8 +1169,33 @@ func (m *redisMeta) SetAttr(ctx Context, inode Ino, set uint16, sugidclearmode u
}, m.inodeKey(inode)))
}

func (m *redisMeta) doReadlink(ctx Context, inode Ino) ([]byte, error) {
return m.rdb.Get(ctx, m.symKey(inode)).Bytes()
func (m *redisMeta) doReadlink(ctx Context, inode Ino, noatime bool) (atime int64, target []byte, err error) {
if noatime {
target, err = m.rdb.Get(ctx, m.symKey(inode)).Bytes()
return
}

attr := &Attr{}
now := time.Now()
err = m.txn(ctx, func(tx *redis.Tx) error {
rs, e := tx.MGet(ctx, m.inodeKey(inode), m.symKey(inode)).Result()
if e != nil {
return e
}
if rs[0] == nil || rs[1] == nil {
return redis.Nil
}
m.parseAttr([]byte(rs[0].(string)), attr)
target = []byte(rs[1].(string))
if !m.atimeNeedsUpdate(attr, now) {
return nil
}
attr.Atime = now.Unix()
attr.Atimensec = uint32(now.Nanosecond())
return tx.Set(ctx, m.inodeKey(inode), m.marshal(attr), 0).Err()
}, m.inodeKey(inode))
atime = attr.Atime
return
}

func (m *redisMeta) doMknod(ctx Context, parent Ino, name string, _type uint8, mode, cumask uint16, rdev uint32, path string, inode *Ino, attr *Attr) syscall.Errno {
Expand Down
48 changes: 41 additions & 7 deletions pkg/meta/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -1130,15 +1130,49 @@ func (m *dbMeta) Fallocate(ctx Context, inode Ino, mode uint8, off uint64, size
return errno(err)
}

func (m *dbMeta) doReadlink(ctx Context, inode Ino) (target []byte, err error) {
err = m.roTxn(func(s *xorm.Session) error {
var l = symlink{Inode: inode}
ok, err := s.Get(&l)
if err == nil && ok {
target = []byte(l.Target)
func (m *dbMeta) doReadlink(ctx Context, inode Ino, noatime bool) (atime int64, target []byte, err error) {
if noatime {
err = m.roTxn(func(s *xorm.Session) error {
var l = symlink{Inode: inode}
ok, err := s.Get(&l)
if err == nil && ok {
target = l.Target
}
return err
})
return
}

attr := &Attr{}
now := time.Now()
err = m.txn(func(s *xorm.Session) error {
nodeAttr := node{Inode: inode}
ok, e := s.ForUpdate().Get(&nodeAttr)
if e != nil {
return e
}
return err
if !ok {
return syscall.ENOENT
}
l := symlink{Inode: inode}
ok, e = s.Get(&l)
if e != nil {
return e
}
if !ok {
return syscall.ENOENT
}
m.parseAttr(&nodeAttr, attr)
target = l.Target
if !m.atimeNeedsUpdate(attr, now) {
return nil
}
nodeAttr.Atime = now.Unix()*1e6 + int64(now.Nanosecond())/1e3
attr.Atime = now.Unix()
_, e = s.Cols("atime").Update(&nodeAttr, &node{Inode: inode})
return e
})
atime = attr.Atime
return
}

Expand Down
27 changes: 25 additions & 2 deletions pkg/meta/tkv.go
Original file line number Diff line number Diff line change
Expand Up @@ -1077,8 +1077,31 @@ func (m *kvMeta) Fallocate(ctx Context, inode Ino, mode uint8, off uint64, size
return errno(err)
}

func (m *kvMeta) doReadlink(ctx Context, inode Ino) ([]byte, error) {
return m.get(m.symKey(inode))
func (m *kvMeta) doReadlink(ctx Context, inode Ino, noatime bool) (atime int64, target []byte, err error) {
if noatime {
target, err = m.get(m.symKey(inode))
return
}

attr := &Attr{}
now := time.Now()
err = m.txn(func(tx *kvTxn) error {
rs := tx.gets(m.inodeKey(inode), m.symKey(inode))
if rs[0] == nil || rs[1] == nil {
return syscall.ENOENT
}
m.parseAttr(rs[0], attr)
target = rs[1]
if !m.atimeNeedsUpdate(attr, now) {
return nil
}
attr.Atime = now.Unix()
attr.Atimensec = uint32(now.Nanosecond())
tx.set(m.inodeKey(inode), m.marshal(attr))
return nil
})
atime = attr.Atime
return
}

func (m *kvMeta) doMknod(ctx Context, parent Ino, name string, _type uint8, mode, cumask uint16, rdev uint32, path string, inode *Ino, attr *Attr) syscall.Errno {
Expand Down

0 comments on commit cdc9658

Please sign in to comment.