Ejemplo n.º 1
0
/*===========================================================================*
 *				fs_utime				     *
 *===========================================================================*/
PUBLIC int fs_utime()
{
  struct puffs_node *pn;
  struct vattr va;
  PUFFS_MAKECRED(pcr, &global_kcred);

  if (is_readonly_fs)
	return(EROFS);

  if (global_pu->pu_ops.puffs_node_setattr == NULL)
	return(EINVAL);

  if( (pn = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.REQ_INODE_NR)) == NULL)
        return(EINVAL);
  
  puffs_vattr_null(&va);
  va.va_atime.tv_nsec = va.va_mtime.tv_nsec = va.va_ctime.tv_nsec = 0;
  va.va_atime.tv_sec = fs_m_in.REQ_ACTIME;
  va.va_mtime.tv_sec = fs_m_in.REQ_MODTIME;
  va.va_ctime.tv_sec = clock_time();

  if (global_pu->pu_ops.puffs_node_setattr(global_pu, pn, &va, pcr) != 0)
	return(EINVAL);

  return(OK);
}
Ejemplo n.º 2
0
/*===========================================================================*
 *                              fs_ftrunc                                    *
 *===========================================================================*/
PUBLIC int fs_ftrunc(void)
{
    int r;
    struct puffs_node *pn;
    off_t start, end;
    PUFFS_MAKECRED(pcr, &global_kcred);

    if ((pn = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.REQ_INODE_NR)) == NULL)
        return(EINVAL);

    start = fs_m_in.REQ_TRC_START_LO;
    end = fs_m_in.REQ_TRC_END_LO;

    if (end == 0) {
        struct vattr va;

        if (pn->pn_va.va_size == start)
            return(OK);

        if (global_pu->pu_ops.puffs_node_setattr == NULL)
            return(EINVAL);

        puffs_vattr_null(&va);
        va.va_size = start;

        r = global_pu->pu_ops.puffs_node_setattr(global_pu, pn, &va, pcr);
        if (r) return(EINVAL);
    } else {
        /* XXX zerofill the given region. Can we make a hole? */
        off_t bytes_left = end - start;
        char* rw_buf;

        if (global_pu->pu_ops.puffs_node_write == NULL)
            return(EINVAL);

        /* XXX split into chunks? */
        rw_buf = malloc(bytes_left);
        if (!rw_buf)
            panic("fs_ftrunc: failed to allocated memory\n");
        memset(rw_buf, 0, bytes_left);

        r = global_pu->pu_ops.puffs_node_write(global_pu, pn, (uint8_t *)rw_buf,
                                               start, (size_t *) &bytes_left, pcr, 0);
        free(rw_buf);
        if (r) return(EINVAL);
    }

    update_times(pn, CTIME | MTIME, 0);

    return(r);
}
Ejemplo n.º 3
0
int
psbuf_get_vattr(struct puffs_framebuf *pb, struct vattr *vap)
{
	uint32_t flags;
	uint32_t val;
	uint32_t tmpval;

	puffs_vattr_null(vap);

	FAILRV(psbuf_get_4(pb, &flags));

	if (flags & SSH_FILEXFER_ATTR_SIZE) {
		FAILRV(psbuf_get_8(pb, &vap->va_size));
		vap->va_bytes = vap->va_size;
	}
	if (flags & SSH_FILEXFER_ATTR_UIDGID) {
		FAILRV(psbuf_get_4(pb, &vap->va_uid));
		FAILRV(psbuf_get_4(pb, &vap->va_gid));
	}
	if (flags & SSH_FILEXFER_ATTR_PERMISSIONS) {
		FAILRV(psbuf_get_4(pb, &tmpval));
		vap->va_mode = tmpval;
		vap->va_type = puffs_mode2vt(vap->va_mode);
	}
	if (flags & SSH_FILEXFER_ATTR_ACCESSTIME) {
		/*
		 * XXX: this is utterly wrong if we want to speak
		 * protocol version 3, but it seems like the
		 * "internet standard" for doing this
		 */
		FAILRV(psbuf_get_4(pb, &val));
		vap->va_atime.tv_sec = val;
		FAILRV(psbuf_get_4(pb, &val));
		vap->va_mtime.tv_sec = val;
		/* make ctime the same as mtime */
		vap->va_ctime.tv_sec = val;

		vap->va_atime.tv_nsec = 0;
		vap->va_ctime.tv_nsec = 0;
		vap->va_mtime.tv_nsec = 0;
	}

	return 0;
}
/*
 * Well, you're probably wondering why this isn't optimized.
 * The reason is simple: my available time is not optimized for
 * size ... so please be patient ;)
 */
struct puffs_node *
puffs_pn_new(struct puffs_usermount *pu, void *privdata)
{
	struct puffs_node *pn;

	pn = calloc(1, sizeof(struct puffs_node));
	if (pn == NULL)
		return NULL;

	pn->pn_data = privdata;
	pn->pn_mnt = pu;
	puffs_vattr_null(&pn->pn_va);

	LIST_INSERT_HEAD(&pu->pu_pnodelst, pn, pn_entries);

	pu->pu_flags |= PUFFS_FLAG_PNCOOKIE;

	return pn;
}
Ejemplo n.º 5
0
struct psshfs_dir *
direnter(struct puffs_node *parent, const char *entryname)
{
	struct psshfs_node *psn_parent = parent->pn_data;
	struct psshfs_dir *pd;
	int i;

	/* create directory entry */
	if (psn_parent->denttot == psn_parent->dentnext)
		allocdirs(psn_parent);

	i = psn_parent->dentnext;
	pd = &psn_parent->dir[i];
	pd->entryname = estrdup(entryname);
	pd->valid = 1;
	pd->attrread = 0;
	puffs_vattr_null(&pd->va);
	psn_parent->dentnext++;

	return pd;
}
Ejemplo n.º 6
0
/*===========================================================================*
 *				fs_readwrite				     *
 *===========================================================================*/
PUBLIC int fs_readwrite(void)
{
  int r = OK, rw_flag;
  cp_grant_id_t gid;
  off_t pos;
  size_t nrbytes, bytes_left, bytes_done;
  struct puffs_node *pn;
  struct vattr va;
  PUFFS_MAKECRED(pcr, &global_kcred);

  if ((pn = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.REQ_INODE_NR)) == NULL) {
  	lpuffs_debug("walk failed...\n");
        return(EINVAL);
  }

  /* Get the values from the request message */
  rw_flag = (fs_m_in.m_type == REQ_READ ? READING : WRITING);
  gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
  pos = (off_t) fs_m_in.REQ_SEEK_POS_LO;
  nrbytes = bytes_left = (size_t) fs_m_in.REQ_NBYTES;

  if (nrbytes > RW_BUFSIZ)
	nrbytes = bytes_left = RW_BUFSIZ;

  memset(getdents_buf, '\0', RW_BUFSIZ);  /* Avoid leaking any data */

  if (rw_flag == READING) {
	if (global_pu->pu_ops.puffs_node_read == NULL)
		return(EINVAL);

	r = global_pu->pu_ops.puffs_node_read(global_pu, pn, (uint8_t *)rw_buf,
						pos, &bytes_left, pcr, 0);
	if (r) {
		lpuffs_debug("puffs_node_read failed\n");
		return(EINVAL);
	}

	bytes_done = nrbytes - bytes_left;
	if (bytes_done) {
		r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) 0,
				   (vir_bytes) rw_buf, bytes_done, D);
		update_times(pn, ATIME, 0);
	}
  } else if (rw_flag == WRITING) {
	/* At first try to change vattr */
	if (global_pu->pu_ops.puffs_node_setattr == NULL)
		return(EINVAL);

	puffs_vattr_null(&va);
	if ( (pos + bytes_left) > pn->pn_va.va_size)
		va.va_size = bytes_left + pos;
	va.va_ctime.tv_sec = va.va_mtime.tv_sec = clock_time();
	va.va_atime.tv_sec = pn->pn_va.va_atime.tv_sec;

	r = global_pu->pu_ops.puffs_node_setattr(global_pu, pn, &va, pcr);
	if (r) return(EINVAL);

	r = sys_safecopyfrom(VFS_PROC_NR, gid, (vir_bytes) 0,
			     (vir_bytes) rw_buf, nrbytes, D);
	if (r != OK) return(EINVAL);

	if (global_pu->pu_ops.puffs_node_write == NULL)
		return(EINVAL);

	r = global_pu->pu_ops.puffs_node_write(global_pu, pn, (uint8_t *)rw_buf,
						pos, &bytes_left, pcr, 0);
	bytes_done = nrbytes - bytes_left;
  }

  if (r != OK) return(EINVAL);

  fs_m_out.RES_SEEK_POS_LO = pos + bytes_done;
  fs_m_out.RES_NBYTES = bytes_done;

  return(r);
}