Example #1
0
static int
zpl_sync_fs(struct super_block *sb, int wait)
{
    fstrans_cookie_t cookie;
    cred_t *cr = CRED();
    int error;

    crhold(cr);
    cookie = spl_fstrans_mark();
    error = -zfs_sync(sb, wait, cr);
    spl_fstrans_unmark(cookie);
    crfree(cr);
    ASSERT3S(error, <=, 0);

    return (error);
}
Example #2
0
static int
zpl_rmdir(struct inode * dir, struct dentry *dentry)
{
	cred_t *cr = CRED();
	int error;
	fstrans_cookie_t cookie;

	crhold(cr);
	cookie = spl_fstrans_mark();
	error = -zfs_rmdir(dir, dname(dentry), NULL, cr, 0);
	spl_fstrans_unmark(cookie);
	crfree(cr);
	ASSERT3S(error, <=, 0);

	return (error);
}
Example #3
0
/*
 * Linux 2.6.x - 2.6.34 API,
 * Through 2.6.34 the nfsd kernel server would pass a NULL 'file struct *'
 * to the fops->fsync() hook.  For this reason, we must be careful not to
 * use filp unconditionally.
 */
static int
zpl_fsync(struct file *filp, struct dentry *dentry, int datasync)
{
	cred_t *cr = CRED();
	int error;
	fstrans_cookie_t cookie;

	crhold(cr);
	cookie = spl_fstrans_mark();
	error = -zfs_fsync(dentry->d_inode, datasync, cr);
	spl_fstrans_unmark(cookie);
	crfree(cr);
	ASSERT3S(error, <=, 0);

	return (error);
}
Example #4
0
static ssize_t
zpl_iter_read_common(struct kiocb *kiocb, const struct iovec *iovp,
    unsigned long nr_segs, size_t count, uio_seg_t seg, size_t skip)
{
	cred_t *cr = CRED();
	struct file *filp = kiocb->ki_filp;
	ssize_t read;

	crhold(cr);
	read = zpl_read_common_iovec(filp->f_mapping->host, iovp, count,
	    nr_segs, &kiocb->ki_pos, seg, filp->f_flags, cr, skip);
	crfree(cr);

	file_accessed(filp);
	return (read);
}
Example #5
0
static int
zpl_iterate(struct file *filp, struct dir_context *ctx)
{
	cred_t *cr = CRED();
	int error;
	fstrans_cookie_t cookie;

	crhold(cr);
	cookie = spl_fstrans_mark();
	error = -zfs_readdir(file_inode(filp), ctx, cr);
	spl_fstrans_unmark(cookie);
	crfree(cr);
	ASSERT3S(error, <=, 0);

	return (error);
}
Example #6
0
static int
zpl_commit_metadata(struct inode *inode)
{
	cred_t *cr = CRED();
	fstrans_cookie_t cookie;
	int error;

	crhold(cr);
	cookie = spl_fstrans_mark();
	error = -zfs_fsync(inode, 0, cr);
	spl_fstrans_unmark(cookie);
	crfree(cr);
	ASSERT3S(error, <=, 0);

	return (error);
}
Example #7
0
/*
 * Get the "ucred" of a process.
 */
struct ucred_s *
pgetucred(proc_t *p)
{
	cred_t *cr;
	struct ucred_s *uc;

	mutex_enter(&p->p_crlock);
	cr = p->p_cred;
	crhold(cr);
	mutex_exit(&p->p_crlock);

	uc = cred2ucred(cr, p->p_pid, NULL, CRED());
	crfree(cr);

	return (uc);
}
Example #8
0
/*
 * When relabeling a process, call out to the policies for the maximum
 * permission allowed for each object type we know about in its memory space,
 * and revoke access (in the least surprising ways we know) when necessary.
 * The process lock is not held here.
 */
void
mac_proc_vm_revoke(struct thread *td)
{
	struct ucred *cred;

	PROC_LOCK(td->td_proc);
	cred = crhold(td->td_proc->p_ucred);
	PROC_UNLOCK(td->td_proc);

	/* XXX freeze all other threads */
	mac_proc_vm_revoke_recurse(td, cred,
	    &td->td_proc->p_vmspace->vm_map);
	/* XXX allow other threads to continue */

	crfree(cred);
}
Example #9
0
static int
zpl_xattr_set(struct inode *ip, const char *name, const void *value,
    size_t size, int flags)
{
	znode_t *zp = ITOZ(ip);
	zfs_sb_t *zsb = ZTOZSB(zp);
	cred_t *cr = CRED();
	int error;

	crhold(cr);
	rw_enter(&ITOZ(ip)->z_xattr_lock, RW_WRITER);

	/*
	 * Before setting the xattr check to see if it already exists.
	 * This is done to ensure the following optional flags are honored.
	 *
	 *   XATTR_CREATE: fail if xattr already exists
	 *   XATTR_REPLACE: fail if xattr does not exist
	 */
	error = __zpl_xattr_get(ip, name, NULL, 0, cr);
	if (error < 0) {
		if (error != -ENODATA)
			goto out;

		if ((error == -ENODATA) && (flags & XATTR_REPLACE))
			goto out;
	} else {
		error = -EEXIST;
		if (flags & XATTR_CREATE)
			goto out;
	}

	/* Preferentially store the xattr as a SA for better performance */
	if (zsb->z_use_sa && zsb->z_xattr_sa && zp->z_is_sa) {
		error = zpl_xattr_set_sa(ip, name, value, size, flags, cr);
		if (error == 0)
			goto out;
	}

	error = zpl_xattr_set_dir(ip, name, value, size, flags, cr);
out:
	rw_exit(&ITOZ(ip)->z_xattr_lock);
	crfree(cr);
	ASSERT3S(error, <=, 0);

	return (error);
}
Example #10
0
const char *
zpl_follow_link(struct dentry *dentry, void **symlink_cookie)
#endif
{
	cred_t *cr = CRED();
	struct inode *ip = dentry->d_inode;
	struct iovec iov;
	uio_t uio;
	char *link;
	int error;
	fstrans_cookie_t cookie;

	crhold(cr);

	iov.iov_len = MAXPATHLEN;
	iov.iov_base = link = kmem_zalloc(MAXPATHLEN, KM_SLEEP);

	uio.uio_iov = &iov;
	uio.uio_iovcnt = 1;
	uio.uio_skip = 0;
	uio.uio_resid = (MAXPATHLEN - 1);
	uio.uio_segflg = UIO_SYSSPACE;

	cookie = spl_fstrans_mark();
	error = -zfs_readlink(ip, &uio, cr);
	spl_fstrans_unmark(cookie);

	if (error)
		kmem_free(link, MAXPATHLEN);

	crfree(cr);

#ifdef HAVE_FOLLOW_LINK_NAMEIDATA
	if (error)
		nd_set_link(nd, ERR_PTR(error));
	else
		nd_set_link(nd, link);

	return (NULL);
#else
	if (error)
		return (ERR_PTR(error));
	else
		return (*symlink_cookie = link);
#endif
}
Example #11
0
static int
zpl_iterate(struct file *filp, struct dir_context *ctx)
{
	struct dentry *dentry = filp->f_path.dentry;
	cred_t *cr = CRED();
	int error;
	fstrans_cookie_t cookie;

	crhold(cr);
	cookie = spl_fstrans_mark();
	error = -zfs_readdir(dentry->d_inode, ctx, cr);
	spl_fstrans_unmark(cookie);
	crfree(cr);
	ASSERT3S(error, <=, 0);

	return (error);
}
Example #12
0
static ssize_t
zpl_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
{
	cred_t *cr = CRED();
	ssize_t read;

	crhold(cr);
	read = zpl_read_common(filp->f_mapping->host, buf, len, *ppos,
	    UIO_USERSPACE, filp->f_flags, cr);
	crfree(cr);

	if (read < 0)
		return (read);

	*ppos += read;
	return (read);
}
Example #13
0
/*
 * Linux 2.6.35 - 3.0 API,
 * As of 2.6.35 the dentry argument to the fops->fsync() hook was deemed
 * redundant.  The dentry is still accessible via filp->f_path.dentry,
 * and we are guaranteed that filp will never be NULL.
 */
static int
zpl_fsync(struct file *filp, int datasync)
{
	struct inode *inode = filp->f_mapping->host;
	cred_t *cr = CRED();
	int error;
	fstrans_cookie_t cookie;

	crhold(cr);
	cookie = spl_fstrans_mark();
	error = -zfs_fsync(inode, datasync, cr);
	spl_fstrans_unmark(cookie);
	crfree(cr);
	ASSERT3S(error, <=, 0);

	return (error);
}
Example #14
0
static struct dentry *
zpl_get_parent(struct dentry *child)
{
	cred_t *cr = CRED();
	struct inode *ip;
	int error;

	crhold(cr);
	error = -zfs_lookup(child->d_inode, "..", &ip, 0, cr, NULL, NULL);
	crfree(cr);
	ASSERT3S(error, <=, 0);

	if (error)
		return ERR_PTR(error);

	return zpl_dentry_obtain_alias(ip);
}
Example #15
0
static ssize_t
zpl_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
{
	cred_t *cr = CRED();
	ssize_t wrote;

	crhold(cr);
	wrote = zpl_write_common(filp->f_mapping->host, buf, len, *ppos,
	    UIO_USERSPACE, filp->f_flags, cr);
	crfree(cr);

	if (wrote < 0)
		return (wrote);

	*ppos += wrote;
	return (wrote);
}
Example #16
0
/*
 * Passively intercepts the thread switch function to increase the thread
 * priority from a user priority to a kernel priority, reducing
 * syscall and trap overhead for the case where no switch occurs.
 *
 * Synchronizes td_ucred with p_ucred.  This is used by system calls,
 * signal handling, faults, AST traps, and anything else that enters the
 * kernel from userland and provides the kernel with a stable read-only
 * copy of the process ucred.
 */
static __inline void
userenter(struct thread *curtd, struct proc *curp)
{
	struct ucred *ocred;
	struct ucred *ncred;

	curtd->td_release = lwkt_passive_release;

	if (curtd->td_ucred != curp->p_ucred) {
		ncred = crhold(curp->p_ucred);
		ocred = curtd->td_ucred;
		curtd->td_ucred = ncred;
		if (ocred)
			crfree(ocred);
	}

}
Example #17
0
static int
zpl_rename(struct inode *sdip, struct dentry *sdentry,
    struct inode *tdip, struct dentry *tdentry)
{
	cred_t *cr = CRED();
	int error;
	fstrans_cookie_t cookie;

	crhold(cr);
	cookie = spl_fstrans_mark();
	error = -zfs_rename(sdip, dname(sdentry), tdip, dname(tdentry), cr, 0);
	spl_fstrans_unmark(cookie);
	crfree(cr);
	ASSERT3S(error, <=, 0);

	return (error);
}
Example #18
0
static int
zpl_open(struct inode *ip, struct file *filp)
{
	cred_t *cr = CRED();
	int error;

	error = generic_file_open(ip, filp);
	if (error)
		return (error);

	crhold(cr);
	error = -zfs_open(ip, filp->f_mode, filp->f_flags, cr);
	crfree(cr);
	ASSERT3S(error, <=, 0);

	return (error);
}
Example #19
0
long
zpl_fallocate_common(struct inode *ip, int mode, loff_t offset, loff_t len)
{
	int error = -EOPNOTSUPP;

#if defined(FALLOC_FL_PUNCH_HOLE) && defined(FALLOC_FL_KEEP_SIZE)
	cred_t *cr = CRED();
	flock64_t bf;
	loff_t olen;
	fstrans_cookie_t cookie;

	if (mode != (FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
		return (error);

	crhold(cr);

	if (offset < 0 || len <= 0)
		return (-EINVAL);

	spl_inode_lock(ip);
	olen = i_size_read(ip);

	if (offset > olen) {
		spl_inode_unlock(ip);
		return (0);
	}
	if (offset + len > olen)
		len = olen - offset;
	bf.l_type = F_WRLCK;
	bf.l_whence = 0;
	bf.l_start = offset;
	bf.l_len = len;
	bf.l_pid = 0;

	cookie = spl_fstrans_mark();
	error = -zfs_space(ip, F_FREESP, &bf, FWRITE, offset, cr);
	spl_fstrans_unmark(cookie);
	spl_inode_unlock(ip);

	crfree(cr);
#endif /* defined(FALLOC_FL_PUNCH_HOLE) && defined(FALLOC_FL_KEEP_SIZE) */

	ASSERT3S(error, <=, 0);
	return (error);
}
Example #20
0
int
pts_alloc_external(int fflags, struct thread *td, struct file *fp,
    struct cdev *dev, const char *name)
{
	int ok, error;
	struct tty *tp;
	struct pts_softc *psc;
	struct proc *p = td->td_proc;
	struct ucred *cred = td->td_ucred;

	/* Resource limiting. */
	PROC_LOCK(p);
	error = racct_add(p, RACCT_NPTS, 1);
	if (error != 0) {
		PROC_UNLOCK(p);
		return (EAGAIN);
	}
	ok = chgptscnt(cred->cr_ruidinfo, 1, lim_cur(td, RLIMIT_NPTS));
	if (!ok) {
		racct_sub(p, RACCT_NPTS, 1);
		PROC_UNLOCK(p);
		return (EAGAIN);
	}
	PROC_UNLOCK(p);

	/* Allocate TTY and softc. */
	psc = malloc(sizeof(struct pts_softc), M_PTS, M_WAITOK|M_ZERO);
	cv_init(&psc->pts_inwait, "ptsin");
	cv_init(&psc->pts_outwait, "ptsout");

	psc->pts_unit = -1;
	psc->pts_cdev = dev;
	psc->pts_cred = crhold(cred);

	tp = tty_alloc(&pts_class, psc);
	knlist_init_mtx(&psc->pts_inpoll.si_note, tp->t_mtx);
	knlist_init_mtx(&psc->pts_outpoll.si_note, tp->t_mtx);

	/* Expose the slave device as well. */
	tty_makedev(tp, td->td_ucred, "%s", name);

	finit(fp, fflags, DTYPE_PTS, tp, &ptsdev_ops);

	return (0);
}
Example #21
0
cfs_file_t *
kern_file_open(const char * filename, int flags, int mode, int *err)
{
	struct nameidata nd;
	cfs_file_t	*fp;
	register struct vnode	*vp;
	int			rc;
	extern struct fileops	vnops;
	extern int nfiles;
        CFS_DECL_CONE_DATA;

        CFS_CONE_IN;
	nfiles++;
	MALLOC_ZONE(fp, cfs_file_t *, sizeof(cfs_file_t), M_FILE, M_WAITOK|M_ZERO);
	bzero(fp, sizeof(cfs_file_t));
	fp->f_count = 1;
        LIST_CIRCLE(fp, f_list);
	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, (char *)filename, current_proc());
	if ((rc = vn_open(&nd, flags, mode)) != 0){
                printf("filp_open failed at (%d)\n", rc);
                if (err != NULL)
                        *err = rc;
                FREE_ZONE(fp, sizeof *fp, M_FILE);
                CFS_CONE_EX;
		return NULL;
	}
	vp = nd.ni_vp;
	fp->f_flag = flags & FMASK;
	fp->f_type = DTYPE_VNODE;
	fp->f_ops = &vnops;
	fp->f_data = (caddr_t)vp;
	fp->f_cred = current_proc()->p_ucred;
	/*
	 * Hold cred to increase reference
	 */
	crhold(fp->f_cred);
	/*
	 * vnode is locked inside vn_open for lookup,
	 * we should release the lock before return
	 */
	VOP_UNLOCK(vp, 0, current_proc());
        CFS_CONE_EX;

	return fp;
}
Example #22
0
static int
zpl_xattr_get(struct inode *ip, const char *name, void *value, size_t size)
{
	znode_t *zp = ITOZ(ip);
	cred_t *cr = CRED();
	fstrans_cookie_t cookie;
	int error;

	crhold(cr);
	cookie = spl_fstrans_mark();
	rw_enter(&zp->z_xattr_lock, RW_READER);
	error = __zpl_xattr_get(ip, name, value, size, cr);
	rw_exit(&zp->z_xattr_lock);
	spl_fstrans_unmark(cookie);
	crfree(cr);

	return (error);
}
Example #23
0
/*
 * Linux 3.1 - 3.x API,
 * As of 3.1 the responsibility to call filemap_write_and_wait_range() has
 * been pushed down in to the .fsync() vfs hook.  Additionally, the i_mutex
 * lock is no longer held by the caller, for zfs we don't require the lock
 * to be held so we don't acquire it.
 */
static int
zpl_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
{
	struct inode *inode = filp->f_mapping->host;
	cred_t *cr = CRED();
	int error;

	error = filemap_write_and_wait_range(inode->i_mapping, start, end);
	if (error)
		return (error);

	crhold(cr);
	error = -zfs_fsync(inode, datasync, cr);
	crfree(cr);
	ASSERT3S(error, <=, 0);

	return (error);
}
Example #24
0
void
osi_Init(void)
{
    static int once = 0;
    if (once++ > 0)		/* just in case */
	return;

    osi_InitGlock();

    if (!afs_osicred_initialized) {
#if defined(AFS_DARWIN80_ENV)
        afs_osi_ctxtp_initialized = 0;
        afs_osi_ctxtp = NULL; /* initialized in afs_Daemon since it has
                                  a proc reference that cannot be changed */
#endif
#if defined(AFS_XBSD_ENV)
	/* Can't just invent one, must use crget() because of mutex */
	afs_osi_credp =
	  crdup(osi_curcred());
#elif defined(AFS_SUN5_ENV)
	afs_osi_credp = kcred;
#else
	memset(&afs_osi_cred, 0, sizeof(afs_ucred_t));
#if defined(AFS_LINUX26_ENV)
        afs_set_cr_group_info(&afs_osi_cred, groups_alloc(0));
#endif
#if defined(AFS_DARWIN80_ENV)
        afs_osi_cred.cr_ref = 1; /* kauth_cred_get_ref needs 1 existing ref */
#else
# if !(defined(AFS_LINUX26_ENV) && defined(STRUCT_TASK_STRUCT_HAS_CRED))
	crhold(&afs_osi_cred);  /* don't let it evaporate */
# endif
#endif

	afs_osi_credp = &afs_osi_cred;
#endif
	afs_osicred_initialized = 1;
    }
#ifdef AFS_SGI64_ENV
    osi_flid.fl_pid = osi_flid.fl_sysid = 0;
#endif

    init_et_to_sys_error();
}
Example #25
0
static int
zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
{
	cred_t *cr = CRED();
	vattr_t *vap;
	struct inode *ip;
	int error;

	crhold(cr);
	vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
	zpl_vap_init(vap, dir, dentry, S_IFLNK | S_IRWXUGO, cr);

	error = -zfs_symlink(dir, dname(dentry), vap, (char *)name, &ip, cr, 0);
	kmem_free(vap, sizeof(vattr_t));
	crfree(cr);
	ASSERT3S(error, <=, 0);

	return (error);
}
Example #26
0
static int
zpl_mkdir(struct inode *dir, struct dentry *dentry, zpl_umode_t mode)
{
	cred_t *cr = CRED();
	vattr_t *vap;
	struct inode *ip;
	int error;

	crhold(cr);
	vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
	zpl_vap_init(vap, dir, dentry, mode | S_IFDIR, cr);

	error = -zfs_mkdir(dir, dname(dentry), vap, &ip, cr, 0, NULL);
	kmem_free(vap, sizeof(vattr_t));
	crfree(cr);
	ASSERT3S(error, <=, 0);

	return (error);
}
Example #27
0
static int
zpl_release(struct inode *ip, struct file *filp)
{
	cred_t *cr = CRED();
	int error;
	fstrans_cookie_t cookie;

	cookie = spl_fstrans_mark();
	if (ITOZ(ip)->z_atime_dirty)
		zfs_mark_inode_dirty(ip);

	crhold(cr);
	error = -zfs_close(ip, filp->f_flags, cr);
	spl_fstrans_unmark(cookie);
	crfree(cr);
	ASSERT3S(error, <=, 0);

	return (error);
}
Example #28
0
static int
filemon_open(struct cdev *dev, int oflags __unused, int devtype __unused,
    struct thread *td)
{
	int error;
	struct filemon *filemon;

	filemon = malloc(sizeof(*filemon), M_FILEMON,
	    M_WAITOK | M_ZERO);
	sx_init(&filemon->lock, "filemon");
	refcount_init(&filemon->refcnt, 1);
	filemon->cred = crhold(td->td_ucred);

	error = devfs_set_cdevpriv(filemon, filemon_dtr);
	if (error != 0)
		filemon_release(filemon);

	return (error);
}
Example #29
0
static int
zpl_mknod(struct inode *dir, struct dentry *dentry, zpl_umode_t mode,
    dev_t rdev)
{
	cred_t *cr = CRED();
	struct inode *ip;
	vattr_t *vap;
	int error;
	fstrans_cookie_t cookie;

	/*
	 * We currently expect Linux to supply rdev=0 for all sockets
	 * and fifos, but we want to know if this behavior ever changes.
	 */
	if (S_ISSOCK(mode) || S_ISFIFO(mode))
		ASSERT(rdev == 0);

	crhold(cr);
	vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
	zpl_vap_init(vap, dir, mode, cr);
	vap->va_rdev = rdev;

	cookie = spl_fstrans_mark();
	error = -zfs_create(dir, dname(dentry), vap, 0, mode, &ip, cr, 0, NULL);
	if (error == 0) {
		d_instantiate(dentry, ip);

		error = zpl_xattr_security_init(ip, dir, &dentry->d_name);
		if (error == 0)
			error = zpl_init_acl(ip, dir);

		if (error)
			(void) zfs_remove(dir, dname(dentry), cr, 0);
	}

	spl_fstrans_unmark(cookie);
	kmem_free(vap, sizeof (vattr_t));
	crfree(cr);
	ASSERT3S(error, <=, 0);

	return (error);
}
Example #30
0
static struct dentry *
zpl_get_parent(struct dentry *child)
{
	cred_t *cr = CRED();
	fstrans_cookie_t cookie;
	struct inode *ip;
	int error;

	crhold(cr);
	cookie = spl_fstrans_mark();
	error = -zfs_lookup(child->d_inode, "..", &ip, 0, cr, NULL, NULL);
	spl_fstrans_unmark(cookie);
	crfree(cr);
	ASSERT3S(error, <=, 0);

	if (error)
		return (ERR_PTR(error));

	return (zpl_dentry_obtain_alias(ip));
}