diff --git a/core/src/main/java/org/dcache/nfs/v4/FileTracker.java b/core/src/main/java/org/dcache/nfs/v4/FileTracker.java index 5ec50cf6..2884653f 100644 --- a/core/src/main/java/org/dcache/nfs/v4/FileTracker.java +++ b/core/src/main/java/org/dcache/nfs/v4/FileTracker.java @@ -100,7 +100,7 @@ public NFS4Client getClient() { * @param inode of opened file. * @param shareAccess type of access required. * @param shareDeny type of access to deny others. - * @return stateid associated with open. + * @return a snapshot of the stateid associated with open. * @throws ShareDeniedException if share reservation conflicts with an existing open. * @throws ChimeraNFSException */ @@ -134,7 +134,8 @@ public stateid4 addOpen(NFS4Client client, StateOwner owner, Inode inode, int sh os.shareAccess |= shareAccess; os.shareDeny |= shareDeny; os.stateid.seqid++; - return os.stateid; + //we need to return copy to avoid modification by concurrent opens + return new stateid4(os.stateid.other, os.stateid.seqid); } } @@ -144,7 +145,8 @@ public stateid4 addOpen(NFS4Client client, StateOwner owner, Inode inode, int sh opens.add(openState); state.addDisposeListener(s -> removeOpen(inode, stateid)); stateid.seqid++; - return stateid; + //we need to return copy to avoid modification by concurrent opens + return new stateid4(stateid.other, stateid.seqid); } finally { lock.unlock(); } @@ -158,7 +160,7 @@ public stateid4 addOpen(NFS4Client client, StateOwner owner, Inode inode, int sh * @param inode of opened file. * @param shareAccess type of access required. * @param shareDeny type of access to deny others. - * @return stateid associated with open. + * @return a snapshot of the stateid associated with open. * @throws ChimeraNFSException */ public stateid4 downgradeOpen(NFS4Client client, stateid4 stateid, Inode inode, int shareAccess, int shareDeny) throws ChimeraNFSException { @@ -187,7 +189,8 @@ public stateid4 downgradeOpen(NFS4Client client, stateid4 stateid, Inode inode, os.shareDeny = shareDeny; os.stateid.seqid++; - return os.stateid; + //we need to return copy to avoid modification by concurrent opens + return new stateid4(os.stateid.other, os.stateid.seqid); } finally { lock.unlock(); }