get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2223133,
    "url": "http://patchwork.ozlabs.org/api/1.1/patches/2223133/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linux-cifs-client/patch/20260414135918.279802-5-sprasad@microsoft.com/",
    "project": {
        "id": 12,
        "url": "http://patchwork.ozlabs.org/api/1.1/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": ""
    },
    "msgid": "<20260414135918.279802-5-sprasad@microsoft.com>",
    "date": "2026-04-14T13:59:16",
    "name": "[5/7] cifs: optimize readdir for small directories",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "1eef6feae22e96910923fa92b78645dda9e39116",
    "submitter": {
        "id": 79368,
        "url": "http://patchwork.ozlabs.org/api/1.1/people/79368/?format=api",
        "name": "Shyam Prasad N",
        "email": "nspmangalore@gmail.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linux-cifs-client/patch/20260414135918.279802-5-sprasad@microsoft.com/mbox/",
    "series": [
        {
            "id": 499852,
            "url": "http://patchwork.ozlabs.org/api/1.1/series/499852/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/linux-cifs-client/list/?series=499852",
            "date": "2026-04-14T13:59:12",
            "name": "[1/7] cifs: change_conf needs to be called for session setup",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/499852/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2223133/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2223133/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "\n <linux-cifs+bounces-10807-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=J4vkquB3;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=linux-cifs+bounces-10807-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=\"J4vkquB3\"",
            "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=209.85.214.170",
            "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 sea.lore.kernel.org (sea.lore.kernel.org\n [IPv6:2600:3c0a:e001:db::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fw5bn3XM6z1yDF\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 15 Apr 2026 00:03:49 +1000 (AEST)",
            "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id CD85D3073D5F\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 14 Apr 2026 13:59:38 +0000 (UTC)",
            "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id B306A3E63BB;\n\tTue, 14 Apr 2026 13:59:36 +0000 (UTC)",
            "from mail-pl1-f170.google.com (mail-pl1-f170.google.com\n [209.85.214.170])\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 136F23E6DC1\n\tfor <linux-cifs@vger.kernel.org>; Tue, 14 Apr 2026 13:59:34 +0000 (UTC)",
            "by mail-pl1-f170.google.com with SMTP id\n d9443c01a7336-2b0afa0210bso26240655ad.2\n        for <linux-cifs@vger.kernel.org>;\n Tue, 14 Apr 2026 06:59:34 -0700 (PDT)",
            "from sprasad-dev1.corp.microsoft.com ([167.220.110.184])\n        by smtp.gmail.com with ESMTPSA id\n d9443c01a7336-2b4612e60dasm59779895ad.38.2026.04.14.06.59.33\n        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n        Tue, 14 Apr 2026 06:59:33 -0700 (PDT)"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776175176; cv=none;\n b=D8ReLInofOLt2xcb9VrXBqiU4xQdsdqJpgqReKgLIrLZptpfA/DdWmPUgVrNhv0y3DWdY8FlD/2fl0fqEupEunRxDY4WbSZwx7pz9myPiPToD3xMD58WwmfOlcNn8/yvj0ybk3rZXjYBE4p1yTV5RRepIvUzJ2+zVhyOiHAfuVo=",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776175176; c=relaxed/simple;\n\tbh=5GjgZTH0uPH6ezZR1ZL8wEvaIJaKUptB6c4rF3tpzuA=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=YrR+YymySust4JgVlfruS7hpuEmMofZenr+RhOoFObezadNq1q5HtCPtmF8bHaBZB+a4HhxttTkZjs14624Y6+nn7kHxT3bGcKltH73GUQC8nKQfjlSZvir68RRP79IWsOjb4pubzEaqzc9vb0SKglbGqYu0dOaVaqylSd0VC6U=",
        "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=J4vkquB3; arc=none smtp.client-ip=209.85.214.170",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=gmail.com; s=20251104; t=1776175174; x=1776779974;\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=S0HB/MgsZLjGb1ql4mboiE30ShmXkH485WaciscovgA=;\n        b=J4vkquB3iNUkj4qO0UCLb/08j46mx1U9sbA11iK9ZHdgntbe0qeFWUQk+/vX04skUo\n         3CgryRIfSJsA9H+N32QQq2DP2U/vHqRgKAOuBQvwwGJYSwWG0B/IHpMyWKUlJo9HTwR4\n         cW3zaZbM0QQDs0hjgwqt6LE4wrtvDBnbdMjnrxSyyaDBK0nqdKRRNWhhld3i5PFVZT7E\n         Iql7Ujs0zHRHSZR/56YJgh5RlnvWzmUY1I9ezGN1uXlRUHRIy4uTNCZIYauSUKQlpgHj\n         iB5o57qgEhYDcpnXgRGdhc2LT9Al35Pd8oh+WaXxkYSZ8i/3wlvvjzF9C3Ac7Hhp3lMe\n         nlOQ==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=1e100.net; s=20251104; t=1776175174; x=1776779974;\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=S0HB/MgsZLjGb1ql4mboiE30ShmXkH485WaciscovgA=;\n        b=g03JXrr2Wh4rrGKOteLLW14wA2yAatR8WQTt7Lrj/W5UdDcjyHM0kJniiFj4knOVQA\n         cPFaQzaUs0fDarhgz8k85uhqMCb6iUDCIKLpJDtY6GUC+o0nhXEh5peZAs8//INIVAck\n         Ch9debg/HhlUIPJqZuq+DK+/O790LVasTGutD3vZBVZtBj/o0pQjVp+Q2nEJwBK98VvD\n         oHqDw8OBML5Kuvyk85a4VZ3GQi8QggBNUaUNyOA1uhhDTi29Estzid38GccaXMy1UhXa\n         WwJFINjgWO9LbnQZUcQ9SB/5spCRwUg8FrUAAGPV53uff2gKxI76CwvIvR7aLPDEnNCg\n         gS6Q==",
        "X-Gm-Message-State": "AOJu0Yxpt4Hq8E82dTsZr6Vlye3zVnlhpbmg6lb45oDbYa7ClkGozQEt\n\txQYR1EPkrT9VO7zo14p2X3fnSH12nEDFIzw071kO0OyH5nbvk21YUgp4xer31nuZZGU=",
        "X-Gm-Gg": "AeBDiet2RucqjFX/U0Y8MPWmYelgYODdk49Ixs+onQKpcn6FsO/39vJFvzk147k1NM7\n\trvJ71+Ob51jbkmaSXezP0VU6dW6KS9xIqYPjews+hMrcayngW0lyIsCHcfCLXB8CmGTI8WeekpF\n\tTgJSD5/D9e2QZguuRjNJevLC/vtcw5XsmV7ppMOePry4E1izE7IUdw1/QZ4GzCUJmitC1fA5PPI\n\tku0cDERhILKEZeEWgXjD/LIPOL5mbmOgZ4BeCrYDd2/9eR7iD2IzjW+tFuPNgUKCePk2Gq9i6aI\n\t4LUfBG+axdO131M9abkJfBk0KXOexlbn4u2vdfbum14uJTvofFGNJxlibDjFHX6nwLajZN6Ak1s\n\tNGTK3Htr93GVDVqFUU/y8SLhO1DJMzKmXi0izZ4oYOYHuOJdz2/B/SqGfryvRPNt4fbDRG/XcDn\n\t5soWddGrGZg8s+H9cChiaWBP7UNOSqyrE7w2IKLVXURf1ux6LboWsT",
        "X-Received": "by 2002:a17:902:cec6:b0:2b0:6b98:59ec with SMTP id\n d9443c01a7336-2b2d5a5d84bmr197419615ad.34.1776175173886;\n        Tue, 14 Apr 2026 06:59:33 -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.com,\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 5/7] cifs: optimize readdir for small directories",
        "Date": "Tue, 14 Apr 2026 19:29:16 +0530",
        "Message-ID": "<20260414135918.279802-5-sprasad@microsoft.com>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<20260414135918.279802-1-sprasad@microsoft.com>",
        "References": "<20260414135918.279802-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   | 148 ++++++++++++++++++++++++++++++++++----\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, 160 insertions(+), 21 deletions(-)",
    "diff": "diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c\nindex 3625030d1912f..5c6fe25204d26 100644\n--- a/fs/smb/client/smb2ops.c\n+++ b/fs/smb/client/smb2ops.c\n@@ -2448,15 +2448,17 @@ 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@@ -2475,7 +2477,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,\n \t\tflags |= CIFS_TRANSFORM_REQ;\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 +2501,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 +2512,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(CIFSMaxBufSize));\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 +2540,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 +2576,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 +2689,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": [
        "5/7"
    ]
}