mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-25 18:59:33 +03:00
Mark additional functions as PF_FSTRANS
Prevent deadlocks by disabling direct reclaim during all NFS, xattr,
ctldir, and super function calls. This is related to 40d06e3
.
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tim Chase <tim@chase2k.com>
Issue #3225
This commit is contained in:
parent
b467db454e
commit
7fad6290eb
@ -226,14 +226,17 @@ zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
|
fstrans_cookie_t cookie;
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
struct inode *ip = NULL;
|
struct inode *ip = NULL;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
crhold(cr);
|
crhold(cr);
|
||||||
|
cookie = spl_fstrans_mark();
|
||||||
error = -zfsctl_snapdir_lookup(dip, dname(dentry), &ip,
|
error = -zfsctl_snapdir_lookup(dip, dname(dentry), &ip,
|
||||||
0, cr, NULL, NULL);
|
0, cr, NULL, NULL);
|
||||||
ASSERT3S(error, <=, 0);
|
ASSERT3S(error, <=, 0);
|
||||||
|
spl_fstrans_unmark(cookie);
|
||||||
crfree(cr);
|
crfree(cr);
|
||||||
|
|
||||||
if (error && error != -ENOENT)
|
if (error && error != -ENOENT)
|
||||||
@ -250,21 +253,23 @@ static int
|
|||||||
zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
|
zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
|
||||||
{
|
{
|
||||||
zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode);
|
zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode);
|
||||||
|
fstrans_cookie_t cookie;
|
||||||
char snapname[MAXNAMELEN];
|
char snapname[MAXNAMELEN];
|
||||||
boolean_t case_conflict;
|
boolean_t case_conflict;
|
||||||
uint64_t id, cookie;
|
uint64_t id, pos;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
ZFS_ENTER(zsb);
|
ZFS_ENTER(zsb);
|
||||||
|
cookie = spl_fstrans_mark();
|
||||||
|
|
||||||
if (!dir_emit_dots(filp, ctx))
|
if (!dir_emit_dots(filp, ctx))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
cookie = ctx->pos;
|
pos = ctx->pos;
|
||||||
while (error == 0) {
|
while (error == 0) {
|
||||||
dsl_pool_config_enter(dmu_objset_pool(zsb->z_os), FTAG);
|
dsl_pool_config_enter(dmu_objset_pool(zsb->z_os), FTAG);
|
||||||
error = -dmu_snapshot_list_next(zsb->z_os, MAXNAMELEN,
|
error = -dmu_snapshot_list_next(zsb->z_os, MAXNAMELEN,
|
||||||
snapname, &id, &cookie, &case_conflict);
|
snapname, &id, &pos, &case_conflict);
|
||||||
dsl_pool_config_exit(dmu_objset_pool(zsb->z_os), FTAG);
|
dsl_pool_config_exit(dmu_objset_pool(zsb->z_os), FTAG);
|
||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
@ -273,9 +278,10 @@ zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
|
|||||||
ZFSCTL_INO_SHARES - id, DT_DIR))
|
ZFSCTL_INO_SHARES - id, DT_DIR))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ctx->pos = cookie;
|
ctx->pos = pos;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
spl_fstrans_unmark(cookie);
|
||||||
ZFS_EXIT(zsb);
|
ZFS_EXIT(zsb);
|
||||||
|
|
||||||
if (error == -ENOENT)
|
if (error == -ENOENT)
|
||||||
@ -414,14 +420,17 @@ zpl_shares_lookup(struct inode *dip, struct dentry *dentry,
|
|||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
fstrans_cookie_t cookie;
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
struct inode *ip = NULL;
|
struct inode *ip = NULL;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
crhold(cr);
|
crhold(cr);
|
||||||
|
cookie = spl_fstrans_mark();
|
||||||
error = -zfsctl_shares_lookup(dip, dname(dentry), &ip,
|
error = -zfsctl_shares_lookup(dip, dname(dentry), &ip,
|
||||||
0, cr, NULL, NULL);
|
0, cr, NULL, NULL);
|
||||||
ASSERT3S(error, <=, 0);
|
ASSERT3S(error, <=, 0);
|
||||||
|
spl_fstrans_unmark(cookie);
|
||||||
crfree(cr);
|
crfree(cr);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -437,12 +446,14 @@ zpl_shares_lookup(struct inode *dip, struct dentry *dentry,
|
|||||||
static int
|
static int
|
||||||
zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
|
zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
|
||||||
{
|
{
|
||||||
|
fstrans_cookie_t cookie;
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode);
|
zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode);
|
||||||
znode_t *dzp;
|
znode_t *dzp;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
ZFS_ENTER(zsb);
|
ZFS_ENTER(zsb);
|
||||||
|
cookie = spl_fstrans_mark();
|
||||||
|
|
||||||
if (zsb->z_shares_dir == 0) {
|
if (zsb->z_shares_dir == 0) {
|
||||||
dir_emit_dots(filp, ctx);
|
dir_emit_dots(filp, ctx);
|
||||||
@ -459,6 +470,7 @@ zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
|
|||||||
|
|
||||||
iput(ZTOI(dzp));
|
iput(ZTOI(dzp));
|
||||||
out:
|
out:
|
||||||
|
spl_fstrans_unmark(cookie);
|
||||||
ZFS_EXIT(zsb);
|
ZFS_EXIT(zsb);
|
||||||
ASSERT3S(error, <=, 0);
|
ASSERT3S(error, <=, 0);
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ zpl_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, int connectable)
|
|||||||
{
|
{
|
||||||
struct inode *ip = dentry->d_inode;
|
struct inode *ip = dentry->d_inode;
|
||||||
#endif /* HAVE_ENCODE_FH_WITH_INODE */
|
#endif /* HAVE_ENCODE_FH_WITH_INODE */
|
||||||
|
fstrans_cookie_t cookie;
|
||||||
fid_t *fid = (fid_t *)fh;
|
fid_t *fid = (fid_t *)fh;
|
||||||
int len_bytes, rc;
|
int len_bytes, rc;
|
||||||
|
|
||||||
@ -48,12 +49,14 @@ zpl_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, int connectable)
|
|||||||
return (255);
|
return (255);
|
||||||
|
|
||||||
fid->fid_len = len_bytes - offsetof(fid_t, fid_data);
|
fid->fid_len = len_bytes - offsetof(fid_t, fid_data);
|
||||||
|
cookie = spl_fstrans_mark();
|
||||||
|
|
||||||
if (zfsctl_is_node(ip))
|
if (zfsctl_is_node(ip))
|
||||||
rc = zfsctl_fid(ip, fid);
|
rc = zfsctl_fid(ip, fid);
|
||||||
else
|
else
|
||||||
rc = zfs_fid(ip, fid);
|
rc = zfs_fid(ip, fid);
|
||||||
|
|
||||||
|
spl_fstrans_unmark(cookie);
|
||||||
len_bytes = offsetof(fid_t, fid_data) + fid->fid_len;
|
len_bytes = offsetof(fid_t, fid_data) + fid->fid_len;
|
||||||
*max_len = roundup(len_bytes, sizeof (__u32)) / sizeof (__u32);
|
*max_len = roundup(len_bytes, sizeof (__u32)) / sizeof (__u32);
|
||||||
|
|
||||||
@ -84,6 +87,7 @@ zpl_fh_to_dentry(struct super_block *sb, struct fid *fh,
|
|||||||
int fh_len, int fh_type)
|
int fh_len, int fh_type)
|
||||||
{
|
{
|
||||||
fid_t *fid = (fid_t *)fh;
|
fid_t *fid = (fid_t *)fh;
|
||||||
|
fstrans_cookie_t cookie;
|
||||||
struct inode *ip;
|
struct inode *ip;
|
||||||
int len_bytes, rc;
|
int len_bytes, rc;
|
||||||
|
|
||||||
@ -94,7 +98,9 @@ zpl_fh_to_dentry(struct super_block *sb, struct fid *fh,
|
|||||||
len_bytes < offsetof(fid_t, fid_data) + fid->fid_len)
|
len_bytes < offsetof(fid_t, fid_data) + fid->fid_len)
|
||||||
return (ERR_PTR(-EINVAL));
|
return (ERR_PTR(-EINVAL));
|
||||||
|
|
||||||
|
cookie = spl_fstrans_mark();
|
||||||
rc = zfs_vget(sb, &ip, fid);
|
rc = zfs_vget(sb, &ip, fid);
|
||||||
|
spl_fstrans_unmark(cookie);
|
||||||
|
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
return (ERR_PTR(-rc));
|
return (ERR_PTR(-rc));
|
||||||
@ -108,11 +114,14 @@ static struct dentry *
|
|||||||
zpl_get_parent(struct dentry *child)
|
zpl_get_parent(struct dentry *child)
|
||||||
{
|
{
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
|
fstrans_cookie_t cookie;
|
||||||
struct inode *ip;
|
struct inode *ip;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
crhold(cr);
|
crhold(cr);
|
||||||
|
cookie = spl_fstrans_mark();
|
||||||
error = -zfs_lookup(child->d_inode, "..", &ip, 0, cr, NULL, NULL);
|
error = -zfs_lookup(child->d_inode, "..", &ip, 0, cr, NULL, NULL);
|
||||||
|
spl_fstrans_unmark(cookie);
|
||||||
crfree(cr);
|
crfree(cr);
|
||||||
ASSERT3S(error, <=, 0);
|
ASSERT3S(error, <=, 0);
|
||||||
|
|
||||||
@ -127,10 +136,13 @@ static int
|
|||||||
zpl_commit_metadata(struct inode *inode)
|
zpl_commit_metadata(struct inode *inode)
|
||||||
{
|
{
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
|
fstrans_cookie_t cookie;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
crhold(cr);
|
crhold(cr);
|
||||||
|
cookie = spl_fstrans_mark();
|
||||||
error = -zfs_fsync(inode, 0, cr);
|
error = -zfs_fsync(inode, 0, cr);
|
||||||
|
spl_fstrans_unmark(cookie);
|
||||||
crfree(cr);
|
crfree(cr);
|
||||||
ASSERT3S(error, <=, 0);
|
ASSERT3S(error, <=, 0);
|
||||||
|
|
||||||
|
@ -136,20 +136,26 @@ zpl_inode_delete(struct inode *ip)
|
|||||||
static void
|
static void
|
||||||
zpl_put_super(struct super_block *sb)
|
zpl_put_super(struct super_block *sb)
|
||||||
{
|
{
|
||||||
|
fstrans_cookie_t cookie;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
cookie = spl_fstrans_mark();
|
||||||
error = -zfs_umount(sb);
|
error = -zfs_umount(sb);
|
||||||
|
spl_fstrans_unmark(cookie);
|
||||||
ASSERT3S(error, <=, 0);
|
ASSERT3S(error, <=, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
zpl_sync_fs(struct super_block *sb, int wait)
|
zpl_sync_fs(struct super_block *sb, int wait)
|
||||||
{
|
{
|
||||||
|
fstrans_cookie_t cookie;
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
crhold(cr);
|
crhold(cr);
|
||||||
|
cookie = spl_fstrans_mark();
|
||||||
error = -zfs_sync(sb, wait, cr);
|
error = -zfs_sync(sb, wait, cr);
|
||||||
|
spl_fstrans_unmark(cookie);
|
||||||
crfree(cr);
|
crfree(cr);
|
||||||
ASSERT3S(error, <=, 0);
|
ASSERT3S(error, <=, 0);
|
||||||
|
|
||||||
@ -159,9 +165,12 @@ zpl_sync_fs(struct super_block *sb, int wait)
|
|||||||
static int
|
static int
|
||||||
zpl_statfs(struct dentry *dentry, struct kstatfs *statp)
|
zpl_statfs(struct dentry *dentry, struct kstatfs *statp)
|
||||||
{
|
{
|
||||||
|
fstrans_cookie_t cookie;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
cookie = spl_fstrans_mark();
|
||||||
error = -zfs_statvfs(dentry, statp);
|
error = -zfs_statvfs(dentry, statp);
|
||||||
|
spl_fstrans_unmark(cookie);
|
||||||
ASSERT3S(error, <=, 0);
|
ASSERT3S(error, <=, 0);
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
@ -170,8 +179,12 @@ zpl_statfs(struct dentry *dentry, struct kstatfs *statp)
|
|||||||
static int
|
static int
|
||||||
zpl_remount_fs(struct super_block *sb, int *flags, char *data)
|
zpl_remount_fs(struct super_block *sb, int *flags, char *data)
|
||||||
{
|
{
|
||||||
|
fstrans_cookie_t cookie;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
cookie = spl_fstrans_mark();
|
||||||
error = -zfs_remount(sb, flags, data);
|
error = -zfs_remount(sb, flags, data);
|
||||||
|
spl_fstrans_unmark(cookie);
|
||||||
ASSERT3S(error, <=, 0);
|
ASSERT3S(error, <=, 0);
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
@ -242,9 +255,12 @@ zpl_show_options(struct seq_file *seq, struct vfsmount *vfsp)
|
|||||||
static int
|
static int
|
||||||
zpl_fill_super(struct super_block *sb, void *data, int silent)
|
zpl_fill_super(struct super_block *sb, void *data, int silent)
|
||||||
{
|
{
|
||||||
|
fstrans_cookie_t cookie;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
cookie = spl_fstrans_mark();
|
||||||
error = -zfs_domount(sb, data, silent);
|
error = -zfs_domount(sb, data, silent);
|
||||||
|
spl_fstrans_unmark(cookie);
|
||||||
ASSERT3S(error, <=, 0);
|
ASSERT3S(error, <=, 0);
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
|
@ -209,9 +209,11 @@ zpl_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
|
|||||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||||
xattr_filldir_t xf = { buffer_size, 0, buffer, dentry->d_inode };
|
xattr_filldir_t xf = { buffer_size, 0, buffer, dentry->d_inode };
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
|
fstrans_cookie_t cookie;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
crhold(cr);
|
crhold(cr);
|
||||||
|
cookie = spl_fstrans_mark();
|
||||||
rw_enter(&zp->z_xattr_lock, RW_READER);
|
rw_enter(&zp->z_xattr_lock, RW_READER);
|
||||||
|
|
||||||
if (zsb->z_use_sa && zp->z_is_sa) {
|
if (zsb->z_use_sa && zp->z_is_sa) {
|
||||||
@ -228,6 +230,7 @@ zpl_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
|
|||||||
out:
|
out:
|
||||||
|
|
||||||
rw_exit(&zp->z_xattr_lock);
|
rw_exit(&zp->z_xattr_lock);
|
||||||
|
spl_fstrans_unmark(cookie);
|
||||||
crfree(cr);
|
crfree(cr);
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
@ -337,12 +340,15 @@ zpl_xattr_get(struct inode *ip, const char *name, void *value, size_t size)
|
|||||||
{
|
{
|
||||||
znode_t *zp = ITOZ(ip);
|
znode_t *zp = ITOZ(ip);
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
|
fstrans_cookie_t cookie;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
crhold(cr);
|
crhold(cr);
|
||||||
|
cookie = spl_fstrans_mark();
|
||||||
rw_enter(&zp->z_xattr_lock, RW_READER);
|
rw_enter(&zp->z_xattr_lock, RW_READER);
|
||||||
error = __zpl_xattr_get(ip, name, value, size, cr);
|
error = __zpl_xattr_get(ip, name, value, size, cr);
|
||||||
rw_exit(&zp->z_xattr_lock);
|
rw_exit(&zp->z_xattr_lock);
|
||||||
|
spl_fstrans_unmark(cookie);
|
||||||
crfree(cr);
|
crfree(cr);
|
||||||
|
|
||||||
return (error);
|
return (error);
|
||||||
@ -482,9 +488,11 @@ zpl_xattr_set(struct inode *ip, const char *name, const void *value,
|
|||||||
znode_t *zp = ITOZ(ip);
|
znode_t *zp = ITOZ(ip);
|
||||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
|
fstrans_cookie_t cookie;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
crhold(cr);
|
crhold(cr);
|
||||||
|
cookie = spl_fstrans_mark();
|
||||||
rw_enter(&ITOZ(ip)->z_xattr_lock, RW_WRITER);
|
rw_enter(&ITOZ(ip)->z_xattr_lock, RW_WRITER);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -522,6 +530,7 @@ zpl_xattr_set(struct inode *ip, const char *name, const void *value,
|
|||||||
error = zpl_xattr_set_dir(ip, name, value, size, flags, cr);
|
error = zpl_xattr_set_dir(ip, name, value, size, flags, cr);
|
||||||
out:
|
out:
|
||||||
rw_exit(&ITOZ(ip)->z_xattr_lock);
|
rw_exit(&ITOZ(ip)->z_xattr_lock);
|
||||||
|
spl_fstrans_unmark(cookie);
|
||||||
crfree(cr);
|
crfree(cr);
|
||||||
ASSERT3S(error, <=, 0);
|
ASSERT3S(error, <=, 0);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user