Import of kernel-5.14.0-687.38.1.el9_8
This commit is contained in:
parent
d8f1f57754
commit
9a883d36ee
@ -12,7 +12,7 @@ RHEL_MINOR = 8
|
||||
#
|
||||
# Use this spot to avoid future merge conflicts.
|
||||
# Do not trim this comment.
|
||||
RHEL_RELEASE = 687.36.1
|
||||
RHEL_RELEASE = 687.38.1
|
||||
|
||||
#
|
||||
# ZSTREAM
|
||||
|
||||
@ -697,9 +697,10 @@
|
||||
#define MSR_AMD64_LBR_SELECT 0xc000010e
|
||||
|
||||
/* Zen4 */
|
||||
#define MSR_ZEN4_BP_CFG 0xc001102e
|
||||
#define MSR_ZEN4_BP_CFG 0xc001102e
|
||||
#define MSR_ZEN4_BP_CFG_BP_SPEC_REDUCE_BIT 4
|
||||
#define MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT 5
|
||||
#define MSR_ZEN2_BP_CFG_BUG_FIX_BIT 33
|
||||
|
||||
/* Fam 19h MSRs */
|
||||
#define MSR_F19H_UMC_PERF_CTL 0xc0010800
|
||||
|
||||
@ -983,6 +983,9 @@ static void init_amd_zen2(struct cpuinfo_x86 *c)
|
||||
init_spectral_chicken(c);
|
||||
fix_erratum_1386(c);
|
||||
zen2_zenbleed_check(c);
|
||||
|
||||
if (!cpu_has(c, X86_FEATURE_HYPERVISOR))
|
||||
msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN2_BP_CFG_BUG_FIX_BIT);
|
||||
}
|
||||
|
||||
static void init_amd_zen3(struct cpuinfo_x86 *c)
|
||||
|
||||
@ -537,10 +537,13 @@ static void cxl_port_release(struct device *dev)
|
||||
xa_destroy(&port->dports);
|
||||
xa_destroy(&port->regions);
|
||||
ida_free(&cxl_port_ida, port->id);
|
||||
if (is_cxl_root(port))
|
||||
|
||||
if (is_cxl_root(port)) {
|
||||
kfree(to_cxl_root(port));
|
||||
else
|
||||
} else {
|
||||
put_device(dev->parent);
|
||||
kfree(port);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t decoders_committed_show(struct device *dev,
|
||||
@ -708,6 +711,7 @@ static struct cxl_port *cxl_port_alloc(struct device *uport_dev,
|
||||
struct cxl_port *iter;
|
||||
|
||||
dev->parent = &parent_port->dev;
|
||||
get_device(dev->parent);
|
||||
port->depth = parent_port->depth + 1;
|
||||
port->parent_dport = parent_dport;
|
||||
|
||||
|
||||
@ -533,23 +533,16 @@ static void esw_update_vport_addr_list(struct mlx5_eswitch *esw,
|
||||
struct mlx5_vport *vport, int list_type)
|
||||
{
|
||||
bool is_uc = list_type == MLX5_NVPRT_LIST_TYPE_UC;
|
||||
u8 (*mac_list)[ETH_ALEN];
|
||||
u8 (*mac_list)[ETH_ALEN] = NULL;
|
||||
struct l2addr_node *node;
|
||||
struct vport_addr *addr;
|
||||
struct hlist_head *hash;
|
||||
struct hlist_node *tmp;
|
||||
int size;
|
||||
int size = 0;
|
||||
int err;
|
||||
int hi;
|
||||
int i;
|
||||
|
||||
size = is_uc ? MLX5_MAX_UC_PER_VPORT(esw->dev) :
|
||||
MLX5_MAX_MC_PER_VPORT(esw->dev);
|
||||
|
||||
mac_list = kcalloc(size, ETH_ALEN, GFP_KERNEL);
|
||||
if (!mac_list)
|
||||
return;
|
||||
|
||||
hash = is_uc ? vport->uc_list : vport->mc_list;
|
||||
|
||||
for_each_l2hash_node(node, tmp, hash, hi) {
|
||||
@ -561,7 +554,7 @@ static void esw_update_vport_addr_list(struct mlx5_eswitch *esw,
|
||||
goto out;
|
||||
|
||||
err = mlx5_query_nic_vport_mac_list(esw->dev, vport->vport, list_type,
|
||||
mac_list, &size);
|
||||
&mac_list, &size);
|
||||
if (err)
|
||||
goto out;
|
||||
esw_debug(esw->dev, "vport[%d] context update %s list size (%d)\n",
|
||||
|
||||
@ -250,35 +250,63 @@ int mlx5_modify_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 mtu)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mtu);
|
||||
|
||||
static int mlx5_vport_max_mac_list_size(struct mlx5_core_dev *dev, u16 vport,
|
||||
enum mlx5_list_type list_type)
|
||||
{
|
||||
void *query_ctx, *hca_caps;
|
||||
int ret = 0;
|
||||
|
||||
if (!vport && !mlx5_core_is_ecpf(dev))
|
||||
return list_type == MLX5_NVPRT_LIST_TYPE_UC ?
|
||||
1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
|
||||
1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
|
||||
|
||||
query_ctx = kzalloc(MLX5_ST_SZ_BYTES(query_hca_cap_out), GFP_KERNEL);
|
||||
if (!query_ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = mlx5_vport_get_other_func_general_cap(dev, vport, query_ctx);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
hca_caps = MLX5_ADDR_OF(query_hca_cap_out, query_ctx, capability);
|
||||
ret = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
|
||||
1 << MLX5_GET(cmd_hca_cap, hca_caps, log_max_current_uc_list) :
|
||||
1 << MLX5_GET(cmd_hca_cap, hca_caps, log_max_current_mc_list);
|
||||
|
||||
out:
|
||||
kfree(query_ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
|
||||
u16 vport,
|
||||
enum mlx5_list_type list_type,
|
||||
u8 addr_list[][ETH_ALEN],
|
||||
int *list_size)
|
||||
u8 (**addr_list)[ETH_ALEN],
|
||||
int *addr_list_size)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)] = {0};
|
||||
int allowed_list_size;
|
||||
void *nic_vport_ctx;
|
||||
int max_list_size;
|
||||
int req_list_size;
|
||||
int out_sz;
|
||||
void *out;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
req_list_size = *list_size;
|
||||
if (!addr_list || !addr_list_size)
|
||||
return -EINVAL;
|
||||
|
||||
max_list_size = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
|
||||
1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
|
||||
1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
|
||||
*addr_list = NULL;
|
||||
*addr_list_size = 0;
|
||||
|
||||
if (req_list_size > max_list_size) {
|
||||
mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
|
||||
req_list_size, max_list_size);
|
||||
req_list_size = max_list_size;
|
||||
}
|
||||
max_list_size = mlx5_vport_max_mac_list_size(dev, vport, list_type);
|
||||
if (max_list_size < 0)
|
||||
return max_list_size;
|
||||
|
||||
out_sz = MLX5_ST_SZ_BYTES(query_nic_vport_context_out) +
|
||||
req_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
|
||||
max_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
|
||||
|
||||
out = kvzalloc(out_sz, GFP_KERNEL);
|
||||
if (!out)
|
||||
@ -297,16 +325,24 @@ int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
|
||||
|
||||
nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
|
||||
nic_vport_context);
|
||||
req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
|
||||
allowed_list_size);
|
||||
allowed_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
|
||||
allowed_list_size);
|
||||
if (!allowed_list_size)
|
||||
goto out;
|
||||
|
||||
*list_size = req_list_size;
|
||||
for (i = 0; i < req_list_size; i++) {
|
||||
*addr_list = kcalloc(allowed_list_size, ETH_ALEN, GFP_KERNEL);
|
||||
if (!*addr_list) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < allowed_list_size; i++) {
|
||||
u8 *mac_addr = MLX5_ADDR_OF(nic_vport_context,
|
||||
nic_vport_ctx,
|
||||
current_uc_mac_address[i]) + 2;
|
||||
ether_addr_copy(addr_list[i], mac_addr);
|
||||
ether_addr_copy((*addr_list)[i], mac_addr);
|
||||
}
|
||||
*addr_list_size = allowed_list_size;
|
||||
out:
|
||||
kvfree(out);
|
||||
return err;
|
||||
|
||||
@ -332,6 +332,13 @@ static int pkey_ioctl_verifyprotk(struct pkey_verifyprotk __user *uvp)
|
||||
if (copy_from_user(&kvp, uvp, sizeof(kvp)))
|
||||
return -EFAULT;
|
||||
|
||||
if (kvp.protkey.len > sizeof(kvp.protkey.protkey)) {
|
||||
PKEY_DBF_ERR("%s protkey length %u exceeds protkey buffer size\n",
|
||||
__func__, kvp.protkey.len);
|
||||
memzero_explicit(&kvp, sizeof(kvp));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
keytype = pkey_aes_bitsize_to_keytype(8 * kvp.protkey.len);
|
||||
if (!keytype) {
|
||||
PKEY_DBF_ERR("%s unknown/unsupported protkey length %u\n",
|
||||
|
||||
@ -257,6 +257,10 @@ static int pckmo_key2protkey(const u8 *key, u32 keylen,
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
if (t->len > *protkeylen) {
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
memcpy(protkey, t->protkey, t->len);
|
||||
*protkeylen = t->len;
|
||||
*protkeytype = t->keytype;
|
||||
|
||||
@ -117,7 +117,7 @@ static const char *path_no_prefix(struct cifs_sb_info *cifs_sb,
|
||||
if (!*path)
|
||||
return path;
|
||||
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
|
||||
if ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_USE_PREFIX_PATH) &&
|
||||
cifs_sb->prepath) {
|
||||
len = strlen(cifs_sb->prepath) + 1;
|
||||
if (unlikely(len > strlen(path)))
|
||||
|
||||
@ -55,7 +55,7 @@ struct cifs_sb_info {
|
||||
struct nls_table *local_nls;
|
||||
struct smb3_fs_context *ctx;
|
||||
atomic_t active;
|
||||
unsigned int mnt_cifs_flags;
|
||||
atomic_t mnt_cifs_flags;
|
||||
struct delayed_work prune_tlinks;
|
||||
struct rcu_head rcu;
|
||||
|
||||
|
||||
@ -122,11 +122,3 @@ struct smb3_notify_info {
|
||||
#define CIFS_GOING_FLAGS_DEFAULT 0x0 /* going down */
|
||||
#define CIFS_GOING_FLAGS_LOGFLUSH 0x1 /* flush log but not data */
|
||||
#define CIFS_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't flush log nor data */
|
||||
|
||||
static inline bool cifs_forced_shutdown(struct cifs_sb_info *sbi)
|
||||
{
|
||||
if (CIFS_MOUNT_SHUTDOWN & sbi->mnt_cifs_flags)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -13,20 +13,6 @@
|
||||
#include "cifsglob.h"
|
||||
#include "cifs_debug.h"
|
||||
|
||||
int cifs_remap(struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
int map_type;
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR)
|
||||
map_type = SFM_MAP_UNI_RSVD;
|
||||
else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
|
||||
map_type = SFU_MAP_UNI_RSVD;
|
||||
else
|
||||
map_type = NO_MAP_UNI_RSVD;
|
||||
|
||||
return map_type;
|
||||
}
|
||||
|
||||
/* Convert character using the SFU - "Services for Unix" remapping range */
|
||||
static bool
|
||||
convert_sfu_char(const __u16 src_char, char *target)
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/nls.h>
|
||||
#include "cifsglob.h"
|
||||
|
||||
#define UNIUPR_NOLOWER /* Example to not expand lower case tables */
|
||||
|
||||
@ -99,7 +100,6 @@ char *cifs_strndup_from_utf16(const char *src, const int maxlen,
|
||||
const struct nls_table *codepage);
|
||||
extern int cifsConvertToUTF16(__le16 *target, const char *source, int maxlen,
|
||||
const struct nls_table *cp, int mapChars);
|
||||
extern int cifs_remap(struct cifs_sb_info *cifs_sb);
|
||||
extern __le16 *cifs_strndup_to_utf16(const char *src, const int maxlen,
|
||||
int *utf16_len, const struct nls_table *cp,
|
||||
int remap);
|
||||
@ -398,4 +398,16 @@ UniStrlwr(register wchar_t *upin)
|
||||
|
||||
#endif
|
||||
|
||||
static inline int cifs_remap(const struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
unsigned int sbflags = cifs_sb_flags(cifs_sb);
|
||||
|
||||
if (sbflags & CIFS_MOUNT_MAP_SFM_CHR)
|
||||
return SFM_MAP_UNI_RSVD;
|
||||
if (sbflags & CIFS_MOUNT_MAP_SPECIAL_CHR)
|
||||
return SFU_MAP_UNI_RSVD;
|
||||
|
||||
return NO_MAP_UNI_RSVD;
|
||||
}
|
||||
|
||||
#endif /* _CIFS_UNICODE_H */
|
||||
|
||||
@ -355,7 +355,7 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) ||
|
||||
if ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_UID_FROM_ACL) ||
|
||||
(cifs_sb_master_tcon(cifs_sb)->posix_extensions)) {
|
||||
uint32_t unix_id;
|
||||
bool is_group;
|
||||
@ -1685,7 +1685,8 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
|
||||
struct smb_acl *dacl_ptr = NULL;
|
||||
struct smb_ntsd *pntsd = NULL; /* acl obtained from server */
|
||||
struct smb_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
|
||||
unsigned int sbflags;
|
||||
struct tcon_link *tlink;
|
||||
struct smb_version_operations *ops;
|
||||
bool mode_from_sid, id_from_sid;
|
||||
@ -1716,15 +1717,9 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
|
||||
mode_from_sid = true;
|
||||
else
|
||||
mode_from_sid = false;
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
|
||||
id_from_sid = true;
|
||||
else
|
||||
id_from_sid = false;
|
||||
sbflags = cifs_sb_flags(cifs_sb);
|
||||
mode_from_sid = sbflags & CIFS_MOUNT_MODE_FROM_SID;
|
||||
id_from_sid = sbflags & CIFS_MOUNT_UID_FROM_ACL;
|
||||
|
||||
/* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */
|
||||
if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */
|
||||
|
||||
@ -226,16 +226,18 @@ cifs_sb_deactive(struct super_block *sb)
|
||||
static int
|
||||
cifs_read_super(struct super_block *sb)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifs_tcon *tcon;
|
||||
unsigned int sbflags;
|
||||
struct timespec64 ts;
|
||||
struct inode *inode;
|
||||
int rc = 0;
|
||||
|
||||
cifs_sb = CIFS_SB(sb);
|
||||
tcon = cifs_sb_master_tcon(cifs_sb);
|
||||
sbflags = cifs_sb_flags(cifs_sb);
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIXACL)
|
||||
if (sbflags & CIFS_MOUNT_POSIXACL)
|
||||
sb->s_flags |= SB_POSIXACL;
|
||||
|
||||
if (tcon->snapshot_time)
|
||||
@ -311,7 +313,7 @@ cifs_read_super(struct super_block *sb)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_NFSD_EXPORT
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
|
||||
if (sbflags & CIFS_MOUNT_SERVER_INUM) {
|
||||
cifs_dbg(FYI, "export ops supported\n");
|
||||
sb->s_export_op = &cifs_export_ops;
|
||||
}
|
||||
@ -389,8 +391,7 @@ statfs_out:
|
||||
|
||||
static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
|
||||
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
|
||||
struct cifs_tcon *tcon = cifs_sb_master_tcon(CIFS_SB(file));
|
||||
struct TCP_Server_Info *server = tcon->ses->server;
|
||||
struct inode *inode = file_inode(file);
|
||||
int rc;
|
||||
@ -416,11 +417,9 @@ out_unlock:
|
||||
static int cifs_permission(struct mnt_idmap *idmap,
|
||||
struct inode *inode, int mask)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
unsigned int sbflags = cifs_sb_flags(CIFS_SB(inode));
|
||||
|
||||
cifs_sb = CIFS_SB(inode->i_sb);
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
|
||||
if (sbflags & CIFS_MOUNT_NO_PERM) {
|
||||
if ((mask & MAY_EXEC) && !execute_ok(inode))
|
||||
return -EACCES;
|
||||
else
|
||||
@ -449,6 +448,7 @@ cifs_alloc_inode(struct super_block *sb)
|
||||
return NULL;
|
||||
cifs_inode->cifsAttrs = ATTR_ARCHIVE; /* default */
|
||||
cifs_inode->time = 0;
|
||||
cifs_inode->time_last_write = 0;
|
||||
/*
|
||||
* Until the file is open and we have gotten oplock info back from the
|
||||
* server, can not assume caching of file data or metadata.
|
||||
@ -561,15 +561,17 @@ cifs_show_security(struct seq_file *s, struct cifs_ses *ses)
|
||||
static void
|
||||
cifs_show_cache_flavor(struct seq_file *s, struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
unsigned int sbflags = cifs_sb_flags(cifs_sb);
|
||||
|
||||
seq_puts(s, ",cache=");
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)
|
||||
if (sbflags & CIFS_MOUNT_STRICT_IO)
|
||||
seq_puts(s, "strict");
|
||||
else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
|
||||
else if (sbflags & CIFS_MOUNT_DIRECT_IO)
|
||||
seq_puts(s, "none");
|
||||
else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE)
|
||||
else if (sbflags & CIFS_MOUNT_RW_CACHE)
|
||||
seq_puts(s, "singleclient"); /* assume only one client access */
|
||||
else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE)
|
||||
else if (sbflags & CIFS_MOUNT_RO_CACHE)
|
||||
seq_puts(s, "ro"); /* read only caching assumed */
|
||||
else
|
||||
seq_puts(s, "loose");
|
||||
@ -630,6 +632,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(root->d_sb);
|
||||
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
|
||||
struct sockaddr *srcaddr;
|
||||
unsigned int sbflags;
|
||||
|
||||
srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr;
|
||||
|
||||
seq_show_option(s, "vers", tcon->ses->server->vals->version_string);
|
||||
@ -663,16 +667,17 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
|
||||
(int)(srcaddr->sa_family));
|
||||
}
|
||||
|
||||
sbflags = cifs_sb_flags(cifs_sb);
|
||||
seq_printf(s, ",uid=%u",
|
||||
from_kuid_munged(&init_user_ns, cifs_sb->ctx->linux_uid));
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
|
||||
if (sbflags & CIFS_MOUNT_OVERR_UID)
|
||||
seq_puts(s, ",forceuid");
|
||||
else
|
||||
seq_puts(s, ",noforceuid");
|
||||
|
||||
seq_printf(s, ",gid=%u",
|
||||
from_kgid_munged(&init_user_ns, cifs_sb->ctx->linux_gid));
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
|
||||
if (sbflags & CIFS_MOUNT_OVERR_GID)
|
||||
seq_puts(s, ",forcegid");
|
||||
else
|
||||
seq_puts(s, ",noforcegid");
|
||||
@ -715,53 +720,53 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
|
||||
seq_puts(s, ",unix");
|
||||
else
|
||||
seq_puts(s, ",nounix");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS)
|
||||
if (sbflags & CIFS_MOUNT_NO_DFS)
|
||||
seq_puts(s, ",nodfs");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
|
||||
if (sbflags & CIFS_MOUNT_POSIX_PATHS)
|
||||
seq_puts(s, ",posixpaths");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
|
||||
if (sbflags & CIFS_MOUNT_SET_UID)
|
||||
seq_puts(s, ",setuids");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
|
||||
if (sbflags & CIFS_MOUNT_UID_FROM_ACL)
|
||||
seq_puts(s, ",idsfromsid");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
|
||||
if (sbflags & CIFS_MOUNT_SERVER_INUM)
|
||||
seq_puts(s, ",serverino");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
|
||||
if (sbflags & CIFS_MOUNT_RWPIDFORWARD)
|
||||
seq_puts(s, ",rwpidforward");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL)
|
||||
if (sbflags & CIFS_MOUNT_NOPOSIXBRL)
|
||||
seq_puts(s, ",forcemand");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
|
||||
if (sbflags & CIFS_MOUNT_NO_XATTR)
|
||||
seq_puts(s, ",nouser_xattr");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
|
||||
if (sbflags & CIFS_MOUNT_MAP_SPECIAL_CHR)
|
||||
seq_puts(s, ",mapchars");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR)
|
||||
if (sbflags & CIFS_MOUNT_MAP_SFM_CHR)
|
||||
seq_puts(s, ",mapposix");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
|
||||
if (sbflags & CIFS_MOUNT_UNX_EMUL)
|
||||
seq_puts(s, ",sfu");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
|
||||
if (sbflags & CIFS_MOUNT_NO_BRL)
|
||||
seq_puts(s, ",nobrl");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_HANDLE_CACHE)
|
||||
if (sbflags & CIFS_MOUNT_NO_HANDLE_CACHE)
|
||||
seq_puts(s, ",nohandlecache");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
|
||||
if (sbflags & CIFS_MOUNT_MODE_FROM_SID)
|
||||
seq_puts(s, ",modefromsid");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
|
||||
if (sbflags & CIFS_MOUNT_CIFS_ACL)
|
||||
seq_puts(s, ",cifsacl");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
|
||||
if (sbflags & CIFS_MOUNT_DYNPERM)
|
||||
seq_puts(s, ",dynperm");
|
||||
if (root->d_sb->s_flags & SB_POSIXACL)
|
||||
seq_puts(s, ",acl");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
|
||||
if (sbflags & CIFS_MOUNT_MF_SYMLINKS)
|
||||
seq_puts(s, ",mfsymlinks");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE)
|
||||
if (sbflags & CIFS_MOUNT_FSCACHE)
|
||||
seq_puts(s, ",fsc");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)
|
||||
if (sbflags & CIFS_MOUNT_NOSSYNC)
|
||||
seq_puts(s, ",nostrictsync");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
|
||||
if (sbflags & CIFS_MOUNT_NO_PERM)
|
||||
seq_puts(s, ",noperm");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID)
|
||||
if (sbflags & CIFS_MOUNT_CIFS_BACKUPUID)
|
||||
seq_printf(s, ",backupuid=%u",
|
||||
from_kuid_munged(&init_user_ns,
|
||||
cifs_sb->ctx->backupuid));
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID)
|
||||
if (sbflags & CIFS_MOUNT_CIFS_BACKUPGID)
|
||||
seq_printf(s, ",backupgid=%u",
|
||||
from_kgid_munged(&init_user_ns,
|
||||
cifs_sb->ctx->backupgid));
|
||||
@ -903,10 +908,10 @@ static int cifs_write_inode(struct inode *inode, struct writeback_control *wbc)
|
||||
|
||||
static int cifs_drop_inode(struct inode *inode)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
unsigned int sbflags = cifs_sb_flags(CIFS_SB(inode));
|
||||
|
||||
/* no serverino => unconditional eviction */
|
||||
return !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) ||
|
||||
return !(sbflags & CIFS_MOUNT_SERVER_INUM) ||
|
||||
generic_drop_inode(inode);
|
||||
}
|
||||
|
||||
@ -944,7 +949,7 @@ cifs_get_root(struct smb3_fs_context *ctx, struct super_block *sb)
|
||||
char *s, *p;
|
||||
char sep;
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH)
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_USE_PREFIX_PATH)
|
||||
return dget(sb->s_root);
|
||||
|
||||
full_path = cifs_build_path_to_root(ctx, cifs_sb,
|
||||
|
||||
@ -1635,6 +1635,7 @@ struct cifsInodeInfo {
|
||||
spinlock_t writers_lock;
|
||||
unsigned int writers; /* Number of writers on this inode */
|
||||
unsigned long time; /* jiffies of last update of inode */
|
||||
unsigned long time_last_write; /* jiffies of last writable close or truncate */
|
||||
u64 uniqueid; /* server inode number */
|
||||
u64 createtime; /* creation time on server */
|
||||
__u8 lease_key[SMB2_LEASE_KEY_SIZE]; /* lease key for this inode */
|
||||
@ -1651,24 +1652,59 @@ CIFS_I(struct inode *inode)
|
||||
return container_of(inode, struct cifsInodeInfo, netfs.inode);
|
||||
}
|
||||
|
||||
static inline struct cifs_sb_info *
|
||||
CIFS_SB(struct super_block *sb)
|
||||
static inline void *cinode_to_fsinfo(struct cifsInodeInfo *cinode)
|
||||
{
|
||||
return cinode->netfs.inode.i_sb->s_fs_info;
|
||||
}
|
||||
|
||||
static inline void *super_to_fsinfo(struct super_block *sb)
|
||||
{
|
||||
return sb->s_fs_info;
|
||||
}
|
||||
|
||||
static inline struct cifs_sb_info *
|
||||
CIFS_FILE_SB(struct file *file)
|
||||
static inline void *inode_to_fsinfo(struct inode *inode)
|
||||
{
|
||||
return CIFS_SB(file_inode(file)->i_sb);
|
||||
return inode->i_sb->s_fs_info;
|
||||
}
|
||||
|
||||
static inline void *file_to_fsinfo(struct file *file)
|
||||
{
|
||||
return file_inode(file)->i_sb->s_fs_info;
|
||||
}
|
||||
|
||||
static inline void *dentry_to_fsinfo(struct dentry *dentry)
|
||||
{
|
||||
return dentry->d_sb->s_fs_info;
|
||||
}
|
||||
|
||||
static inline void *const_dentry_to_fsinfo(const struct dentry *dentry)
|
||||
{
|
||||
return dentry->d_sb->s_fs_info;
|
||||
}
|
||||
|
||||
#define CIFS_SB(_ptr) \
|
||||
((struct cifs_sb_info *) \
|
||||
_Generic((_ptr), \
|
||||
struct cifsInodeInfo * : cinode_to_fsinfo, \
|
||||
const struct dentry * : const_dentry_to_fsinfo, \
|
||||
struct super_block * : super_to_fsinfo, \
|
||||
struct dentry * : dentry_to_fsinfo, \
|
||||
struct inode * : inode_to_fsinfo, \
|
||||
struct file * : file_to_fsinfo)(_ptr))
|
||||
|
||||
/*
|
||||
* Use atomic_t for @cifs_sb->mnt_cifs_flags as it is currently accessed
|
||||
* locklessly and may be changed concurrently by mount/remount and reconnect
|
||||
* paths.
|
||||
*/
|
||||
static inline unsigned int cifs_sb_flags(const struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
return atomic_read(&cifs_sb->mnt_cifs_flags);
|
||||
}
|
||||
|
||||
static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
|
||||
return '/';
|
||||
else
|
||||
return '\\';
|
||||
return (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_POSIX_PATHS) ? '/' : '\\';
|
||||
}
|
||||
|
||||
static inline void
|
||||
@ -2448,9 +2484,8 @@ static inline bool __cifs_cache_state_check(struct cifsInodeInfo *cinode,
|
||||
unsigned int oplock_flags,
|
||||
unsigned int sb_flags)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(cinode->netfs.inode.i_sb);
|
||||
unsigned int sflags = cifs_sb_flags(CIFS_SB(cinode));
|
||||
unsigned int oplock = READ_ONCE(cinode->oplock);
|
||||
unsigned int sflags = cifs_sb->mnt_cifs_flags;
|
||||
|
||||
return (oplock & oplock_flags) || (sflags & sb_flags);
|
||||
}
|
||||
@ -2470,4 +2505,9 @@ static inline void cifs_reset_oplock(struct cifsInodeInfo *cinode)
|
||||
WRITE_ONCE(cinode->oplock, 0);
|
||||
}
|
||||
|
||||
static inline bool cifs_forced_shutdown(const struct cifs_sb_info *sbi)
|
||||
{
|
||||
return cifs_sb_flags(sbi) & CIFS_MOUNT_SHUTDOWN;
|
||||
}
|
||||
|
||||
#endif /* _CIFS_GLOB_H */
|
||||
|
||||
@ -2918,8 +2918,8 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
|
||||
{
|
||||
struct cifs_sb_info *old = CIFS_SB(sb);
|
||||
struct cifs_sb_info *new = mnt_data->cifs_sb;
|
||||
unsigned int oldflags = old->mnt_cifs_flags & CIFS_MOUNT_MASK;
|
||||
unsigned int newflags = new->mnt_cifs_flags & CIFS_MOUNT_MASK;
|
||||
unsigned int oldflags = cifs_sb_flags(old) & CIFS_MOUNT_MASK;
|
||||
unsigned int newflags = cifs_sb_flags(new) & CIFS_MOUNT_MASK;
|
||||
|
||||
if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK))
|
||||
return 0;
|
||||
@ -2974,9 +2974,9 @@ static int match_prepath(struct super_block *sb,
|
||||
struct smb3_fs_context *ctx = mnt_data->ctx;
|
||||
struct cifs_sb_info *old = CIFS_SB(sb);
|
||||
struct cifs_sb_info *new = mnt_data->cifs_sb;
|
||||
bool old_set = (old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
|
||||
bool old_set = (cifs_sb_flags(old) & CIFS_MOUNT_USE_PREFIX_PATH) &&
|
||||
old->prepath;
|
||||
bool new_set = (new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
|
||||
bool new_set = (cifs_sb_flags(new) & CIFS_MOUNT_USE_PREFIX_PATH) &&
|
||||
new->prepath;
|
||||
|
||||
if (tcon->origin_fullpath &&
|
||||
@ -3007,7 +3007,7 @@ cifs_match_super(struct super_block *sb, void *data)
|
||||
cifs_sb = CIFS_SB(sb);
|
||||
|
||||
/* We do not want to use a superblock that has been shutdown */
|
||||
if (CIFS_MOUNT_SHUTDOWN & cifs_sb->mnt_cifs_flags) {
|
||||
if (cifs_forced_shutdown(cifs_sb)) {
|
||||
spin_unlock(&cifs_tcp_ses_lock);
|
||||
return 0;
|
||||
}
|
||||
@ -3534,18 +3534,20 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
|
||||
cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
|
||||
else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
|
||||
cifs_dbg(FYI, "negotiated posix acl support\n");
|
||||
if (cifs_sb)
|
||||
cifs_sb->mnt_cifs_flags |=
|
||||
CIFS_MOUNT_POSIXACL;
|
||||
if (cifs_sb) {
|
||||
atomic_or(CIFS_MOUNT_POSIXACL,
|
||||
&cifs_sb->mnt_cifs_flags);
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx && ctx->posix_paths == 0)
|
||||
cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
|
||||
else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
|
||||
cifs_dbg(FYI, "negotiate posix pathnames\n");
|
||||
if (cifs_sb)
|
||||
cifs_sb->mnt_cifs_flags |=
|
||||
CIFS_MOUNT_POSIX_PATHS;
|
||||
if (cifs_sb) {
|
||||
atomic_or(CIFS_MOUNT_POSIX_PATHS,
|
||||
&cifs_sb->mnt_cifs_flags);
|
||||
}
|
||||
}
|
||||
|
||||
cifs_dbg(FYI, "Negotiate caps 0x%x\n", (int)cap);
|
||||
@ -3583,6 +3585,8 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
|
||||
int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
struct smb3_fs_context *ctx = cifs_sb->ctx;
|
||||
unsigned int sbflags;
|
||||
int rc = 0;
|
||||
|
||||
INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);
|
||||
INIT_LIST_HEAD(&cifs_sb->tcon_sb_link);
|
||||
@ -3607,17 +3611,16 @@ int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb)
|
||||
}
|
||||
ctx->local_nls = cifs_sb->local_nls;
|
||||
|
||||
smb3_update_mnt_flags(cifs_sb);
|
||||
sbflags = smb3_update_mnt_flags(cifs_sb);
|
||||
|
||||
if (ctx->direct_io)
|
||||
cifs_dbg(FYI, "mounting share using direct i/o\n");
|
||||
if (ctx->cache_ro) {
|
||||
cifs_dbg(VFS, "mounting share with read only caching. Ensure that the share will not be modified while in use.\n");
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RO_CACHE;
|
||||
sbflags |= CIFS_MOUNT_RO_CACHE;
|
||||
} else if (ctx->cache_rw) {
|
||||
cifs_dbg(VFS, "mounting share in single client RW caching mode. Ensure that no other systems will be accessing the share.\n");
|
||||
cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_RO_CACHE |
|
||||
CIFS_MOUNT_RW_CACHE);
|
||||
sbflags |= CIFS_MOUNT_RO_CACHE | CIFS_MOUNT_RW_CACHE;
|
||||
}
|
||||
|
||||
if ((ctx->cifs_acl) && (ctx->dynperm))
|
||||
@ -3626,16 +3629,19 @@ int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb)
|
||||
if (ctx->prepath) {
|
||||
cifs_sb->prepath = kstrdup(ctx->prepath, GFP_KERNEL);
|
||||
if (cifs_sb->prepath == NULL)
|
||||
return -ENOMEM;
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
|
||||
rc = -ENOMEM;
|
||||
else
|
||||
sbflags |= CIFS_MOUNT_USE_PREFIX_PATH;
|
||||
}
|
||||
|
||||
return 0;
|
||||
atomic_set(&cifs_sb->mnt_cifs_flags, sbflags);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Release all succeed connections */
|
||||
void cifs_mount_put_conns(struct cifs_mount_ctx *mnt_ctx)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb;
|
||||
int rc = 0;
|
||||
|
||||
if (mnt_ctx->tcon)
|
||||
@ -3647,7 +3653,7 @@ void cifs_mount_put_conns(struct cifs_mount_ctx *mnt_ctx)
|
||||
mnt_ctx->ses = NULL;
|
||||
mnt_ctx->tcon = NULL;
|
||||
mnt_ctx->server = NULL;
|
||||
mnt_ctx->cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_POSIX_PATHS;
|
||||
atomic_andnot(CIFS_MOUNT_POSIX_PATHS, &cifs_sb->mnt_cifs_flags);
|
||||
free_xid(mnt_ctx->xid);
|
||||
}
|
||||
|
||||
@ -3701,15 +3707,18 @@ out:
|
||||
int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
|
||||
{
|
||||
struct TCP_Server_Info *server;
|
||||
struct cifs_tcon *tcon = NULL;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct smb3_fs_context *ctx;
|
||||
struct cifs_tcon *tcon = NULL;
|
||||
unsigned int sbflags;
|
||||
int rc = 0;
|
||||
|
||||
if (WARN_ON_ONCE(!mnt_ctx || !mnt_ctx->server || !mnt_ctx->ses || !mnt_ctx->fs_ctx ||
|
||||
!mnt_ctx->cifs_sb)) {
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
if (WARN_ON_ONCE(!mnt_ctx))
|
||||
return -EINVAL;
|
||||
if (WARN_ON_ONCE(!mnt_ctx->server || !mnt_ctx->ses ||
|
||||
!mnt_ctx->fs_ctx || !mnt_ctx->cifs_sb)) {
|
||||
mnt_ctx->tcon = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
server = mnt_ctx->server;
|
||||
ctx = mnt_ctx->fs_ctx;
|
||||
@ -3728,9 +3737,10 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
|
||||
* path (i.e., do not remap / and \ and do not map any special characters)
|
||||
*/
|
||||
if (tcon->posix_extensions) {
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;
|
||||
cifs_sb->mnt_cifs_flags &= ~(CIFS_MOUNT_MAP_SFM_CHR |
|
||||
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
atomic_or(CIFS_MOUNT_POSIX_PATHS, &cifs_sb->mnt_cifs_flags);
|
||||
atomic_andnot(CIFS_MOUNT_MAP_SFM_CHR |
|
||||
CIFS_MOUNT_MAP_SPECIAL_CHR,
|
||||
&cifs_sb->mnt_cifs_flags);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
|
||||
@ -3754,15 +3764,15 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
|
||||
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
|
||||
tcon->unix_ext = 0; /* server does not support them */
|
||||
|
||||
sbflags = cifs_sb_flags(cifs_sb);
|
||||
/* do not care if a following call succeed - informational */
|
||||
if (!tcon->pipe && server->ops->qfs_tcon) {
|
||||
server->ops->qfs_tcon(mnt_ctx->xid, tcon, cifs_sb);
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) {
|
||||
if (sbflags & CIFS_MOUNT_RO_CACHE) {
|
||||
if (tcon->fsDevInfo.DeviceCharacteristics &
|
||||
cpu_to_le32(FILE_READ_ONLY_DEVICE))
|
||||
cifs_dbg(VFS, "mounted to read only share\n");
|
||||
else if ((cifs_sb->mnt_cifs_flags &
|
||||
CIFS_MOUNT_RW_CACHE) == 0)
|
||||
else if (!(sbflags & CIFS_MOUNT_RW_CACHE))
|
||||
cifs_dbg(VFS, "read only mount of RW share\n");
|
||||
/* no need to log a RW mount of a typical RW share */
|
||||
}
|
||||
@ -3774,7 +3784,7 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
|
||||
* Inside cifs_fscache_get_super_cookie it checks
|
||||
* that we do not get super cookie twice.
|
||||
*/
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE)
|
||||
if (sbflags & CIFS_MOUNT_FSCACHE)
|
||||
cifs_fscache_get_super_cookie(tcon);
|
||||
|
||||
out:
|
||||
@ -3897,7 +3907,8 @@ int cifs_is_path_remote(struct cifs_mount_ctx *mnt_ctx)
|
||||
cifs_sb, full_path, tcon->Flags & SMB_SHARE_IS_IN_DFS);
|
||||
if (rc != 0) {
|
||||
cifs_server_dbg(VFS, "cannot query dirs between root and final path, enabling CIFS_MOUNT_USE_PREFIX_PATH\n");
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
|
||||
atomic_or(CIFS_MOUNT_USE_PREFIX_PATH,
|
||||
&cifs_sb->mnt_cifs_flags);
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
@ -3928,7 +3939,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
|
||||
* Force the use of prefix path to support failover on DFS paths that resolve to targets
|
||||
* that have different prefix paths.
|
||||
*/
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
|
||||
atomic_or(CIFS_MOUNT_USE_PREFIX_PATH, &cifs_sb->mnt_cifs_flags);
|
||||
kfree(cifs_sb->prepath);
|
||||
cifs_sb->prepath = ctx->prepath;
|
||||
ctx->prepath = NULL;
|
||||
@ -4548,7 +4559,7 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
|
||||
kuid_t fsuid = current_fsuid();
|
||||
int err;
|
||||
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
|
||||
if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_MULTIUSER))
|
||||
return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
|
||||
|
||||
spin_lock(&cifs_sb->tlink_tree_lock);
|
||||
|
||||
@ -1333,7 +1333,7 @@ int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb)
|
||||
* Force the use of prefix path to support failover on DFS paths that resolve to targets
|
||||
* that have different prefix paths.
|
||||
*/
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
|
||||
atomic_or(CIFS_MOUNT_USE_PREFIX_PATH, &cifs_sb->mnt_cifs_flags);
|
||||
|
||||
refresh_tcon_referral(tcon, true);
|
||||
return 0;
|
||||
|
||||
@ -83,10 +83,11 @@ char *__build_path_from_dentry_optional_prefix(struct dentry *direntry, void *pa
|
||||
const char *tree, int tree_len,
|
||||
bool prefix)
|
||||
{
|
||||
int dfsplen;
|
||||
int pplen = 0;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry);
|
||||
unsigned int sbflags = cifs_sb_flags(cifs_sb);
|
||||
char dirsep = CIFS_DIR_SEP(cifs_sb);
|
||||
int pplen = 0;
|
||||
int dfsplen;
|
||||
char *s;
|
||||
|
||||
if (unlikely(!page))
|
||||
@ -97,7 +98,7 @@ char *__build_path_from_dentry_optional_prefix(struct dentry *direntry, void *pa
|
||||
else
|
||||
dfsplen = 0;
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH)
|
||||
if (sbflags & CIFS_MOUNT_USE_PREFIX_PATH)
|
||||
pplen = cifs_sb->prepath ? strlen(cifs_sb->prepath) + 1 : 0;
|
||||
|
||||
s = dentry_path_raw(direntry, page, PATH_MAX);
|
||||
@ -124,7 +125,7 @@ char *__build_path_from_dentry_optional_prefix(struct dentry *direntry, void *pa
|
||||
if (dfsplen) {
|
||||
s -= dfsplen;
|
||||
memcpy(s, tree, dfsplen);
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
|
||||
if (sbflags & CIFS_MOUNT_POSIX_PATHS) {
|
||||
int i;
|
||||
for (i = 0; i < dfsplen; i++) {
|
||||
if (s[i] == '\\')
|
||||
@ -153,7 +154,7 @@ char *build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page
|
||||
static int
|
||||
check_name(struct dentry *direntry, struct cifs_tcon *tcon)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry);
|
||||
int i;
|
||||
|
||||
if (unlikely(tcon->fsAttrInfo.MaxPathNameComponentLength &&
|
||||
@ -161,7 +162,7 @@ check_name(struct dentry *direntry, struct cifs_tcon *tcon)
|
||||
le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength)))
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
|
||||
if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_POSIX_PATHS)) {
|
||||
for (i = 0; i < direntry->d_name.len; i++) {
|
||||
if (direntry->d_name.name[i] == '\\') {
|
||||
cifs_dbg(FYI, "Invalid file name\n");
|
||||
@ -182,11 +183,12 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned
|
||||
int rc = -ENOENT;
|
||||
int create_options = CREATE_NOT_DIR;
|
||||
int desired_access;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
|
||||
struct cifs_tcon *tcon = tlink_tcon(tlink);
|
||||
const char *full_path;
|
||||
void *page = alloc_dentry_path();
|
||||
struct inode *newinode = NULL;
|
||||
unsigned int sbflags = cifs_sb_flags(cifs_sb);
|
||||
int disposition;
|
||||
struct TCP_Server_Info *server = tcon->ses->server;
|
||||
struct cifs_open_parms oparms;
|
||||
@ -375,7 +377,7 @@ retry_open:
|
||||
.device = 0,
|
||||
};
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
||||
if (sbflags & CIFS_MOUNT_SET_UID) {
|
||||
args.uid = current_fsuid();
|
||||
if (inode->i_mode & S_ISGID)
|
||||
args.gid = inode->i_gid;
|
||||
@ -412,9 +414,9 @@ cifs_create_get_file_info:
|
||||
if (server->ops->set_lease_key)
|
||||
server->ops->set_lease_key(newinode, fid);
|
||||
if ((*oplock & CIFS_CREATE_ACTION) && S_ISREG(newinode->i_mode)) {
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
|
||||
if (sbflags & CIFS_MOUNT_DYNPERM)
|
||||
newinode->i_mode = mode;
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
||||
if (sbflags & CIFS_MOUNT_SET_UID) {
|
||||
newinode->i_uid = current_fsuid();
|
||||
if (inode->i_mode & S_ISGID)
|
||||
newinode->i_gid = inode->i_gid;
|
||||
@ -459,18 +461,20 @@ int
|
||||
cifs_atomic_open(struct inode *inode, struct dentry *direntry,
|
||||
struct file *file, unsigned int oflags, umode_t mode)
|
||||
{
|
||||
int rc;
|
||||
unsigned int xid;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
|
||||
struct cifs_open_info_data buf = {};
|
||||
struct TCP_Server_Info *server;
|
||||
struct cifsFileInfo *file_info;
|
||||
struct cifs_pending_open open;
|
||||
struct cifs_fid fid = {};
|
||||
struct tcon_link *tlink;
|
||||
struct cifs_tcon *tcon;
|
||||
struct TCP_Server_Info *server;
|
||||
struct cifs_fid fid = {};
|
||||
struct cifs_pending_open open;
|
||||
unsigned int sbflags;
|
||||
unsigned int xid;
|
||||
__u32 oplock;
|
||||
struct cifsFileInfo *file_info;
|
||||
struct cifs_open_info_data buf = {};
|
||||
int rc;
|
||||
|
||||
if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))
|
||||
if (unlikely(cifs_forced_shutdown(cifs_sb)))
|
||||
return -EIO;
|
||||
|
||||
/*
|
||||
@ -506,7 +510,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
|
||||
cifs_dbg(FYI, "parent inode = 0x%p name is: %pd and dentry = 0x%p\n",
|
||||
inode, direntry, direntry);
|
||||
|
||||
tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb));
|
||||
tlink = cifs_sb_tlink(cifs_sb);
|
||||
if (IS_ERR(tlink)) {
|
||||
rc = PTR_ERR(tlink);
|
||||
goto out_free_xid;
|
||||
@ -543,13 +547,13 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (file->f_flags & O_DIRECT &&
|
||||
CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) {
|
||||
if (CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
|
||||
sbflags = cifs_sb_flags(cifs_sb);
|
||||
if ((file->f_flags & O_DIRECT) && (sbflags & CIFS_MOUNT_STRICT_IO)) {
|
||||
if (sbflags & CIFS_MOUNT_NO_BRL)
|
||||
file->f_op = &cifs_file_direct_nobrl_ops;
|
||||
else
|
||||
file->f_op = &cifs_file_direct_ops;
|
||||
}
|
||||
}
|
||||
|
||||
file_info = cifs_new_fileinfo(&fid, file, tlink, oplock, buf.symlink_target);
|
||||
if (file_info == NULL) {
|
||||
|
||||
@ -581,11 +581,19 @@ void _cifsFileInfo_put(struct cifsFileInfo *cifs_file,
|
||||
* close because it may cause a error when we open this file
|
||||
* again and get at least level II oplock.
|
||||
*/
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_STRICT_IO)
|
||||
set_bit(CIFS_INO_INVALID_MAPPING, &cifsi->flags);
|
||||
cifs_set_oplock_level(cifsi, 0);
|
||||
}
|
||||
|
||||
if (OPEN_FMODE(cifs_file->f_flags) & FMODE_WRITE) {
|
||||
/* Stamp while open_file_lock is held; covers all close paths
|
||||
* including background I/O. Pairs with smp_load_acquire() in
|
||||
* is_size_safe_to_change().
|
||||
*/
|
||||
smp_store_release(&cifsi->time_last_write, jiffies);
|
||||
}
|
||||
|
||||
spin_unlock(&cifsi->open_file_lock);
|
||||
spin_unlock(&tcon->open_file_lock);
|
||||
|
||||
@ -630,11 +638,11 @@ void _cifsFileInfo_put(struct cifsFileInfo *cifs_file,
|
||||
int cifs_file_flush(const unsigned int xid, struct inode *inode,
|
||||
struct cifsFileInfo *cfile)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
|
||||
struct cifs_tcon *tcon;
|
||||
int rc;
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOSSYNC)
|
||||
return 0;
|
||||
|
||||
if (cfile && (OPEN_FMODE(cfile->f_flags) & FMODE_WRITE)) {
|
||||
@ -690,24 +698,24 @@ static int cifs_do_truncate(const unsigned int xid, struct dentry *dentry)
|
||||
int cifs_open(struct inode *inode, struct file *file)
|
||||
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
|
||||
struct cifs_open_info_data data = {};
|
||||
struct cifsFileInfo *cfile = NULL;
|
||||
struct TCP_Server_Info *server;
|
||||
struct cifs_pending_open open;
|
||||
bool posix_open_ok = false;
|
||||
struct cifs_fid fid = {};
|
||||
struct tcon_link *tlink;
|
||||
struct cifs_tcon *tcon;
|
||||
const char *full_path;
|
||||
unsigned int sbflags;
|
||||
int rc = -EACCES;
|
||||
unsigned int xid;
|
||||
__u32 oplock;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct TCP_Server_Info *server;
|
||||
struct cifs_tcon *tcon;
|
||||
struct tcon_link *tlink;
|
||||
struct cifsFileInfo *cfile = NULL;
|
||||
void *page;
|
||||
const char *full_path;
|
||||
bool posix_open_ok = false;
|
||||
struct cifs_fid fid = {};
|
||||
struct cifs_pending_open open;
|
||||
struct cifs_open_info_data data = {};
|
||||
|
||||
xid = get_xid();
|
||||
|
||||
cifs_sb = CIFS_SB(inode->i_sb);
|
||||
if (unlikely(cifs_forced_shutdown(cifs_sb))) {
|
||||
free_xid(xid);
|
||||
return -EIO;
|
||||
@ -731,9 +739,9 @@ int cifs_open(struct inode *inode, struct file *file)
|
||||
cifs_dbg(FYI, "inode = 0x%p file flags are 0x%x for %s\n",
|
||||
inode, file->f_flags, full_path);
|
||||
|
||||
if (file->f_flags & O_DIRECT &&
|
||||
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) {
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
|
||||
sbflags = cifs_sb_flags(cifs_sb);
|
||||
if ((file->f_flags & O_DIRECT) && (sbflags & CIFS_MOUNT_STRICT_IO)) {
|
||||
if (sbflags & CIFS_MOUNT_NO_BRL)
|
||||
file->f_op = &cifs_file_direct_nobrl_ops;
|
||||
else
|
||||
file->f_op = &cifs_file_direct_ops;
|
||||
@ -884,7 +892,7 @@ cifs_relock_file(struct cifsFileInfo *cfile)
|
||||
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
|
||||
int rc = 0;
|
||||
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(cinode);
|
||||
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
|
||||
|
||||
down_read_nested(&cinode->lock_sem, SINGLE_DEPTH_NESTING);
|
||||
@ -897,7 +905,7 @@ cifs_relock_file(struct cifsFileInfo *cfile)
|
||||
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
|
||||
if (cap_unix(tcon->ses) &&
|
||||
(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
|
||||
((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
|
||||
((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOPOSIXBRL) == 0))
|
||||
rc = cifs_push_posix_locks(cfile);
|
||||
else
|
||||
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
|
||||
@ -1100,11 +1108,12 @@ void smb2_deferred_work_close(struct work_struct *work)
|
||||
{
|
||||
struct cifsFileInfo *cfile = container_of(work,
|
||||
struct cifsFileInfo, deferred.work);
|
||||
struct cifsInodeInfo *cinode = CIFS_I(d_inode(cfile->dentry));
|
||||
|
||||
spin_lock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
|
||||
spin_lock(&cinode->deferred_lock);
|
||||
cifs_del_deferred_close(cfile);
|
||||
cfile->deferred_close_scheduled = false;
|
||||
spin_unlock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
|
||||
spin_unlock(&cinode->deferred_lock);
|
||||
_cifsFileInfo_put(cfile, true, false);
|
||||
}
|
||||
|
||||
@ -1683,7 +1692,7 @@ cifs_push_locks(struct cifsFileInfo *cfile)
|
||||
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
|
||||
int rc = 0;
|
||||
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(cinode);
|
||||
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
|
||||
|
||||
/* we are going to update can_cache_brlcks here - need a write access */
|
||||
@ -1696,7 +1705,7 @@ cifs_push_locks(struct cifsFileInfo *cfile)
|
||||
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
|
||||
if (cap_unix(tcon->ses) &&
|
||||
(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
|
||||
((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
|
||||
((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOPOSIXBRL) == 0))
|
||||
rc = cifs_push_posix_locks(cfile);
|
||||
else
|
||||
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
|
||||
@ -2099,11 +2108,11 @@ int cifs_flock(struct file *file, int cmd, struct file_lock *fl)
|
||||
|
||||
cifs_read_flock(fl, &type, &lock, &unlock, &wait_flag,
|
||||
tcon->ses->server);
|
||||
cifs_sb = CIFS_FILE_SB(file);
|
||||
cifs_sb = CIFS_SB(file);
|
||||
|
||||
if (cap_unix(tcon->ses) &&
|
||||
(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
|
||||
((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
|
||||
((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOPOSIXBRL) == 0))
|
||||
posix_lck = true;
|
||||
|
||||
if (!lock && !unlock) {
|
||||
@ -2126,14 +2135,14 @@ int cifs_flock(struct file *file, int cmd, struct file_lock *fl)
|
||||
|
||||
int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
|
||||
{
|
||||
int rc, xid;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(file);
|
||||
struct cifsFileInfo *cfile;
|
||||
int lock = 0, unlock = 0;
|
||||
bool wait_flag = false;
|
||||
bool posix_lck = false;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifs_tcon *tcon;
|
||||
struct cifsFileInfo *cfile;
|
||||
__u32 type;
|
||||
int rc, xid;
|
||||
|
||||
rc = -EACCES;
|
||||
xid = get_xid();
|
||||
@ -2147,12 +2156,11 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
|
||||
|
||||
cifs_read_flock(flock, &type, &lock, &unlock, &wait_flag,
|
||||
tcon->ses->server);
|
||||
cifs_sb = CIFS_FILE_SB(file);
|
||||
set_bit(CIFS_INO_CLOSE_ON_LOCK, &CIFS_I(d_inode(cfile->dentry))->flags);
|
||||
|
||||
if (cap_unix(tcon->ses) &&
|
||||
(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
|
||||
((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
|
||||
((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOPOSIXBRL) == 0))
|
||||
posix_lck = true;
|
||||
/*
|
||||
* BB add code here to normalize offset and length to account for
|
||||
@ -2280,11 +2288,11 @@ cifs_write(struct cifsFileInfo *open_file, __u32 pid, const char *write_data,
|
||||
struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
|
||||
bool fsuid_only)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode);
|
||||
struct cifsFileInfo *open_file = NULL;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->netfs.inode.i_sb);
|
||||
|
||||
/* only filter by fsuid on multiuser mounts */
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
|
||||
if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_MULTIUSER))
|
||||
fsuid_only = false;
|
||||
|
||||
spin_lock(&cifs_inode->open_file_lock);
|
||||
@ -2337,10 +2345,10 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags,
|
||||
return rc;
|
||||
}
|
||||
|
||||
cifs_sb = CIFS_SB(cifs_inode->netfs.inode.i_sb);
|
||||
cifs_sb = CIFS_SB(cifs_inode);
|
||||
|
||||
/* only filter by fsuid on multiuser mounts */
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
|
||||
if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_MULTIUSER))
|
||||
fsuid_only = false;
|
||||
|
||||
spin_lock(&cifs_inode->open_file_lock);
|
||||
@ -3125,10 +3133,10 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
|
||||
int rc;
|
||||
struct inode *inode = mapping->host;
|
||||
struct cifsFileInfo *cfile = file->private_data;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry);
|
||||
__u32 pid;
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_RWPIDFORWARD)
|
||||
pid = cfile->pid;
|
||||
else
|
||||
pid = current->tgid;
|
||||
@ -3225,7 +3233,7 @@ int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
|
||||
struct TCP_Server_Info *server;
|
||||
struct cifsFileInfo *smbfile = file->private_data;
|
||||
struct inode *inode = file_inode(file);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(file);
|
||||
|
||||
rc = file_write_and_wait_range(file, start, end);
|
||||
if (rc) {
|
||||
@ -3239,7 +3247,7 @@ int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
|
||||
file, datasync);
|
||||
|
||||
tcon = tlink_tcon(smbfile->tlink);
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) {
|
||||
if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOSSYNC)) {
|
||||
server = tcon->ses->server;
|
||||
if (server->ops->flush == NULL) {
|
||||
rc = -ENOSYS;
|
||||
@ -3490,7 +3498,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
|
||||
size_t start;
|
||||
unsigned int xid;
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_RWPIDFORWARD)
|
||||
pid = open_file->pid;
|
||||
else
|
||||
pid = current->tgid;
|
||||
@ -3753,7 +3761,7 @@ static ssize_t __cifs_writev(
|
||||
if (rc <= 0)
|
||||
return rc;
|
||||
|
||||
cifs_sb = CIFS_FILE_SB(file);
|
||||
cifs_sb = CIFS_SB(file);
|
||||
cfile = file->private_data;
|
||||
tcon = tlink_tcon(cfile->tlink);
|
||||
|
||||
@ -3851,7 +3859,7 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
struct cifsInodeInfo *cinode = CIFS_I(inode);
|
||||
struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
|
||||
ssize_t rc;
|
||||
|
||||
inode_lock(inode);
|
||||
@ -3865,7 +3873,7 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
|
||||
if (rc <= 0)
|
||||
goto out;
|
||||
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) &&
|
||||
if ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOPOSIXBRL) &&
|
||||
(cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(from),
|
||||
server->vals->exclusive_lock_type, 0,
|
||||
NULL, CIFS_WRITE_OP))) {
|
||||
@ -3889,7 +3897,7 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from)
|
||||
{
|
||||
struct inode *inode = file_inode(iocb->ki_filp);
|
||||
struct cifsInodeInfo *cinode = CIFS_I(inode);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
|
||||
struct cifsFileInfo *cfile = (struct cifsFileInfo *)
|
||||
iocb->ki_filp->private_data;
|
||||
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
|
||||
@ -3902,7 +3910,7 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from)
|
||||
if (CIFS_CACHE_WRITE(cinode)) {
|
||||
if (cap_unix(tcon->ses) &&
|
||||
(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability))
|
||||
&& ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) {
|
||||
&& ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOPOSIXBRL) == 0)) {
|
||||
written = generic_file_write_iter(iocb, from);
|
||||
goto out;
|
||||
}
|
||||
@ -4239,7 +4247,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
|
||||
|
||||
server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_RWPIDFORWARD)
|
||||
pid = open_file->pid;
|
||||
else
|
||||
pid = current->tgid;
|
||||
@ -4496,7 +4504,7 @@ static ssize_t __cifs_readv(
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
cifs_sb = CIFS_FILE_SB(file);
|
||||
cifs_sb = CIFS_SB(file);
|
||||
cfile = file->private_data;
|
||||
tcon = tlink_tcon(cfile->tlink);
|
||||
|
||||
@ -4597,7 +4605,7 @@ cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to)
|
||||
{
|
||||
struct inode *inode = file_inode(iocb->ki_filp);
|
||||
struct cifsInodeInfo *cinode = CIFS_I(inode);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
|
||||
struct cifsFileInfo *cfile = (struct cifsFileInfo *)
|
||||
iocb->ki_filp->private_data;
|
||||
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
|
||||
@ -4614,7 +4622,7 @@ cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to)
|
||||
if (!CIFS_CACHE_READ(cinode))
|
||||
return cifs_user_readv(iocb, to);
|
||||
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)
|
||||
if ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOPOSIXBRL) == 0)
|
||||
return generic_file_read_iter(iocb, to);
|
||||
|
||||
/*
|
||||
@ -4649,7 +4657,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
|
||||
__u32 pid;
|
||||
|
||||
xid = get_xid();
|
||||
cifs_sb = CIFS_FILE_SB(file);
|
||||
cifs_sb = CIFS_SB(file);
|
||||
|
||||
/* FIXME: set up handlers for larger reads and/or convert to async */
|
||||
rsize = min_t(unsigned int, cifs_sb->ctx->rsize, CIFSMaxBufSize);
|
||||
@ -4668,7 +4676,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_RWPIDFORWARD)
|
||||
pid = open_file->pid;
|
||||
else
|
||||
pid = current->tgid;
|
||||
@ -4924,7 +4932,7 @@ static void cifs_readahead(struct readahead_control *ractl)
|
||||
{
|
||||
int rc;
|
||||
struct cifsFileInfo *open_file = ractl->file->private_data;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(ractl->file);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(ractl->file);
|
||||
struct TCP_Server_Info *server;
|
||||
pid_t pid;
|
||||
unsigned int xid, nr_pages, last_batch_size = 0, cache_nr_pages = 0;
|
||||
@ -4935,7 +4943,7 @@ static void cifs_readahead(struct readahead_control *ractl)
|
||||
|
||||
xid = get_xid();
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_RWPIDFORWARD)
|
||||
pid = open_file->pid;
|
||||
else
|
||||
pid = current->tgid;
|
||||
@ -5181,16 +5189,28 @@ static int is_inode_writable(struct cifsInodeInfo *cifs_inode)
|
||||
bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file,
|
||||
bool from_readdir)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
unsigned long tlw;
|
||||
|
||||
if (!cifsInode)
|
||||
return true;
|
||||
|
||||
cifs_sb = CIFS_SB(cifsInode);
|
||||
|
||||
if (is_inode_writable(cifsInode) ||
|
||||
((cifsInode->oplock & CIFS_CACHE_RW_FLG) != 0 && from_readdir)) {
|
||||
/* This inode is open for write at least once */
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
|
||||
cifs_sb = CIFS_SB(cifsInode->netfs.inode.i_sb);
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
|
||||
/*
|
||||
* Readdir data is unreliable when we have writable handles or
|
||||
* an exclusive lease -- never allow it to change i_size, even
|
||||
* on direct-IO mounts where the server's directory metadata
|
||||
* can still lag behind the actual file state.
|
||||
*/
|
||||
if (from_readdir)
|
||||
return false;
|
||||
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_DIRECT_IO) {
|
||||
/* since no page cache to corrupt on directio
|
||||
we can change size safely */
|
||||
return true;
|
||||
@ -5200,8 +5220,40 @@ bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file,
|
||||
return true;
|
||||
|
||||
return false;
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* No writable handles open. Check whether we are within the attribute
|
||||
* cache validity window of a recent local modification.
|
||||
*
|
||||
* For the close() path: _cifsFileInfo_put() stamps time_last_write
|
||||
* (via smp_store_release()) before releasing open_file_lock. That
|
||||
* spin_unlock() is a store-release that pairs with the spin_lock()
|
||||
* (load-acquire) in is_inode_writable() above, so if
|
||||
* is_inode_writable() returned false the smp_load_acquire() below is
|
||||
* guaranteed to observe any time_last_write update from a concurrent
|
||||
* close(), covering all close paths including background I/O.
|
||||
*
|
||||
* For the setattr/truncate paths: those callers use smp_store_release()
|
||||
* directly; the smp_load_acquire() below pairs with that store. There
|
||||
* is no shared lock between setattr and readdir, so this relies on
|
||||
* acquire-release semantics alone. The store propagation latency on
|
||||
* weakly-ordered architectures (nanoseconds) is negligible relative to
|
||||
* the acregmax window (seconds) and the readdir RPC round-trip
|
||||
* (milliseconds), making this a sound design choice in practice.
|
||||
*
|
||||
* time_last_write == 0 means the inode has never been written locally;
|
||||
* skip the window check to avoid false positives near boot time when
|
||||
* jiffies is still close to INITIAL_JIFFIES on 32-bit systems.
|
||||
*/
|
||||
if (from_readdir) {
|
||||
/* Pairs with smp_store_release() in _cifsFileInfo_put() and setattr. */
|
||||
tlw = smp_load_acquire(&cifsInode->time_last_write);
|
||||
if (tlw && time_before(jiffies, tlw + cifs_sb->ctx->acregmax))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cifs_write_begin(struct file *file, struct address_space *mapping,
|
||||
@ -5355,7 +5407,7 @@ void cifs_oplock_break(struct work_struct *work)
|
||||
server = tcon->ses->server;
|
||||
|
||||
scoped_guard(spinlock, &cinode->open_file_lock) {
|
||||
unsigned int sbflags = cifs_sb->mnt_cifs_flags;
|
||||
unsigned int sbflags = cifs_sb_flags(cifs_sb);
|
||||
|
||||
server->ops->downgrade_oplock(server, cinode, cfile->oplock_level,
|
||||
cfile->oplock_epoch, &purge_cache);
|
||||
|
||||
@ -2084,161 +2084,160 @@ smb3_cleanup_fs_context(struct smb3_fs_context *ctx)
|
||||
kfree(ctx);
|
||||
}
|
||||
|
||||
void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb)
|
||||
unsigned int smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
unsigned int sbflags = cifs_sb_flags(cifs_sb);
|
||||
struct smb3_fs_context *ctx = cifs_sb->ctx;
|
||||
|
||||
if (ctx->nodfs)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_DFS;
|
||||
sbflags |= CIFS_MOUNT_NO_DFS;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_DFS;
|
||||
sbflags &= ~CIFS_MOUNT_NO_DFS;
|
||||
|
||||
if (ctx->noperm)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
|
||||
sbflags |= CIFS_MOUNT_NO_PERM;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_PERM;
|
||||
sbflags &= ~CIFS_MOUNT_NO_PERM;
|
||||
|
||||
if (ctx->setuids)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
|
||||
sbflags |= CIFS_MOUNT_SET_UID;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SET_UID;
|
||||
sbflags &= ~CIFS_MOUNT_SET_UID;
|
||||
|
||||
if (ctx->setuidfromacl)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UID_FROM_ACL;
|
||||
sbflags |= CIFS_MOUNT_UID_FROM_ACL;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_UID_FROM_ACL;
|
||||
sbflags &= ~CIFS_MOUNT_UID_FROM_ACL;
|
||||
|
||||
if (ctx->server_ino)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
|
||||
sbflags |= CIFS_MOUNT_SERVER_INUM;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
|
||||
sbflags &= ~CIFS_MOUNT_SERVER_INUM;
|
||||
|
||||
if (ctx->remap)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SFM_CHR;
|
||||
sbflags |= CIFS_MOUNT_MAP_SFM_CHR;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MAP_SFM_CHR;
|
||||
sbflags &= ~CIFS_MOUNT_MAP_SFM_CHR;
|
||||
|
||||
if (ctx->sfu_remap)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
|
||||
sbflags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MAP_SPECIAL_CHR;
|
||||
sbflags &= ~CIFS_MOUNT_MAP_SPECIAL_CHR;
|
||||
|
||||
if (ctx->no_xattr)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
|
||||
sbflags |= CIFS_MOUNT_NO_XATTR;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_XATTR;
|
||||
sbflags &= ~CIFS_MOUNT_NO_XATTR;
|
||||
|
||||
if (ctx->sfu_emul)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
|
||||
sbflags |= CIFS_MOUNT_UNX_EMUL;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_UNX_EMUL;
|
||||
sbflags &= ~CIFS_MOUNT_UNX_EMUL;
|
||||
|
||||
if (ctx->nobrl)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
|
||||
sbflags |= CIFS_MOUNT_NO_BRL;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_BRL;
|
||||
sbflags &= ~CIFS_MOUNT_NO_BRL;
|
||||
|
||||
if (ctx->nohandlecache)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_HANDLE_CACHE;
|
||||
sbflags |= CIFS_MOUNT_NO_HANDLE_CACHE;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_HANDLE_CACHE;
|
||||
sbflags &= ~CIFS_MOUNT_NO_HANDLE_CACHE;
|
||||
|
||||
if (ctx->nostrictsync)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
|
||||
sbflags |= CIFS_MOUNT_NOSSYNC;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NOSSYNC;
|
||||
sbflags &= ~CIFS_MOUNT_NOSSYNC;
|
||||
|
||||
if (ctx->mand_lock)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
|
||||
sbflags |= CIFS_MOUNT_NOPOSIXBRL;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NOPOSIXBRL;
|
||||
sbflags &= ~CIFS_MOUNT_NOPOSIXBRL;
|
||||
|
||||
if (ctx->rwpidforward)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
|
||||
sbflags |= CIFS_MOUNT_RWPIDFORWARD;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_RWPIDFORWARD;
|
||||
sbflags &= ~CIFS_MOUNT_RWPIDFORWARD;
|
||||
|
||||
if (ctx->mode_ace)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MODE_FROM_SID;
|
||||
sbflags |= CIFS_MOUNT_MODE_FROM_SID;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MODE_FROM_SID;
|
||||
sbflags &= ~CIFS_MOUNT_MODE_FROM_SID;
|
||||
|
||||
if (ctx->cifs_acl)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
|
||||
sbflags |= CIFS_MOUNT_CIFS_ACL;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_CIFS_ACL;
|
||||
sbflags &= ~CIFS_MOUNT_CIFS_ACL;
|
||||
|
||||
if (ctx->backupuid_specified)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID;
|
||||
sbflags |= CIFS_MOUNT_CIFS_BACKUPUID;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_CIFS_BACKUPUID;
|
||||
sbflags &= ~CIFS_MOUNT_CIFS_BACKUPUID;
|
||||
|
||||
if (ctx->backupgid_specified)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID;
|
||||
sbflags |= CIFS_MOUNT_CIFS_BACKUPGID;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_CIFS_BACKUPGID;
|
||||
sbflags &= ~CIFS_MOUNT_CIFS_BACKUPGID;
|
||||
|
||||
if (ctx->override_uid)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
|
||||
sbflags |= CIFS_MOUNT_OVERR_UID;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_OVERR_UID;
|
||||
sbflags &= ~CIFS_MOUNT_OVERR_UID;
|
||||
|
||||
if (ctx->override_gid)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
|
||||
sbflags |= CIFS_MOUNT_OVERR_GID;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_OVERR_GID;
|
||||
sbflags &= ~CIFS_MOUNT_OVERR_GID;
|
||||
|
||||
if (ctx->dynperm)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
|
||||
sbflags |= CIFS_MOUNT_DYNPERM;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_DYNPERM;
|
||||
sbflags &= ~CIFS_MOUNT_DYNPERM;
|
||||
|
||||
if (ctx->fsc)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
|
||||
sbflags |= CIFS_MOUNT_FSCACHE;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_FSCACHE;
|
||||
sbflags &= ~CIFS_MOUNT_FSCACHE;
|
||||
|
||||
if (ctx->multiuser)
|
||||
cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
|
||||
CIFS_MOUNT_NO_PERM);
|
||||
sbflags |= CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_NO_PERM;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MULTIUSER;
|
||||
sbflags &= ~CIFS_MOUNT_MULTIUSER;
|
||||
|
||||
|
||||
if (ctx->strict_io)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO;
|
||||
sbflags |= CIFS_MOUNT_STRICT_IO;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_STRICT_IO;
|
||||
sbflags &= ~CIFS_MOUNT_STRICT_IO;
|
||||
|
||||
if (ctx->direct_io)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
|
||||
sbflags |= CIFS_MOUNT_DIRECT_IO;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_DIRECT_IO;
|
||||
sbflags &= ~CIFS_MOUNT_DIRECT_IO;
|
||||
|
||||
if (ctx->mfsymlinks)
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
|
||||
sbflags |= CIFS_MOUNT_MF_SYMLINKS;
|
||||
else
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MF_SYMLINKS;
|
||||
if (ctx->mfsymlinks) {
|
||||
if (ctx->sfu_emul) {
|
||||
/*
|
||||
* Our SFU ("Services for Unix") emulation allows now
|
||||
* creating new and reading existing SFU symlinks.
|
||||
* Older Linux kernel versions were not able to neither
|
||||
* read existing nor create new SFU symlinks. But
|
||||
* creating and reading SFU style mknod and FIFOs was
|
||||
* supported for long time. When "mfsymlinks" and
|
||||
* "sfu" are both enabled at the same time, it allows
|
||||
* reading both types of symlinks, but will only create
|
||||
* them with mfsymlinks format. This allows better
|
||||
* Apple compatibility, compatibility with older Linux
|
||||
* kernel clients (probably better for Samba too)
|
||||
* while still recognizing old Windows style symlinks.
|
||||
*/
|
||||
cifs_dbg(VFS, "mount options mfsymlinks and sfu both enabled\n");
|
||||
}
|
||||
}
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SHUTDOWN;
|
||||
sbflags &= ~CIFS_MOUNT_MF_SYMLINKS;
|
||||
|
||||
return;
|
||||
if (ctx->mfsymlinks && ctx->sfu_emul) {
|
||||
/*
|
||||
* Our SFU ("Services for Unix") emulation allows now
|
||||
* creating new and reading existing SFU symlinks.
|
||||
* Older Linux kernel versions were not able to neither
|
||||
* read existing nor create new SFU symlinks. But
|
||||
* creating and reading SFU style mknod and FIFOs was
|
||||
* supported for long time. When "mfsymlinks" and
|
||||
* "sfu" are both enabled at the same time, it allows
|
||||
* reading both types of symlinks, but will only create
|
||||
* them with mfsymlinks format. This allows better
|
||||
* Apple compatibility, compatibility with older Linux
|
||||
* kernel clients (probably better for Samba too)
|
||||
* while still recognizing old Windows style symlinks.
|
||||
*/
|
||||
cifs_dbg(VFS, "mount options mfsymlinks and sfu both enabled\n");
|
||||
}
|
||||
sbflags &= ~CIFS_MOUNT_SHUTDOWN;
|
||||
atomic_set(&cifs_sb->mnt_cifs_flags, sbflags);
|
||||
return sbflags;
|
||||
}
|
||||
|
||||
@ -372,7 +372,7 @@ static inline struct smb3_fs_context *smb3_fc2context(const struct fs_context *f
|
||||
|
||||
extern int smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx);
|
||||
extern int smb3_sync_session_ctx_passwords(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses);
|
||||
extern void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb);
|
||||
unsigned int smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb);
|
||||
|
||||
/*
|
||||
* max deferred close timeout (jiffies) - 2^30
|
||||
|
||||
@ -30,30 +30,31 @@
|
||||
|
||||
static void cifs_set_ops(struct inode *inode)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
|
||||
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
|
||||
unsigned int sbflags = cifs_sb_flags(cifs_sb);
|
||||
|
||||
switch (inode->i_mode & S_IFMT) {
|
||||
case S_IFREG:
|
||||
inode->i_op = &cifs_file_inode_ops;
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
|
||||
if (sbflags & CIFS_MOUNT_DIRECT_IO) {
|
||||
if (sbflags & CIFS_MOUNT_NO_BRL)
|
||||
inode->i_fop = &cifs_file_direct_nobrl_ops;
|
||||
else
|
||||
inode->i_fop = &cifs_file_direct_ops;
|
||||
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) {
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
|
||||
} else if (sbflags & CIFS_MOUNT_STRICT_IO) {
|
||||
if (sbflags & CIFS_MOUNT_NO_BRL)
|
||||
inode->i_fop = &cifs_file_strict_nobrl_ops;
|
||||
else
|
||||
inode->i_fop = &cifs_file_strict_ops;
|
||||
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
|
||||
} else if (sbflags & CIFS_MOUNT_NO_BRL)
|
||||
inode->i_fop = &cifs_file_nobrl_ops;
|
||||
else { /* not direct, send byte range locks */
|
||||
inode->i_fop = &cifs_file_ops;
|
||||
}
|
||||
|
||||
/* check if server can support readahead */
|
||||
if (cifs_sb_master_tcon(cifs_sb)->ses->server->max_read <
|
||||
PAGE_SIZE + MAX_CIFS_HDR_SIZE)
|
||||
if (tcon->ses->server->max_read < PAGE_SIZE + MAX_CIFS_HDR_SIZE)
|
||||
inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
|
||||
else
|
||||
inode->i_data.a_ops = &cifs_addr_ops;
|
||||
@ -178,7 +179,7 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr,
|
||||
|
||||
/* if dynperm is set, don't clobber existing mode */
|
||||
if (inode->i_state & I_NEW ||
|
||||
!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM))
|
||||
!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_DYNPERM))
|
||||
inode->i_mode = fattr->cf_mode;
|
||||
|
||||
cifs_i->cifsAttrs = fattr->cf_cifsattrs;
|
||||
@ -208,6 +209,8 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr,
|
||||
* calculating num blocks.
|
||||
*/
|
||||
inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;
|
||||
} else if (from_readdir && i_size_read(inode) != fattr->cf_eof) {
|
||||
cifs_i->time = 0;
|
||||
}
|
||||
|
||||
if (S_ISLNK(fattr->cf_mode) && fattr->cf_symlink_target) {
|
||||
@ -229,10 +232,8 @@ cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
|
||||
return;
|
||||
|
||||
fattr->cf_uniqueid = iunique(sb, ROOT_I);
|
||||
if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_SERVER_INUM))
|
||||
fattr->cf_uniqueid = iunique(sb, ROOT_I);
|
||||
}
|
||||
|
||||
/* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */
|
||||
@ -240,6 +241,8 @@ void
|
||||
cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
|
||||
struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
unsigned int sbflags;
|
||||
|
||||
memset(fattr, 0, sizeof(*fattr));
|
||||
fattr->cf_uniqueid = le64_to_cpu(info->UniqueId);
|
||||
fattr->cf_bytes = le64_to_cpu(info->NumOfBytes);
|
||||
@ -298,8 +301,9 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
|
||||
break;
|
||||
}
|
||||
|
||||
sbflags = cifs_sb_flags(cifs_sb);
|
||||
fattr->cf_uid = cifs_sb->ctx->linux_uid;
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) {
|
||||
if (!(sbflags & CIFS_MOUNT_OVERR_UID)) {
|
||||
u64 id = le64_to_cpu(info->Uid);
|
||||
if (id < ((uid_t)-1)) {
|
||||
kuid_t uid = make_kuid(&init_user_ns, id);
|
||||
@ -309,7 +313,7 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
|
||||
}
|
||||
|
||||
fattr->cf_gid = cifs_sb->ctx->linux_gid;
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) {
|
||||
if (!(sbflags & CIFS_MOUNT_OVERR_GID)) {
|
||||
u64 id = le64_to_cpu(info->Gid);
|
||||
if (id < ((gid_t)-1)) {
|
||||
kgid_t gid = make_kgid(&init_user_ns, id);
|
||||
@ -363,7 +367,7 @@ static int update_inode_info(struct super_block *sb,
|
||||
*
|
||||
* If file type or uniqueid is different, return error.
|
||||
*/
|
||||
if (unlikely((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
|
||||
if (unlikely((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_SERVER_INUM) &&
|
||||
CIFS_I(*inode)->uniqueid != fattr->cf_uniqueid)) {
|
||||
CIFS_I(*inode)->time = 0; /* force reval */
|
||||
return -ESTALE;
|
||||
@ -449,7 +453,7 @@ static int cifs_get_unix_fattr(const unsigned char *full_path,
|
||||
cifs_fill_uniqueid(sb, fattr);
|
||||
|
||||
/* check for Minshall+French symlinks */
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_MF_SYMLINKS) {
|
||||
tmprc = check_mf_symlink(xid, tcon, cifs_sb, fattr, full_path);
|
||||
cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc);
|
||||
}
|
||||
@ -1062,7 +1066,7 @@ cifs_backup_query_path_info(int xid,
|
||||
else if ((tcon->ses->capabilities &
|
||||
tcon->ses->server->vals->cap_nt_find) == 0)
|
||||
info.info_level = SMB_FIND_FILE_INFO_STANDARD;
|
||||
else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
|
||||
else if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_SERVER_INUM)
|
||||
info.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;
|
||||
else /* no srvino useful for fallback to some netapp */
|
||||
info.info_level = SMB_FIND_FILE_DIRECTORY_INFO;
|
||||
@ -1090,7 +1094,7 @@ static void cifs_set_fattr_ino(int xid, struct cifs_tcon *tcon, struct super_blo
|
||||
struct TCP_Server_Info *server = tcon->ses->server;
|
||||
int rc;
|
||||
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
|
||||
if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_SERVER_INUM)) {
|
||||
if (*inode)
|
||||
fattr->cf_uniqueid = CIFS_I(*inode)->uniqueid;
|
||||
else
|
||||
@ -1244,14 +1248,15 @@ static int cifs_get_fattr(struct cifs_open_info_data *data,
|
||||
struct inode **inode,
|
||||
const char *full_path)
|
||||
{
|
||||
struct cifs_open_info_data tmp_data = {};
|
||||
struct cifs_tcon *tcon;
|
||||
struct TCP_Server_Info *server;
|
||||
struct tcon_link *tlink;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
|
||||
struct cifs_open_info_data tmp_data = {};
|
||||
void *smb1_backup_rsp_buf = NULL;
|
||||
int rc = 0;
|
||||
struct TCP_Server_Info *server;
|
||||
struct cifs_tcon *tcon;
|
||||
struct tcon_link *tlink;
|
||||
unsigned int sbflags;
|
||||
int tmprc = 0;
|
||||
int rc = 0;
|
||||
|
||||
tlink = cifs_sb_tlink(cifs_sb);
|
||||
if (IS_ERR(tlink))
|
||||
@ -1351,16 +1356,17 @@ static int cifs_get_fattr(struct cifs_open_info_data *data,
|
||||
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
|
||||
handle_mnt_opt:
|
||||
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
|
||||
sbflags = cifs_sb_flags(cifs_sb);
|
||||
/* query for SFU type info if supported and needed */
|
||||
if ((fattr->cf_cifsattrs & ATTR_SYSTEM) &&
|
||||
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) {
|
||||
(sbflags & CIFS_MOUNT_UNX_EMUL)) {
|
||||
tmprc = cifs_sfu_type(fattr, full_path, cifs_sb, xid);
|
||||
if (tmprc)
|
||||
cifs_dbg(FYI, "cifs_sfu_type failed: %d\n", tmprc);
|
||||
}
|
||||
|
||||
/* fill in 0777 bits from ACL */
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) {
|
||||
if (sbflags & CIFS_MOUNT_MODE_FROM_SID) {
|
||||
rc = cifs_acl_to_fattr(cifs_sb, fattr, *inode,
|
||||
true, full_path, fid);
|
||||
if (rc == -EREMOTE)
|
||||
@ -1370,7 +1376,7 @@ handle_mnt_opt:
|
||||
__func__, rc);
|
||||
goto out;
|
||||
}
|
||||
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
|
||||
} else if (sbflags & CIFS_MOUNT_CIFS_ACL) {
|
||||
rc = cifs_acl_to_fattr(cifs_sb, fattr, *inode,
|
||||
false, full_path, fid);
|
||||
if (rc == -EREMOTE)
|
||||
@ -1380,7 +1386,7 @@ handle_mnt_opt:
|
||||
__func__, rc);
|
||||
goto out;
|
||||
}
|
||||
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
|
||||
} else if (sbflags & CIFS_MOUNT_UNX_EMUL)
|
||||
/* fill in remaining high mode bits e.g. SUID, VTX */
|
||||
cifs_sfu_mode(fattr, full_path, cifs_sb, xid);
|
||||
else if (!(tcon->posix_extensions))
|
||||
@ -1390,7 +1396,7 @@ handle_mnt_opt:
|
||||
|
||||
|
||||
/* check for Minshall+French symlinks */
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
|
||||
if (sbflags & CIFS_MOUNT_MF_SYMLINKS) {
|
||||
tmprc = check_mf_symlink(xid, tcon, cifs_sb, fattr, full_path);
|
||||
cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc);
|
||||
}
|
||||
@ -1490,7 +1496,7 @@ static int smb311_posix_get_fattr(struct cifs_open_info_data *data,
|
||||
* 3. Tweak fattr based on mount options
|
||||
*/
|
||||
/* check for Minshall+French symlinks */
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_MF_SYMLINKS) {
|
||||
tmprc = check_mf_symlink(xid, tcon, cifs_sb, fattr, full_path);
|
||||
cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc);
|
||||
}
|
||||
@ -1641,7 +1647,7 @@ struct inode *cifs_root_iget(struct super_block *sb)
|
||||
int len;
|
||||
int rc;
|
||||
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH)
|
||||
if ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_USE_PREFIX_PATH)
|
||||
&& cifs_sb->prepath) {
|
||||
len = strlen(cifs_sb->prepath);
|
||||
path = kzalloc(len + 2 /* leading sep + null */, GFP_KERNEL);
|
||||
@ -2078,8 +2084,9 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode,
|
||||
const char *full_path, struct cifs_sb_info *cifs_sb,
|
||||
struct cifs_tcon *tcon, const unsigned int xid)
|
||||
{
|
||||
int rc = 0;
|
||||
struct inode *inode = NULL;
|
||||
unsigned int sbflags;
|
||||
int rc = 0;
|
||||
|
||||
if (tcon->posix_extensions) {
|
||||
rc = smb311_posix_get_inode_info(&inode, full_path,
|
||||
@ -2119,6 +2126,7 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode,
|
||||
if (parent->i_mode & S_ISGID)
|
||||
mode |= S_ISGID;
|
||||
|
||||
sbflags = cifs_sb_flags(cifs_sb);
|
||||
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
|
||||
if (tcon->unix_ext) {
|
||||
struct cifs_unix_set_info_args args = {
|
||||
@ -2128,7 +2136,7 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode,
|
||||
.mtime = NO_CHANGE_64,
|
||||
.device = 0,
|
||||
};
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
||||
if (sbflags & CIFS_MOUNT_SET_UID) {
|
||||
args.uid = current_fsuid();
|
||||
if (parent->i_mode & S_ISGID)
|
||||
args.gid = parent->i_gid;
|
||||
@ -2146,14 +2154,14 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode,
|
||||
{
|
||||
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
|
||||
struct TCP_Server_Info *server = tcon->ses->server;
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
|
||||
if (!(sbflags & CIFS_MOUNT_CIFS_ACL) &&
|
||||
(mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo)
|
||||
server->ops->mkdir_setinfo(inode, full_path, cifs_sb,
|
||||
tcon, xid);
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
|
||||
if (sbflags & CIFS_MOUNT_DYNPERM)
|
||||
inode->i_mode = (mode | S_IFDIR);
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
||||
if (sbflags & CIFS_MOUNT_SET_UID) {
|
||||
inode->i_uid = current_fsuid();
|
||||
if (inode->i_mode & S_ISGID)
|
||||
inode->i_gid = parent->i_gid;
|
||||
@ -2668,7 +2676,7 @@ cifs_dentry_needs_reval(struct dentry *dentry)
|
||||
{
|
||||
struct inode *inode = d_inode(dentry);
|
||||
struct cifsInodeInfo *cifs_i = CIFS_I(inode);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
|
||||
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
|
||||
struct cached_fid *cfid = NULL;
|
||||
|
||||
@ -2709,7 +2717,7 @@ cifs_dentry_needs_reval(struct dentry *dentry)
|
||||
}
|
||||
|
||||
/* hardlinked files w/ noserverino get "special" treatment */
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
|
||||
if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_SERVER_INUM) &&
|
||||
S_ISREG(inode->i_mode) && inode->i_nlink != 1)
|
||||
return true;
|
||||
|
||||
@ -2752,9 +2760,9 @@ cifs_wait_bit_killable(struct wait_bit_key *key, int mode)
|
||||
int
|
||||
cifs_revalidate_mapping(struct inode *inode)
|
||||
{
|
||||
int rc;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
|
||||
unsigned long *flags = &CIFS_I(inode)->flags;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
int rc;
|
||||
|
||||
/* swapfiles are not supposed to be shared */
|
||||
if (IS_SWAPFILE(inode))
|
||||
@ -2767,7 +2775,7 @@ cifs_revalidate_mapping(struct inode *inode)
|
||||
|
||||
if (test_and_clear_bit(CIFS_INO_INVALID_MAPPING, flags)) {
|
||||
/* for cache=singleclient, do not invalidate */
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE)
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_RW_CACHE)
|
||||
goto skip_invalidate;
|
||||
|
||||
rc = cifs_invalidate_mapping(inode);
|
||||
@ -2887,10 +2895,11 @@ int cifs_revalidate_dentry(struct dentry *dentry)
|
||||
int cifs_getattr(struct mnt_idmap *idmap, const struct path *path,
|
||||
struct kstat *stat, u32 request_mask, unsigned int flags)
|
||||
{
|
||||
struct dentry *dentry = path->dentry;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(path->dentry);
|
||||
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
|
||||
struct dentry *dentry = path->dentry;
|
||||
struct inode *inode = d_inode(dentry);
|
||||
unsigned int sbflags;
|
||||
int rc;
|
||||
|
||||
if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))
|
||||
@ -2947,12 +2956,13 @@ int cifs_getattr(struct mnt_idmap *idmap, const struct path *path,
|
||||
* enabled, and the admin hasn't overridden them, set the ownership
|
||||
* to the fsuid/fsgid of the current process.
|
||||
*/
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) &&
|
||||
!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
|
||||
sbflags = cifs_sb_flags(cifs_sb);
|
||||
if ((sbflags & CIFS_MOUNT_MULTIUSER) &&
|
||||
!(sbflags & CIFS_MOUNT_CIFS_ACL) &&
|
||||
!tcon->unix_ext) {
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID))
|
||||
if (!(sbflags & CIFS_MOUNT_OVERR_UID))
|
||||
stat->uid = current_fsuid();
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID))
|
||||
if (!(sbflags & CIFS_MOUNT_OVERR_GID))
|
||||
stat->gid = current_fsgid();
|
||||
}
|
||||
return 0;
|
||||
@ -3096,7 +3106,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
|
||||
void *page = alloc_dentry_path();
|
||||
struct inode *inode = d_inode(direntry);
|
||||
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
|
||||
struct tcon_link *tlink;
|
||||
struct cifs_tcon *pTcon;
|
||||
struct cifs_unix_set_info_args *args = NULL;
|
||||
@ -3107,7 +3117,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
|
||||
|
||||
xid = get_xid();
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NO_PERM)
|
||||
attrs->ia_valid |= ATTR_FORCE;
|
||||
|
||||
rc = setattr_prepare(&nop_mnt_idmap, direntry, attrs);
|
||||
@ -3144,6 +3154,17 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
|
||||
rc = 0;
|
||||
|
||||
if (attrs->ia_valid & ATTR_SIZE) {
|
||||
if (attrs->ia_size != i_size_read(inode)) {
|
||||
/* Stamp before RPC. On failure the stamp remains: restoring a
|
||||
* stale snapshot could silently erase a concurrent
|
||||
* _cifsFileInfo_put() close stamp. readdir is suppressed
|
||||
* until the stamp expires; stat() bypasses this via the
|
||||
* from_readdir=false path in is_size_safe_to_change() and
|
||||
* always returns an authoritative QUERY_INFO result.
|
||||
* Pairs with smp_load_acquire() in is_size_safe_to_change().
|
||||
*/
|
||||
smp_store_release(&cifsInode->time_last_write, jiffies);
|
||||
}
|
||||
rc = cifs_file_set_size(xid, direntry, full_path,
|
||||
open_file, attrs->ia_size);
|
||||
if (rc != 0)
|
||||
@ -3260,26 +3281,26 @@ out:
|
||||
static int
|
||||
cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
||||
{
|
||||
unsigned int xid;
|
||||
struct inode *inode = d_inode(direntry);
|
||||
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
|
||||
unsigned int sbflags = cifs_sb_flags(cifs_sb);
|
||||
struct cifsFileInfo *cfile = NULL;
|
||||
void *page = alloc_dentry_path();
|
||||
__u64 mode = NO_CHANGE_64;
|
||||
kuid_t uid = INVALID_UID;
|
||||
kgid_t gid = INVALID_GID;
|
||||
struct inode *inode = d_inode(direntry);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
|
||||
struct cifsFileInfo *cfile = NULL;
|
||||
const char *full_path;
|
||||
void *page = alloc_dentry_path();
|
||||
int rc = -EACCES;
|
||||
__u32 dosattr = 0;
|
||||
__u64 mode = NO_CHANGE_64;
|
||||
bool posix = cifs_sb_master_tcon(cifs_sb)->posix_extensions;
|
||||
int rc = -EACCES;
|
||||
unsigned int xid;
|
||||
|
||||
xid = get_xid();
|
||||
|
||||
cifs_dbg(FYI, "setattr on file %pd attrs->ia_valid 0x%x\n",
|
||||
direntry, attrs->ia_valid);
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
|
||||
if (sbflags & CIFS_MOUNT_NO_PERM)
|
||||
attrs->ia_valid |= ATTR_FORCE;
|
||||
|
||||
rc = setattr_prepare(&nop_mnt_idmap, direntry, attrs);
|
||||
@ -3322,6 +3343,17 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
||||
}
|
||||
|
||||
if (attrs->ia_valid & ATTR_SIZE) {
|
||||
if (attrs->ia_size != i_size_read(inode)) {
|
||||
/* Stamp before RPC. On failure the stamp remains: restoring a
|
||||
* stale snapshot could silently erase a concurrent
|
||||
* _cifsFileInfo_put() close stamp. readdir is suppressed
|
||||
* until the stamp expires; stat() bypasses this via the
|
||||
* from_readdir=false path in is_size_safe_to_change() and
|
||||
* always returns an authoritative QUERY_INFO result.
|
||||
* Pairs with smp_load_acquire() in is_size_safe_to_change().
|
||||
*/
|
||||
smp_store_release(&cifsInode->time_last_write, jiffies);
|
||||
}
|
||||
rc = cifs_file_set_size(xid, direntry, full_path,
|
||||
cfile, attrs->ia_size);
|
||||
if (rc != 0)
|
||||
@ -3340,8 +3372,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
||||
if (attrs->ia_valid & ATTR_GID)
|
||||
gid = attrs->ia_gid;
|
||||
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) ||
|
||||
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) {
|
||||
if (sbflags & (CIFS_MOUNT_CIFS_ACL | CIFS_MOUNT_MODE_FROM_SID)) {
|
||||
if (uid_valid(uid) || gid_valid(gid)) {
|
||||
mode = NO_CHANGE_64;
|
||||
rc = id_mode_to_cifs_acl(inode, full_path, &mode,
|
||||
@ -3352,9 +3383,9 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
||||
goto cifs_setattr_exit;
|
||||
}
|
||||
}
|
||||
} else
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID))
|
||||
} else if (!(sbflags & CIFS_MOUNT_SET_UID)) {
|
||||
attrs->ia_valid &= ~(ATTR_UID | ATTR_GID);
|
||||
}
|
||||
|
||||
/* skip mode change if it's just for clearing setuid/setgid */
|
||||
if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
|
||||
@ -3363,9 +3394,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
||||
if (attrs->ia_valid & ATTR_MODE) {
|
||||
mode = attrs->ia_mode;
|
||||
rc = 0;
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) ||
|
||||
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) ||
|
||||
posix) {
|
||||
if ((sbflags & (CIFS_MOUNT_CIFS_ACL | CIFS_MOUNT_MODE_FROM_SID)) ||
|
||||
cifs_sb_master_tcon(cifs_sb)->posix_extensions) {
|
||||
rc = id_mode_to_cifs_acl(inode, full_path, &mode,
|
||||
INVALID_UID, INVALID_GID);
|
||||
if (rc) {
|
||||
@ -3387,7 +3417,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
||||
dosattr = cifsInode->cifsAttrs | ATTR_READONLY;
|
||||
|
||||
/* fix up mode if we're not using dynperm */
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
|
||||
if ((sbflags & CIFS_MOUNT_DYNPERM) == 0)
|
||||
attrs->ia_mode = inode->i_mode & ~S_IWUGO;
|
||||
} else if ((mode & S_IWUGO) &&
|
||||
(cifsInode->cifsAttrs & ATTR_READONLY)) {
|
||||
@ -3398,7 +3428,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
||||
dosattr |= ATTR_NORMAL;
|
||||
|
||||
/* reset local inode permissions to normal */
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
|
||||
if (!(sbflags & CIFS_MOUNT_DYNPERM)) {
|
||||
attrs->ia_mode &= ~(S_IALLUGO);
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
attrs->ia_mode |=
|
||||
@ -3407,7 +3437,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
||||
attrs->ia_mode |=
|
||||
cifs_sb->ctx->file_mode;
|
||||
}
|
||||
} else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
|
||||
} else if (!(sbflags & CIFS_MOUNT_DYNPERM)) {
|
||||
/* ignore mode change - ATTR_READONLY hasn't changed */
|
||||
attrs->ia_valid &= ~ATTR_MODE;
|
||||
}
|
||||
|
||||
@ -220,7 +220,7 @@ static int cifs_shutdown(struct super_block *sb, unsigned long arg)
|
||||
*/
|
||||
case CIFS_GOING_FLAGS_LOGFLUSH:
|
||||
case CIFS_GOING_FLAGS_NOLOGFLUSH:
|
||||
sbi->mnt_cifs_flags |= CIFS_MOUNT_SHUTDOWN;
|
||||
atomic_or(CIFS_MOUNT_SHUTDOWN, &sbi->mnt_cifs_flags);
|
||||
goto shutdown_good;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
|
||||
@ -568,14 +568,15 @@ int
|
||||
cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
|
||||
struct dentry *direntry, const char *symname)
|
||||
{
|
||||
int rc = -EOPNOTSUPP;
|
||||
unsigned int xid;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
|
||||
struct inode *newinode = NULL;
|
||||
struct tcon_link *tlink;
|
||||
struct cifs_tcon *pTcon;
|
||||
const char *full_path;
|
||||
int rc = -EOPNOTSUPP;
|
||||
unsigned int sbflags;
|
||||
unsigned int xid;
|
||||
void *page;
|
||||
struct inode *newinode = NULL;
|
||||
|
||||
if (unlikely(cifs_forced_shutdown(cifs_sb)))
|
||||
return -EIO;
|
||||
@ -604,6 +605,7 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
|
||||
cifs_dbg(FYI, "symname is %s\n", symname);
|
||||
|
||||
/* BB what if DFS and this volume is on different share? BB */
|
||||
sbflags = cifs_sb_flags(cifs_sb);
|
||||
rc = -EOPNOTSUPP;
|
||||
switch (cifs_symlink_type(cifs_sb)) {
|
||||
case CIFS_SYMLINK_TYPE_UNIX:
|
||||
@ -618,14 +620,14 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
|
||||
break;
|
||||
|
||||
case CIFS_SYMLINK_TYPE_MFSYMLINKS:
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
|
||||
if (sbflags & CIFS_MOUNT_MF_SYMLINKS) {
|
||||
rc = create_mf_symlink(xid, pTcon, cifs_sb,
|
||||
full_path, symname);
|
||||
}
|
||||
break;
|
||||
|
||||
case CIFS_SYMLINK_TYPE_SFU:
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
|
||||
if (sbflags & CIFS_MOUNT_UNX_EMUL) {
|
||||
rc = __cifs_sfu_make_node(xid, inode, direntry, pTcon,
|
||||
full_path, S_IFLNK,
|
||||
0, symname);
|
||||
|
||||
@ -561,13 +561,15 @@ dump_smb(void *buf, int smb_buf_length)
|
||||
void
|
||||
cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
|
||||
unsigned int sbflags = cifs_sb_flags(cifs_sb);
|
||||
|
||||
if (sbflags & CIFS_MOUNT_SERVER_INUM) {
|
||||
struct cifs_tcon *tcon = NULL;
|
||||
|
||||
if (cifs_sb->master_tlink)
|
||||
tcon = cifs_sb_master_tcon(cifs_sb);
|
||||
|
||||
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
|
||||
atomic_andnot(CIFS_MOUNT_SERVER_INUM, &cifs_sb->mnt_cifs_flags);
|
||||
cifs_sb->mnt_cifs_serverino_autodisabled = true;
|
||||
cifs_dbg(VFS, "Autodisabling the use of server inode numbers on %s\n",
|
||||
tcon ? tcon->tree_name : "new server");
|
||||
@ -668,11 +670,13 @@ void cifs_done_oplock_break(struct cifsInodeInfo *cinode)
|
||||
bool
|
||||
backup_cred(struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) {
|
||||
unsigned int sbflags = cifs_sb_flags(cifs_sb);
|
||||
|
||||
if (sbflags & CIFS_MOUNT_CIFS_BACKUPUID) {
|
||||
if (uid_eq(cifs_sb->ctx->backupuid, current_fsuid()))
|
||||
return true;
|
||||
}
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) {
|
||||
if (sbflags & CIFS_MOUNT_CIFS_BACKUPGID) {
|
||||
if (in_group_p(cifs_sb->ctx->backupgid))
|
||||
return true;
|
||||
}
|
||||
@ -770,7 +774,7 @@ cifs_del_deferred_close(struct cifsFileInfo *cfile)
|
||||
void
|
||||
cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode)
|
||||
{
|
||||
struct cifsFileInfo *cfile = NULL;
|
||||
struct cifsFileInfo *cfile = NULL, *failed_cfile = NULL;
|
||||
struct file_list *tmp_list, *tmp_next_list;
|
||||
LIST_HEAD(file_head);
|
||||
|
||||
@ -786,8 +790,10 @@ cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode)
|
||||
spin_unlock(&cifs_inode->deferred_lock);
|
||||
|
||||
tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
|
||||
if (tmp_list == NULL)
|
||||
if (tmp_list == NULL) {
|
||||
failed_cfile = cfile;
|
||||
break;
|
||||
}
|
||||
tmp_list->cfile = cfile;
|
||||
list_add_tail(&tmp_list->list, &file_head);
|
||||
}
|
||||
@ -795,6 +801,9 @@ cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode)
|
||||
}
|
||||
spin_unlock(&cifs_inode->open_file_lock);
|
||||
|
||||
if (failed_cfile)
|
||||
_cifsFileInfo_put(failed_cfile, false, false);
|
||||
|
||||
list_for_each_entry_safe(tmp_list, tmp_next_list, &file_head, list) {
|
||||
_cifsFileInfo_put(tmp_list->cfile, false, false);
|
||||
list_del(&tmp_list->list);
|
||||
@ -805,7 +814,7 @@ cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode)
|
||||
void
|
||||
cifs_close_all_deferred_files(struct cifs_tcon *tcon)
|
||||
{
|
||||
struct cifsFileInfo *cfile;
|
||||
struct cifsFileInfo *cfile, *failed_cfile = NULL;
|
||||
struct file_list *tmp_list, *tmp_next_list;
|
||||
LIST_HEAD(file_head);
|
||||
|
||||
@ -818,8 +827,10 @@ cifs_close_all_deferred_files(struct cifs_tcon *tcon)
|
||||
spin_unlock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
|
||||
|
||||
tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
|
||||
if (tmp_list == NULL)
|
||||
if (tmp_list == NULL) {
|
||||
failed_cfile = cfile;
|
||||
break;
|
||||
}
|
||||
tmp_list->cfile = cfile;
|
||||
list_add_tail(&tmp_list->list, &file_head);
|
||||
}
|
||||
@ -827,6 +838,9 @@ cifs_close_all_deferred_files(struct cifs_tcon *tcon)
|
||||
}
|
||||
spin_unlock(&tcon->open_file_lock);
|
||||
|
||||
if (failed_cfile)
|
||||
_cifsFileInfo_put(failed_cfile, true, false);
|
||||
|
||||
list_for_each_entry_safe(tmp_list, tmp_next_list, &file_head, list) {
|
||||
_cifsFileInfo_put(tmp_list->cfile, true, false);
|
||||
list_del(&tmp_list->list);
|
||||
@ -838,7 +852,7 @@ void cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon,
|
||||
struct dentry *dentry)
|
||||
{
|
||||
struct file_list *tmp_list, *tmp_next_list;
|
||||
struct cifsFileInfo *cfile;
|
||||
struct cifsFileInfo *cfile, *failed_cfile = NULL;
|
||||
LIST_HEAD(file_head);
|
||||
|
||||
spin_lock(&tcon->open_file_lock);
|
||||
@ -851,14 +865,19 @@ void cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon,
|
||||
spin_unlock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
|
||||
|
||||
tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
|
||||
if (tmp_list == NULL)
|
||||
if (tmp_list == NULL) {
|
||||
failed_cfile = cfile;
|
||||
break;
|
||||
}
|
||||
tmp_list->cfile = cfile;
|
||||
list_add_tail(&tmp_list->list, &file_head);
|
||||
}
|
||||
}
|
||||
spin_unlock(&tcon->open_file_lock);
|
||||
|
||||
if (failed_cfile)
|
||||
_cifsFileInfo_put(failed_cfile, true, false);
|
||||
|
||||
list_for_each_entry_safe(tmp_list, tmp_next_list, &file_head, list) {
|
||||
_cifsFileInfo_put(tmp_list->cfile, true, false);
|
||||
list_del(&tmp_list->list);
|
||||
@ -1395,7 +1414,7 @@ int cifs_update_super_prepath(struct cifs_sb_info *cifs_sb, char *prefix)
|
||||
convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
|
||||
}
|
||||
|
||||
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
|
||||
atomic_or(CIFS_MOUNT_USE_PREFIX_PATH, &cifs_sb->mnt_cifs_flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1424,7 +1443,7 @@ int cifs_inval_name_dfs_link_error(const unsigned int xid,
|
||||
* look up or tcon is not DFS.
|
||||
*/
|
||||
if (strlen(full_path) < 2 || !cifs_sb ||
|
||||
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) ||
|
||||
(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NO_DFS) ||
|
||||
!is_tcon_dfs(tcon))
|
||||
return 0;
|
||||
|
||||
|
||||
@ -121,7 +121,7 @@ retry:
|
||||
* want to clobber the existing one with the one that
|
||||
* the readdir code created.
|
||||
*/
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM))
|
||||
if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_SERVER_INUM))
|
||||
fattr->cf_uniqueid = CIFS_I(inode)->uniqueid;
|
||||
|
||||
/*
|
||||
@ -177,6 +177,7 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
|
||||
struct cifs_open_info_data data = {
|
||||
.reparse = { .tag = fattr->cf_cifstag, },
|
||||
};
|
||||
unsigned int sbflags;
|
||||
|
||||
fattr->cf_uid = cifs_sb->ctx->linux_uid;
|
||||
fattr->cf_gid = cifs_sb->ctx->linux_gid;
|
||||
@ -215,12 +216,12 @@ out_reparse:
|
||||
* may look wrong since the inodes may not have timed out by the time
|
||||
* "ls" does a stat() call on them.
|
||||
*/
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) ||
|
||||
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID))
|
||||
sbflags = cifs_sb_flags(cifs_sb);
|
||||
if (sbflags & (CIFS_MOUNT_CIFS_ACL | CIFS_MOUNT_MODE_FROM_SID))
|
||||
fattr->cf_flags |= CIFS_FATTR_NEED_REVAL;
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL &&
|
||||
fattr->cf_cifsattrs & ATTR_SYSTEM) {
|
||||
if ((sbflags & CIFS_MOUNT_UNX_EMUL) &&
|
||||
(fattr->cf_cifsattrs & ATTR_SYSTEM)) {
|
||||
if (fattr->cf_eof == 0) {
|
||||
fattr->cf_mode &= ~S_IFMT;
|
||||
fattr->cf_mode |= S_IFIFO;
|
||||
@ -345,13 +346,14 @@ static int
|
||||
_initiate_cifs_search(const unsigned int xid, struct file *file,
|
||||
const char *full_path)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(file);
|
||||
struct tcon_link *tlink = NULL;
|
||||
struct TCP_Server_Info *server;
|
||||
struct cifsFileInfo *cifsFile;
|
||||
struct cifs_tcon *tcon;
|
||||
unsigned int sbflags;
|
||||
__u16 search_flags;
|
||||
int rc = 0;
|
||||
struct cifsFileInfo *cifsFile;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
|
||||
struct tcon_link *tlink = NULL;
|
||||
struct cifs_tcon *tcon;
|
||||
struct TCP_Server_Info *server;
|
||||
|
||||
if (file->private_data == NULL) {
|
||||
tlink = cifs_sb_tlink(cifs_sb);
|
||||
@ -385,6 +387,7 @@ _initiate_cifs_search(const unsigned int xid, struct file *file,
|
||||
cifs_dbg(FYI, "Full path: %s start at: %lld\n", full_path, file->f_pos);
|
||||
|
||||
ffirst_retry:
|
||||
sbflags = cifs_sb_flags(cifs_sb);
|
||||
/* test for Unix extensions */
|
||||
/* but now check for them on the share/mount not on the SMB session */
|
||||
/* if (cap_unix(tcon->ses) { */
|
||||
@ -395,7 +398,7 @@ ffirst_retry:
|
||||
else if ((tcon->ses->capabilities &
|
||||
tcon->ses->server->vals->cap_nt_find) == 0) {
|
||||
cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD;
|
||||
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
|
||||
} else if (sbflags & CIFS_MOUNT_SERVER_INUM) {
|
||||
cifsFile->srch_inf.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;
|
||||
} else /* not srvinos - BB fixme add check for backlevel? */ {
|
||||
cifsFile->srch_inf.info_level = SMB_FIND_FILE_FULL_DIRECTORY_INFO;
|
||||
@ -411,8 +414,7 @@ ffirst_retry:
|
||||
|
||||
if (rc == 0) {
|
||||
cifsFile->invalidHandle = false;
|
||||
} else if ((rc == -EOPNOTSUPP) &&
|
||||
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
|
||||
} else if (rc == -EOPNOTSUPP && (sbflags & CIFS_MOUNT_SERVER_INUM)) {
|
||||
cifs_autodisable_serverino(cifs_sb);
|
||||
goto ffirst_retry;
|
||||
}
|
||||
@ -690,7 +692,7 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos,
|
||||
loff_t first_entry_in_buffer;
|
||||
loff_t index_to_find = pos;
|
||||
struct cifsFileInfo *cfile = file->private_data;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(file);
|
||||
struct TCP_Server_Info *server = tcon->ses->server;
|
||||
/* check if index in the buffer */
|
||||
|
||||
@ -955,6 +957,7 @@ static int cifs_filldir(char *find_entry, struct file *file,
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
|
||||
struct cifs_dirent de = { NULL, };
|
||||
struct cifs_fattr fattr;
|
||||
unsigned int sbflags;
|
||||
struct qstr name;
|
||||
int rc = 0;
|
||||
|
||||
@ -1019,15 +1022,15 @@ static int cifs_filldir(char *find_entry, struct file *file,
|
||||
break;
|
||||
}
|
||||
|
||||
if (de.ino && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
|
||||
sbflags = cifs_sb_flags(cifs_sb);
|
||||
if (de.ino && (sbflags & CIFS_MOUNT_SERVER_INUM)) {
|
||||
fattr.cf_uniqueid = de.ino;
|
||||
} else {
|
||||
fattr.cf_uniqueid = iunique(sb, ROOT_I);
|
||||
cifs_autodisable_serverino(cifs_sb);
|
||||
}
|
||||
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) &&
|
||||
couldbe_mf_symlink(&fattr))
|
||||
if ((sbflags & CIFS_MOUNT_MF_SYMLINKS) && couldbe_mf_symlink(&fattr))
|
||||
/*
|
||||
* trying to get the type and mode can be slow,
|
||||
* so just call those regular files for now, and mark
|
||||
@ -1058,7 +1061,7 @@ int cifs_readdir(struct file *file, struct dir_context *ctx)
|
||||
const char *full_path;
|
||||
void *page = alloc_dentry_path();
|
||||
struct cached_fid *cfid = NULL;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(file);
|
||||
|
||||
xid = get_xid();
|
||||
|
||||
|
||||
@ -55,17 +55,18 @@ static int create_native_symlink(const unsigned int xid, struct inode *inode,
|
||||
const char *full_path, const char *symname)
|
||||
{
|
||||
struct reparse_symlink_data_buffer *buf = NULL;
|
||||
struct cifs_open_info_data data = {};
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
|
||||
const char *symroot = cifs_sb->ctx->symlinkroot;
|
||||
struct inode *new;
|
||||
struct kvec iov;
|
||||
__le16 *path = NULL;
|
||||
bool directory;
|
||||
char *symlink_target = NULL;
|
||||
char *sym = NULL;
|
||||
struct cifs_open_info_data data = {};
|
||||
char sep = CIFS_DIR_SEP(cifs_sb);
|
||||
char *symlink_target = NULL;
|
||||
u16 len, plen, poff, slen;
|
||||
unsigned int sbflags;
|
||||
__le16 *path = NULL;
|
||||
struct inode *new;
|
||||
char *sym = NULL;
|
||||
struct kvec iov;
|
||||
bool directory;
|
||||
int rc = 0;
|
||||
|
||||
if (strlen(symname) > REPARSE_SYM_PATH_MAX)
|
||||
@ -83,8 +84,8 @@ static int create_native_symlink(const unsigned int xid, struct inode *inode,
|
||||
.symlink_target = symlink_target,
|
||||
};
|
||||
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) &&
|
||||
symroot && symname[0] == '/') {
|
||||
sbflags = cifs_sb_flags(cifs_sb);
|
||||
if (!(sbflags & CIFS_MOUNT_POSIX_PATHS) && symroot && symname[0] == '/') {
|
||||
/*
|
||||
* This is a request to create an absolute symlink on the server
|
||||
* which does not support POSIX paths, and expects symlink in
|
||||
@ -164,7 +165,7 @@ static int create_native_symlink(const unsigned int xid, struct inode *inode,
|
||||
* mask these characters in NT object prefix by '_' and then change
|
||||
* them back.
|
||||
*/
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) && symname[0] == '/')
|
||||
if (!(sbflags & CIFS_MOUNT_POSIX_PATHS) && symname[0] == '/')
|
||||
sym[0] = sym[1] = sym[2] = sym[5] = '_';
|
||||
|
||||
path = cifs_convert_path_to_utf16(sym, cifs_sb);
|
||||
@ -173,7 +174,7 @@ static int create_native_symlink(const unsigned int xid, struct inode *inode,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) && symname[0] == '/') {
|
||||
if (!(sbflags & CIFS_MOUNT_POSIX_PATHS) && symname[0] == '/') {
|
||||
sym[0] = '\\';
|
||||
sym[1] = sym[2] = '?';
|
||||
sym[5] = ':';
|
||||
@ -197,7 +198,7 @@ static int create_native_symlink(const unsigned int xid, struct inode *inode,
|
||||
slen = 2 * UniStrnlen((wchar_t *)path, REPARSE_SYM_PATH_MAX);
|
||||
poff = 0;
|
||||
plen = slen;
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) && symname[0] == '/') {
|
||||
if (!(sbflags & CIFS_MOUNT_POSIX_PATHS) && symname[0] == '/') {
|
||||
/*
|
||||
* For absolute NT symlinks skip leading "\\??\\" in PrintName as
|
||||
* PrintName is user visible location in DOS/Win32 format (not in NT format).
|
||||
@ -822,7 +823,7 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) &&
|
||||
if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_POSIX_PATHS) &&
|
||||
symroot && !relative) {
|
||||
/*
|
||||
* This is an absolute symlink from the server which does not
|
||||
|
||||
@ -32,7 +32,7 @@ static inline kuid_t wsl_make_kuid(struct cifs_sb_info *cifs_sb,
|
||||
{
|
||||
u32 uid = le32_to_cpu(*(__le32 *)ptr);
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_OVERR_UID)
|
||||
return cifs_sb->ctx->linux_uid;
|
||||
return make_kuid(current_user_ns(), uid);
|
||||
}
|
||||
@ -42,7 +42,7 @@ static inline kgid_t wsl_make_kgid(struct cifs_sb_info *cifs_sb,
|
||||
{
|
||||
u32 gid = le32_to_cpu(*(__le32 *)ptr);
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_OVERR_GID)
|
||||
return cifs_sb->ctx->linux_gid;
|
||||
return make_kgid(current_user_ns(), gid);
|
||||
}
|
||||
|
||||
@ -1211,7 +1211,7 @@ static int cifs_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid,
|
||||
__u64 volatile_fid, __u16 net_fid,
|
||||
struct cifsInodeInfo *cinode, unsigned int oplock)
|
||||
{
|
||||
unsigned int sbflags = CIFS_SB(cinode->netfs.inode.i_sb)->mnt_cifs_flags;
|
||||
unsigned int sbflags = cifs_sb_flags(CIFS_SB(cinode));
|
||||
__u8 op;
|
||||
|
||||
op = !!((oplock & CIFS_CACHE_READ_FLG) || (sbflags & CIFS_MOUNT_RO_CACHE));
|
||||
@ -1346,7 +1346,8 @@ cifs_make_node(unsigned int xid, struct inode *inode,
|
||||
struct dentry *dentry, struct cifs_tcon *tcon,
|
||||
const char *full_path, umode_t mode, dev_t dev)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode);
|
||||
unsigned int sbflags = cifs_sb_flags(cifs_sb);
|
||||
struct inode *newinode = NULL;
|
||||
int rc;
|
||||
|
||||
@ -1362,7 +1363,7 @@ cifs_make_node(unsigned int xid, struct inode *inode,
|
||||
.mtime = NO_CHANGE_64,
|
||||
.device = dev,
|
||||
};
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
||||
if (sbflags & CIFS_MOUNT_SET_UID) {
|
||||
args.uid = current_fsuid();
|
||||
args.gid = current_fsgid();
|
||||
} else {
|
||||
@ -1381,7 +1382,7 @@ cifs_make_node(unsigned int xid, struct inode *inode,
|
||||
if (rc == 0)
|
||||
d_instantiate(dentry, newinode);
|
||||
return rc;
|
||||
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
|
||||
} else if (sbflags & CIFS_MOUNT_UNX_EMUL) {
|
||||
/*
|
||||
* Check if mounted with mount parm 'sfu' mount parm.
|
||||
* SFU emulation should work with all servers
|
||||
|
||||
@ -74,7 +74,7 @@ int smb2_fix_symlink_target_type(char **target, bool directory, struct cifs_sb_i
|
||||
* POSIX server does not distinguish between symlinks to file and
|
||||
* symlink directory. So nothing is needed to fix on the client side.
|
||||
*/
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_POSIX_PATHS)
|
||||
return 0;
|
||||
|
||||
if (!*target)
|
||||
|
||||
@ -454,17 +454,8 @@ calc_size_exit:
|
||||
__le16 *
|
||||
cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
int len;
|
||||
const char *start_of_path;
|
||||
__le16 *to;
|
||||
int map_type;
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR)
|
||||
map_type = SFM_MAP_UNI_RSVD;
|
||||
else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
|
||||
map_type = SFU_MAP_UNI_RSVD;
|
||||
else
|
||||
map_type = NO_MAP_UNI_RSVD;
|
||||
int len;
|
||||
|
||||
/* Windows doesn't allow paths beginning with \ */
|
||||
if (from[0] == '\\')
|
||||
@ -478,14 +469,13 @@ cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)
|
||||
} else
|
||||
start_of_path = from;
|
||||
|
||||
to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len,
|
||||
cifs_sb->local_nls, map_type);
|
||||
return to;
|
||||
return cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len,
|
||||
cifs_sb->local_nls, cifs_remap(cifs_sb));
|
||||
}
|
||||
|
||||
__le32 smb2_get_lease_state(struct cifsInodeInfo *cinode, unsigned int oplock)
|
||||
{
|
||||
unsigned int sbflags = CIFS_SB(cinode->netfs.inode.i_sb)->mnt_cifs_flags;
|
||||
unsigned int sbflags = cifs_sb_flags(CIFS_SB(cinode));
|
||||
__le32 lease = 0;
|
||||
|
||||
if ((oplock & CIFS_CACHE_WRITE_FLG) || (sbflags & CIFS_MOUNT_RW_CACHE))
|
||||
|
||||
@ -951,7 +951,7 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
rc = -EREMOTE;
|
||||
}
|
||||
if (rc == -EREMOTE && IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) &&
|
||||
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS))
|
||||
(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NO_DFS))
|
||||
rc = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
@ -2637,7 +2637,7 @@ static int smb2_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid,
|
||||
__u64 volatile_fid, __u16 net_fid,
|
||||
struct cifsInodeInfo *cinode, unsigned int oplock)
|
||||
{
|
||||
unsigned int sbflags = CIFS_SB(cinode->netfs.inode.i_sb)->mnt_cifs_flags;
|
||||
unsigned int sbflags = cifs_sb_flags(CIFS_SB(cinode));
|
||||
__u8 op;
|
||||
|
||||
if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING)
|
||||
@ -5312,7 +5312,7 @@ static int smb2_make_node(unsigned int xid, struct inode *inode,
|
||||
struct dentry *dentry, struct cifs_tcon *tcon,
|
||||
const char *full_path, umode_t mode, dev_t dev)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
unsigned int sbflags = cifs_sb_flags(CIFS_SB(inode));
|
||||
int rc = -EOPNOTSUPP;
|
||||
|
||||
/*
|
||||
@ -5321,7 +5321,7 @@ static int smb2_make_node(unsigned int xid, struct inode *inode,
|
||||
* supports block and char device, socket & fifo,
|
||||
* and was used by default in earlier versions of Windows
|
||||
*/
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
|
||||
if (sbflags & CIFS_MOUNT_UNX_EMUL) {
|
||||
rc = cifs_sfu_make_node(xid, inode, dentry, tcon,
|
||||
full_path, mode, dev);
|
||||
} else if (CIFS_REPARSE_SUPPORT(tcon)) {
|
||||
|
||||
@ -3144,22 +3144,19 @@ SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
|
||||
}
|
||||
|
||||
if ((oparms->disposition != FILE_OPEN) && (oparms->cifs_sb)) {
|
||||
unsigned int sbflags = cifs_sb_flags(oparms->cifs_sb);
|
||||
bool set_mode;
|
||||
bool set_owner;
|
||||
|
||||
if ((oparms->cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) &&
|
||||
(oparms->mode != ACL_NO_MODE))
|
||||
if ((sbflags & CIFS_MOUNT_MODE_FROM_SID) &&
|
||||
oparms->mode != ACL_NO_MODE) {
|
||||
set_mode = true;
|
||||
else {
|
||||
} else {
|
||||
set_mode = false;
|
||||
oparms->mode = ACL_NO_MODE;
|
||||
}
|
||||
|
||||
if (oparms->cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
|
||||
set_owner = true;
|
||||
else
|
||||
set_owner = false;
|
||||
|
||||
set_owner = sbflags & CIFS_MOUNT_UID_FROM_ACL;
|
||||
if (set_owner | set_mode) {
|
||||
cifs_dbg(FYI, "add sd with mode 0x%x\n", oparms->mode);
|
||||
rc = add_sd_context(iov, &n_iov, oparms->mode, set_owner);
|
||||
|
||||
@ -150,7 +150,7 @@ static int cifs_xattr_set(const struct xattr_handler *handler,
|
||||
break;
|
||||
}
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NO_XATTR)
|
||||
goto out;
|
||||
|
||||
if (pTcon->ses->server->ops->set_EA) {
|
||||
@ -310,7 +310,7 @@ static int cifs_xattr_get(const struct xattr_handler *handler,
|
||||
break;
|
||||
}
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NO_XATTR)
|
||||
goto out;
|
||||
|
||||
if (pTcon->ses->server->ops->query_all_EAs)
|
||||
@ -399,7 +399,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
|
||||
if (unlikely(cifs_forced_shutdown(cifs_sb)))
|
||||
return -EIO;
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
|
||||
if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NO_XATTR)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
tlink = cifs_sb_tlink(cifs_sb);
|
||||
|
||||
@ -96,8 +96,8 @@ int mlx5_query_hca_vport_node_guid(struct mlx5_core_dev *dev,
|
||||
int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
|
||||
u16 vport,
|
||||
enum mlx5_list_type list_type,
|
||||
u8 addr_list[][ETH_ALEN],
|
||||
int *list_size);
|
||||
u8 (**mac_list)[ETH_ALEN],
|
||||
int *mac_list_size);
|
||||
int mlx5_modify_nic_vport_mac_list(struct mlx5_core_dev *dev,
|
||||
enum mlx5_list_type list_type,
|
||||
u8 addr_list[][ETH_ALEN],
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
|
||||
kernel.rhel,1,Red Hat,kernel-core,5.14.0-687.36.1.el9.x86_64,mailto:secalert@redhat.com
|
||||
kernel.almalinux,1,AlmaLinux,kernel-core,5.14.0-687.36.1.el9.x86_64,mailto:security@almalinux.org
|
||||
kernel.rhel,1,Red Hat,kernel-core,5.14.0-687.38.1.el9.x86_64,mailto:secalert@redhat.com
|
||||
kernel.almalinux,1,AlmaLinux,kernel-core,5.14.0-687.38.1.el9.x86_64,mailto:security@almalinux.org
|
||||
|
||||
18
mm/slub.c
18
mm/slub.c
@ -3782,15 +3782,17 @@ static inline void slab_post_alloc_hook(struct kmem_cache *s,
|
||||
flags &= gfp_allowed_mask;
|
||||
|
||||
/*
|
||||
* For kmalloc object, the allocated memory size(object_size) is likely
|
||||
* larger than the requested size(orig_size). If redzone check is
|
||||
* enabled for the extra space, don't zero it, as it will be redzoned
|
||||
* soon. The redzone operation for this extra space could be seen as a
|
||||
* replacement of current poisoning under certain debug option, and
|
||||
* won't break other sanity checks.
|
||||
* For kmalloc object, the allocated size (object_size) can be larger
|
||||
* than the requested size (orig_size). We however need to zero the
|
||||
* whole object_size to handle possible later krealloc() with
|
||||
*__GFP_ZERO properly.
|
||||
*
|
||||
* But if we keep track of the requested size, krealloc() uses that
|
||||
* information. Additionally if red zoning is enabled, the extra space
|
||||
* is also red zone, so we should not overwrite it. So limit zeroing to
|
||||
* orig_size if we track it.
|
||||
*/
|
||||
if (kmem_cache_debug_flags(s, SLAB_STORE_USER | SLAB_RED_ZONE) &&
|
||||
(s->flags & SLAB_KMALLOC))
|
||||
if (slub_debug_orig_size(s))
|
||||
zero_size = orig_size;
|
||||
|
||||
/*
|
||||
|
||||
@ -2504,13 +2504,56 @@ static inline int add_nested_action_start(struct sw_flow_actions **sfa,
|
||||
return used;
|
||||
}
|
||||
|
||||
static inline void add_nested_action_end(struct sw_flow_actions *sfa,
|
||||
int st_offset)
|
||||
static inline int add_nested_action_end(struct sw_flow_actions *sfa,
|
||||
int st_offset)
|
||||
{
|
||||
struct nlattr *a = (struct nlattr *) ((unsigned char *)sfa->actions +
|
||||
st_offset);
|
||||
struct nlattr *a;
|
||||
u32 attr_len;
|
||||
|
||||
a->nla_len = sfa->actions_len - st_offset;
|
||||
if (WARN_ON_ONCE(st_offset < 0 ||
|
||||
(u32)st_offset > sfa->actions_len))
|
||||
return -EINVAL;
|
||||
|
||||
attr_len = sfa->actions_len - (u32)st_offset;
|
||||
if (WARN_ON_ONCE(attr_len < NLA_HDRLEN))
|
||||
return -EINVAL;
|
||||
|
||||
if (attr_len > U16_MAX)
|
||||
return -EMSGSIZE;
|
||||
|
||||
a = (struct nlattr *)((u8 *)sfa->actions + st_offset);
|
||||
a->nla_len = attr_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Free the generated action-list tail at @start and truncate it.
|
||||
* If @nested, @start points to its containing nlattr header.
|
||||
*/
|
||||
static void ovs_nla_trim(struct sw_flow_actions *sfa, int start, bool nested)
|
||||
{
|
||||
const struct nlattr *actions;
|
||||
u32 len;
|
||||
|
||||
if (start < 0)
|
||||
return;
|
||||
|
||||
if (WARN_ON_ONCE((u32)start > sfa->actions_len))
|
||||
return;
|
||||
|
||||
actions = (const struct nlattr *)((u8 *)sfa->actions + start);
|
||||
len = sfa->actions_len - (u32)start;
|
||||
|
||||
if (nested) {
|
||||
if (len < NLA_HDRLEN)
|
||||
goto out;
|
||||
|
||||
actions = (const struct nlattr *)((u8 *)actions + NLA_HDRLEN);
|
||||
len -= NLA_HDRLEN;
|
||||
}
|
||||
|
||||
ovs_nla_free_nested_actions(actions, len);
|
||||
out:
|
||||
sfa->actions_len = start;
|
||||
}
|
||||
|
||||
static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
|
||||
@ -2530,6 +2573,7 @@ static int validate_and_copy_sample(struct net *net, const struct nlattr *attr,
|
||||
const struct nlattr *attrs[OVS_SAMPLE_ATTR_MAX + 1];
|
||||
const struct nlattr *probability, *actions;
|
||||
const struct nlattr *a;
|
||||
int actions_start;
|
||||
int rem, start, err;
|
||||
struct sample_arg arg;
|
||||
|
||||
@ -2573,18 +2617,27 @@ static int validate_and_copy_sample(struct net *net, const struct nlattr *attr,
|
||||
err = ovs_nla_add_action(sfa, OVS_SAMPLE_ATTR_ARG, &arg, sizeof(arg),
|
||||
log);
|
||||
if (err)
|
||||
return err;
|
||||
goto err;
|
||||
|
||||
actions_start = (*sfa)->actions_len;
|
||||
err = __ovs_nla_copy_actions(net, actions, key, sfa,
|
||||
eth_type, vlan_tci, mpls_label_count, log,
|
||||
depth + 1);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
goto err_free;
|
||||
|
||||
add_nested_action_end(*sfa, start);
|
||||
err = add_nested_action_end(*sfa, start);
|
||||
if (err)
|
||||
goto err_free;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free:
|
||||
ovs_nla_trim(*sfa, actions_start, false);
|
||||
err:
|
||||
(*sfa)->actions_len = start;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int validate_and_copy_dec_ttl(struct net *net,
|
||||
@ -2632,18 +2685,31 @@ static int validate_and_copy_dec_ttl(struct net *net,
|
||||
return start;
|
||||
|
||||
action_start = add_nested_action_start(sfa, OVS_DEC_TTL_ATTR_ACTION, log);
|
||||
if (action_start < 0)
|
||||
return action_start;
|
||||
if (action_start < 0) {
|
||||
err = action_start;
|
||||
goto err;
|
||||
}
|
||||
|
||||
err = __ovs_nla_copy_actions(net, actions, key, sfa, eth_type,
|
||||
vlan_tci, mpls_label_count, log,
|
||||
depth + 1);
|
||||
if (err)
|
||||
return err;
|
||||
goto err_free;
|
||||
|
||||
add_nested_action_end(*sfa, action_start);
|
||||
add_nested_action_end(*sfa, start);
|
||||
err = add_nested_action_end(*sfa, action_start);
|
||||
if (err)
|
||||
goto err_free;
|
||||
|
||||
err = add_nested_action_end(*sfa, start);
|
||||
if (err)
|
||||
goto err_free;
|
||||
return 0;
|
||||
|
||||
err_free:
|
||||
ovs_nla_trim(*sfa, action_start, true);
|
||||
err:
|
||||
(*sfa)->actions_len = start;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int validate_and_copy_clone(struct net *net,
|
||||
@ -2654,6 +2720,7 @@ static int validate_and_copy_clone(struct net *net,
|
||||
u32 mpls_label_count, bool log, bool last,
|
||||
u32 depth)
|
||||
{
|
||||
int actions_start;
|
||||
int start, err;
|
||||
u32 exec;
|
||||
|
||||
@ -2669,17 +2736,26 @@ static int validate_and_copy_clone(struct net *net,
|
||||
err = ovs_nla_add_action(sfa, OVS_CLONE_ATTR_EXEC, &exec,
|
||||
sizeof(exec), log);
|
||||
if (err)
|
||||
return err;
|
||||
goto err;
|
||||
|
||||
actions_start = (*sfa)->actions_len;
|
||||
err = __ovs_nla_copy_actions(net, attr, key, sfa,
|
||||
eth_type, vlan_tci, mpls_label_count, log,
|
||||
depth + 1);
|
||||
if (err)
|
||||
return err;
|
||||
goto err_free;
|
||||
|
||||
add_nested_action_end(*sfa, start);
|
||||
err = add_nested_action_end(*sfa, start);
|
||||
if (err)
|
||||
goto err_free;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free:
|
||||
ovs_nla_trim(*sfa, actions_start, false);
|
||||
err:
|
||||
(*sfa)->actions_len = start;
|
||||
return err;
|
||||
}
|
||||
|
||||
void ovs_match_init(struct sw_flow_match *match,
|
||||
@ -2771,20 +2847,20 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
|
||||
tun_dst = metadata_dst_alloc(key.tun_opts_len, METADATA_IP_TUNNEL,
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!tun_dst)
|
||||
return -ENOMEM;
|
||||
if (!tun_dst) {
|
||||
err = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
err = dst_cache_init(&tun_dst->u.tun_info.dst_cache, GFP_KERNEL);
|
||||
if (err) {
|
||||
dst_release((struct dst_entry *)tun_dst);
|
||||
return err;
|
||||
}
|
||||
if (err)
|
||||
goto err_free_tun_dst;
|
||||
|
||||
a = __add_action(sfa, OVS_KEY_ATTR_TUNNEL_INFO, NULL,
|
||||
sizeof(*ovs_tun), log);
|
||||
if (IS_ERR(a)) {
|
||||
dst_release((struct dst_entry *)tun_dst);
|
||||
return PTR_ERR(a);
|
||||
err = PTR_ERR(a);
|
||||
goto err_free_tun_dst;
|
||||
}
|
||||
|
||||
ovs_tun = nla_data(a);
|
||||
@ -2805,8 +2881,16 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
|
||||
ip_tunnel_info_opts_set(tun_info,
|
||||
TUN_METADATA_OPTS(&key, key.tun_opts_len),
|
||||
key.tun_opts_len, dst_opt_type);
|
||||
add_nested_action_end(*sfa, start);
|
||||
err = add_nested_action_end(*sfa, start);
|
||||
if (WARN_ON_ONCE(err))
|
||||
goto err_free_tun_dst;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_tun_dst:
|
||||
dst_release((struct dst_entry *)tun_dst);
|
||||
err:
|
||||
(*sfa)->actions_len = start;
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -2981,7 +3065,7 @@ static int validate_set(const struct nlattr *a,
|
||||
|
||||
/* Convert non-masked non-tunnel set actions to masked set actions. */
|
||||
if (!masked && key_type != OVS_KEY_ATTR_TUNNEL) {
|
||||
int start, len = key_len * 2;
|
||||
int err, start, len = key_len * 2;
|
||||
struct nlattr *at;
|
||||
|
||||
*skip_copy = true;
|
||||
@ -2993,8 +3077,11 @@ static int validate_set(const struct nlattr *a,
|
||||
return start;
|
||||
|
||||
at = __add_action(sfa, key_type, NULL, len, log);
|
||||
if (IS_ERR(at))
|
||||
return PTR_ERR(at);
|
||||
if (IS_ERR(at)) {
|
||||
err = PTR_ERR(at);
|
||||
(*sfa)->actions_len = start;
|
||||
return err;
|
||||
}
|
||||
|
||||
memcpy(nla_data(at), nla_data(ovs_key), key_len); /* Key. */
|
||||
memset(nla_data(at) + key_len, 0xff, key_len); /* Mask. */
|
||||
@ -3004,7 +3091,11 @@ static int validate_set(const struct nlattr *a,
|
||||
|
||||
mask->ipv6_label &= htonl(0x000FFFFF);
|
||||
}
|
||||
add_nested_action_end(*sfa, start);
|
||||
err = add_nested_action_end(*sfa, start);
|
||||
if (WARN_ON_ONCE(err)) {
|
||||
(*sfa)->actions_len = start;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -3050,7 +3141,8 @@ static int validate_and_copy_check_pkt_len(struct net *net,
|
||||
const struct nlattr *acts_if_greater, *acts_if_lesser_eq;
|
||||
struct nlattr *a[OVS_CHECK_PKT_LEN_ATTR_MAX + 1];
|
||||
struct check_pkt_len_arg arg;
|
||||
int nested_acts_start;
|
||||
int greater_acts_start = -1;
|
||||
int lesser_acts_start = -1;
|
||||
int start, err;
|
||||
|
||||
err = nla_parse_deprecated_strict(a, OVS_CHECK_PKT_LEN_ATTR_MAX,
|
||||
@ -3085,37 +3177,58 @@ static int validate_and_copy_check_pkt_len(struct net *net,
|
||||
err = ovs_nla_add_action(sfa, OVS_CHECK_PKT_LEN_ATTR_ARG, &arg,
|
||||
sizeof(arg), log);
|
||||
if (err)
|
||||
return err;
|
||||
goto err_free;
|
||||
|
||||
nested_acts_start = add_nested_action_start(sfa,
|
||||
OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL, log);
|
||||
if (nested_acts_start < 0)
|
||||
return nested_acts_start;
|
||||
lesser_acts_start =
|
||||
add_nested_action_start(sfa,
|
||||
OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL,
|
||||
log);
|
||||
if (lesser_acts_start < 0) {
|
||||
err = lesser_acts_start;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
err = __ovs_nla_copy_actions(net, acts_if_lesser_eq, key, sfa,
|
||||
eth_type, vlan_tci, mpls_label_count, log,
|
||||
depth + 1);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
goto err_free;
|
||||
|
||||
add_nested_action_end(*sfa, nested_acts_start);
|
||||
err = add_nested_action_end(*sfa, lesser_acts_start);
|
||||
if (err)
|
||||
goto err_free;
|
||||
|
||||
nested_acts_start = add_nested_action_start(sfa,
|
||||
OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER, log);
|
||||
if (nested_acts_start < 0)
|
||||
return nested_acts_start;
|
||||
greater_acts_start =
|
||||
add_nested_action_start(sfa,
|
||||
OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER,
|
||||
log);
|
||||
if (greater_acts_start < 0) {
|
||||
err = greater_acts_start;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
err = __ovs_nla_copy_actions(net, acts_if_greater, key, sfa,
|
||||
eth_type, vlan_tci, mpls_label_count, log,
|
||||
depth + 1);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
goto err_free;
|
||||
|
||||
add_nested_action_end(*sfa, nested_acts_start);
|
||||
add_nested_action_end(*sfa, start);
|
||||
err = add_nested_action_end(*sfa, greater_acts_start);
|
||||
if (err)
|
||||
goto err_free;
|
||||
|
||||
err = add_nested_action_end(*sfa, start);
|
||||
if (err)
|
||||
goto err_free;
|
||||
return 0;
|
||||
|
||||
err_free:
|
||||
ovs_nla_trim(*sfa, greater_acts_start, true);
|
||||
ovs_nla_trim(*sfa, lesser_acts_start, true);
|
||||
ovs_nla_trim(*sfa, start, false);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int validate_psample(const struct nlattr *attr)
|
||||
|
||||
@ -1,3 +1,23 @@
|
||||
* Mon Aug 10 2026 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [5.14.0-687.38.1.el9_8]
|
||||
- cifs: fix time_last_write stamp placement in setattr/truncate paths (Paulo Alcantara) [RHEL-192999]
|
||||
- cifs: consolidate time_last_write stamp into _cifsFileInfo_put() (Paulo Alcantara) [RHEL-192999]
|
||||
- cifs: fix cifsFileInfo leak on kmalloc failure in deferred close drain paths (Paulo Alcantara) [RHEL-192999]
|
||||
- cifs: prevent readdir from changing file size due to stale directory metadata (Paulo Alcantara) [RHEL-192999]
|
||||
- smb: client: fix dir separator in SMB1 UNIX mounts (Paulo Alcantara) [RHEL-192999]
|
||||
- smb: client: fix sbflags initialization (Paulo Alcantara) [RHEL-192999]
|
||||
- smb: client: use atomic_t for mnt_cifs_flags (Paulo Alcantara) [RHEL-192999]
|
||||
- mm/slab: do not limit zeroing to orig_size when only red zoning is enabled (Rafael Aquini) [RHEL-223404] {CVE-2026-64368}
|
||||
Resolves: RHEL-192999, RHEL-223404
|
||||
|
||||
* Fri Aug 07 2026 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [5.14.0-687.37.1.el9_8]
|
||||
- s390/pkey: Check length in pkey_pckmo handler implementation (Ramesh Chhetri) [RHEL-215578]
|
||||
- s390/pkey: Check length in PKEY_VERIFYPROTK ioctl (Ramesh Chhetri) [RHEL-215580]
|
||||
- net: openvswitch: reject oversized nested action attrs (CKI Backport Bot) [RHEL-222495] {CVE-2026-64531}
|
||||
- cxl/port: Fix use after free of parent_port in cxl_detach_ep() (Myron Stowe) [RHEL-180691] {CVE-2026-31530}
|
||||
- net/mlx5: Fix slab-out-of-bounds in mlx5_query_nic_vport_mac_list (CKI Backport Bot) [RHEL-213036]
|
||||
- x86/CPU/AMD: Prevent improper isolation of shared resources in Zen2's op cache (Dennis Chen) [RHEL-188790] {CVE-2025-54518}
|
||||
Resolves: RHEL-180691, RHEL-188790, RHEL-213036, RHEL-215578, RHEL-215580, RHEL-222495
|
||||
|
||||
* Wed Aug 05 2026 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [5.14.0-687.36.1.el9_8]
|
||||
- powerpc/powernv/iommu: iommu incorrectly bypass DMA APIs (Mamatha Inamdar) [RHEL-215575]
|
||||
- powerpc/iommu: bypass DMA APIs for coherent allocations for pre-mapped memory (Mamatha Inamdar) [RHEL-215575]
|
||||
|
||||
@ -686,8 +686,9 @@
|
||||
#define MSR_AMD64_LBR_SELECT 0xc000010e
|
||||
|
||||
/* Zen4 */
|
||||
#define MSR_ZEN4_BP_CFG 0xc001102e
|
||||
#define MSR_ZEN4_BP_CFG 0xc001102e
|
||||
#define MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT 5
|
||||
#define MSR_ZEN2_BP_CFG_BUG_FIX_BIT 33
|
||||
|
||||
/* Fam 19h MSRs */
|
||||
#define MSR_F19H_UMC_PERF_CTL 0xc0010800
|
||||
|
||||
Loading…
Reference in New Issue
Block a user