@@ -2512,7 +2512,8 @@ struct fea {
/* optionally followed by value */
} __attribute__((packed));
/* flags for _FEA.fEA */
-#define FEA_NEEDEA 0x80 /* need EA bit */
+#define FEA_NEEDEA 0x80 /* need EA bit */
+#define FEA_DELETEEA 0x40 /* delete EA, EA length MUST be 0. POSIX only */
struct fealist {
__le32 list_len;
@@ -459,7 +459,9 @@ extern ssize_t CIFSSMBQAllEAs(const unsigned int
xid, struct cifs_tcon *tcon,
extern int CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
const char *fileName, const char *ea_name,
const void *ea_value, const __u16 ea_value_len,
- const struct nls_table *nls_codepage, int remap_special_chars);
+ const struct nls_table *nls_codepage, int remap_special_chars,
+ bool is_posix /* if posix try to set using newer xattr op */,
+ bool set_delete /* if posix xattr delete flag should be set */);
extern int CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon,
__u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen);
extern int CIFSSMBSetCIFSACL(const unsigned int, struct cifs_tcon *, __u16,
@@ -6208,7 +6208,7 @@ int
CIFSSMBSetEA(const unsigned int xid, struct cifs_tcon *tcon,
const char *fileName, const char *ea_name, const void *ea_value,
const __u16 ea_value_len, const struct nls_table *nls_codepage,
- int remap)
+ int remap, bool is_posix, bool is_posix_delete)
{
struct smb_com_transaction2_spi_req *pSMB = NULL;
struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
@@ -6259,8 +6259,10 @@ SetEARetry:
param_offset = offsetof(struct smb_com_transaction2_spi_req,
InformationLevel) - 4;
offset = param_offset + params;
- pSMB->InformationLevel =
- cpu_to_le16(SMB_SET_FILE_EA);
+ if (is_posix)
+ pSMB->InformationLevel = cpu_to_le16(SMB_SET_XATTR);
+ else
+ pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_EA);
parm_data =
(struct fealist *) (((char *) &pSMB->hdr.Protocol) +
@@ -6273,7 +6275,11 @@ SetEARetry:
byte_count = 3 /* pad */ + params + count;
pSMB->DataCount = cpu_to_le16(count);
parm_data->list_len = cpu_to_le32(count);
- parm_data->list[0].EA_flags = 0;
+ if (is_posix_delete)
+ parm_data->list[0].EA_flags = FEA_DELETEEA;
+ else
+ parm_data->list[0].EA_flags = 0;
+
/* we checked above that name len is less than 255 */
parm_data->list[0].name_len = (__u8)name_len;
/* EA names are always ASCII */
@@ -1,7 +1,7 @@
/*
* fs/cifs/xattr.c
*
- * Copyright (c) International Business Machines Corp., 2003, 2007
+ * Copyright (c) International Business Machines Corp., 2003, 2013
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -69,22 +69,35 @@ int cifs_removexattr(struct dentry *direntry,
const char *ea_name)
}
if (ea_name == NULL) {
cifs_dbg(FYI, "Null xattr names not supported\n");
- } else if (strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)
+ goto remove_ea_exit;
+ }
+
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
+ goto remove_ea_exit;
+
+ if (le64_to_cpu(pTcon->fsUnixInfo.Capability)& CIFS_UNIX_XATTR_CAP) {
+ rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, NULL,
+ (__u16)0, cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR,
+ true /* posix */, true /* set posix delete flag */);
+ cifs_dbg(FYI, "posix removeea of %s rc = %d", full_path, rc);
+
+ /* If unable to remove with posix call try older xattr level */
+ if (!rc)
+ goto remove_ea_exit;
+ }
+
+ if (strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)
&& (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN))) {
cifs_dbg(FYI,
"illegal xattr request %s (only user namespace supported)\n",
ea_name);
- /* BB what if no namespace prefix? */
- /* Should we just pass them to server, except for
- system and perhaps security prefixes? */
} else {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
- goto remove_ea_exit;
-
ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */
rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, NULL,
(__u16)0, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+ cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR,
+ false /* not posix */, false /* do not set del flag */);
}
remove_ea_exit: