@Override public device_addr4 getDeviceInfo(CompoundContext context, deviceid4 deviceId) { /* in case of MDS access we return the same interface which client already connected to */ if (deviceId.equals(MDS_ID)) { return deviceAddrOf( new RoundRobinStripingPattern<InetSocketAddress[]>(), new InetSocketAddress[] {context.getRpcCall().getTransport().getLocalSocketAddress()}); } PoolDS ds = _poolDeviceMap.getByDeviceId(deviceId); if (ds == null) { return null; } return ds.getDeviceAddr(); }
@Override public void process(CompoundContext context, nfs_resop4 result) { final WRITE4res res = result.opwrite; try { NfsMover mover = _activeIO.get(_args.opwrite.stateid); if (mover == null) { throw new ChimeraNFSException( nfsstat.NFSERR_BAD_STATEID, "No mover associated with given stateid"); } mover.attachSession(context.getSession()); if (mover.getIoMode() != IoMode.WRITE) { throw new ChimeraNFSException( nfsstat.NFSERR_PERM, "an attempt to write without IO mode enabled"); } long offset = _args.opwrite.offset.value; RepositoryChannel fc = mover.getMoverChannel(); _args.opwrite.data.rewind(); int bytesWritten = fc.write(_args.opwrite.data, offset); res.status = nfsstat.NFS_OK; res.resok4 = new WRITE4resok(); res.resok4.count = new count4(bytesWritten); res.resok4.committed = stable_how4.FILE_SYNC4; res.resok4.writeverf = new verifier4(); res.resok4.writeverf.value = new byte[nfs4_prot.NFS4_VERIFIER_SIZE]; _log.debug("MOVER: {}@{} written, {} requested.", bytesWritten, offset, bytesWritten); } catch (ChimeraNFSException he) { _log.debug(he.getMessage()); res.status = he.getStatus(); } catch (IOException ioe) { _log.error("DSWRITE: ", ioe); res.status = nfsstat.NFSERR_IO; } catch (Exception e) { _log.error("DSWRITE: ", e); res.status = nfsstat.NFSERR_SERVERFAULT; } }
/** * ask pool manager for a file * * <p>On successful reply from pool manager corresponding O request will be sent to the pool to * start a NFS mover. * * @throws ChimeraNFSException in case of NFS friendly errors ( like ACCESS ) * @throws IOException in case of any other errors */ @Override public Layout layoutGet(CompoundContext context, Inode nfsInode, int ioMode, stateid4 stateid) throws IOException { FsInode inode = _fileFileSystemProvider.inodeFromBytes(nfsInode.getFileId()); CDC cdc = CDC.reset(_cellName, _domainName); try { NDC.push(inode.toString()); NDC.push(context.getRpcCall().getTransport().getRemoteSocketAddress().toString()); deviceid4 deviceid; if (inode.type() != FsInodeType.INODE || inode.getLevel() != 0) { /* * all non regular files ( AKA pnfs dot files ) provided by door itself. */ deviceid = MDS_ID; } else { final InetSocketAddress remote = context.getRpcCall().getTransport().getRemoteSocketAddress(); final PnfsId pnfsId = new PnfsId(inode.toString()); final NFS4ProtocolInfo protocolInfo = new NFS4ProtocolInfo(remote, new org.dcache.chimera.nfs.v4.xdr.stateid4(stateid)); Transfer.initSession(); NfsTransfer transfer = _ioMessages.get(stateid); if (transfer == null) { transfer = new NfsTransfer(_pnfsHandler, context.getRpcCall().getCredential().getSubject()); transfer.setProtocolInfo(protocolInfo); transfer.setCellName(this.getCellName()); transfer.setDomainName(this.getCellDomainName()); transfer.setBillingStub(_billingStub); transfer.setPoolStub(_poolManagerStub); transfer.setPoolManagerStub(_poolManagerStub); transfer.setPnfsId(pnfsId); transfer.setClientAddress(remote); transfer.readNameSpaceEntry(); _ioMessages.put(stateid, transfer); PoolDS ds = getPool(transfer, ioMode); deviceid = ds.getDeviceId(); } else { PoolDS ds = transfer.waitForRedirect(NFS_RETRY_PERIOD); deviceid = ds.getDeviceId(); } } nfs_fh4 fh = new nfs_fh4(nfsInode.toNfsHandle()); // -1 is special value, which means entire file layout4 layout = Layout.getLayoutSegment(deviceid, fh, ioMode, 0, nfs4_prot.NFS4_UINT64_MAX); return new Layout(true, stateid, new layout4[] {layout}); } catch (FileInCacheException e) { cleanStateAndKillMover(stateid); throw new ChimeraNFSException(nfsstat.NFSERR_IO, e.getMessage()); } catch (CacheException e) { cleanStateAndKillMover(stateid); /* * error 243: file is broken on tape. * can't do a much. Tell it to client. */ int status = e.getRc() == CacheException.BROKEN_ON_TAPE ? nfsstat.NFSERR_IO : nfsstat.NFSERR_LAYOUTTRYLATER; throw new ChimeraNFSException(status, e.getMessage()); } catch (InterruptedException e) { cleanStateAndKillMover(stateid); throw new ChimeraNFSException(nfsstat.NFSERR_LAYOUTTRYLATER, e.getMessage()); } finally { cdc.close(); } }