fn write()

in src/fs.rs [586:664]


    fn write(
        &mut self,
        _req: &Request<'_>,
        inode: u64,
        fh: u64,
        offset: i64,
        data: &[u8],
        _write_flags: u32,
        _flags: i32,
        _lock_owner: Option<u64>,
        reply: ReplyWrite,
    ) {
        let now = SystemTime::now();
        debug!(
            "Got a write request. inode={}, fh={}, offset={}, size={}",
            inode,
            fh,
            offset,
            data.len()
        );

        let fh_clone = fh;
        let mut fh_map = self.file_handles.write().unwrap();
        let cursor_or_none = fh_map.get_mut(&fh_clone);

        if cursor_or_none.is_none() {
            error!("write(): didn't find the fh {}", fh);
            reply.error(libc::EBADF);
            return;
        }

        let inode_clone = inode;
        let mut attr_map = self.inode_to_attr.write().unwrap();
        let attr_or_none = attr_map.get_mut(&inode_clone);
        if attr_or_none.is_none() {
            error!("write(): Didn't find inode {}", inode);
            reply.error(libc::EBADF);
            return;
        }

        let cursor = cursor_or_none.unwrap();
        let remaining = cursor.buffer.capacity() - cursor.buffer.len();
        let cursor_position = cursor.offset + (cursor.buffer.len() as u64);

        debug!(
            "cursor has URI {}, offset {}, 'position' {}, and remaining {}",
            cursor.session_uri, cursor.offset, cursor_position, remaining
        );

        // Only allow writing at the offset.
        if (offset as u64) != cursor_position {
            error!(
                "Got a write for offset {}. But cursor is at {} (we only support appending)",
                offset, cursor_position
            );
            reply.error(libc::EINVAL);
            return;
        }

        let result = self.tokio_rt.block_on(async {
            super::gcs::append_bytes_with_client(&self.gcs_client, cursor, data).await
        });

        if result.is_err() {
            reply.error(libc::EIO);
            return;
        }

        let len = result.unwrap() as u64;

        // We wrote the bytes! Update our attrs.
        reply.written(len as u32);
        let mut attr = attr_or_none.unwrap();
        // Update our atime/mtime.
        attr.atime = now;
        attr.mtime = now;
        // Update the bytes written.
        attr.size += len;
    }