mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-27 03:19:35 +03:00
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 <tuxoko@gmail.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Issue #1962
This commit is contained in:
parent
c2d439dffd
commit
7dc71949f2
@ -235,13 +235,9 @@ zfs_close(struct inode *ip, int flag, cred_t *cr)
|
|||||||
ZFS_ENTER(zsb);
|
ZFS_ENTER(zsb);
|
||||||
ZFS_VERIFY_ZP(zp);
|
ZFS_VERIFY_ZP(zp);
|
||||||
|
|
||||||
/*
|
/* Decrement the synchronous opens in the znode */
|
||||||
* Zero the synchronous opens in the znode. Under Linux the
|
|
||||||
* zfs_close() hook is not symmetric with zfs_open(), it is
|
|
||||||
* only called once when the last reference is dropped.
|
|
||||||
*/
|
|
||||||
if (flag & O_SYNC)
|
if (flag & O_SYNC)
|
||||||
zp->z_sync_cnt = 0;
|
atomic_dec_32(&zp->z_sync_cnt);
|
||||||
|
|
||||||
if (!zfs_has_ctldir(zp) && zsb->z_vscan && S_ISREG(ip->i_mode) &&
|
if (!zfs_has_ctldir(zp) && zsb->z_vscan && S_ISREG(ip->i_mode) &&
|
||||||
!(zp->z_pflags & ZFS_AV_QUARANTINED) && zp->z_size > 0)
|
!(zp->z_pflags & ZFS_AV_QUARANTINED) && zp->z_size > 0)
|
||||||
|
@ -36,15 +36,16 @@ zpl_open(struct inode *ip, struct file *filp)
|
|||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
error = generic_file_open(ip, filp);
|
||||||
|
if (error)
|
||||||
|
return (error);
|
||||||
|
|
||||||
crhold(cr);
|
crhold(cr);
|
||||||
error = -zfs_open(ip, filp->f_mode, filp->f_flags, cr);
|
error = -zfs_open(ip, filp->f_mode, filp->f_flags, cr);
|
||||||
crfree(cr);
|
crfree(cr);
|
||||||
ASSERT3S(error, <=, 0);
|
ASSERT3S(error, <=, 0);
|
||||||
|
|
||||||
if (error)
|
return (error);
|
||||||
return (error);
|
|
||||||
|
|
||||||
return generic_file_open(ip, filp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
Loading…
Reference in New Issue
Block a user