diff --git a/modules/dcache-nfs/src/main/java/org/dcache/chimera/nfsv41/door/NFSv41Door.java b/modules/dcache-nfs/src/main/java/org/dcache/chimera/nfsv41/door/NFSv41Door.java index fee833d3922..1009383b334 100644 --- a/modules/dcache-nfs/src/main/java/org/dcache/chimera/nfsv41/door/NFSv41Door.java +++ b/modules/dcache-nfs/src/main/java/org/dcache/chimera/nfsv41/door/NFSv41Door.java @@ -786,6 +786,7 @@ public Layout layoutGet(CompoundContext context, LAYOUTGET4args args) final stateid4 stateid = Stateids.getCurrentStateidIfNeeded(context, args.loga_stateid); LayoutDriver layoutDriver = getLayoutDriver(layoutType); + NfsTransfer transfer = null; final NFS4Client client; if (context.getMinorversion() == 0) { @@ -819,7 +820,7 @@ public Layout layoutGet(CompoundContext context, LAYOUTGET4args args) throw new LayoutUnavailableException("special DOT file"); } - NfsTransfer transfer = layoutStateid != null ? _transfers.get(layoutStateid) : null; + transfer = layoutStateid != null ? _transfers.get(layoutStateid) : null; if (transfer == null) { Transfer.initSession(false, false); NDC.push(pnfsId.toString()); @@ -896,6 +897,20 @@ public Layout layoutGet(CompoundContext context, LAYOUTGET4args args) */ client.releaseState(stateid); throw new StaleException("File is removed", e); + } catch (PermissionDeniedCacheException e) { + // pool selection due to stage protection or an overwrite attempt of an existing file. + if (transfer.getPool() == null) { + // safe to forget + _log.error("Removing pool-less transfer for client {} for file {}: {}", + toAddrString(context.getRemoteSocketAddress().getAddress()), + transfer.getPnfsId(), e.getMessage()); + _transfers.remove(transfer.getStateid().stateid()); + } else { + // should never happen + _log.error("Report to support@dcache.org: Unexpected permission denied for transfer {} with assigned pool: {}", transfer, e.toString()); + } + + throw new PermException(e.getMessage(), e); } catch (CacheException | ChimeraFsException | TimeoutException | ExecutionException e) { throw asNfsException(e, LayoutTryLaterException.class); } catch (InterruptedException e) { @@ -1492,7 +1507,7 @@ deviceid4[] selectDataServers(long timeout) throws * allow writes only into new files */ if (!attr.getStorageInfo().isCreatedOnly()) { - throw new PermException("Can't modify existing file"); + throw new PermissionDeniedCacheException("Can't modify existing file"); } // REVISIT: this have to go into Transfer class.