Skip to content

Commit e548a59

Browse files
committed
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
1 parent 7af6322 commit e548a59

File tree

4 files changed

+53
-4
lines changed

4 files changed

+53
-4
lines changed

module/zfs/zpl_ctldir.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,14 +226,17 @@ zpl_snapdir_lookup(struct inode *dip, struct dentry *dentry,
226226
#endif
227227

228228
{
229+
fstrans_cookie_t cookie;
229230
cred_t *cr = CRED();
230231
struct inode *ip = NULL;
231232
int error;
232233

233234
crhold(cr);
235+
cookie = spl_fstrans_mark();
234236
error = -zfsctl_snapdir_lookup(dip, dname(dentry), &ip,
235237
0, cr, NULL, NULL);
236238
ASSERT3S(error, <=, 0);
239+
spl_fstrans_unmark(cookie);
237240
crfree(cr);
238241

239242
if (error && error != -ENOENT)
@@ -250,21 +253,23 @@ static int
250253
zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
251254
{
252255
zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode);
256+
fstrans_cookie_t cookie;
253257
char snapname[MAXNAMELEN];
254258
boolean_t case_conflict;
255-
uint64_t id, cookie;
259+
uint64_t id, pos;
256260
int error = 0;
257261

258262
ZFS_ENTER(zsb);
263+
cookie = spl_fstrans_mark();
259264

260265
if (!dir_emit_dots(filp, ctx))
261266
goto out;
262267

263-
cookie = ctx->pos;
268+
pos = ctx->pos;
264269
while (error == 0) {
265270
dsl_pool_config_enter(dmu_objset_pool(zsb->z_os), FTAG);
266271
error = -dmu_snapshot_list_next(zsb->z_os, MAXNAMELEN,
267-
snapname, &id, &cookie, &case_conflict);
272+
snapname, &id, &pos, &case_conflict);
268273
dsl_pool_config_exit(dmu_objset_pool(zsb->z_os), FTAG);
269274
if (error)
270275
goto out;
@@ -273,9 +278,10 @@ zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
273278
ZFSCTL_INO_SHARES - id, DT_DIR))
274279
goto out;
275280

276-
ctx->pos = cookie;
281+
ctx->pos = pos;
277282
}
278283
out:
284+
spl_fstrans_unmark(cookie);
279285
ZFS_EXIT(zsb);
280286

281287
if (error == -ENOENT)
@@ -414,14 +420,17 @@ zpl_shares_lookup(struct inode *dip, struct dentry *dentry,
414420
unsigned int flags)
415421
#endif
416422
{
423+
fstrans_cookie_t cookie;
417424
cred_t *cr = CRED();
418425
struct inode *ip = NULL;
419426
int error;
420427

421428
crhold(cr);
429+
cookie = spl_fstrans_mark();
422430
error = -zfsctl_shares_lookup(dip, dname(dentry), &ip,
423431
0, cr, NULL, NULL);
424432
ASSERT3S(error, <=, 0);
433+
spl_fstrans_unmark(cookie);
425434
crfree(cr);
426435

427436
if (error) {
@@ -437,12 +446,14 @@ zpl_shares_lookup(struct inode *dip, struct dentry *dentry,
437446
static int
438447
zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
439448
{
449+
fstrans_cookie_t cookie;
440450
cred_t *cr = CRED();
441451
zfs_sb_t *zsb = ITOZSB(filp->f_path.dentry->d_inode);
442452
znode_t *dzp;
443453
int error = 0;
444454

445455
ZFS_ENTER(zsb);
456+
cookie = spl_fstrans_mark();
446457

447458
if (zsb->z_shares_dir == 0) {
448459
dir_emit_dots(filp, ctx);
@@ -459,6 +470,7 @@ zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
459470

460471
iput(ZTOI(dzp));
461472
out:
473+
spl_fstrans_unmark(cookie);
462474
ZFS_EXIT(zsb);
463475
ASSERT3S(error, <=, 0);
464476

module/zfs/zpl_export.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ zpl_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, int connectable)
3939
{
4040
struct inode *ip = dentry->d_inode;
4141
#endif /* HAVE_ENCODE_FH_WITH_INODE */
42+
fstrans_cookie_t cookie;
4243
fid_t *fid = (fid_t *)fh;
4344
int len_bytes, rc;
4445

@@ -48,12 +49,14 @@ zpl_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, int connectable)
4849
return (255);
4950

5051
fid->fid_len = len_bytes - offsetof(fid_t, fid_data);
52+
cookie = spl_fstrans_mark();
5153

5254
if (zfsctl_is_node(ip))
5355
rc = zfsctl_fid(ip, fid);
5456
else
5557
rc = zfs_fid(ip, fid);
5658

59+
spl_fstrans_unmark(cookie);
5760
len_bytes = offsetof(fid_t, fid_data) + fid->fid_len;
5861
*max_len = roundup(len_bytes, sizeof (__u32)) / sizeof (__u32);
5962

@@ -84,6 +87,7 @@ zpl_fh_to_dentry(struct super_block *sb, struct fid *fh,
8487
int fh_len, int fh_type)
8588
{
8689
fid_t *fid = (fid_t *)fh;
90+
fstrans_cookie_t cookie;
8791
struct inode *ip;
8892
int len_bytes, rc;
8993

@@ -94,7 +98,9 @@ zpl_fh_to_dentry(struct super_block *sb, struct fid *fh,
9498
len_bytes < offsetof(fid_t, fid_data) + fid->fid_len)
9599
return (ERR_PTR(-EINVAL));
96100

101+
cookie = spl_fstrans_mark();
97102
rc = zfs_vget(sb, &ip, fid);
103+
spl_fstrans_unmark(cookie);
98104

99105
if (rc != 0)
100106
return (ERR_PTR(-rc));
@@ -108,11 +114,14 @@ static struct dentry *
108114
zpl_get_parent(struct dentry *child)
109115
{
110116
cred_t *cr = CRED();
117+
fstrans_cookie_t cookie;
111118
struct inode *ip;
112119
int error;
113120

114121
crhold(cr);
122+
cookie = spl_fstrans_mark();
115123
error = -zfs_lookup(child->d_inode, "..", &ip, 0, cr, NULL, NULL);
124+
spl_fstrans_unmark(cookie);
116125
crfree(cr);
117126
ASSERT3S(error, <=, 0);
118127

@@ -127,10 +136,13 @@ static int
127136
zpl_commit_metadata(struct inode *inode)
128137
{
129138
cred_t *cr = CRED();
139+
fstrans_cookie_t cookie;
130140
int error;
131141

132142
crhold(cr);
143+
cookie = spl_fstrans_mark();
133144
error = -zfs_fsync(inode, 0, cr);
145+
spl_fstrans_unmark(cookie);
134146
crfree(cr);
135147
ASSERT3S(error, <=, 0);
136148

module/zfs/zpl_super.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,20 +136,26 @@ zpl_inode_delete(struct inode *ip)
136136
static void
137137
zpl_put_super(struct super_block *sb)
138138
{
139+
fstrans_cookie_t cookie;
139140
int error;
140141

142+
cookie = spl_fstrans_mark();
141143
error = -zfs_umount(sb);
144+
spl_fstrans_unmark(cookie);
142145
ASSERT3S(error, <=, 0);
143146
}
144147

145148
static int
146149
zpl_sync_fs(struct super_block *sb, int wait)
147150
{
151+
fstrans_cookie_t cookie;
148152
cred_t *cr = CRED();
149153
int error;
150154

151155
crhold(cr);
156+
cookie = spl_fstrans_mark();
152157
error = -zfs_sync(sb, wait, cr);
158+
spl_fstrans_unmark(cookie);
153159
crfree(cr);
154160
ASSERT3S(error, <=, 0);
155161

@@ -159,9 +165,12 @@ zpl_sync_fs(struct super_block *sb, int wait)
159165
static int
160166
zpl_statfs(struct dentry *dentry, struct kstatfs *statp)
161167
{
168+
fstrans_cookie_t cookie;
162169
int error;
163170

171+
cookie = spl_fstrans_mark();
164172
error = -zfs_statvfs(dentry, statp);
173+
spl_fstrans_unmark(cookie);
165174
ASSERT3S(error, <=, 0);
166175

167176
return (error);
@@ -170,8 +179,12 @@ zpl_statfs(struct dentry *dentry, struct kstatfs *statp)
170179
static int
171180
zpl_remount_fs(struct super_block *sb, int *flags, char *data)
172181
{
182+
fstrans_cookie_t cookie;
173183
int error;
184+
185+
cookie = spl_fstrans_mark();
174186
error = -zfs_remount(sb, flags, data);
187+
spl_fstrans_unmark(cookie);
175188
ASSERT3S(error, <=, 0);
176189

177190
return (error);
@@ -242,9 +255,12 @@ zpl_show_options(struct seq_file *seq, struct vfsmount *vfsp)
242255
static int
243256
zpl_fill_super(struct super_block *sb, void *data, int silent)
244257
{
258+
fstrans_cookie_t cookie;
245259
int error;
246260

261+
cookie = spl_fstrans_mark();
247262
error = -zfs_domount(sb, data, silent);
263+
spl_fstrans_unmark(cookie);
248264
ASSERT3S(error, <=, 0);
249265

250266
return (error);

module/zfs/zpl_xattr.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,11 @@ zpl_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
209209
zfs_sb_t *zsb = ZTOZSB(zp);
210210
xattr_filldir_t xf = { buffer_size, 0, buffer, dentry->d_inode };
211211
cred_t *cr = CRED();
212+
fstrans_cookie_t cookie;
212213
int error = 0;
213214

214215
crhold(cr);
216+
cookie = spl_fstrans_mark();
215217
rw_enter(&zp->z_xattr_lock, RW_READER);
216218

217219
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)
228230
out:
229231

230232
rw_exit(&zp->z_xattr_lock);
233+
spl_fstrans_unmark(cookie);
231234
crfree(cr);
232235

233236
return (error);
@@ -337,12 +340,15 @@ zpl_xattr_get(struct inode *ip, const char *name, void *value, size_t size)
337340
{
338341
znode_t *zp = ITOZ(ip);
339342
cred_t *cr = CRED();
343+
fstrans_cookie_t cookie;
340344
int error;
341345

342346
crhold(cr);
347+
cookie = spl_fstrans_mark();
343348
rw_enter(&zp->z_xattr_lock, RW_READER);
344349
error = __zpl_xattr_get(ip, name, value, size, cr);
345350
rw_exit(&zp->z_xattr_lock);
351+
spl_fstrans_unmark(cookie);
346352
crfree(cr);
347353

348354
return (error);
@@ -482,9 +488,11 @@ zpl_xattr_set(struct inode *ip, const char *name, const void *value,
482488
znode_t *zp = ITOZ(ip);
483489
zfs_sb_t *zsb = ZTOZSB(zp);
484490
cred_t *cr = CRED();
491+
fstrans_cookie_t cookie;
485492
int error;
486493

487494
crhold(cr);
495+
cookie = spl_fstrans_mark();
488496
rw_enter(&ITOZ(ip)->z_xattr_lock, RW_WRITER);
489497

490498
/*
@@ -522,6 +530,7 @@ zpl_xattr_set(struct inode *ip, const char *name, const void *value,
522530
error = zpl_xattr_set_dir(ip, name, value, size, flags, cr);
523531
out:
524532
rw_exit(&ITOZ(ip)->z_xattr_lock);
533+
spl_fstrans_unmark(cookie);
525534
crfree(cr);
526535
ASSERT3S(error, <=, 0);
527536

0 commit comments

Comments
 (0)