Search in sources :

Example 1 with StaleException

use of org.dcache.nfs.status.StaleException in project dcache by dCache.

the class ChimeraVfs method setattr.

@Override
public void setattr(Inode inode, Stat stat) throws IOException {
    FsInode fsInode = toFsInode(inode);
    try {
        if (shouldRejectAttributeUpdates(fsInode, _fs)) {
            throw new PermException("setStat not allowed.");
        }
        // OperationSETATTR have already checked for a valid open stateid
        if (stat.isDefined(Stat.StatAttribute.SIZE)) {
            var chimeraStat = fsInode.stat();
            int type = chimeraStat.getMode() & UnixPermission.F_TYPE;
            switch(type) {
                case UnixPermission.S_IFREG:
                    // ok
                    break;
                case UnixPermission.S_IFDIR:
                    throw new IsDirException("Can't update size of a directory");
                default:
                    throw new InvalException("Can't update size of a non file object");
            }
            // allow set size only for newly created files
            if (fsInode.type() == FsInodeType.INODE && chimeraStat.getState() != FileState.CREATED) {
                throw new PermException("Can't change size of existing file");
            }
        }
        org.dcache.chimera.posix.Stat chimeraStat = toChimeraStat(stat);
        // convert empty setattr to noop
        if (!chimeraStat.getDefinedAttributeses().isEmpty()) {
            fsInode.setStat(chimeraStat);
        }
    } catch (InvalidArgumentChimeraException e) {
        throw new InvalException(e.getMessage());
    } catch (IsDirChimeraException e) {
        throw new IsDirException(e.getMessage());
    } catch (FileNotFoundChimeraFsException e) {
        throw new StaleException(e.getMessage());
    } catch (PermissionDeniedChimeraFsException e) {
        throw new PermException(e.getMessage());
    }
}
Also used : IsDirException(org.dcache.nfs.status.IsDirException) InvalException(org.dcache.nfs.status.InvalException) IsDirChimeraException(org.dcache.chimera.IsDirChimeraException) InvalidArgumentChimeraException(org.dcache.chimera.InvalidArgumentChimeraException) FileNotFoundChimeraFsException(org.dcache.chimera.FileNotFoundChimeraFsException) PermissionDeniedChimeraFsException(org.dcache.chimera.PermissionDeniedChimeraFsException) FsInode(org.dcache.chimera.FsInode) PermException(org.dcache.nfs.status.PermException) StaleException(org.dcache.nfs.status.StaleException)

Example 2 with StaleException

use of org.dcache.nfs.status.StaleException in project dcache by dCache.

the class ChimeraVfs method setAcl.

@Override
public void setAcl(Inode inode, nfsace4[] acl) throws IOException {
    FsInode fsInode = toFsInode(inode);
    List<ACE> dacl = new ArrayList<>();
    for (nfsace4 ace : acl) {
        dacl.add(valueOf(ace, _idMapping));
    }
    try {
        _fs.setACL(fsInode, dacl);
    } catch (FileNotFoundChimeraFsException e) {
        throw new StaleException(e.getMessage());
    }
}
Also used : FileNotFoundChimeraFsException(org.dcache.chimera.FileNotFoundChimeraFsException) org.dcache.nfs.v4.xdr.nfsace4(org.dcache.nfs.v4.xdr.nfsace4) ACE4_INHERIT_ONLY_ACE(org.dcache.nfs.v4.xdr.nfs4_prot.ACE4_INHERIT_ONLY_ACE) ACE(org.dcache.acl.ACE) FsInode(org.dcache.chimera.FsInode) ArrayList(java.util.ArrayList) StaleException(org.dcache.nfs.status.StaleException)

Example 3 with StaleException

use of org.dcache.nfs.status.StaleException in project dcache by dCache.

the class NFSv41Door method layoutGet.

/**
 * 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, LAYOUTGET4args args) throws IOException {
    Inode nfsInode = context.currentInode();
    layouttype4 layoutType = layouttype4.valueOf(args.loga_layout_type);
    final stateid4 stateid = Stateids.getCurrentStateidIfNeeded(context, args.loga_stateid);
    LayoutDriver layoutDriver = getLayoutDriver(layoutType);
    final NFS4Client client;
    if (context.getMinorversion() == 0) {
        /* if we need to run proxy-io with NFSv4.0 */
        client = context.getStateHandler().getClientIdByStateId(stateid);
    } else {
        client = context.getSession().getClient();
    }
    CDC cdcContext = CDC.reset(getCellName(), getCellDomainName());
    try {
        FsInode inode = _chimeraVfs.inodeFromBytes(nfsInode.getFileId());
        PnfsId pnfsId = new PnfsId(inode.getId());
        deviceid4[] devices;
        final NFS4State openStateId = client.state(stateid).getOpenState();
        final NFS4State layoutStateId;
        // serialize all requests by the same stateid
        synchronized (openStateId) {
            if (inode.type() != FsInodeType.INODE || inode.getLevel() != 0) {
                /*
                     * all non regular files ( AKA pnfs dot files ) provided by door itself.
                     */
                throw new LayoutUnavailableException("special DOT file");
            }
            final InetSocketAddress remote = context.getRpcCall().getTransport().getRemoteSocketAddress();
            final NFS4ProtocolInfo protocolInfo = new NFS4ProtocolInfo(remote, new org.dcache.chimera.nfs.v4.xdr.stateid4(stateid), nfsInode.toNfsHandle());
            NfsTransfer transfer = _transfers.get(openStateId.stateid());
            if (transfer == null) {
                Transfer.initSession(false, false);
                NDC.push(pnfsId.toString());
                NDC.push(context.getRpcCall().getTransport().getRemoteSocketAddress().toString());
                transfer = args.loga_iomode == layoutiomode4.LAYOUTIOMODE4_RW ? new WriteTransfer(_pnfsHandler, client, openStateId, nfsInode, context.getRpcCall().getCredential().getSubject()) : new ReadTransfer(_pnfsHandler, client, openStateId, nfsInode, context.getRpcCall().getCredential().getSubject());
                transfer.setProtocolInfo(protocolInfo);
                transfer.setCellAddress(getCellAddress());
                transfer.setBillingStub(_billingStub);
                transfer.setPoolStub(_poolStub);
                transfer.setPoolManagerStub(_poolManagerStub);
                transfer.setPnfsId(pnfsId);
                transfer.setClientAddress(remote);
                transfer.setIoQueue(_ioQueue);
                transfer.setKafkaSender(_kafkaSender);
                /*
                     * As all our layouts marked 'return-on-close', stop mover when
                     * open-state disposed on CLOSE.
                     */
                final NfsTransfer t = transfer;
                openStateId.addDisposeListener(state -> {
                    /*
                         * Cleanup transfer when state invalidated.
                         */
                    if (t.hasMover()) {
                        // to work correctly with proxy-io. As modern rhel clients (>= 7) use flex_files by default it's ok.
                        if (layoutType == layouttype4.LAYOUT4_FLEX_FILES && client.isLeaseValid() && client.getCB() != null) {
                            /*
                                 * Due to race in the Linux kernel client, a server might see CLOSE before
                                 * the last WRITE operation have been processed by a data server. Thus,
                                 * recall the layout (enforce dirty page flushing) and return a NFS4ERR_DELAY.
                                 *
                                 * see: https://bugzilla.redhat.com/show_bug.cgi?id=1901524
                                 */
                            _log.warn("Deploying work-around for buggy client {} issuing CLOSE before LAYOUT_RETURN for transfer {}@{} of {}", t.getMoverId(), t.getPool(), t.getPnfsId(), t.getClient().getRemoteAddress());
                            t.recallLayout(_callbackExecutor);
                            throw new DelayException("Close before layoutreturn");
                        } else {
                            _log.warn("Removing orphan mover: {}@{} for {} by {}", t.getMoverId(), t.getPool(), t.getPnfsId(), t.getClient().getRemoteAddress());
                            t.shutdownMover();
                        }
                    }
                    if (t.isWrite()) {
                        /* write request keep in the message map to
                             * avoid re-creates and trigger errors.
                             */
                        _transfers.remove(openStateId.stateid());
                    }
                });
                _transfers.put(openStateId.stateid(), transfer);
            } else {
                // keep debug context in sync
                transfer.restoreSession();
                NDC.push(pnfsId.toString());
                NDC.push(context.getRpcCall().getTransport().getRemoteSocketAddress().toString());
            }
            layoutStateId = transfer.getStateid();
            devices = transfer.getPoolDataServers(NFS_REQUEST_BLOCKING);
        }
        // -1 is special value, which means entire file
        layout4 layout = new layout4();
        layout.lo_iomode = args.loga_iomode;
        layout.lo_offset = new offset4(0);
        layout.lo_length = new length4(nfs4_prot.NFS4_UINT64_MAX);
        layout.lo_content = layoutDriver.getLayoutContent(stateid, NFSv4Defaults.NFS4_STRIPE_SIZE, new nfs_fh4(nfsInode.toNfsHandle()), devices);
        layoutStateId.bumpSeqid();
        if (args.loga_iomode == layoutiomode4.LAYOUTIOMODE4_RW) {
            // in case of WRITE, invalidate vfs cache on close
            layoutStateId.addDisposeListener(state -> _vfsCache.invalidateStatCache(nfsInode));
        }
        return new Layout(true, layoutStateId.stateid(), new layout4[] { layout });
    } catch (FileNotFoundCacheException e) {
        /*
             * The file is removed before we was able to start a mover.
             * Invalidate state as client will not send CLOSE for a stale file
             * handle.
             *
             * NOTICE: according POSIX, the opened file must be still accessible
             * after remove as long as it not closed. We violate that requirement
             * in favor of dCache shared state simplicity.
             */
        client.releaseState(stateid);
        throw new StaleException("File is removed", e);
    } catch (CacheException | ChimeraFsException | TimeoutException | ExecutionException e) {
        throw asNfsException(e, LayoutTryLaterException.class);
    } catch (InterruptedException e) {
        throw new LayoutTryLaterException(e.getMessage(), e);
    } finally {
        cdcContext.close();
    }
}
Also used : org.dcache.nfs.v4.xdr.layouttype4(org.dcache.nfs.v4.xdr.layouttype4) DelayException(org.dcache.nfs.status.DelayException) CDC(dmg.cells.nucleus.CDC) FileNotFoundCacheException(diskCacheV111.util.FileNotFoundCacheException) CacheException(diskCacheV111.util.CacheException) FileNotInCacheException(diskCacheV111.util.FileNotInCacheException) PermissionDeniedCacheException(diskCacheV111.util.PermissionDeniedCacheException) InetSocketAddress(java.net.InetSocketAddress) NFS4State(org.dcache.nfs.v4.NFS4State) org.dcache.nfs.v4.xdr.layout4(org.dcache.nfs.v4.xdr.layout4) org.dcache.nfs.v4.xdr.nfs_fh4(org.dcache.nfs.v4.xdr.nfs_fh4) ChimeraFsException(org.dcache.chimera.ChimeraFsException) LayoutDriver(org.dcache.nfs.v4.LayoutDriver) NfsV41FileLayoutDriver(org.dcache.nfs.v4.NfsV41FileLayoutDriver) FlexFileLayoutDriver(org.dcache.nfs.v4.FlexFileLayoutDriver) FsInode(org.dcache.chimera.FsInode) org.dcache.nfs.v4.xdr.stateid4(org.dcache.nfs.v4.xdr.stateid4) StaleException(org.dcache.nfs.status.StaleException) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException) org.dcache.nfs.v4.xdr.deviceid4(org.dcache.nfs.v4.xdr.deviceid4) PnfsId(diskCacheV111.util.PnfsId) NFS4ProtocolInfo(org.dcache.chimera.nfsv41.mover.NFS4ProtocolInfo) NFS4Client(org.dcache.nfs.v4.NFS4Client) FsInode(org.dcache.chimera.FsInode) Inode(org.dcache.nfs.vfs.Inode) org.dcache.nfs.v4.xdr.offset4(org.dcache.nfs.v4.xdr.offset4) Layout(org.dcache.nfs.v4.Layout) org.dcache.nfs.v4.xdr.length4(org.dcache.nfs.v4.xdr.length4) FileNotFoundCacheException(diskCacheV111.util.FileNotFoundCacheException) LayoutUnavailableException(org.dcache.nfs.status.LayoutUnavailableException) LayoutTryLaterException(org.dcache.nfs.status.LayoutTryLaterException)

Example 4 with StaleException

use of org.dcache.nfs.status.StaleException in project dcache by dCache.

the class ChimeraVfs method getAcl.

@Override
public nfsace4[] getAcl(Inode inode) throws IOException {
    FsInode fsInode = toFsInode(inode);
    try {
        nfsace4[] aces;
        List<ACE> dacl = _fs.getACL(fsInode);
        org.dcache.chimera.posix.Stat stat = fsInode.statCache();
        nfsace4[] unixAcl = Acls.of(stat.getMode(), fsInode.isDirectory());
        aces = new nfsace4[dacl.size() + unixAcl.length];
        int i = 0;
        for (ACE ace : dacl) {
            aces[i] = valueOf(ace, _idMapping);
            i++;
        }
        System.arraycopy(unixAcl, 0, aces, i, unixAcl.length);
        return Acls.compact(aces);
    } catch (FileNotFoundChimeraFsException e) {
        throw new StaleException(e.getMessage());
    }
}
Also used : FileNotFoundChimeraFsException(org.dcache.chimera.FileNotFoundChimeraFsException) org.dcache.nfs.v4.xdr.nfsace4(org.dcache.nfs.v4.xdr.nfsace4) ACE4_INHERIT_ONLY_ACE(org.dcache.nfs.v4.xdr.nfs4_prot.ACE4_INHERIT_ONLY_ACE) ACE(org.dcache.acl.ACE) FsInode(org.dcache.chimera.FsInode) StaleException(org.dcache.nfs.status.StaleException)

Aggregations

FsInode (org.dcache.chimera.FsInode)4 StaleException (org.dcache.nfs.status.StaleException)4 FileNotFoundChimeraFsException (org.dcache.chimera.FileNotFoundChimeraFsException)3 ACE (org.dcache.acl.ACE)2 ACE4_INHERIT_ONLY_ACE (org.dcache.nfs.v4.xdr.nfs4_prot.ACE4_INHERIT_ONLY_ACE)2 org.dcache.nfs.v4.xdr.nfsace4 (org.dcache.nfs.v4.xdr.nfsace4)2 CacheException (diskCacheV111.util.CacheException)1 FileNotFoundCacheException (diskCacheV111.util.FileNotFoundCacheException)1 FileNotInCacheException (diskCacheV111.util.FileNotInCacheException)1 PermissionDeniedCacheException (diskCacheV111.util.PermissionDeniedCacheException)1 PnfsId (diskCacheV111.util.PnfsId)1 CDC (dmg.cells.nucleus.CDC)1 InetSocketAddress (java.net.InetSocketAddress)1 ArrayList (java.util.ArrayList)1 ExecutionException (java.util.concurrent.ExecutionException)1 TimeoutException (java.util.concurrent.TimeoutException)1 ChimeraFsException (org.dcache.chimera.ChimeraFsException)1 InvalidArgumentChimeraException (org.dcache.chimera.InvalidArgumentChimeraException)1 IsDirChimeraException (org.dcache.chimera.IsDirChimeraException)1 PermissionDeniedChimeraFsException (org.dcache.chimera.PermissionDeniedChimeraFsException)1