summaryrefslogtreecommitdiffstats
path: root/module/zfs/zpl_file.c
diff options
context:
space:
mode:
authorChunwei Chen <[email protected]>2013-12-17 10:18:25 -0800
committerBrian Behlendorf <[email protected]>2013-12-17 10:28:27 -0800
commit7dc71949f2f013a7bf744230d60770893ce23a6a (patch)
tree3ae0c13c4f599ce5a619542519646c2a9b007c42 /module/zfs/zpl_file.c
parentc2d439dffd4c404d39e82e5b174a338515080f26 (diff)
Fix z_sync_cnt decrement in zfs_close
The comment in zfs_close states that "Under Linux the zfs_close() hook is not symmetric with zfs_open()". This is not true. zfs_open/zfs_close is associated with every successful struct file creation/deletion, which should always be balanced. Here is an example of what's wrong: Process A B open(O_SYNC) z_sync_cnt = 1 open(O_SYNC) z_sync_cnt = 2 close() z_sync_cnt = 0 So z_sync_cnt is 0 even if B still has the file with O_SYNC. Also moves the generic_file_open call before zfs_open to ensure that in the case generic_file_open fails z_sync_cnt is not incremented. This is safe because generic_file_open has no side effects. Signed-off-by: Chunwei Chen <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Issue #1962
Diffstat (limited to 'module/zfs/zpl_file.c')
-rw-r--r--module/zfs/zpl_file.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c
index 0d46eee02..690f93838 100644
--- a/module/zfs/zpl_file.c
+++ b/module/zfs/zpl_file.c
@@ -36,15 +36,16 @@ 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);
- if (error)
- return (error);
-
- return generic_file_open(ip, filp);
+ return (error);
}
static int