func()

in internal/fs/inode/file.go [462:529]


func (f *FileInode) Attributes(
	ctx context.Context) (attrs fuseops.InodeAttributes, err error) {
	attrs = f.attrs

	// Obtain default information from the source object.
	attrs.Mtime = f.src.Updated
	attrs.Size = f.src.Size

	// If the source object has an mtime metadata key, use that instead of its
	// update time.
	// If the file was copied via gsutil, we'll have goog-reserved-file-mtime
	if strTimestamp, ok := f.src.Metadata["goog-reserved-file-mtime"]; ok {
		if timestamp, err := strconv.ParseInt(strTimestamp, 0, 64); err == nil {
			attrs.Mtime = time.Unix(timestamp, 0)
		}
	}

	// Otherwise, if its been synced with gcsfuse before, we'll have gcsfuse_mtime
	if formatted, ok := f.src.Metadata["gcsfuse_mtime"]; ok {
		attrs.Mtime, err = time.Parse(time.RFC3339Nano, formatted)
		if err != nil {
			err = fmt.Errorf("time.Parse(%q): %w", formatted, err)
			return
		}
	}

	// If we've got local content, its size and (maybe) mtime take precedence.
	if f.content != nil {
		var sr gcsx.StatResult
		sr, err = f.content.Stat()
		if err != nil {
			err = fmt.Errorf("stat: %w", err)
			return
		}

		attrs.Size = uint64(sr.Size)
		if sr.Mtime != nil {
			attrs.Mtime = *sr.Mtime
		}
	}

	if f.bwh != nil {
		writeFileInfo := f.bwh.WriteFileInfo()
		attrs.Mtime = writeFileInfo.Mtime
		attrs.Size = uint64(writeFileInfo.TotalSize)
	}

	// We require only that atime and ctime be "reasonable".
	attrs.Atime = attrs.Mtime
	attrs.Ctime = attrs.Mtime

	// If the object has been clobbered, we reflect that as the inode being
	// unlinked.
	_, clobbered, err := f.clobbered(ctx, false, false)
	if err != nil {
		err = fmt.Errorf("clobbered: %w", err)
		return
	}

	attrs.Nlink = 1

	// For local files, also checking if file is unlinked locally.
	if clobbered || (f.IsLocal() && f.IsUnlinked()) {
		attrs.Nlink = 0
	}

	return
}