From patchwork Thu Oct 22 09:20:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 11850643 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.6 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 27A4AC4363A for ; Thu, 22 Oct 2020 09:20:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AB73B2463D for ; Thu, 22 Oct 2020 09:20:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WuQsNI93" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2505111AbgJVJU0 (ORCPT ); Thu, 22 Oct 2020 05:20:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41980 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2504822AbgJVJUZ (ORCPT ); Thu, 22 Oct 2020 05:20:25 -0400 Received: from mail-lf1-x12e.google.com (mail-lf1-x12e.google.com [IPv6:2a00:1450:4864:20::12e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 11641C0613CE for ; Thu, 22 Oct 2020 02:20:24 -0700 (PDT) Received: by mail-lf1-x12e.google.com with SMTP id b1so1343490lfp.11 for ; Thu, 22 Oct 2020 02:20:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=cW51ELFkmOfKkgqt00V48XzQV73NLjCLNzLHEvbdghk=; b=WuQsNI93SEU3jHHx9WqjmbyvMV3IpgwAK+A+h9T64T7uBz7LjGs0Jfz0xhzZkAfGMD rb2zGBXf+NAUCNgrFEYGgQZSdrHKdJ5oQraNgKX25WuereZfP1/4WVphflnyJThQxB2D q1iA9cG/Vw37aSGC9MmXwXRmh0vqd5Y9XYy53WNQ6rhv3pvBGV8ATDt4xqpibNDkU0wW ak7z4XzXQc/Gj5uOvLmX7nJyCUM3a3pmhAukUhKmnCT8dw+/sM+WfWvOKPtj4ydhwzBH 8dwIel9BQRuJSp4YY5fF95E4tprQohiHTzy1UYn8+2abNDCKzBLHi373HKG19vRk+1U6 RSzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=cW51ELFkmOfKkgqt00V48XzQV73NLjCLNzLHEvbdghk=; b=CVrqdu7AvPZQOpKxL368ZrxnP2ym9tnf1pdR3VHjEf+RTlHo+ZOzs72qNjkHICz0Ok UdIQMEAPkPG4saeQUu2BFNWXi1Jp6zovwDwPkKNg38/toGW2dp3MUydyZnIreqgnPgFK AiLnZxZ+GGnBFGi81dJyMHXLHQn3V3INtQ6Xuahj4AH9bqmza/phrSoB/esDCfhRKTuD 85ZPKfyulxoXp6hdjeh5m2SoJa3JLQd4o512pWCNWuzDhDlC6tDsr6/8AyURO2qKqjNA pZ+0jWp9w/DoXmpPnGAEBBFiJxFp9yhsjnPB7+qq63DPj3IJeQSE3qKbwu2tsLqV9jR5 Hp4Q== X-Gm-Message-State: AOAM530BBlcmlKVKJ8sam5ZLIZjyXaoYiboUs0IF/5/mUOu1oi7s5+UI FyfdhR0fU+k45rLBMsh1WeU6l8zRxjLaevg8zxeIfIFeMt8jGQ== X-Google-Smtp-Source: ABdhPJwv5yFLwoFB4W1YGkS5xOjsNybmgTH4dHbNWAd3Z6mZgi05MAwOXxnvEZ4qXDuXfUcfyZcSijNy6sRWxw1WOb0= X-Received: by 2002:a19:c381:: with SMTP id t123mr463102lff.499.1603358422226; Thu, 22 Oct 2020 02:20:22 -0700 (PDT) MIME-Version: 1.0 From: Steve French Date: Thu, 22 Oct 2020 04:20:10 -0500 Message-ID: Subject: [PATCH][WIP] query smb3 reparse tags for special files To: CIFS , samba-technical Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org WSL defines special files with various reparse tags smbfsctl.h:#define IO_REPARSE_TAG_LX_SYMLINK 0xA000001D smbfsctl.h:#define IO_REPARSE_TAG_LX_FIFO 0x80000024 smbfsctl.h:#define IO_REPARSE_TAG_LX_CHR 0x80000025 smbfsctl.h:#define IO_REPARSE_TAG_LX_BLK 0x80000026 These also make sense for us to use more broadly because it simplifies readdir but ... my first attempt at querying this using infolevel 33 FileReparsePointInformation (see MS-FSCC section 2.4.35) failed ... with Windows 10 returning STATUS_NOT_SUPPORTED when querying various reparse points (created by WSL indirectly) including fifos, symlinks and char devices. I can switch approaches and try to do the smb3 fsctl to query reparse info instead but was hoping that query info would work. Any idea if there is another info level that would allow me to query the tag? In any case, here is the WIP first stage of the patch - I have to add a second patch to add the fsctl query diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index b6925aeeb621..484ec2d8c5c9 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -298,6 +298,10 @@ struct smb_version_operations { /* query file data from the server */ int (*query_file_info)(const unsigned int, struct cifs_tcon *, struct cifs_fid *, FILE_ALL_INFO *); + /* query reparse tag from srv to determine which type of special file */ + int (*query_reparse_tag)(const unsigned int xid, struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, const char *path, + __u32 *reparse_tag); /* get server index number */ int (*get_srv_inum)(const unsigned int, struct cifs_tcon *, struct cifs_sb_info *, const char *, diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index daec31be8571..fe20643450a1 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -916,6 +916,7 @@ cifs_get_inode_info(struct inode **inode, void *smb1_backup_rsp_buf = NULL; int rc = 0; int tmprc = 0; + __u32 reparse_tag = 0; tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) @@ -941,6 +942,16 @@ cifs_get_inode_info(struct inode **inode, full_path, tmp_data, &adjust_tz, &symlink); data = tmp_data; + + /* + * If the file is a reparse point, it is more complicated + * since we have to check if its reparse tag matches a known + * special file type e.g. symlink or fifo or char etc. + */ + if ((le32_to_cpu(data->Attributes) & ATTR_REPARSE) && + (server->ops->query_reparse_tag)) + rc = server->ops->query_reparse_tag(xid, tcon, cifs_sb, + full_path, &reparse_tag); } /* diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c index df6212e55e10..109ec166aa6a 100644 --- a/fs/cifs/smb2inode.c +++ b/fs/cifs/smb2inode.c @@ -503,10 +503,26 @@ move_smb2_info_to_cifs(FILE_ALL_INFO *dst, struct smb2_file_all_info *src) dst->IndexNumber1 = 0; /* we don't use it */ } +/* query reparse tag from srv to determine which type of special file */ +int smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, const char *path, __u32 *tag) +{ + int rc = 0; + __u32 create_options = OPEN_REPARSE_POINT; + struct cifsFileInfo *cfile; + + cifs_get_readable_path(tcon, path, &cfile); + + /* TODO update below */ + /* rc = smb2_fsctl_get_tag(xid, tcon, cifs_sb, path,... */ + + return rc; +} + int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path, - FILE_ALL_INFO *data, bool *adjust_tz, bool *symlink) + FILE_ALL_INFO *data, bool *adjust_tz, bool *reparse) { int rc; struct smb2_file_all_info *smb2_data; @@ -516,7 +532,7 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, struct cached_fid *cfid = NULL; *adjust_tz = false; - *symlink = false; + *reparse = false; smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2, GFP_KERNEL); @@ -548,7 +564,7 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, ACL_NO_MODE, smb2_data, SMB2_OP_QUERY_INFO, cfile); if (rc == -EOPNOTSUPP) { - *symlink = true; + *reparse = true; create_options |= OPEN_REPARSE_POINT; /* Failed on a symbolic link - query a reparse point info */ @@ -570,7 +586,7 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path, - struct smb311_posix_qinfo *data, bool *adjust_tz, bool *symlink) + struct smb311_posix_qinfo *data, bool *adjust_tz, bool *reparse) { int rc; __u32 create_options = 0; @@ -578,7 +594,7 @@ smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, struct smb311_posix_qinfo *smb2_data; *adjust_tz = false; - *symlink = false; + *reparse = false; /* BB TODO: Make struct larger when add support for parsing owner SIDs */ smb2_data = kzalloc(sizeof(struct smb311_posix_qinfo), @@ -599,7 +615,7 @@ smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, ACL_NO_MODE, smb2_data, SMB2_OP_POSIX_QUERY_INFO, cfile); if (rc == -EOPNOTSUPP) { /* BB TODO: When support for special files added to Samba re-verify this path */ - *symlink = true; + *reparse = true; create_options |= OPEN_REPARSE_POINT; /* Failed on a symbolic link - query a reparse point info */ diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index 171f54965703..14244d288b80 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h @@ -1691,6 +1691,11 @@ struct smb2_file_eof_info { /* encoding of request for level 10 */ __le64 EndOfFile; /* new end of file value */ } __packed; /* level 20 Set */ +struct smb2_file_reparse_point_info { + __le64 IndexNumber; + __le32 Tag; +} __packed; + struct smb2_file_network_open_info { __le64 CreationTime; __le64 LastAccessTime; diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 67c50d78caa1..d4110447ee3a 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h @@ -77,6 +77,9 @@ extern void close_shroot_lease(struct cached_fid *cfid); extern void close_shroot_lease_locked(struct cached_fid *cfid); extern void move_smb2_info_to_cifs(FILE_ALL_INFO *dst, struct smb2_file_all_info *src); +extern int smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon, + struct cifs_sb_info *cifs_sb, const char *path, + __u32 *reparse_tag); extern int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path, FILE_ALL_INFO *data,