From: ronnie sahlberg <ronniesahlberg@gmail.com>
To: Steve French <smfrench@gmail.com>
Cc: Ronnie Sahlberg <lsahlber@redhat.com>,
linux-cifs <linux-cifs@vger.kernel.org>
Subject: Re: [PATCH] cifs: add mount option to encode xattr names as hexadecimal
Date: Fri, 21 Jun 2019 10:31:35 +1000 [thread overview]
Message-ID: <CAN05THQgBNqN4j42v=Td-h49yw2U4S1fNTNBuW8Sk6QrbyKrQQ@mail.gmail.com> (raw)
In-Reply-To: <CAH2r5mv4LEo9T70uBfjQb5M3uc0phsXOgXTFD6qWByGfha9MFg@mail.gmail.com>
On Fri, Jun 21, 2019 at 10:20 AM Steve French <smfrench@gmail.com> wrote:
>
> Do you remember which xfstests this fixes?
I will take a look. As far as I remember we do run all those affected
xfstests in the buildbot.
I just pointed the failing tests to one of the samba hosts instead of
the default win2016 test server.
>
> Also any ideas on whether we still need a fix for deleting an empty or
> nonexistent xattr?
I think these bugs are already fixed in the current tree. At least for SMB2+.
>
> On Thu, Jun 20, 2019 at 7:03 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
> >
> > We store xattrs as Extended Attributes for SMB.
> > Some servers treat the EA names as case-insensitive as well as converting them to all upper-case.
> >
> > This addresses that issue by adding a new mount option to convert all EA names to/from
> > hexadecimal representation.
> >
> > Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> > ---
> > fs/cifs/cifs_fs_sb.h | 1 +
> > fs/cifs/cifsfs.c | 3 +++
> > fs/cifs/cifsglob.h | 3 ++-
> > fs/cifs/connect.c | 7 +++++++
> > fs/cifs/smb2ops.c | 58 ++++++++++++++++++++++++++++++++++++++++------------
> > 5 files changed, 58 insertions(+), 14 deletions(-)
> >
> > diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
> > index ed49222abecb..11fb5f4d2b0e 100644
> > --- a/fs/cifs/cifs_fs_sb.h
> > +++ b/fs/cifs/cifs_fs_sb.h
> > @@ -52,6 +52,7 @@
> > #define CIFS_MOUNT_UID_FROM_ACL 0x2000000 /* try to get UID via special SID */
> > #define CIFS_MOUNT_NO_HANDLE_CACHE 0x4000000 /* disable caching dir handles */
> > #define CIFS_MOUNT_NO_DFS 0x8000000 /* disable DFS resolving */
> > +#define CIFS_MOUNT_ENCODED_XATTR 0x10000000 /* encode the xattr names */
> >
> > struct cifs_sb_info {
> > struct rb_root tlink_tree;
> > diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> > index d06edebf3a73..c3c837ee3c4e 100644
> > --- a/fs/cifs/cifsfs.c
> > +++ b/fs/cifs/cifsfs.c
> > @@ -471,6 +471,9 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
> > else
> > seq_puts(s, ",noforcegid");
> >
> > + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_ENCODED_XATTR)
> > + seq_puts(s, ",endodedxattr");
> > +
> > cifs_show_address(s, tcon->ses->server);
> >
> > if (!tcon->unix_ext)
> > diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> > index 4777b3c4a92c..b479207f7f74 100644
> > --- a/fs/cifs/cifsglob.h
> > +++ b/fs/cifs/cifsglob.h
> > @@ -585,6 +585,7 @@ struct smb_vol {
> > bool resilient:1; /* noresilient not required since not fored for CA */
> > bool domainauto:1;
> > bool rdma:1;
> > + bool encoded_xattr:1;
> > unsigned int bsize;
> > unsigned int rsize;
> > unsigned int wsize;
> > @@ -617,7 +618,7 @@ struct smb_vol {
> > CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \
> > CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \
> > CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID | \
> > - CIFS_MOUNT_NO_DFS)
> > + CIFS_MOUNT_NO_DFS|CIFS_MOUNT_ENCODED_XATTR)
> >
> > /**
> > * Generic VFS superblock mount flags (s_flags) to consider when
> > diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> > index 51f272377ae1..f955b28a9b38 100644
> > --- a/fs/cifs/connect.c
> > +++ b/fs/cifs/connect.c
> > @@ -97,6 +97,7 @@ enum {
> > Opt_persistent, Opt_nopersistent,
> > Opt_resilient, Opt_noresilient,
> > Opt_domainauto, Opt_rdma,
> > + Opt_encodedxattr,
> >
> > /* Mount options which take numeric value */
> > Opt_backupuid, Opt_backupgid, Opt_uid,
> > @@ -194,6 +195,7 @@ static const match_table_t cifs_mount_option_tokens = {
> > { Opt_noresilient, "noresilienthandles"},
> > { Opt_domainauto, "domainauto"},
> > { Opt_rdma, "rdma"},
> > + { Opt_encodedxattr, "encodedxattr" },
> >
> > { Opt_backupuid, "backupuid=%s" },
> > { Opt_backupgid, "backupgid=%s" },
> > @@ -1911,6 +1913,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
> > case Opt_rdma:
> > vol->rdma = true;
> > break;
> > + case Opt_encodedxattr:
> > + vol->encoded_xattr = 1;
> > + break;
> >
> > /* Numeric Values */
> > case Opt_backupuid:
> > @@ -3986,6 +3991,8 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
> > cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
> > if (pvolume_info->override_gid)
> > cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
> > + if (pvolume_info->encoded_xattr)
> > + cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_ENCODED_XATTR;
> > if (pvolume_info->dynperm)
> > cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
> > if (pvolume_info->fsc)
> > diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
> > index 376577cc4159..e2684a6627bb 100644
> > --- a/fs/cifs/smb2ops.c
> > +++ b/fs/cifs/smb2ops.c
> > @@ -891,7 +891,8 @@ smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
> > static ssize_t
> > move_smb2_ea_to_cifs(char *dst, size_t dst_size,
> > struct smb2_file_full_ea_info *src, size_t src_size,
> > - const unsigned char *ea_name)
> > + const unsigned char *ea_name,
> > + struct cifs_sb_info *cifs_sb)
> > {
> > int rc = 0;
> > unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
> > @@ -905,6 +906,18 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size,
> > value = &src->ea_data[src->ea_name_length + 1];
> > value_len = (size_t)le16_to_cpu(src->ea_value_length);
> >
> > + if (cifs_sb->mnt_cifs_flags | CIFS_MOUNT_ENCODED_XATTR) {
> > + if (name_len & 0x01) {
> > + rc = -EINVAL;
> > + goto out;
> > + }
> > + name_len = name_len / 2;
> > + if (hex2bin(name, name, name_len)) {
> > + rc = -EINVAL;
> > + goto out;
> > + }
> > + }
> > +
> > if (name_len == 0)
> > break;
> >
> > @@ -1018,7 +1031,8 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon,
> > info = (struct smb2_file_full_ea_info *)(
> > le16_to_cpu(rsp->OutputBufferOffset) + (char *)rsp);
> > rc = move_smb2_ea_to_cifs(ea_data, buf_size, info,
> > - le32_to_cpu(rsp->OutputBufferLength), ea_name);
> > + le32_to_cpu(rsp->OutputBufferLength),
> > + ea_name, cifs_sb);
> >
> > qeas_exit:
> > kfree(utf16_path);
> > @@ -1029,13 +1043,14 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon,
> >
> > static int
> > smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
> > - const char *path, const char *ea_name, const void *ea_value,
> > + const char *path, const char *name, const void *ea_value,
> > const __u16 ea_value_len, const struct nls_table *nls_codepage,
> > struct cifs_sb_info *cifs_sb)
> > {
> > struct cifs_ses *ses = tcon->ses;
> > __le16 *utf16_path = NULL;
> > - int ea_name_len = strlen(ea_name);
> > + char *ea_name = (char *)name;
> > + int ea_name_len = strlen(name);
> > int flags = 0;
> > int len;
> > struct smb_rqst rqst[3];
> > @@ -1050,21 +1065,36 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
> > void *data[1];
> > struct smb2_file_full_ea_info *ea = NULL;
> > struct kvec close_iov[1];
> > - int rc;
> > + int i, rc;
> > +
> > + memset(rqst, 0, sizeof(rqst));
> > + resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
> > + memset(rsp_iov, 0, sizeof(rsp_iov));
> >
> > if (smb3_encryption_required(tcon))
> > flags |= CIFS_TRANSFORM_REQ;
> >
> > - if (ea_name_len > 255)
> > - return -EINVAL;
> > + /* Do we need to encode the name in hex ? */
> > + if (cifs_sb->mnt_cifs_flags | CIFS_MOUNT_ENCODED_XATTR) {
> > + ea_name = kzalloc(ea_name_len * 2 + 1, GFP_KERNEL);
> > + if (ea_name == NULL) {
> > + rc = -ENOMEM;
> > + goto sea_exit;
> > + }
> > + bin2hex(ea_name, name, ea_name_len);
> > + ea_name_len = 2 * ea_name_len;
> > + }
> >
> > - utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
> > - if (!utf16_path)
> > - return -ENOMEM;
> > + if (ea_name_len > 255) {
> > + rc = -EINVAL;
> > + goto sea_exit;
> > + }
> >
> > - memset(rqst, 0, sizeof(rqst));
> > - resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
> > - memset(rsp_iov, 0, sizeof(rsp_iov));
> > + utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
> > + if (!utf16_path) {
> > + rc = -ENOMEM;
> > + goto sea_exit;
> > + }
> >
> > if (ses->server->ops->query_all_EAs) {
> > if (!ea_value) {
> > @@ -1137,6 +1167,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
> > resp_buftype, rsp_iov);
> >
> > sea_exit:
> > + if (cifs_sb->mnt_cifs_flags | CIFS_MOUNT_ENCODED_XATTR)
> > + kfree(ea_name);
> > kfree(ea);
> > kfree(utf16_path);
> > SMB2_open_free(&rqst[0]);
> > --
> > 2.13.6
> >
>
>
> --
> Thanks,
>
> Steve
next prev parent reply other threads:[~2019-06-21 0:31 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-21 0:02 [PATCH] cifs: add mount option to encode xattr names as hexadecimal Ronnie Sahlberg
2019-06-21 0:16 ` Steve French
2019-06-21 0:31 ` ronnie sahlberg [this message]
2019-07-16 5:35 ` Steve French
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAN05THQgBNqN4j42v=Td-h49yw2U4S1fNTNBuW8Sk6QrbyKrQQ@mail.gmail.com' \
--to=ronniesahlberg@gmail.com \
--cc=linux-cifs@vger.kernel.org \
--cc=lsahlber@redhat.com \
--cc=smfrench@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).