get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2225528/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2225528,
    "url": "http://patchwork.ozlabs.org/api/patches/2225528/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linux-cifs-client/patch/20260421063955.99164-5-sprasad@microsoft.com/",
    "project": {
        "id": 12,
        "url": "http://patchwork.ozlabs.org/api/projects/12/?format=api",
        "name": "Linux CIFS Client",
        "link_name": "linux-cifs-client",
        "list_id": "linux-cifs.vger.kernel.org",
        "list_email": "linux-cifs@vger.kernel.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260421063955.99164-5-sprasad@microsoft.com>",
    "list_archive_url": null,
    "date": "2026-04-21T06:39:53",
    "name": "[v2,5/7] cifs: optimize readdir for small directories",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "60a1a2a4c85ac135b7ee6219d59fabfab062f60c",
    "submitter": {
        "id": 79368,
        "url": "http://patchwork.ozlabs.org/api/people/79368/?format=api",
        "name": "Shyam Prasad N",
        "email": "nspmangalore@gmail.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linux-cifs-client/patch/20260421063955.99164-5-sprasad@microsoft.com/mbox/",
    "series": [
        {
            "id": 500744,
            "url": "http://patchwork.ozlabs.org/api/series/500744/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/linux-cifs-client/list/?series=500744",
            "date": "2026-04-21T06:39:49",
            "name": "[v2,1/7] cifs: change_conf needs to be called for session setup",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/500744/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2225528/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2225528/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "\n <linux-cifs+bounces-10979-incoming=patchwork.ozlabs.org@vger.kernel.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "linux-cifs@vger.kernel.org"
        ],
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=iPw5mI8V;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=linux-cifs+bounces-10979-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)",
            "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com\n header.b=\"iPw5mI8V\"",
            "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=209.85.215.181",
            "smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com",
            "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=gmail.com"
        ],
        "Received": [
            "from tor.lore.kernel.org (tor.lore.kernel.org\n [IPv6:2600:3c04:e001:36c::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g0CR439cMz1yGt\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 21 Apr 2026 16:40:32 +1000 (AEST)",
            "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id 9A0A9301C95F\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 21 Apr 2026 06:40:19 +0000 (UTC)",
            "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 72226382367;\n\tTue, 21 Apr 2026 06:40:18 +0000 (UTC)",
            "from mail-pg1-f181.google.com (mail-pg1-f181.google.com\n [209.85.215.181])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id BCDDD38735D\n\tfor <linux-cifs@vger.kernel.org>; Tue, 21 Apr 2026 06:40:16 +0000 (UTC)",
            "by mail-pg1-f181.google.com with SMTP id\n 41be03b00d2f7-c79662bbd2eso2584546a12.3\n        for <linux-cifs@vger.kernel.org>;\n Mon, 20 Apr 2026 23:40:16 -0700 (PDT)",
            "from sprasad-dev1.corp.microsoft.com ([167.220.110.184])\n        by smtp.gmail.com with ESMTPSA id\n 41be03b00d2f7-c7977031729sm10032811a12.25.2026.04.20.23.40.14\n        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n        Mon, 20 Apr 2026 23:40:14 -0700 (PDT)"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776753618; cv=none;\n b=Ye5dpmcRrUr9fk+OlRJYR7KffuIW+UFbKdyAE+wyjzDPLEC+ZqOECGQdmcLKKnRb/KfPWmloDijF9du0q+WvWWk1XPQD8eX+ENife4nOQFqCj05HYL9VkOp8ua5f+Fd/ku433PjCYLIhaSVR8bxEszjWVtm4FmHKoOWkoSbXORY=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776753618; c=relaxed/simple;\n\tbh=TjQCsyImF5U2sGLyk39BsOFNwcIVtp1SdvF+F//wutM=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=WiBuL+0ODl6wQdU5cQbTq3vD89eQfvrPjSh9eeK4G+wuGtnLiaE9MDcReFtnW2Snk9Q5LmJy729SkkkOmVTQd6j9WI7092BiQU2nOpOKfM1+jRwbNrgGbQT6ekBgEj0ZBEp3bP/833D1o63tnQxSleZ3pID3D7kYByst6f2nenI=",
        "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com;\n spf=pass smtp.mailfrom=gmail.com;\n dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com\n header.b=iPw5mI8V; arc=none smtp.client-ip=209.85.215.181",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=gmail.com; s=20251104; t=1776753616; x=1777358416;\n darn=vger.kernel.org;\n        h=content-transfer-encoding:mime-version:references:in-reply-to\n         :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n         :message-id:reply-to;\n        bh=eFVzoGUrnWztIccizbPMwOMp0aqT60GfJJhBLxZaJzE=;\n        b=iPw5mI8VKifLjt4JM4Ao3CBsPyyPFZyP/otEbzZKT9PHw0YMBSHWT7Yvv0JXbtsO5k\n         DPD7gtv5JLkdgq28CZWRK5PYRADCfQwjq8YK77lxEKzaQ0l2AQ5YabLWOhDLOgfyts3O\n         qfwRF2UZXXb9vLPM94lm7tR/LRQaPFPbEwozYrwUAA1vL3WsjoRnjl6RZKfJPqvV0nkZ\n         7BMYbY7BwAmK6oQQfgmlyBKRsMM/qyGWdqMsqbLmhHVf9qIdTNfuNuHCi1ZhoBKhHMgl\n         MlsxF1HVwBHj4UNu5UYiyU+9HG7G5ZMbkEZXpDRSFrfZyiGpoFGwlbXaYBMeqqRQfErj\n         dXbw==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=1e100.net; s=20251104; t=1776753616; x=1777358416;\n        h=content-transfer-encoding:mime-version:references:in-reply-to\n         :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n         :to:cc:subject:date:message-id:reply-to;\n        bh=eFVzoGUrnWztIccizbPMwOMp0aqT60GfJJhBLxZaJzE=;\n        b=EMP6zOHXdeAjlDqK9vVoa8oyxvIj65XLxnLm4xAZ3j57/ySvAL9xNqvwOo6HDAlM2K\n         Fhh9RSNRUT6w1QlVjyaQ2HHIsgKqMQTRVKTYe1cLstJm97ir9yF1dMIxbVUpSkJJc1UZ\n         +7vgW0fshNWSbUlnAsCgjTBN+u9JT/quNwO2OD3SxiqVVV/M5xmYM/ccwMoHSGoOs/bi\n         rTXAf4JVDGcqf9NdAcJkE1K1Ukrr4jPMaEVj/DIMiKf9AAlJ1i9q3L4xPvR02yIpEqr3\n         B+KBw4jYGrK7pjgBQZ0pB6WXkVSEjGdd4+IgVyCfY9rEjSuzUyfpns+DOupOfE8XQBdN\n         vfnQ==",
        "X-Gm-Message-State": "AOJu0YwKLYRtBD7QvaJTPsKbu9MwcNfVbXHsFKPx5Lgc55ccBDFgXWCz\n\tjl8+O3uQdysmrF4XslbX8R7t87d/Wr+0tGoLD0R2sJhnjliFnVMkyJDNrmw1qXVsExU=",
        "X-Gm-Gg": "AeBDieuvJDKINcttzwxQ3+0aYp2oXLFz9Yk/3dlCPx+Y5xDKGhYiQgJZiQNZjcfl+iJ\n\tduSebyMzWik5bR5X7UK9jcSFODrXcDyXZXsQz7mOO8ZHLEp4nSVEVJLCB9ItCRQFJNDSampRhVa\n\t+5JbNbABW2kjeV2aGzTdXfy2buWgE3UOJBsbcek1DlE6Ns/1Tl8Oxqx7FvJwx6SJc0BmvxQcmpm\n\tobuAHI202Fp6s1ae6YL9wtH1wEYUYMr5/AbHe8mGnzQqr5laW9Cg1ItTPBPki7Naplae+yBUdXU\n\tT5d6VduuqvsHdoY8bHUPLUHxZ4Ko+B9k2qK3ZWMKgz+slnrMgkV/vOkxbhic60TK1w+fD+yltTv\n\tLQCgbt57E5pdyof5UQD5vL+FFBg4k9Wqaavo3yqRqTB9RXrZb2szL0a9LT2eC3n4xVnhiw5ktzr\n\tJYyqr74aMapT03wXCJhPNCo5Sq5WReiJ5oZbWrTCqXtXqttLpAZhlj71GXvOiTqNGb",
        "X-Received": "by 2002:a05:6a20:4326:b0:39f:3559:7501 with SMTP id\n adf61e73a8af0-3a08d8eb11bmr19749107637.41.1776753615389;\n        Mon, 20 Apr 2026 23:40:15 -0700 (PDT)",
        "From": "nspmangalore@gmail.com",
        "X-Google-Original-From": "sprasad@microsoft.com",
        "To": "linux-cifs@vger.kernel.org,\n\tsmfrench@gmail.com,\n\tpc@manguebit.org,\n\tbharathsm@microsoft.com,\n\tdhowells@redhat.com,\n\thenrique.carvalho@suse.com,\n\tematsumiya@suse.de",
        "Cc": "Shyam Prasad N <sprasad@microsoft.com>",
        "Subject": "[PATCH v2 5/7] cifs: optimize readdir for small directories",
        "Date": "Tue, 21 Apr 2026 12:09:53 +0530",
        "Message-ID": "<20260421063955.99164-5-sprasad@microsoft.com>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<20260421063955.99164-1-sprasad@microsoft.com>",
        "References": "<20260421063955.99164-1-sprasad@microsoft.com>",
        "Precedence": "bulk",
        "X-Mailing-List": "linux-cifs@vger.kernel.org",
        "List-Id": "<linux-cifs.vger.kernel.org>",
        "List-Subscribe": "<mailto:linux-cifs+subscribe@vger.kernel.org>",
        "List-Unsubscribe": "<mailto:linux-cifs+unsubscribe@vger.kernel.org>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit"
    },
    "content": "From: Shyam Prasad N <sprasad@microsoft.com>\n\nFor small directories (where the entire directory contents could be\nread in a single QueryDir request), we currently do an extra\nround-trip just to get a STATUS_NO_MORE_FILES back from the server.\n\nThis change avoids doing that by adding another QueryDir to the first\ncompound to the server for readdir. i.e. first request to readdir\nwill correspond to a compound of (OPEN+QD1+QD2). QD2 will request\nfor a smaller size (in anticipation of STATUS_NO_MORE_FILES).\n\nSigned-off-by: Shyam Prasad N <sprasad@microsoft.com>\n---\n fs/smb/client/smb2ops.c   | 156 ++++++++++++++++++++++++++++++++++----\n fs/smb/client/smb2pdu.c   |  19 +++--\n fs/smb/client/smb2pdu.h   |  11 +++\n fs/smb/client/smb2proto.h |   3 +-\n 4 files changed, 168 insertions(+), 21 deletions(-)",
    "diff": "diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c\nindex 3625030d1912f..dd1f5b91dbc98 100644\n--- a/fs/smb/client/smb2ops.c\n+++ b/fs/smb/client/smb2ops.c\n@@ -2448,18 +2448,21 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,\n \t\t     struct cifs_search_info *srch_inf)\n {\n \t__le16 *utf16_path;\n-\tstruct smb_rqst rqst[2];\n-\tstruct kvec rsp_iov[2];\n-\tint resp_buftype[2];\n+\tstruct smb_rqst rqst[3];\n+\tstruct kvec rsp_iov[3];\n+\tint resp_buftype[3];\n \tstruct kvec open_iov[SMB2_CREATE_IOV_SIZE];\n-\tstruct kvec qd_iov[SMB2_QUERY_DIRECTORY_IOV_SIZE];\n+\tstruct kvec qd_iov[SMB2_QUERY_DIRECTORY_IOV_SIZE + 1]; /* +1 for padding */\n+\tstruct kvec qd2_iov[SMB2_QUERY_DIRECTORY_IOV_SIZE + 1]; /* +1 for padding */\n \tint rc, flags = 0;\n \tu8 oplock = SMB2_OPLOCK_LEVEL_NONE;\n \tstruct cifs_open_parms oparms;\n \tstruct smb2_query_directory_rsp *qd_rsp = NULL;\n+\tstruct smb2_query_directory_rsp *qd2_rsp = NULL;\n \tstruct smb2_create_rsp *op_rsp = NULL;\n \tstruct TCP_Server_Info *server;\n \tint retries = 0, cur_sleep = 0;\n+\tunsigned int compound_resp_bufsize;\n \n replay_again:\n \t/* reinitialize for possible replay */\n@@ -2474,8 +2477,15 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,\n \tif (smb3_encryption_required(tcon))\n \t\tflags |= CIFS_TRANSFORM_REQ;\n \n+\t/*\n+\t * Clamp compound Create+QD1+QD2 response sizing to a response size\n+\t * for suited for one credit even if CIFSMaxBufSize is tuned larger\n+\t */\n+\tcompound_resp_bufsize = min_t(unsigned int, CIFSMaxBufSize,\n+\t\t\t\t      SMB2_MAX_BUFFER_SIZE);\n+\n \tmemset(rqst, 0, sizeof(rqst));\n-\tresp_buftype[0] = resp_buftype[1] = CIFS_NO_BUFFER;\n+\tresp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;\n \tmemset(rsp_iov, 0, sizeof(rsp_iov));\n \n \t/* Open */\n@@ -2499,7 +2509,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,\n \t\tgoto qdf_free;\n \tsmb2_set_next_command(tcon, &rqst[0]);\n \n-\t/* Query directory */\n+\t/* First Query directory */\n \tsrch_inf->entries_in_buffer = 0;\n \tsrch_inf->index_of_last_entry = 2;\n \n@@ -2510,11 +2520,27 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,\n \trc = SMB2_query_directory_init(xid, tcon, server,\n \t\t\t\t       &rqst[1],\n \t\t\t\t       COMPOUND_FID, COMPOUND_FID,\n-\t\t\t\t       0, srch_inf->info_level);\n+\t\t\t\t       0, srch_inf->info_level,\n+\t\t\t\t       SMB2_QD1_OUTPUT_SIZE(compound_resp_bufsize));\n \tif (rc)\n \t\tgoto qdf_free;\n \n \tsmb2_set_related(&rqst[1]);\n+\tsmb2_set_next_command(tcon, &rqst[1]);\n+\n+\t/* Second Query directory - minimal size to check if more data exists */\n+\tmemset(&qd2_iov, 0, sizeof(qd2_iov));\n+\trqst[2].rq_iov = qd2_iov;\n+\trqst[2].rq_nvec = SMB2_QUERY_DIRECTORY_IOV_SIZE;\n+\n+\trc = SMB2_query_directory_init(xid, tcon, server,\n+\t\t\t\t       &rqst[2],\n+\t\t\t\t       COMPOUND_FID, COMPOUND_FID,\n+\t\t\t\t       0, srch_inf->info_level, SMB2_QD2_RESPONSE_SIZE);\n+\tif (rc)\n+\t\tgoto qdf_free;\n+\n+\tsmb2_set_related(&rqst[2]);\n \n \tif (retries) {\n \t\t/* Back-off before retry */\n@@ -2522,10 +2548,11 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,\n \t\t\tmsleep(cur_sleep);\n \t\tsmb2_set_replay(server, &rqst[0]);\n \t\tsmb2_set_replay(server, &rqst[1]);\n+\t\tsmb2_set_replay(server, &rqst[2]);\n \t}\n \n \trc = compound_send_recv(xid, tcon->ses, server,\n-\t\t\t\tflags, 2, rqst,\n+\t\t\t\tflags, 3, rqst,\n \t\t\t\tresp_buftype, rsp_iov);\n \n \t/* If the open failed there is nothing to do */\n@@ -2557,14 +2584,111 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,\n \t\tgoto qdf_free;\n \t}\n \n-\trc = smb2_parse_query_directory(tcon, &rsp_iov[1], resp_buftype[1],\n-\t\t\t\t\tsrch_inf);\n-\tif (rc) {\n-\t\ttrace_smb3_query_dir_err(xid, fid->persistent_fid, tcon->tid,\n-\t\t\ttcon->ses->Suid, 0, 0, rc);\n-\t\tgoto qdf_free;\n+\tqd2_rsp = (struct smb2_query_directory_rsp *)rsp_iov[2].iov_base;\n+\n+\t/*\n+\t * If QD2 has data, combine QD1 and QD2 responses before parsing.\n+\t * The server cursor advances past both responses, so we can't discard QD2.\n+\t */\n+\tif (qd2_rsp && qd2_rsp->hdr.Status == STATUS_SUCCESS &&\n+\t    le32_to_cpu(qd2_rsp->OutputBufferLength) > 0) {\n+\t\tchar *combined_buf;\n+\t\tsize_t qd1_data_len, qd2_data_len, combined_len;\n+\t\tu16 qd1_offset, qd2_offset;\n+\t\tstruct smb2_query_directory_rsp *combined_rsp;\n+\t\tstruct kvec combined_iov;\n+\t\tFILE_DIRECTORY_INFO *last_entry_in_qd1;\n+\t\tchar *qd1_entries_start, *qd2_entries_start;\n+\t\tunsigned int next_offset;\n+\n+\t\tqd1_offset = le16_to_cpu(qd_rsp->OutputBufferOffset);\n+\t\tqd2_offset = le16_to_cpu(qd2_rsp->OutputBufferOffset);\n+\t\tqd1_data_len = le32_to_cpu(qd_rsp->OutputBufferLength);\n+\t\tqd2_data_len = le32_to_cpu(qd2_rsp->OutputBufferLength);\n+\n+\t\t/* Allocate buffer for: QD1 header + QD1 data + QD2 data */\n+\t\tcombined_len = qd1_offset + qd1_data_len + qd2_data_len;\n+\t\tcombined_buf = kmalloc(combined_len, GFP_KERNEL);\n+\t\tif (!combined_buf) {\n+\t\t\trc = -ENOMEM;\n+\t\t\tgoto qdf_free;\n+\t\t}\n+\n+\t\t/* Copy QD1 header and data */\n+\t\tmemcpy(combined_buf, qd_rsp, qd1_offset + qd1_data_len);\n+\n+\t\t/* Append QD2 data (directory entries only, not the header) */\n+\t\tmemcpy(combined_buf + qd1_offset + qd1_data_len,\n+\t\t       (char *)qd2_rsp + qd2_offset, qd2_data_len);\n+\n+\t\t/* Update OutputBufferLength to reflect combined data */\n+\t\tcombined_rsp = (struct smb2_query_directory_rsp *)combined_buf;\n+\t\tcombined_rsp->OutputBufferLength = cpu_to_le32(qd1_data_len + qd2_data_len);\n+\n+\t\t/*\n+\t\t * Chain QD1 and QD2 entries: find the last entry in QD1 and update\n+\t\t * its NextEntryOffset to point to the first entry in QD2.\n+\t\t */\n+\t\tif (qd1_data_len > 0) {\n+\t\t\tqd1_entries_start = combined_buf + qd1_offset;\n+\t\t\tqd2_entries_start = combined_buf + qd1_offset + qd1_data_len;\n+\t\t\tlast_entry_in_qd1 = (FILE_DIRECTORY_INFO *)qd1_entries_start;\n+\n+\t\t\t/* Walk QD1 entries to find the last one with bounds checking */\n+\t\t\twhile (1) {\n+\t\t\t\tchar *end_of_qd1 = qd1_entries_start + qd1_data_len;\n+\n+\t\t\t\tnext_offset = le32_to_cpu(last_entry_in_qd1->NextEntryOffset);\n+\t\t\t\tif (next_offset == 0)\n+\t\t\t\t\tbreak;  /* Found last entry */\n+\n+\t\t\t\t/* Bounds check before advancing */\n+\t\t\t\tif ((char *)last_entry_in_qd1 + next_offset >= end_of_qd1) {\n+\t\t\t\t\tcifs_dbg(VFS, \"query_dir_first: invalid NextEntryOffset in QD1\\n\");\n+\t\t\t\t\tkfree(combined_buf);\n+\t\t\t\t\trc = -EIO;\n+\t\t\t\t\tgoto qdf_free;\n+\t\t\t\t}\n+\n+\t\t\t\tlast_entry_in_qd1 = (FILE_DIRECTORY_INFO *)((char *)last_entry_in_qd1 + next_offset);\n+\t\t\t}\n+\n+\t\t\t/* Chain last QD1 entry to first QD2 entry */\n+\t\t\tlast_entry_in_qd1->NextEntryOffset = cpu_to_le32(qd2_entries_start - (char *)last_entry_in_qd1);\n+\t\t}\n+\n+\t\t/* Parse the combined buffer */\n+\t\tcombined_iov.iov_base = combined_buf;\n+\t\tcombined_iov.iov_len = combined_len;\n+\t\trc = smb2_parse_query_directory(tcon, &combined_iov, CIFS_DYNAMIC_BUFFER,\n+\t\t\t\t\t\tsrch_inf);\n+\t\tif (rc) {\n+\t\t\tkfree(combined_buf);\n+\t\t\ttrace_smb3_query_dir_err(xid, fid->persistent_fid, tcon->tid,\n+\t\t\t\t\t\t tcon->ses->Suid, 0, 0, rc);\n+\t\t\tgoto qdf_free;\n+\t\t}\n+\t\t/* Ownership of combined_buf transferred to srch_inf->ntwrk_buf_start */\n+\t\tsrch_inf->endOfSearch = false;\n+\t\tcifs_dbg(FYI, \"query_dir_first: combined QD1 and QD2, %d entries\\n\",\n+\t\t\t srch_inf->entries_in_buffer);\n+\t} else {\n+\t\t/* No data in QD2, just parse QD1 */\n+\t\trc = smb2_parse_query_directory(tcon, &rsp_iov[1], resp_buftype[1],\n+\t\t\t\t\t\tsrch_inf);\n+\t\tif (rc) {\n+\t\t\ttrace_smb3_query_dir_err(xid, fid->persistent_fid, tcon->tid,\n+\t\t\t\t\t\t tcon->ses->Suid, 0, 0, rc);\n+\t\t\tgoto qdf_free;\n+\t\t}\n+\t\tresp_buftype[1] = CIFS_NO_BUFFER;\n+\n+\t\t/* Check if QD2 indicates end of directory */\n+\t\tif (qd2_rsp && qd2_rsp->hdr.Status == STATUS_NO_MORE_FILES) {\n+\t\t\tsrch_inf->endOfSearch = true;\n+\t\t\tcifs_dbg(FYI, \"query_dir_first: small directory, all entries read\\n\");\n+\t\t}\n \t}\n-\tresp_buftype[1] = CIFS_NO_BUFFER;\n \n \ttrace_smb3_query_dir_done(xid, fid->persistent_fid, tcon->tid,\n \t\t\ttcon->ses->Suid, 0, srch_inf->entries_in_buffer);\n@@ -2573,8 +2697,10 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,\n \tkfree(utf16_path);\n \tSMB2_open_free(&rqst[0]);\n \tSMB2_query_directory_free(&rqst[1]);\n+\tSMB2_query_directory_free(&rqst[2]);\n \tfree_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);\n \tfree_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);\n+\tfree_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);\n \n \tif (is_replayable_error(rc) &&\n \t    smb2_should_replay(tcon, &retries, &cur_sleep))\ndiff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c\nindex 49dca84b169e6..2d55246d2851b 100644\n--- a/fs/smb/client/smb2pdu.c\n+++ b/fs/smb/client/smb2pdu.c\n@@ -5504,18 +5504,27 @@ int SMB2_query_directory_init(const unsigned int xid,\n \t\t\t      struct TCP_Server_Info *server,\n \t\t\t      struct smb_rqst *rqst,\n \t\t\t      u64 persistent_fid, u64 volatile_fid,\n-\t\t\t      int index, int info_level)\n+\t\t\t      int index, int info_level,\n+\t\t\t      unsigned int output_size)\n {\n \tstruct smb2_query_directory_req *req;\n \tunsigned char *bufptr;\n \t__le16 asteriks = cpu_to_le16('*');\n-\tunsigned int output_size = CIFSMaxBufSize -\n-\t\tMAX_SMB2_CREATE_RESPONSE_SIZE -\n-\t\tMAX_SMB2_CLOSE_RESPONSE_SIZE;\n \tunsigned int total_len;\n \tstruct kvec *iov = rqst->rq_iov;\n \tint len, rc;\n \n+\t/*\n+\t * Use provided output_size, or default to CIFSMaxBufSize calculation.\n+\t * The default is for standalone QueryDir (smb2_query_dir_next).\n+\t * For compounds, the caller should pass explicit output_size.\n+\t */\n+\tif (output_size == 0) {\n+\t\toutput_size = CIFSMaxBufSize -\n+\t\t\tMAX_SMB2_CREATE_RESPONSE_SIZE -\n+\t\t\tMAX_SMB2_CLOSE_RESPONSE_SIZE;\n+\t}\n+\n \trc = smb2_plain_req_init(SMB2_QUERY_DIRECTORY, tcon, server,\n \t\t\t\t (void **) &req, &total_len);\n \tif (rc)\n@@ -5697,7 +5706,7 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,\n \trc = SMB2_query_directory_init(xid, tcon, server,\n \t\t\t\t       &rqst, persistent_fid,\n \t\t\t\t       volatile_fid, index,\n-\t\t\t\t       srch_inf->info_level);\n+\t\t\t\t       srch_inf->info_level, 0);\n \tif (rc)\n \t\tgoto qdir_exit;\n \ndiff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h\nindex 30d70097fe2fa..7b7a864520c68 100644\n--- a/fs/smb/client/smb2pdu.h\n+++ b/fs/smb/client/smb2pdu.h\n@@ -129,6 +129,17 @@ struct share_redirect_error_context_rsp {\n  */\n #define MAX_SMB2_CREATE_RESPONSE_SIZE 880\n \n+/* Size of the minimal QueryDir response for checking if more data exists */\n+#define SMB2_QD2_RESPONSE_SIZE 4096\n+\n+/*\n+ * Output buffer size for first QueryDir in Create+QD1+QD2 compound.\n+ * Accounts for shared buffer space needed for all three responses.\n+ */\n+#define SMB2_QD1_OUTPUT_SIZE(bufsize) \\\n+\t((bufsize) - MAX_SMB2_CREATE_RESPONSE_SIZE - \\\n+\t sizeof(struct smb2_hdr) - SMB2_QD2_RESPONSE_SIZE)\n+\n #define SMB2_LEASE_READ_CACHING_HE\t0x01\n #define SMB2_LEASE_HANDLE_CACHING_HE\t0x02\n #define SMB2_LEASE_WRITE_CACHING_HE\t0x04\ndiff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h\nindex 230bb1e9f4e19..9de7d2fe8d466 100644\n--- a/fs/smb/client/smb2proto.h\n+++ b/fs/smb/client/smb2proto.h\n@@ -194,7 +194,8 @@ int SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,\n int SMB2_query_directory_init(const unsigned int xid, struct cifs_tcon *tcon,\n \t\t\t      struct TCP_Server_Info *server,\n \t\t\t      struct smb_rqst *rqst, u64 persistent_fid,\n-\t\t\t      u64 volatile_fid, int index, int info_level);\n+\t\t\t      u64 volatile_fid, int index, int info_level,\n+\t\t\t      unsigned int output_size);\n void SMB2_query_directory_free(struct smb_rqst *rqst);\n int SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon,\n \t\t u64 persistent_fid, u64 volatile_fid, u32 pid,\n",
    "prefixes": [
        "v2",
        "5/7"
    ]
}