[jcifs] JCIFS 1.3.15 Performance Issue

Joseph Kramer jkramer at vivisimo.com
Wed Nov 10 11:08:28 MST 2010


Using the 1.3.14 JCIFS library I was seeing speeds of ~15 gb/hr while crawling a SMB share and after 1.3.15 I am now seeing speeds of ~5 gb/hr.  My code opens handles before calling getServerSid to avoid a NT_STATUS_TOO_MANY_OPENED_FILES error.  This required overloading the getServerSid method in SID.java.  See code below:

Added to SID.java (should look really familiar as it is a mostly a copy and paste from the existing getServerSid method):

        public static SID getServerSid(DcerpcHandle handle) throws IOException {
synchronized (sid_cache) {
                LsaPolicyHandle policyHandle = null;
                lsarpc.LsarDomainInfo info = new lsarpc.LsarDomainInfo();
                MsrpcQueryInformationPolicy rpc;

                try {
                        policyHandle = new LsaPolicyHandle(handle, null, 0x00000001);
                        rpc = new MsrpcQueryInformationPolicy(policyHandle,
                                        (short) lsarpc.POLICY_INFO_ACCOUNT_DOMAIN, info);
                        handle.sendrecv(rpc);
                        if (rpc.retval != 0)
                                throw new SmbException(rpc.retval, false);

                        return new SID(info.sid, SID.SID_TYPE_DOMAIN, (new UnicodeString(
                                        info.name, false)).toString(), null, false);
                } finally {
                        if (policyHandle != null) {
                                policyHandle.close();
                        }
                }
}
        }

To attempt to increase performance I made the following code changes that got the speeds back up, but reintroduced the LsaPolicyHandle NT_STATUS_TOO_MANY_OPENED_FILES error.  How NOT to solve the performance problem:

Modified SID.java (removed synchronized lock):

        public static SID getServerSid(DcerpcHandle handle) throws IOException {
                LsaPolicyHandle policyHandle = null;
                lsarpc.LsarDomainInfo info = new lsarpc.LsarDomainInfo();
                MsrpcQueryInformationPolicy rpc;

                try {
                        policyHandle = new LsaPolicyHandle(handle, null, 0x00000001);
                        rpc = new MsrpcQueryInformationPolicy(policyHandle,
                                        (short) lsarpc.POLICY_INFO_ACCOUNT_DOMAIN, info);
                        handle.sendrecv(rpc);
                        if (rpc.retval != 0)
                                throw new SmbException(rpc.retval, false);

                        return new SID(info.sid, SID.SID_TYPE_DOMAIN, (new UnicodeString(
                                        info.name, false)).toString(), null, false);
                } finally {
                        if (policyHandle != null) {
                                policyHandle.close();
                        }
                }
        }

Modified DcerpcHandle.java (changed synchronized lock from synchronized(this) to a private bind lock):

    private Object BIND_LOCK = new Object();

    public void bind() throws DcerpcException, IOException {
synchronized (BIND_LOCK) {
        try {
            state = 1;
            DcerpcMessage bind = new DcerpcBind(binding, this);
            sendrecv(bind);
        } catch (IOException ioe) {
            state = 0;
            throw ioe;
        }
}
    }

Any thoughts on where to look to improve performance would be greatly appreciated.  I'll also be happy to submit a patch back to the JCIFS project once this performance issue is solved.

Thanks,
Joe


More information about the jCIFS mailing list