Update lisafs to handle size=0 for FGetXattr RPC.

As per getxattr(2), if size=0 the syscall should return the size of the
attribute value. In the case of lisafs (and even 9P), the GetXattr RPC returns
a string, not an integer. The semantics here should be that if size=0, then the
entire attribute value is returned. 9P already implements this. Update lisafs
to do so.

PiperOrigin-RevId: 429717050
This commit is contained in:
Ayush Ranjan
2022-02-18 23:20:54 -08:00
committed by gVisor bot
parent 901ff4e06d
commit 6e5b602ee1
4 changed files with 23 additions and 9 deletions
+1 -1
View File
@@ -101,7 +101,7 @@ func NewClient(sock *unet.Socket) (*Client, Inode, error) {
mountReq MountReq
mountResp MountResp
)
if err := c.SndRcvMessage(Mount, uint32(mountReq.SizeBytes()), mountReq.MarshalBytes, mountResp.CheckedUnmarshal, nil, mountResp.String, mountResp.String); err != nil {
if err := c.SndRcvMessage(Mount, uint32(mountReq.SizeBytes()), mountReq.MarshalBytes, mountResp.CheckedUnmarshal, nil, mountReq.String, mountResp.String); err != nil {
return nil, Inode{}, err
}
+9 -4
View File
@@ -458,13 +458,18 @@ type ControlFDImpl interface {
Renamed()
// GetXattr returns extended attributes of this file. It returns the number
// of bytes written into dataBuf.
// of bytes written into the buffer returned by getValueBuf which can be used
// to request buffer for some size.
//
// If the value is larger than len(dataBuf), implementations may return
// ERANGE to indicate that the buffer is too small.
// If the value is larger than size, implementations may return ERANGE to
// indicate that the buffer is too small.
//
// N.B. size may be 0, in which can the implementation must first find out
// the attribute value size using getxattr(2) by passing size=0. Then request
// a buffer large enough using getValueBuf and write the value there.
//
// On the server, GetXattr has a read concurrency guarantee.
GetXattr(name string, dataBuf []byte) (uint16, error)
GetXattr(name string, size uint32, getValueBuf func(uint32) []byte) (uint16, error)
// SetXattr sets extended attributes on this file.
//
+4 -2
View File
@@ -1295,17 +1295,19 @@ func FGetXattrHandler(c *Connection, comm Communicator, payloadLen uint32) (uint
// FGetXattrResp simply is a wrapper around SizedString.
var valueLen primitive.Uint16
respMetaSize := uint32(valueLen.SizeBytes())
payloadBuf := comm.PayloadBuf(respMetaSize + uint32(req.BufSize))
var n uint16
if err := fd.safelyRead(func() error {
if fd.node.isDeleted() {
return unix.EINVAL
}
n, err = fd.impl.GetXattr(string(req.Name), payloadBuf[respMetaSize:])
n, err = fd.impl.GetXattr(string(req.Name), uint32(req.BufSize), func(dataLen uint32) []byte {
return comm.PayloadBuf(dataLen + respMetaSize)[respMetaSize:]
})
return err
}); err != nil {
return 0, err
}
payloadBuf := comm.PayloadBuf(respMetaSize)
valueLen = primitive.Uint16(n)
valueLen.MarshalBytes(payloadBuf)
return respMetaSize + uint32(n), nil
+9 -2
View File
@@ -668,14 +668,21 @@ func (fd *controlFDLisa) Renamed() {
}
// GetXattr implements lisafs.ControlFDImpl.GetXattr.
func (fd *controlFDLisa) GetXattr(name string, dataBuf []byte) (uint16, error) {
func (fd *controlFDLisa) GetXattr(name string, size uint32, getValueBuf func(uint32) []byte) (uint16, error) {
if !fd.Conn().ServerImpl().(*LisafsServer).config.EnableVerityXattr {
return 0, unix.EOPNOTSUPP
}
if _, ok := verityXattrs[name]; !ok {
return 0, unix.EOPNOTSUPP
}
n, err := unix.Fgetxattr(fd.hostFD, name, dataBuf)
if size == 0 {
n, err := unix.Fgetxattr(fd.hostFD, name, nil)
if err != nil {
return 0, err
}
size = uint32(n)
}
n, err := unix.Fgetxattr(fd.hostFD, name, getValueBuf(size))
return uint16(n), err
}