static ssize_t zpl_write_common_iovec(struct inode *ip, const struct iovec *iovp, size_t count, unsigned long nr_segs, loff_t *ppos, uio_seg_t segment, int flags, cred_t *cr, size_t skip) { ssize_t wrote; uio_t uio; int error; fstrans_cookie_t cookie; if (flags & O_APPEND) *ppos = i_size_read(ip); uio.uio_iov = iovp; uio.uio_skip = skip; uio.uio_resid = count; uio.uio_iovcnt = nr_segs; uio.uio_loffset = *ppos; uio.uio_limit = MAXOFFSET_T; uio.uio_segflg = segment; cookie = spl_fstrans_mark(); error = -zfs_write(ip, &uio, flags, cr); spl_fstrans_unmark(cookie); if (error < 0) return (error); wrote = count - uio.uio_resid; *ppos += wrote; task_io_account_write(wrote); return (wrote); }
ssize_t zpl_write_common(struct inode *ip, const char *buf, size_t len, loff_t pos, uio_seg_t segment, int flags, cred_t *cr) { int error; ssize_t wrote; struct iovec iov; uio_t uio; iov.iov_base = (void *)buf; iov.iov_len = len; uio.uio_iov = &iov; uio.uio_resid = len, uio.uio_iovcnt = 1; uio.uio_loffset = pos; uio.uio_limit = MAXOFFSET_T; uio.uio_segflg = segment; error = -zfs_write(ip, &uio, flags, cr); if (error < 0) return (error); wrote = len - uio.uio_resid; task_io_account_write(wrote); return (wrote); }
static int lzfs_xattr_security_set(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int type) #endif { vnode_t *vp; vnode_t *dvp; vnode_t *xvp; vattr_t *vap; int err = 0; const struct cred *cred = get_current_cred(); struct iovec iov = { .iov_base = (void *) value, .iov_len = size, }; char *xattr_name = NULL; uio_t uio = { .uio_iov = &iov, .uio_resid = size, .uio_iovcnt = 1, .uio_loffset = (offset_t)0, .uio_limit = MAXOFFSET_T, .uio_segflg = UIO_SYSSPACE, }; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) dvp = LZFS_ITOV(inode); #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) dvp = LZFS_ITOV(dentry->d_inode); #endif err = zfs_lookup(dvp, NULL, &vp, NULL, LOOKUP_XATTR | CREATE_XATTR_DIR, NULL, (struct cred *) cred, NULL, NULL, NULL); if(err) { return -err; } if(!value) { err =zfs_remove(vp, (char *) name, (struct cred *)cred, NULL, 0); return -err; } vap = kmalloc(sizeof(vattr_t), GFP_KERNEL); ASSERT(vap != NULL); memset(vap, 0, sizeof(vap)); vap->va_type = VREG; vap->va_mode = 0644; vap->va_mask = AT_TYPE|AT_MODE; vap->va_uid = current_fsuid(); vap->va_gid = current_fsgid(); xattr_name = kzalloc(strlen(name) + 10, GFP_KERNEL); xattr_name = strncpy(xattr_name, "security.", 9); xattr_name = strncat(xattr_name, name, strlen(name)); err = zfs_create(vp, xattr_name, vap, 0, 0644, &xvp, (struct cred *)cred, 0, NULL, NULL); kfree(vap); kfree(xattr_name); if(err) { return -err; } err = zfs_write(xvp, &uio, 0, (cred_t *)cred, NULL); put_cred(cred); if(err) { return -err; } return -err; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) static size_t lzfs_xattr_security_list(struct inode *inode, char *list, size_t list_size, const char *name, size_t name_len) #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) static size_t lzfs_xattr_security_list(struct dentry *dentry, char *list, size_t list_size, const char *name, size_t name_len, int type) #endif { const size_t total_len = name_len + 1; if (list && total_len <= list_size) { memcpy(list, name, name_len); list[name_len] = '\0'; } return total_len; } int lzfs_init_security(struct dentry *dentry, struct inode *dir) { int err; size_t len; void *value; char *name; err = security_inode_init_security(dentry->d_inode, dir, &name, &value, &len); if (err) { if (err == -EOPNOTSUPP) return 0; return err; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) err = lzfs_xattr_security_set(dentry->d_inode, name, value, len, 0); #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33) err = lzfs_xattr_security_set(dentry, name, value, len, 0, 0); #endif kfree(name); kfree(value); return err; } struct xattr_handler lzfs_xattr_security_handler = { .prefix = XATTR_SECURITY_PREFIX, .list = lzfs_xattr_security_list, .get = lzfs_xattr_security_get, .set = lzfs_xattr_security_set, };