Skip to content

Commit

Permalink
Remove unneeded crhold()/crfree() calls in Linux ZPL
Browse files Browse the repository at this point in the history
The Solaris ZPL functions take a cred_t argument which is frequently
not used.  The Linux ZPL, which is effectively a wrapper around the
Solaris ZPL gets the cred_t value via CRED() which must then be held
with crhold() prior to calling the Solaris ZPL.  The crhold()/crfree()
management involve atomic operations which can consume excessive time
on large-scale NUMA systems, particularly in highly-concurrent workloads
with a high volume of file IO system calls.

This patch passes a NULL instead of a valid cred_t in cases where the
credential is not used by the Solaris ZPL.  The zfs_space() function,
however, can also be called inode operations so now it will now only
use the cred_t argument if it is set.
  • Loading branch information
dweeezil committed Sep 14, 2015
1 parent 7a27ad0 commit db3d7c7
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 48 deletions.
2 changes: 1 addition & 1 deletion module/zfs/zfs_vnops.c
Original file line number Diff line number Diff line change
Expand Up @@ -4393,7 +4393,7 @@ zfs_space(struct inode *ip, int cmd, flock64_t *bfp, int flag,
* On Linux we can get here through truncate_range() which
* operates directly on inodes, so we need to check access rights.
*/
if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr))) {
if (cr && (error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr))) {
ZFS_EXIT(zsb);
return (error);
}
Expand Down
58 changes: 11 additions & 47 deletions module/zfs/zpl_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,16 @@
static int
zpl_open(struct inode *ip, struct file *filp)
{
cred_t *cr = CRED();
int error;
fstrans_cookie_t cookie;

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

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

return (error);
Expand All @@ -55,18 +52,15 @@ zpl_open(struct inode *ip, struct file *filp)
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);
error = -zfs_close(ip, filp->f_flags, NULL);
spl_fstrans_unmark(cookie);
crfree(cr);
ASSERT3S(error, <=, 0);

return (error);
Expand All @@ -76,15 +70,12 @@ 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);
error = -zfs_readdir(dentry->d_inode, ctx, NULL);
spl_fstrans_unmark(cookie);
crfree(cr);
ASSERT3S(error, <=, 0);

return (error);
Expand Down Expand Up @@ -114,15 +105,12 @@ zpl_readdir(struct file *filp, void *dirent, filldir_t filldir)
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);
error = -zfs_fsync(dentry->d_inode, datasync, NULL);
spl_fstrans_unmark(cookie);
crfree(cr);
ASSERT3S(error, <=, 0);

return (error);
Expand All @@ -145,15 +133,12 @@ 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);
error = -zfs_fsync(inode, datasync, NULL);
spl_fstrans_unmark(cookie);
crfree(cr);
ASSERT3S(error, <=, 0);

return (error);
Expand All @@ -176,19 +161,16 @@ 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;
fstrans_cookie_t cookie;

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

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

return (error);
Expand Down Expand Up @@ -250,13 +232,10 @@ zpl_read_common(struct inode *ip, const char *buf, size_t len, loff_t *ppos,
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);
UIO_USERSPACE, filp->f_flags, NULL);

return (read);
}
Expand All @@ -265,14 +244,11 @@ 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);
nr_segs, &kiocb->ki_pos, seg, filp->f_flags, NULL, skip);

return (read);
}
Expand Down Expand Up @@ -352,13 +328,10 @@ zpl_write_common(struct inode *ip, const char *buf, size_t len, loff_t *ppos,
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);
UIO_USERSPACE, filp->f_flags, NULL);

return (wrote);
}
Expand All @@ -367,14 +340,11 @@ static ssize_t
zpl_iter_write_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 wrote;

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

return (wrote);
}
Expand Down Expand Up @@ -638,16 +608,13 @@ 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);

Expand All @@ -667,11 +634,9 @@ zpl_fallocate_common(struct inode *ip, int mode, loff_t offset, loff_t len)
bf.l_pid = 0;

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

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

ASSERT3S(error, <=, 0);
Expand Down Expand Up @@ -772,7 +737,6 @@ zpl_ioctl_setflags(struct file *filp, void __user *arg)
if (ioctl_flags & FS_NODUMP_FL)
xoap->xoa_nodump = B_TRUE;

crhold(cr);
cookie = spl_fstrans_mark();
error = -zfs_setattr(ip, (vattr_t *)&xva, 0, cr);
spl_fstrans_unmark(cookie);
Expand Down

0 comments on commit db3d7c7

Please sign in to comment.