Exemplo n.º 1
0
static int
sfs_namefile(struct inode *node, struct iobuf *iob) {
    struct sfs_disk_entry *entry;
    if (iob->io_resid <= 2 || (entry = kmalloc(sizeof(struct sfs_disk_entry))) == NULL) {
        return -E_NO_MEM;
    }

    struct sfs_fs *sfs = fsop_info(vop_fs(node), sfs);
    struct sfs_inode *sin = vop_info(node, sfs_inode);

    int ret;
    uint32_t ino;
    char *ptr = iob->io_base + iob->io_resid;
    size_t alen, resid = iob->io_resid - 2;
    
    vop_ref_inc(node);
    while ((ino = sin->ino) != SFS_BLKN_ROOT) {
        struct inode *parent;
        if ((ret = sfs_load_parent(sfs, sin, &parent)) != 0) {
            goto failed;
        }
        vop_ref_dec(node);
        
        node = parent, sin = vop_info(node, sfs_inode);
        assert(ino != sin->ino && sin->din->type == SFS_TYPE_DIR);

        if ((ret = trylock_sin(sin)) != 0) {
            goto failed;
        }
        ret = sfs_dirent_findino_nolock(sfs, sin, ino, entry);
        unlock_sin(sin);

        if (ret != 0) {
            goto failed;
        }

        if ((alen = strlen(entry->name) + 1) > resid) {
            goto failed_nomem;
        }
        resid -= alen, ptr -= alen;
        memcpy(ptr, entry->name, alen - 1);
        ptr[alen - 1] = '/';
    }
    vop_ref_dec(node);
    alen = iob->io_resid - resid - 2;
    ptr = memmove(iob->io_base + 1, ptr, alen);
    ptr[-1] = '/', ptr[alen] = '\0';
    iobuf_skip(iob, alen);
    kfree(entry);
    return 0;

failed_nomem:
    ret = -E_NO_MEM;
failed:
    vop_ref_dec(node);
    kfree(entry);
    return ret;
}
Exemplo n.º 2
0
static int pipe_inode_write(struct inode *node, struct iobuf *iob)
{
	struct pipe_inode *pin = vop_info(node, pipe_inode);
	if (pin->pin_type != PIN_WRONLY) {
		return -E_INVAL;
	}
	size_t ret;
	if ((ret =
	     pipe_state_write(pin->state, iob->io_base, iob->io_resid)) != 0) {
		iobuf_skip(iob, ret);
	}
	return 0;
}
Exemplo n.º 3
0
static int pipe_inode_namefile(struct inode *node, struct iobuf *iob)
{
	struct pipe_inode *pin = vop_info(node, pipe_inode);
	size_t len = (pin->name != NULL) ? strlen(pin->name) : 0;
	if (iob->io_resid < len + 1) {
		return -E_NO_MEM;
	}
	if (pin->name != NULL) {
		memcpy(iob->io_base, pin->name, len);
	}
	((char *)(iob->io_base))[len++] = '\0';
	iobuf_skip(iob, len);
	return 0;
}
Exemplo n.º 4
0
static int pipe_inode_write(struct inode *node, struct iobuf *iob, int io_flags)
{
  bool no_block = (io_flags & O_NONBLOCK) ? 1 : 0;
	struct pipe_inode *pin = vop_info(node, pipe_inode);
	if (pin->pin_type != PIN_WRONLY) {
		return -E_INVAL;
	}
	size_t ret;
	if ((ret =
	     pipe_state_write(pin->state, iob->io_base, iob->io_resid, no_block)) != 0) {
		iobuf_skip(iob, ret);
	}
	return 0;
}
Exemplo n.º 5
0
/*
 * iobuf_move_zeros - set io buffer zero
 * @copiedp:  the size of data memcopied
 */
int
iobuf_move_zeros(struct iobuf *iob, size_t len, size_t *copiedp) {
    size_t alen;
    if ((alen = iob->io_resid) > len) {
        alen = len;
    }
    if (alen > 0) {
        memset(iob->io_base, 0, alen);
        iobuf_skip(iob, alen), len -= alen;
    }
    if (copiedp != NULL) {
        *copiedp = alen;
    }
    return (len == 0) ? 0 : -E_NO_MEM;
}
Exemplo n.º 6
0
/*
 * sfs_io - Rd/Wr file. the wrapper of sfs_io_nolock
            with lock protect
 */
static inline int
sfs_io(struct inode *node, struct iobuf *iob, bool write) {
    struct sfs_fs *sfs = fsop_info(vop_fs(node), sfs);
    struct sfs_inode *sin = vop_info(node, sfs_inode);
    int ret;
    lock_sin(sin);
    {
        size_t alen = iob->io_resid;
        ret = sfs_io_nolock(sfs, sin, iob->io_base, iob->io_offset, &alen, write);
        if (alen != 0) {
            iobuf_skip(iob, alen);
        }
    }
    unlock_sin(sin);
    return ret;
}
Exemplo n.º 7
0
/* iobuf_move - move data  (iob->io_base ---> data OR  data --> iob->io.base) in memory
 * @copiedp:  the size of data memcopied
 *
 * iobuf_move may be called repeatedly on the same io to transfer
 * additional data until the available buffer space the io refers to
 * is exhausted.
 */
int
iobuf_move(struct iobuf *iob, void *data, size_t len, bool m2b, size_t *copiedp) {
    size_t alen;
    if ((alen = iob->io_resid) > len) {
        alen = len;
    }
    if (alen > 0) {
        void *src = iob->io_base, *dst = data;
        if (m2b) {
            void *tmp = src;
            src = dst, dst = tmp;
        }
        memmove(dst, src, alen);
        iobuf_skip(iob, alen), len -= alen;
    }
    if (copiedp != NULL) {
        *copiedp = alen;
    }
    return (len == 0) ? 0 : -E_NO_MEM;
}