{"id":2175168,"url":"http://patchwork.ozlabs.org/api/1.0/patches/2175168/?format=json","project":{"id":12,"url":"http://patchwork.ozlabs.org/api/1.0/projects/12/?format=json","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":"<20251217134456.16735-2-chenxiaosong.chenxiaosong@linux.dev>","date":"2025-12-17T13:44:56","name":"[RFC,cifs-utils,1/1] smbinfo: add notify subcommand","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"1bb24c6eca53c38a35d34a40a2f6b8a37c65d9f6","submitter":{"id":91884,"url":"http://patchwork.ozlabs.org/api/1.0/people/91884/?format=json","name":"ChenXiaoSong","email":"chenxiaosong.chenxiaosong@linux.dev"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-cifs-client/patch/20251217134456.16735-2-chenxiaosong.chenxiaosong@linux.dev/mbox/","series":[{"id":485692,"url":"http://patchwork.ozlabs.org/api/1.0/series/485692/?format=json","date":"2025-12-17T13:44:55","name":"smbinfo: add notify subcommand","version":1,"mbox":"http://patchwork.ozlabs.org/series/485692/mbox/"}],"check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2175168/checks/","tags":{},"headers":{"Return-Path":"\n <linux-cifs+bounces-8343-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 (1024-bit key;\n unprotected) header.d=linux.dev header.i=@linux.dev header.a=rsa-sha256\n header.s=key1 header.b=DRagxY4G;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=172.234.253.10; helo=sea.lore.kernel.org;\n envelope-from=linux-cifs+bounces-8343-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev\n header.b=\"DRagxY4G\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=95.215.58.179","smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=linux.dev","smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=linux.dev"],"Received":["from sea.lore.kernel.org (sea.lore.kernel.org [172.234.253.10])\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 4dWb9J6nJnz1y0P\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 18 Dec 2025 01:03:00 +1100 (AEDT)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 7708C309009F\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 17 Dec 2025 13:56:56 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 0C4CB33C535;\n\tWed, 17 Dec 2025 13:46:18 +0000 (UTC)","from out-179.mta1.migadu.com (out-179.mta1.migadu.com\n [95.215.58.179])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id DBA6534D385\n\tfor <linux-cifs@vger.kernel.org>; Wed, 17 Dec 2025 13:46:15 +0000 (UTC)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1765979177; cv=none;\n b=cUBfq/RWCY0s3mLSOmBL7ZR0EmM6et7pAk3xjqWgmKjmLqAVwqNXODOUwvFK/GadV4Zs+up2DtyodVy0ynSzp8sj8tcImGBLYaESVqO3qYT2oKqMesYqvQMztOSpRk569jB/OfNvNoUpMX2CRS5H0WYgr0lMUTVPVT8eUwiA2kU=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1765979177; c=relaxed/simple;\n\tbh=VEkg/V5oSVgx+3EfEekjGYOSSqZEb77Q/qbldjVi0As=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=OR4oCpugN3GrJFLuG0nHg0UHacNhG/8q3zG/1zkwtvVoT0uvJz2qgpwdbanEk6WMvPeAj9ja9csSwKbw6/nkgPX5Q4zU2iQukj0PBU9ambSPJ8bDk9stC36b7EWZKUpEDqEusTQAUmPpEG7xp9g6rR3EFtdJioop9YR3LBqvUH4=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=linux.dev;\n spf=pass smtp.mailfrom=linux.dev;\n dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev\n header.b=DRagxY4G; arc=none smtp.client-ip=95.215.58.179","X-Report-Abuse":"Please report any abuse attempt to abuse@migadu.com and\n include these headers.","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1;\n\tt=1765979173;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\t to:to:cc:cc:mime-version:mime-version:\n\t content-transfer-encoding:content-transfer-encoding:\n\t in-reply-to:in-reply-to:references:references;\n\tbh=w8pl6rlSZOCulCyW7BJBDkso7j9C6ZnAZqianP6s1Vw=;\n\tb=DRagxY4GBnPfZJJOTxyu4QyWYI8u4uZ2AjTa4k1Fd5DjgayUuupaNbYEF8GBpFJkdxtRVI\n\tjwdJ+7JxjurWVdKqL2EeeYjsWyzeTMP+G10X+J+0aiQSISUXZR5I6kI32Vc5Q+c3mTm/rG\n\tusJiErJvrgQHSOxbNZ7jASQL2urKgUI=","From":"chenxiaosong.chenxiaosong@linux.dev","To":"sfrench@samba.org,\n\tsmfrench@gmail.com,\n\tlinkinjeon@kernel.org,\n\tlinkinjeon@samba.org,\n\tpc@manguebit.org,\n\tronniesahlberg@gmail.com,\n\tsprasad@microsoft.com,\n\ttom@talpey.com,\n\tbharathsm@microsoft.com,\n\tsenozhatsky@chromium.org","Cc":"linux-cifs@vger.kernel.org,\n\tChenXiaoSong <chenxiaosong@kylinos.cn>,\n\tSteve French <stfrench@microsoft.com>","Subject":"[PATCH RFC cifs-utils 1/1] smbinfo: add notify subcommand","Date":"Wed, 17 Dec 2025 21:44:56 +0800","Message-ID":"<20251217134456.16735-2-chenxiaosong.chenxiaosong@linux.dev>","In-Reply-To":"<20251217134456.16735-1-chenxiaosong.chenxiaosong@linux.dev>","References":"<20251217134456.16735-1-chenxiaosong.chenxiaosong@linux.dev>","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","X-Migadu-Flow":"FLOW_OUT"},"content":"From: ChenXiaoSong <chenxiaosong@kylinos.cn>\n\nAdd `notify` subcommand to query a directory for change notifications.\n\nExample:\n\n  ./smbinfo notify /mnt/dir\n  # Then create a new file `/server/export/dir/file` on SMB server\n  Notify completed, returned data_len is 20\n  00000000:  00 00 00 00 01 00 00 00  08 00 00 00 66 00 69 00  ............f.i.\n  00000010:  6c 00 65 00                                       l.e.\n\nLink: https://lore.kernel.org/linux-cifs/CAH2r5msHiZWzP5hdtPgb+wV3DL3J31RtgQRLQeuhCa_ULt3PfA@mail.gmail.com/\nSuggested-by: Steve French <stfrench@microsoft.com>\nSigned-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>\n---\n smbinfo     | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++\n smbinfo.rst |  2 ++\n 2 files changed, 71 insertions(+)","diff":"diff --git a/smbinfo b/smbinfo\nindex 2e9e42d..2be2395 100755\n--- a/smbinfo\n+++ b/smbinfo\n@@ -27,6 +27,7 @@ import struct\n import stat\n import datetime\n import calendar\n+import threading\n \n VERBOSE = False\n \n@@ -36,6 +37,7 @@ CIFS_ENUMERATE_SNAPSHOTS = 0x800ccf06\n CIFS_DUMP_KEY            = 0xc03acf08\n CIFS_DUMP_FULL_KEY       = 0xc011cf0a\n CIFS_GET_TCON_INFO       = 0x800ccf0c\n+CIFS_IOC_NOTIFY_INFO     = 0xc009cf0b\n \n # large enough input buffer length\n INPUT_BUFFER_LENGTH = 16384\n@@ -294,6 +296,10 @@ def main():\n     sap.add_argument(\"file\")\n     sap.set_defaults(func=cmd_gettconinfo)\n \n+    sap = subp.add_parser(\"notify\", help=\"Query a directory for change notifications\")\n+    sap.add_argument(\"file\")\n+    sap.set_defaults(func=cmd_notify)\n+\n     # parse arguments\n     args = ap.parse_args()\n \n@@ -905,5 +911,68 @@ def cmd_gettconinfo(args):\n     print(\"TCON Id: 0x%x\"%tcon.tid)\n     print(\"Session Id: 0x%x\"%tcon.session_id)\n \n+def cmd_notify(args):\n+    thread = threading.Thread(target=notify_thread, args=(args,))\n+    thread.start()\n+\n+    try:\n+        thread.join()\n+    except KeyboardInterrupt:\n+        return False\n+\n+def notify_thread(args):\n+    # See `struct smb3_notify_info` in linux kernel fs/smb/client/cifs_ioctl.h\n+    completion_filter = 0xFFF\n+    watch_tree = False\n+    data_len = 1000\n+\n+    fmt = \"<IBI\"\n+    buf = bytearray(struct.pack(fmt, completion_filter, watch_tree, data_len))\n+    buf.extend(bytearray(data_len))\n+\n+    try:\n+        fd = os.open(args.file, os.O_RDONLY)\n+        fcntl.ioctl(fd, CIFS_IOC_NOTIFY_INFO, buf, True)\n+    except Exception as e:\n+        print(\"syscall failed: %s\"%e)\n+        return False\n+\n+    _, _, data_len = struct.unpack_from(fmt, buf, 0)\n+    print(\"Notify completed, returned data_len is\", data_len)\n+    notify_data, = struct.unpack_from(f'{data_len}s', buf, struct.calcsize(fmt))\n+    print_notify(notify_data)\n+\n+def print_notify(notify_data):\n+    if notify_data is None:\n+        return\n+\n+    data_size = len(notify_data)\n+    if data_size == 0:\n+        return\n+\n+    BYTES_PER_LINE = 16\n+    for offset in range(0, data_size, BYTES_PER_LINE):\n+        chunk = notify_data[offset:offset + BYTES_PER_LINE]\n+\n+        # raw hex data\n+        hex_bytes = \"\".join(\n+            (\" \" if i % 8 == 0 else \"\") + f\"{x:02x} \"\n+            for i, x in enumerate(chunk)\n+        )\n+\n+        # padding\n+        pad_len = BYTES_PER_LINE - len(chunk)\n+        pad = \"   \" * pad_len\n+        if (pad_len >= 8):\n+            pad += \" \" * (pad_len // 8)\n+\n+        # ASCII\n+        ascii_part = \"\".join(\n+            chr(x) if 31 < x < 127 else \".\"\n+            for x in chunk\n+        )\n+\n+        print(f\"{offset:08x}: {hex_bytes}{pad} {ascii_part}\")\n+\n if __name__ == '__main__':\n     main()\ndiff --git a/smbinfo.rst b/smbinfo.rst\nindex 17270c5..91b8895 100644\n--- a/smbinfo.rst\n+++ b/smbinfo.rst\n@@ -98,6 +98,8 @@ the SMB3 traffic of this mount can be decryped e.g. via wireshark\n \n `gettconinfo`: Prints both the TCON Id and Session Id for a cifs file.\n \n+`notify`: Query a directory for change notifications.\n+\n *****\n NOTES\n *****\n","prefixes":["RFC","cifs-utils","1/1"]}