diff options
| -rw-r--r-- | fs/cifs/cifsglob.h | 2 | ||||
| -rw-r--r-- | fs/cifs/cifsproto.h | 3 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 3 | ||||
| -rw-r--r-- | fs/cifs/smb2ops.c | 60 | ||||
| -rw-r--r-- | fs/cifs/smb2pdu.c | 10 | ||||
| -rw-r--r-- | fs/cifs/smb2proto.h | 3 | ||||
| -rw-r--r-- | fs/cifs/xattr.c | 2 |
7 files changed, 79 insertions, 4 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 221693fe49ec..808486c29f0d 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -421,7 +421,7 @@ struct smb_version_operations { | |||
| 421 | size_t, struct cifs_sb_info *); | 421 | size_t, struct cifs_sb_info *); |
| 422 | int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *, | 422 | int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *, |
| 423 | const char *, const void *, const __u16, | 423 | const char *, const void *, const __u16, |
| 424 | const struct nls_table *, int); | 424 | const struct nls_table *, struct cifs_sb_info *); |
| 425 | struct cifs_ntsd * (*get_acl)(struct cifs_sb_info *, struct inode *, | 425 | struct cifs_ntsd * (*get_acl)(struct cifs_sb_info *, struct inode *, |
| 426 | const char *, u32 *); | 426 | const char *, u32 *); |
| 427 | struct cifs_ntsd * (*get_acl_by_fid)(struct cifs_sb_info *, | 427 | struct cifs_ntsd * (*get_acl_by_fid)(struct cifs_sb_info *, |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 6eb3147132e3..4143c9dec463 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -484,7 +484,8 @@ extern ssize_t CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon, | |||
| 484 | extern int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon, | 484 | extern int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon, |
| 485 | const char *fileName, const char *ea_name, | 485 | const char *fileName, const char *ea_name, |
| 486 | const void *ea_value, const __u16 ea_value_len, | 486 | const void *ea_value, const __u16 ea_value_len, |
| 487 | const struct nls_table *nls_codepage, int remap_special_chars); | 487 | const struct nls_table *nls_codepage, |
| 488 | struct cifs_sb_info *cifs_sb); | ||
| 488 | extern int CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, | 489 | extern int CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, |
| 489 | __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen); | 490 | __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen); |
| 490 | extern int CIFSSMBSetCIFSACL(const unsigned int, struct cifs_tcon *, __u16, | 491 | extern int CIFSSMBSetCIFSACL(const unsigned int, struct cifs_tcon *, __u16, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 72a53bd19865..48455afefec8 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -6264,7 +6264,7 @@ int | |||
| 6264 | CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon, | 6264 | CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon, |
| 6265 | const char *fileName, const char *ea_name, const void *ea_value, | 6265 | const char *fileName, const char *ea_name, const void *ea_value, |
| 6266 | const __u16 ea_value_len, const struct nls_table *nls_codepage, | 6266 | const __u16 ea_value_len, const struct nls_table *nls_codepage, |
| 6267 | int remap) | 6267 | struct cifs_sb_info *cifs_sb) |
| 6268 | { | 6268 | { |
| 6269 | struct smb_com_transaction2_spi_req *pSMB = NULL; | 6269 | struct smb_com_transaction2_spi_req *pSMB = NULL; |
| 6270 | struct smb_com_transaction2_spi_rsp *pSMBr = NULL; | 6270 | struct smb_com_transaction2_spi_rsp *pSMBr = NULL; |
| @@ -6273,6 +6273,7 @@ CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon, | |||
| 6273 | int rc = 0; | 6273 | int rc = 0; |
| 6274 | int bytes_returned = 0; | 6274 | int bytes_returned = 0; |
| 6275 | __u16 params, param_offset, byte_count, offset, count; | 6275 | __u16 params, param_offset, byte_count, offset, count; |
| 6276 | int remap = cifs_remap(cifs_sb); | ||
| 6276 | 6277 | ||
| 6277 | cifs_dbg(FYI, "In SetEA\n"); | 6278 | cifs_dbg(FYI, "In SetEA\n"); |
| 6278 | SetEARetry: | 6279 | SetEARetry: |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 78516d3a133c..fb2934b9b97c 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
| @@ -558,6 +558,62 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon, | |||
| 558 | return rc; | 558 | return rc; |
| 559 | } | 559 | } |
| 560 | 560 | ||
| 561 | |||
| 562 | static int | ||
| 563 | smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, | ||
| 564 | const char *path, const char *ea_name, const void *ea_value, | ||
| 565 | const __u16 ea_value_len, const struct nls_table *nls_codepage, | ||
| 566 | struct cifs_sb_info *cifs_sb) | ||
| 567 | { | ||
| 568 | int rc; | ||
| 569 | __le16 *utf16_path; | ||
| 570 | __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; | ||
| 571 | struct cifs_open_parms oparms; | ||
| 572 | struct cifs_fid fid; | ||
| 573 | struct smb2_file_full_ea_info *ea; | ||
| 574 | int ea_name_len = strlen(ea_name); | ||
| 575 | int len; | ||
| 576 | |||
| 577 | if (ea_name_len > 255) | ||
| 578 | return -EINVAL; | ||
| 579 | |||
| 580 | utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); | ||
| 581 | if (!utf16_path) | ||
| 582 | return -ENOMEM; | ||
| 583 | |||
| 584 | oparms.tcon = tcon; | ||
| 585 | oparms.desired_access = FILE_WRITE_EA; | ||
| 586 | oparms.disposition = FILE_OPEN; | ||
| 587 | oparms.create_options = 0; | ||
| 588 | oparms.fid = &fid; | ||
| 589 | oparms.reconnect = false; | ||
| 590 | |||
| 591 | rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL); | ||
| 592 | kfree(utf16_path); | ||
| 593 | if (rc) { | ||
| 594 | cifs_dbg(FYI, "open failed rc=%d\n", rc); | ||
| 595 | return rc; | ||
| 596 | } | ||
| 597 | |||
| 598 | len = sizeof(ea) + ea_name_len + ea_value_len + 1; | ||
| 599 | ea = kzalloc(len, GFP_KERNEL); | ||
| 600 | if (ea == NULL) { | ||
| 601 | SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); | ||
| 602 | return -ENOMEM; | ||
| 603 | } | ||
| 604 | |||
| 605 | ea->ea_name_length = ea_name_len; | ||
| 606 | ea->ea_value_length = cpu_to_le16(ea_value_len); | ||
| 607 | memcpy(ea->ea_data, ea_name, ea_name_len + 1); | ||
| 608 | memcpy(ea->ea_data + ea_name_len + 1, ea_value, ea_value_len); | ||
| 609 | |||
| 610 | rc = SMB2_set_ea(xid, tcon, fid.persistent_fid, fid.volatile_fid, ea, | ||
| 611 | len); | ||
| 612 | SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); | ||
| 613 | |||
| 614 | return rc; | ||
| 615 | } | ||
| 616 | |||
| 561 | static bool | 617 | static bool |
| 562 | smb2_can_echo(struct TCP_Server_Info *server) | 618 | smb2_can_echo(struct TCP_Server_Info *server) |
| 563 | { | 619 | { |
| @@ -2706,6 +2762,7 @@ struct smb_version_operations smb20_operations = { | |||
| 2706 | .select_sectype = smb2_select_sectype, | 2762 | .select_sectype = smb2_select_sectype, |
| 2707 | #ifdef CONFIG_CIFS_XATTR | 2763 | #ifdef CONFIG_CIFS_XATTR |
| 2708 | .query_all_EAs = smb2_query_eas, | 2764 | .query_all_EAs = smb2_query_eas, |
| 2765 | .set_EA = smb2_set_ea, | ||
| 2709 | #endif /* CIFS_XATTR */ | 2766 | #endif /* CIFS_XATTR */ |
| 2710 | #ifdef CONFIG_CIFS_ACL | 2767 | #ifdef CONFIG_CIFS_ACL |
| 2711 | .get_acl = get_smb2_acl, | 2768 | .get_acl = get_smb2_acl, |
| @@ -2799,6 +2856,7 @@ struct smb_version_operations smb21_operations = { | |||
| 2799 | .select_sectype = smb2_select_sectype, | 2856 | .select_sectype = smb2_select_sectype, |
| 2800 | #ifdef CONFIG_CIFS_XATTR | 2857 | #ifdef CONFIG_CIFS_XATTR |
| 2801 | .query_all_EAs = smb2_query_eas, | 2858 | .query_all_EAs = smb2_query_eas, |
| 2859 | .set_EA = smb2_set_ea, | ||
| 2802 | #endif /* CIFS_XATTR */ | 2860 | #endif /* CIFS_XATTR */ |
| 2803 | #ifdef CONFIG_CIFS_ACL | 2861 | #ifdef CONFIG_CIFS_ACL |
| 2804 | .get_acl = get_smb2_acl, | 2862 | .get_acl = get_smb2_acl, |
| @@ -2902,6 +2960,7 @@ struct smb_version_operations smb30_operations = { | |||
| 2902 | .select_sectype = smb2_select_sectype, | 2960 | .select_sectype = smb2_select_sectype, |
| 2903 | #ifdef CONFIG_CIFS_XATTR | 2961 | #ifdef CONFIG_CIFS_XATTR |
| 2904 | .query_all_EAs = smb2_query_eas, | 2962 | .query_all_EAs = smb2_query_eas, |
| 2963 | .set_EA = smb2_set_ea, | ||
| 2905 | #endif /* CIFS_XATTR */ | 2964 | #endif /* CIFS_XATTR */ |
| 2906 | #ifdef CONFIG_CIFS_ACL | 2965 | #ifdef CONFIG_CIFS_ACL |
| 2907 | .get_acl = get_smb2_acl, | 2966 | .get_acl = get_smb2_acl, |
| @@ -3006,6 +3065,7 @@ struct smb_version_operations smb311_operations = { | |||
| 3006 | .select_sectype = smb2_select_sectype, | 3065 | .select_sectype = smb2_select_sectype, |
| 3007 | #ifdef CONFIG_CIFS_XATTR | 3066 | #ifdef CONFIG_CIFS_XATTR |
| 3008 | .query_all_EAs = smb2_query_eas, | 3067 | .query_all_EAs = smb2_query_eas, |
| 3068 | .set_EA = smb2_set_ea, | ||
| 3009 | #endif /* CIFS_XATTR */ | 3069 | #endif /* CIFS_XATTR */ |
| 3010 | }; | 3070 | }; |
| 3011 | #endif /* CIFS_SMB311 */ | 3071 | #endif /* CIFS_SMB311 */ |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index bf0ba3c15b63..d7595e735304 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
| @@ -3197,6 +3197,16 @@ SMB2_set_acl(const unsigned int xid, struct cifs_tcon *tcon, | |||
| 3197 | } | 3197 | } |
| 3198 | 3198 | ||
| 3199 | int | 3199 | int |
| 3200 | SMB2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, | ||
| 3201 | u64 persistent_fid, u64 volatile_fid, | ||
| 3202 | struct smb2_file_full_ea_info *buf, int len) | ||
| 3203 | { | ||
| 3204 | return send_set_info(xid, tcon, persistent_fid, volatile_fid, | ||
| 3205 | current->tgid, FILE_FULL_EA_INFORMATION, SMB2_O_INFO_FILE, | ||
| 3206 | 0, 1, (void **)&buf, &len); | ||
| 3207 | } | ||
| 3208 | |||
| 3209 | int | ||
| 3200 | SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, | 3210 | SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, |
| 3201 | const u64 persistent_fid, const u64 volatile_fid, | 3211 | const u64 persistent_fid, const u64 volatile_fid, |
| 3202 | __u8 oplock_level) | 3212 | __u8 oplock_level) |
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 183389bfc8f6..003217099ef3 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h | |||
| @@ -172,6 +172,9 @@ extern int SMB2_set_info(const unsigned int xid, struct cifs_tcon *tcon, | |||
| 172 | extern int SMB2_set_acl(const unsigned int xid, struct cifs_tcon *tcon, | 172 | extern int SMB2_set_acl(const unsigned int xid, struct cifs_tcon *tcon, |
| 173 | u64 persistent_fid, u64 volatile_fid, | 173 | u64 persistent_fid, u64 volatile_fid, |
| 174 | struct cifs_ntsd *pnntsd, int pacllen, int aclflag); | 174 | struct cifs_ntsd *pnntsd, int pacllen, int aclflag); |
| 175 | extern int SMB2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, | ||
| 176 | u64 persistent_fid, u64 volatile_fid, | ||
| 177 | struct smb2_file_full_ea_info *buf, int len); | ||
| 175 | extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, | 178 | extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, |
| 176 | u64 persistent_fid, u64 volatile_fid); | 179 | u64 persistent_fid, u64 volatile_fid); |
| 177 | extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, | 180 | extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, |
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index de50e749ff05..52f975d848a0 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
| @@ -84,7 +84,7 @@ static int cifs_xattr_set(const struct xattr_handler *handler, | |||
| 84 | if (pTcon->ses->server->ops->set_EA) | 84 | if (pTcon->ses->server->ops->set_EA) |
| 85 | rc = pTcon->ses->server->ops->set_EA(xid, pTcon, | 85 | rc = pTcon->ses->server->ops->set_EA(xid, pTcon, |
| 86 | full_path, name, value, (__u16)size, | 86 | full_path, name, value, (__u16)size, |
| 87 | cifs_sb->local_nls, cifs_remap(cifs_sb)); | 87 | cifs_sb->local_nls, cifs_sb); |
| 88 | break; | 88 | break; |
| 89 | 89 | ||
| 90 | case XATTR_CIFS_ACL: { | 90 | case XATTR_CIFS_ACL: { |
