Import of kernel-5.14.0-570.58.1.el9_6
This commit is contained in:
parent
fdf04f711e
commit
ae5089045c
@ -12,7 +12,7 @@ RHEL_MINOR = 6
|
|||||||
#
|
#
|
||||||
# Use this spot to avoid future merge conflicts.
|
# Use this spot to avoid future merge conflicts.
|
||||||
# Do not trim this comment.
|
# Do not trim this comment.
|
||||||
RHEL_RELEASE = 570.55.1
|
RHEL_RELEASE = 570.58.1
|
||||||
|
|
||||||
#
|
#
|
||||||
# ZSTREAM
|
# ZSTREAM
|
||||||
|
|||||||
11
block/bio.c
11
block/bio.c
@ -1154,9 +1154,10 @@ EXPORT_SYMBOL(bio_add_page);
|
|||||||
void bio_add_folio_nofail(struct bio *bio, struct folio *folio, size_t len,
|
void bio_add_folio_nofail(struct bio *bio, struct folio *folio, size_t len,
|
||||||
size_t off)
|
size_t off)
|
||||||
{
|
{
|
||||||
|
unsigned long nr = off / PAGE_SIZE;
|
||||||
|
|
||||||
WARN_ON_ONCE(len > UINT_MAX);
|
WARN_ON_ONCE(len > UINT_MAX);
|
||||||
WARN_ON_ONCE(off > UINT_MAX);
|
__bio_add_page(bio, folio_page(folio, nr), len, off % PAGE_SIZE);
|
||||||
__bio_add_page(bio, &folio->page, len, off);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1176,9 +1177,11 @@ void bio_add_folio_nofail(struct bio *bio, struct folio *folio, size_t len,
|
|||||||
bool bio_add_folio(struct bio *bio, struct folio *folio, size_t len,
|
bool bio_add_folio(struct bio *bio, struct folio *folio, size_t len,
|
||||||
size_t off)
|
size_t off)
|
||||||
{
|
{
|
||||||
if (len > UINT_MAX || off > UINT_MAX)
|
unsigned long nr = off / PAGE_SIZE;
|
||||||
|
|
||||||
|
if (len > UINT_MAX)
|
||||||
return false;
|
return false;
|
||||||
return bio_add_page(bio, &folio->page, len, off) > 0;
|
return bio_add_page(bio, folio_page(folio, nr), len, off % PAGE_SIZE) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __bio_release_pages(struct bio *bio, bool mark_dirty)
|
void __bio_release_pages(struct bio *bio, bool mark_dirty)
|
||||||
|
|||||||
@ -66,14 +66,21 @@ nfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
|
|||||||
{
|
{
|
||||||
struct nfs_fattr *fattr = NULL;
|
struct nfs_fattr *fattr = NULL;
|
||||||
struct nfs_fh *server_fh = nfs_exp_embedfh(fid->raw);
|
struct nfs_fh *server_fh = nfs_exp_embedfh(fid->raw);
|
||||||
size_t fh_size = offsetof(struct nfs_fh, data) + server_fh->size;
|
size_t fh_size = offsetof(struct nfs_fh, data);
|
||||||
const struct nfs_rpc_ops *rpc_ops;
|
const struct nfs_rpc_ops *rpc_ops;
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
int len = EMBED_FH_OFF + XDR_QUADLEN(fh_size);
|
int len = EMBED_FH_OFF;
|
||||||
u32 *p = fid->raw;
|
u32 *p = fid->raw;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
/* Initial check of bounds */
|
||||||
|
if (fh_len < len + XDR_QUADLEN(fh_size) ||
|
||||||
|
fh_len > XDR_QUADLEN(NFS_MAXFHSIZE))
|
||||||
|
return NULL;
|
||||||
|
/* Calculate embedded filehandle size */
|
||||||
|
fh_size += server_fh->size;
|
||||||
|
len += XDR_QUADLEN(fh_size);
|
||||||
/* NULL translates to ESTALE */
|
/* NULL translates to ESTALE */
|
||||||
if (fh_len < len || fh_type != len)
|
if (fh_len < len || fh_type != len)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@ -276,7 +276,7 @@ ff_lseg_match_mirrors(struct pnfs_layout_segment *l1,
|
|||||||
struct pnfs_layout_segment *l2)
|
struct pnfs_layout_segment *l2)
|
||||||
{
|
{
|
||||||
const struct nfs4_ff_layout_segment *fl1 = FF_LAYOUT_LSEG(l1);
|
const struct nfs4_ff_layout_segment *fl1 = FF_LAYOUT_LSEG(l1);
|
||||||
const struct nfs4_ff_layout_segment *fl2 = FF_LAYOUT_LSEG(l1);
|
const struct nfs4_ff_layout_segment *fl2 = FF_LAYOUT_LSEG(l2);
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
if (fl1->mirror_array_cnt != fl2->mirror_array_cnt)
|
if (fl1->mirror_array_cnt != fl2->mirror_array_cnt)
|
||||||
|
|||||||
@ -195,6 +195,7 @@ void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
|
|||||||
if (!(flags & NFS_INO_REVAL_FORCED))
|
if (!(flags & NFS_INO_REVAL_FORCED))
|
||||||
flags &= ~(NFS_INO_INVALID_MODE |
|
flags &= ~(NFS_INO_INVALID_MODE |
|
||||||
NFS_INO_INVALID_OTHER |
|
NFS_INO_INVALID_OTHER |
|
||||||
|
NFS_INO_INVALID_BTIME |
|
||||||
NFS_INO_INVALID_XATTR);
|
NFS_INO_INVALID_XATTR);
|
||||||
flags &= ~(NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_SIZE);
|
flags &= ~(NFS_INO_INVALID_CHANGE | NFS_INO_INVALID_SIZE);
|
||||||
}
|
}
|
||||||
@ -519,6 +520,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
|
|||||||
memset(&inode->i_atime, 0, sizeof(inode->i_atime));
|
memset(&inode->i_atime, 0, sizeof(inode->i_atime));
|
||||||
memset(&inode->i_mtime, 0, sizeof(inode->i_mtime));
|
memset(&inode->i_mtime, 0, sizeof(inode->i_mtime));
|
||||||
inode_set_ctime(inode, 0, 0);
|
inode_set_ctime(inode, 0, 0);
|
||||||
|
memset(&nfsi->btime, 0, sizeof(nfsi->btime));
|
||||||
inode_set_iversion_raw(inode, 0);
|
inode_set_iversion_raw(inode, 0);
|
||||||
inode->i_size = 0;
|
inode->i_size = 0;
|
||||||
clear_nlink(inode);
|
clear_nlink(inode);
|
||||||
@ -542,6 +544,10 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
|
|||||||
inode_set_ctime_to_ts(inode, fattr->ctime);
|
inode_set_ctime_to_ts(inode, fattr->ctime);
|
||||||
else if (fattr_supported & NFS_ATTR_FATTR_CTIME)
|
else if (fattr_supported & NFS_ATTR_FATTR_CTIME)
|
||||||
nfs_set_cache_invalid(inode, NFS_INO_INVALID_CTIME);
|
nfs_set_cache_invalid(inode, NFS_INO_INVALID_CTIME);
|
||||||
|
if (fattr->valid & NFS_ATTR_FATTR_BTIME)
|
||||||
|
nfsi->btime = fattr->btime;
|
||||||
|
else if (fattr_supported & NFS_ATTR_FATTR_BTIME)
|
||||||
|
nfs_set_cache_invalid(inode, NFS_INO_INVALID_BTIME);
|
||||||
if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
|
if (fattr->valid & NFS_ATTR_FATTR_CHANGE)
|
||||||
inode_set_iversion_raw(inode, fattr->change_attr);
|
inode_set_iversion_raw(inode, fattr->change_attr);
|
||||||
else
|
else
|
||||||
@ -885,6 +891,7 @@ static void nfs_readdirplus_parent_cache_hit(struct dentry *dentry)
|
|||||||
|
|
||||||
static u32 nfs_get_valid_attrmask(struct inode *inode)
|
static u32 nfs_get_valid_attrmask(struct inode *inode)
|
||||||
{
|
{
|
||||||
|
u64 fattr_valid = NFS_SERVER(inode)->fattr_valid;
|
||||||
unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
|
unsigned long cache_validity = READ_ONCE(NFS_I(inode)->cache_validity);
|
||||||
u32 reply_mask = STATX_INO | STATX_TYPE;
|
u32 reply_mask = STATX_INO | STATX_TYPE;
|
||||||
|
|
||||||
@ -904,6 +911,9 @@ static u32 nfs_get_valid_attrmask(struct inode *inode)
|
|||||||
reply_mask |= STATX_UID | STATX_GID;
|
reply_mask |= STATX_UID | STATX_GID;
|
||||||
if (!(cache_validity & NFS_INO_INVALID_BLOCKS))
|
if (!(cache_validity & NFS_INO_INVALID_BLOCKS))
|
||||||
reply_mask |= STATX_BLOCKS;
|
reply_mask |= STATX_BLOCKS;
|
||||||
|
if (!(cache_validity & NFS_INO_INVALID_BTIME) &&
|
||||||
|
(fattr_valid & NFS_ATTR_FATTR_BTIME))
|
||||||
|
reply_mask |= STATX_BTIME;
|
||||||
if (!(cache_validity & NFS_INO_INVALID_CHANGE))
|
if (!(cache_validity & NFS_INO_INVALID_CHANGE))
|
||||||
reply_mask |= STATX_CHANGE_COOKIE;
|
reply_mask |= STATX_CHANGE_COOKIE;
|
||||||
return reply_mask;
|
return reply_mask;
|
||||||
@ -914,6 +924,7 @@ int nfs_getattr(struct mnt_idmap *idmap, const struct path *path,
|
|||||||
{
|
{
|
||||||
struct inode *inode = d_inode(path->dentry);
|
struct inode *inode = d_inode(path->dentry);
|
||||||
struct nfs_server *server = NFS_SERVER(inode);
|
struct nfs_server *server = NFS_SERVER(inode);
|
||||||
|
u64 fattr_valid = server->fattr_valid;
|
||||||
unsigned long cache_validity;
|
unsigned long cache_validity;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
bool force_sync = query_flags & AT_STATX_FORCE_SYNC;
|
bool force_sync = query_flags & AT_STATX_FORCE_SYNC;
|
||||||
@ -924,9 +935,12 @@ int nfs_getattr(struct mnt_idmap *idmap, const struct path *path,
|
|||||||
|
|
||||||
request_mask &= STATX_TYPE | STATX_MODE | STATX_NLINK | STATX_UID |
|
request_mask &= STATX_TYPE | STATX_MODE | STATX_NLINK | STATX_UID |
|
||||||
STATX_GID | STATX_ATIME | STATX_MTIME | STATX_CTIME |
|
STATX_GID | STATX_ATIME | STATX_MTIME | STATX_CTIME |
|
||||||
STATX_INO | STATX_SIZE | STATX_BLOCKS |
|
STATX_INO | STATX_SIZE | STATX_BLOCKS | STATX_BTIME |
|
||||||
STATX_CHANGE_COOKIE;
|
STATX_CHANGE_COOKIE;
|
||||||
|
|
||||||
|
if (!(fattr_valid & NFS_ATTR_FATTR_BTIME))
|
||||||
|
request_mask &= ~STATX_BTIME;
|
||||||
|
|
||||||
if ((query_flags & AT_STATX_DONT_SYNC) && !force_sync) {
|
if ((query_flags & AT_STATX_DONT_SYNC) && !force_sync) {
|
||||||
if (readdirplus_enabled)
|
if (readdirplus_enabled)
|
||||||
nfs_readdirplus_parent_cache_hit(path->dentry);
|
nfs_readdirplus_parent_cache_hit(path->dentry);
|
||||||
@ -958,7 +972,7 @@ int nfs_getattr(struct mnt_idmap *idmap, const struct path *path,
|
|||||||
/* Is the user requesting attributes that might need revalidation? */
|
/* Is the user requesting attributes that might need revalidation? */
|
||||||
if (!(request_mask & (STATX_MODE|STATX_NLINK|STATX_ATIME|STATX_CTIME|
|
if (!(request_mask & (STATX_MODE|STATX_NLINK|STATX_ATIME|STATX_CTIME|
|
||||||
STATX_MTIME|STATX_UID|STATX_GID|
|
STATX_MTIME|STATX_UID|STATX_GID|
|
||||||
STATX_SIZE|STATX_BLOCKS|
|
STATX_SIZE|STATX_BLOCKS|STATX_BTIME|
|
||||||
STATX_CHANGE_COOKIE)))
|
STATX_CHANGE_COOKIE)))
|
||||||
goto out_no_revalidate;
|
goto out_no_revalidate;
|
||||||
|
|
||||||
@ -982,6 +996,8 @@ int nfs_getattr(struct mnt_idmap *idmap, const struct path *path,
|
|||||||
do_update |= cache_validity & NFS_INO_INVALID_OTHER;
|
do_update |= cache_validity & NFS_INO_INVALID_OTHER;
|
||||||
if (request_mask & STATX_BLOCKS)
|
if (request_mask & STATX_BLOCKS)
|
||||||
do_update |= cache_validity & NFS_INO_INVALID_BLOCKS;
|
do_update |= cache_validity & NFS_INO_INVALID_BLOCKS;
|
||||||
|
if (request_mask & STATX_BTIME)
|
||||||
|
do_update |= cache_validity & NFS_INO_INVALID_BTIME;
|
||||||
|
|
||||||
if (do_update) {
|
if (do_update) {
|
||||||
if (readdirplus_enabled)
|
if (readdirplus_enabled)
|
||||||
@ -1003,6 +1019,7 @@ out_no_revalidate:
|
|||||||
stat->attributes |= STATX_ATTR_CHANGE_MONOTONIC;
|
stat->attributes |= STATX_ATTR_CHANGE_MONOTONIC;
|
||||||
if (S_ISDIR(inode->i_mode))
|
if (S_ISDIR(inode->i_mode))
|
||||||
stat->blksize = NFS_SERVER(inode)->dtsize;
|
stat->blksize = NFS_SERVER(inode)->dtsize;
|
||||||
|
stat->btime = NFS_I(inode)->btime;
|
||||||
out:
|
out:
|
||||||
trace_nfs_getattr_exit(inode, err);
|
trace_nfs_getattr_exit(inode, err);
|
||||||
return err;
|
return err;
|
||||||
@ -1894,7 +1911,7 @@ static int nfs_inode_finish_partial_attr_update(const struct nfs_fattr *fattr,
|
|||||||
NFS_INO_INVALID_ATIME | NFS_INO_INVALID_CTIME |
|
NFS_INO_INVALID_ATIME | NFS_INO_INVALID_CTIME |
|
||||||
NFS_INO_INVALID_MTIME | NFS_INO_INVALID_SIZE |
|
NFS_INO_INVALID_MTIME | NFS_INO_INVALID_SIZE |
|
||||||
NFS_INO_INVALID_BLOCKS | NFS_INO_INVALID_OTHER |
|
NFS_INO_INVALID_BLOCKS | NFS_INO_INVALID_OTHER |
|
||||||
NFS_INO_INVALID_NLINK;
|
NFS_INO_INVALID_NLINK | NFS_INO_INVALID_BTIME;
|
||||||
unsigned long cache_validity = NFS_I(inode)->cache_validity;
|
unsigned long cache_validity = NFS_I(inode)->cache_validity;
|
||||||
enum nfs4_change_attr_type ctype = NFS_SERVER(inode)->change_attr_type;
|
enum nfs4_change_attr_type ctype = NFS_SERVER(inode)->change_attr_type;
|
||||||
|
|
||||||
@ -2160,7 +2177,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|||||||
bool attr_changed = false;
|
bool attr_changed = false;
|
||||||
bool have_delegation;
|
bool have_delegation;
|
||||||
|
|
||||||
dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%x)\n",
|
dfprintk(VFS, "NFS: %s(%s/%lu fh_crc=0x%08x ct=%d info=0x%llx)\n",
|
||||||
__func__, inode->i_sb->s_id, inode->i_ino,
|
__func__, inode->i_sb->s_id, inode->i_ino,
|
||||||
nfs_display_fhandle_hash(NFS_FH(inode)),
|
nfs_display_fhandle_hash(NFS_FH(inode)),
|
||||||
atomic_read(&inode->i_count), fattr->valid);
|
atomic_read(&inode->i_count), fattr->valid);
|
||||||
@ -2255,7 +2272,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|||||||
| NFS_INO_INVALID_BLOCKS
|
| NFS_INO_INVALID_BLOCKS
|
||||||
| NFS_INO_INVALID_NLINK
|
| NFS_INO_INVALID_NLINK
|
||||||
| NFS_INO_INVALID_MODE
|
| NFS_INO_INVALID_MODE
|
||||||
| NFS_INO_INVALID_OTHER;
|
| NFS_INO_INVALID_OTHER
|
||||||
|
| NFS_INO_INVALID_BTIME;
|
||||||
if (S_ISDIR(inode->i_mode))
|
if (S_ISDIR(inode->i_mode))
|
||||||
nfs_force_lookup_revalidate(inode);
|
nfs_force_lookup_revalidate(inode);
|
||||||
attr_changed = true;
|
attr_changed = true;
|
||||||
@ -2289,6 +2307,12 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
|
|||||||
nfsi->cache_validity |=
|
nfsi->cache_validity |=
|
||||||
save_cache_validity & NFS_INO_INVALID_CTIME;
|
save_cache_validity & NFS_INO_INVALID_CTIME;
|
||||||
|
|
||||||
|
if (fattr->valid & NFS_ATTR_FATTR_BTIME)
|
||||||
|
nfsi->btime = fattr->btime;
|
||||||
|
else if (fattr_supported & NFS_ATTR_FATTR_BTIME)
|
||||||
|
nfsi->cache_validity |=
|
||||||
|
save_cache_validity & NFS_INO_INVALID_BTIME;
|
||||||
|
|
||||||
/* Check if our cached file size is stale */
|
/* Check if our cached file size is stale */
|
||||||
if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
|
if (fattr->valid & NFS_ATTR_FATTR_SIZE) {
|
||||||
new_isize = nfs_size_to_loff_t(fattr->size);
|
new_isize = nfs_size_to_loff_t(fattr->size);
|
||||||
|
|||||||
@ -618,9 +618,12 @@ nfs_write_match_verf(const struct nfs_writeverf *verf,
|
|||||||
|
|
||||||
static inline gfp_t nfs_io_gfp_mask(void)
|
static inline gfp_t nfs_io_gfp_mask(void)
|
||||||
{
|
{
|
||||||
if (current->flags & PF_WQ_WORKER)
|
gfp_t ret = current_gfp_context(GFP_KERNEL);
|
||||||
return GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN;
|
|
||||||
return GFP_KERNEL;
|
/* For workers __GFP_NORETRY only with __GFP_IO or __GFP_FS */
|
||||||
|
if ((current->flags & PF_WQ_WORKER) && ret == GFP_KERNEL)
|
||||||
|
ret |= __GFP_NORETRY | __GFP_NOWARN;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -210,6 +210,7 @@ const u32 nfs4_fattr_bitmap[3] = {
|
|||||||
| FATTR4_WORD1_RAWDEV
|
| FATTR4_WORD1_RAWDEV
|
||||||
| FATTR4_WORD1_SPACE_USED
|
| FATTR4_WORD1_SPACE_USED
|
||||||
| FATTR4_WORD1_TIME_ACCESS
|
| FATTR4_WORD1_TIME_ACCESS
|
||||||
|
| FATTR4_WORD1_TIME_CREATE
|
||||||
| FATTR4_WORD1_TIME_METADATA
|
| FATTR4_WORD1_TIME_METADATA
|
||||||
| FATTR4_WORD1_TIME_MODIFY
|
| FATTR4_WORD1_TIME_MODIFY
|
||||||
| FATTR4_WORD1_MOUNTED_ON_FILEID,
|
| FATTR4_WORD1_MOUNTED_ON_FILEID,
|
||||||
@ -231,6 +232,7 @@ static const u32 nfs4_pnfs_open_bitmap[3] = {
|
|||||||
| FATTR4_WORD1_RAWDEV
|
| FATTR4_WORD1_RAWDEV
|
||||||
| FATTR4_WORD1_SPACE_USED
|
| FATTR4_WORD1_SPACE_USED
|
||||||
| FATTR4_WORD1_TIME_ACCESS
|
| FATTR4_WORD1_TIME_ACCESS
|
||||||
|
| FATTR4_WORD1_TIME_CREATE
|
||||||
| FATTR4_WORD1_TIME_METADATA
|
| FATTR4_WORD1_TIME_METADATA
|
||||||
| FATTR4_WORD1_TIME_MODIFY,
|
| FATTR4_WORD1_TIME_MODIFY,
|
||||||
FATTR4_WORD2_MDSTHRESHOLD
|
FATTR4_WORD2_MDSTHRESHOLD
|
||||||
@ -311,6 +313,9 @@ static void nfs4_bitmap_copy_adjust(__u32 *dst, const __u32 *src,
|
|||||||
if (!(cache_validity & NFS_INO_INVALID_OTHER))
|
if (!(cache_validity & NFS_INO_INVALID_OTHER))
|
||||||
dst[1] &= ~(FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP);
|
dst[1] &= ~(FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP);
|
||||||
|
|
||||||
|
if (!(cache_validity & NFS_INO_INVALID_BTIME))
|
||||||
|
dst[1] &= ~FATTR4_WORD1_TIME_CREATE;
|
||||||
|
|
||||||
if (nfs_have_delegated_mtime(inode)) {
|
if (nfs_have_delegated_mtime(inode)) {
|
||||||
if (!(cache_validity & NFS_INO_INVALID_ATIME))
|
if (!(cache_validity & NFS_INO_INVALID_ATIME))
|
||||||
dst[1] &= ~FATTR4_WORD1_TIME_ACCESS;
|
dst[1] &= ~FATTR4_WORD1_TIME_ACCESS;
|
||||||
@ -1282,7 +1287,8 @@ nfs4_update_changeattr_locked(struct inode *inode,
|
|||||||
NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL |
|
NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL |
|
||||||
NFS_INO_INVALID_SIZE | NFS_INO_INVALID_OTHER |
|
NFS_INO_INVALID_SIZE | NFS_INO_INVALID_OTHER |
|
||||||
NFS_INO_INVALID_BLOCKS | NFS_INO_INVALID_NLINK |
|
NFS_INO_INVALID_BLOCKS | NFS_INO_INVALID_NLINK |
|
||||||
NFS_INO_INVALID_MODE | NFS_INO_INVALID_XATTR;
|
NFS_INO_INVALID_MODE | NFS_INO_INVALID_BTIME |
|
||||||
|
NFS_INO_INVALID_XATTR;
|
||||||
nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
|
nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
|
||||||
}
|
}
|
||||||
nfsi->attrtimeo_timestamp = jiffies;
|
nfsi->attrtimeo_timestamp = jiffies;
|
||||||
@ -4021,6 +4027,10 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
|
|||||||
server->fattr_valid &= ~NFS_ATTR_FATTR_CTIME;
|
server->fattr_valid &= ~NFS_ATTR_FATTR_CTIME;
|
||||||
if (!(res.attr_bitmask[1] & FATTR4_WORD1_TIME_MODIFY))
|
if (!(res.attr_bitmask[1] & FATTR4_WORD1_TIME_MODIFY))
|
||||||
server->fattr_valid &= ~NFS_ATTR_FATTR_MTIME;
|
server->fattr_valid &= ~NFS_ATTR_FATTR_MTIME;
|
||||||
|
if (!(res.attr_bitmask[1] & FATTR4_WORD1_TIME_MODIFY))
|
||||||
|
server->fattr_valid &= ~NFS_ATTR_FATTR_MTIME;
|
||||||
|
if (!(res.attr_bitmask[1] & FATTR4_WORD1_TIME_CREATE))
|
||||||
|
server->fattr_valid &= ~NFS_ATTR_FATTR_BTIME;
|
||||||
memcpy(server->attr_bitmask_nl, res.attr_bitmask,
|
memcpy(server->attr_bitmask_nl, res.attr_bitmask,
|
||||||
sizeof(server->attr_bitmask));
|
sizeof(server->attr_bitmask));
|
||||||
server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
|
server->attr_bitmask_nl[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
|
||||||
@ -5728,6 +5738,8 @@ void nfs4_bitmask_set(__u32 bitmask[], const __u32 src[],
|
|||||||
bitmask[1] |= FATTR4_WORD1_TIME_MODIFY;
|
bitmask[1] |= FATTR4_WORD1_TIME_MODIFY;
|
||||||
if (cache_validity & NFS_INO_INVALID_BLOCKS)
|
if (cache_validity & NFS_INO_INVALID_BLOCKS)
|
||||||
bitmask[1] |= FATTR4_WORD1_SPACE_USED;
|
bitmask[1] |= FATTR4_WORD1_SPACE_USED;
|
||||||
|
if (cache_validity & NFS_INO_INVALID_BTIME)
|
||||||
|
bitmask[1] |= FATTR4_WORD1_TIME_CREATE;
|
||||||
|
|
||||||
if (cache_validity & NFS_INO_INVALID_SIZE)
|
if (cache_validity & NFS_INO_INVALID_SIZE)
|
||||||
bitmask[0] |= FATTR4_WORD0_SIZE;
|
bitmask[0] |= FATTR4_WORD0_SIZE;
|
||||||
|
|||||||
@ -30,7 +30,8 @@
|
|||||||
{ NFS_ATTR_FATTR_CTIME, "CTIME" }, \
|
{ NFS_ATTR_FATTR_CTIME, "CTIME" }, \
|
||||||
{ NFS_ATTR_FATTR_CHANGE, "CHANGE" }, \
|
{ NFS_ATTR_FATTR_CHANGE, "CHANGE" }, \
|
||||||
{ NFS_ATTR_FATTR_OWNER_NAME, "OWNER_NAME" }, \
|
{ NFS_ATTR_FATTR_OWNER_NAME, "OWNER_NAME" }, \
|
||||||
{ NFS_ATTR_FATTR_GROUP_NAME, "GROUP_NAME" })
|
{ NFS_ATTR_FATTR_GROUP_NAME, "GROUP_NAME" }, \
|
||||||
|
{ NFS_ATTR_FATTR_BTIME, "BTIME" })
|
||||||
|
|
||||||
DECLARE_EVENT_CLASS(nfs4_clientid_event,
|
DECLARE_EVENT_CLASS(nfs4_clientid_event,
|
||||||
TP_PROTO(
|
TP_PROTO(
|
||||||
|
|||||||
@ -1631,6 +1631,7 @@ static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
|
|||||||
| FATTR4_WORD1_RAWDEV
|
| FATTR4_WORD1_RAWDEV
|
||||||
| FATTR4_WORD1_SPACE_USED
|
| FATTR4_WORD1_SPACE_USED
|
||||||
| FATTR4_WORD1_TIME_ACCESS
|
| FATTR4_WORD1_TIME_ACCESS
|
||||||
|
| FATTR4_WORD1_TIME_CREATE
|
||||||
| FATTR4_WORD1_TIME_METADATA
|
| FATTR4_WORD1_TIME_METADATA
|
||||||
| FATTR4_WORD1_TIME_MODIFY;
|
| FATTR4_WORD1_TIME_MODIFY;
|
||||||
attrs[2] |= FATTR4_WORD2_SECURITY_LABEL;
|
attrs[2] |= FATTR4_WORD2_SECURITY_LABEL;
|
||||||
@ -4215,6 +4216,24 @@ static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, str
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int decode_attr_time_create(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec64 *time)
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
|
||||||
|
time->tv_sec = 0;
|
||||||
|
time->tv_nsec = 0;
|
||||||
|
if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_CREATE - 1U)))
|
||||||
|
return -EIO;
|
||||||
|
if (likely(bitmap[1] & FATTR4_WORD1_TIME_CREATE)) {
|
||||||
|
status = decode_attr_time(xdr, time);
|
||||||
|
if (status == 0)
|
||||||
|
status = NFS_ATTR_FATTR_BTIME;
|
||||||
|
bitmap[1] &= ~FATTR4_WORD1_TIME_CREATE;
|
||||||
|
}
|
||||||
|
dprintk("%s: btime=%lld\n", __func__, time->tv_sec);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec64 *time)
|
static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec64 *time)
|
||||||
{
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
@ -4798,6 +4817,11 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
|
|||||||
goto xdr_error;
|
goto xdr_error;
|
||||||
fattr->valid |= status;
|
fattr->valid |= status;
|
||||||
|
|
||||||
|
status = decode_attr_time_create(xdr, bitmap, &fattr->btime);
|
||||||
|
if (status < 0)
|
||||||
|
goto xdr_error;
|
||||||
|
fattr->valid |= status;
|
||||||
|
|
||||||
status = decode_attr_time_metadata(xdr, bitmap, &fattr->ctime);
|
status = decode_attr_time_metadata(xdr, bitmap, &fattr->ctime);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
goto xdr_error;
|
goto xdr_error;
|
||||||
|
|||||||
@ -32,7 +32,8 @@
|
|||||||
{ NFS_INO_INVALID_BLOCKS, "INVALID_BLOCKS" }, \
|
{ NFS_INO_INVALID_BLOCKS, "INVALID_BLOCKS" }, \
|
||||||
{ NFS_INO_INVALID_XATTR, "INVALID_XATTR" }, \
|
{ NFS_INO_INVALID_XATTR, "INVALID_XATTR" }, \
|
||||||
{ NFS_INO_INVALID_NLINK, "INVALID_NLINK" }, \
|
{ NFS_INO_INVALID_NLINK, "INVALID_NLINK" }, \
|
||||||
{ NFS_INO_INVALID_MODE, "INVALID_MODE" })
|
{ NFS_INO_INVALID_MODE, "INVALID_MODE" }, \
|
||||||
|
{ NFS_INO_INVALID_BTIME, "INVALID_BTIME" })
|
||||||
|
|
||||||
#define nfs_show_nfsi_flags(v) \
|
#define nfs_show_nfsi_flags(v) \
|
||||||
__print_flags(v, "|", \
|
__print_flags(v, "|", \
|
||||||
|
|||||||
@ -514,7 +514,7 @@ static int persistent_ram_post_init(struct persistent_ram_zone *prz, u32 sig,
|
|||||||
sig ^= PERSISTENT_RAM_SIG;
|
sig ^= PERSISTENT_RAM_SIG;
|
||||||
|
|
||||||
if (prz->buffer->sig == sig) {
|
if (prz->buffer->sig == sig) {
|
||||||
if (buffer_size(prz) == 0) {
|
if (buffer_size(prz) == 0 && buffer_start(prz) == 0) {
|
||||||
pr_debug("found existing empty buffer\n");
|
pr_debug("found existing empty buffer\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -86,7 +86,7 @@
|
|||||||
#define SMB_INTERFACE_POLL_INTERVAL 600
|
#define SMB_INTERFACE_POLL_INTERVAL 600
|
||||||
|
|
||||||
/* maximum number of PDUs in one compound */
|
/* maximum number of PDUs in one compound */
|
||||||
#define MAX_COMPOUND 7
|
#define MAX_COMPOUND 10
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default number of credits to keep available for SMB3.
|
* Default number of credits to keep available for SMB3.
|
||||||
@ -1921,9 +1921,12 @@ static inline bool is_replayable_error(int error)
|
|||||||
|
|
||||||
|
|
||||||
/* cifs_get_writable_file() flags */
|
/* cifs_get_writable_file() flags */
|
||||||
#define FIND_WR_ANY 0
|
enum cifs_writable_file_flags {
|
||||||
#define FIND_WR_FSUID_ONLY 1
|
FIND_WR_ANY = 0U,
|
||||||
#define FIND_WR_WITH_DELETE 2
|
FIND_WR_FSUID_ONLY = (1U << 0),
|
||||||
|
FIND_WR_WITH_DELETE = (1U << 1),
|
||||||
|
FIND_WR_NO_PENDING_DELETE = (1U << 2),
|
||||||
|
};
|
||||||
|
|
||||||
#define MID_FREE 0
|
#define MID_FREE 0
|
||||||
#define MID_REQUEST_ALLOCATED 1
|
#define MID_REQUEST_ALLOCATED 1
|
||||||
@ -2357,6 +2360,8 @@ struct smb2_compound_vars {
|
|||||||
struct kvec qi_iov;
|
struct kvec qi_iov;
|
||||||
struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
|
struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
|
||||||
struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
|
struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
|
||||||
|
struct kvec unlink_iov[SMB2_SET_INFO_IOV_SIZE];
|
||||||
|
struct kvec rename_iov[SMB2_SET_INFO_IOV_SIZE];
|
||||||
struct kvec close_iov;
|
struct kvec close_iov;
|
||||||
struct smb2_file_rename_info rename_info;
|
struct smb2_file_rename_info rename_info;
|
||||||
struct smb2_file_link_info link_info;
|
struct smb2_file_link_info link_info;
|
||||||
|
|||||||
@ -293,8 +293,8 @@ extern void cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode);
|
|||||||
|
|
||||||
extern void cifs_close_all_deferred_files(struct cifs_tcon *cifs_tcon);
|
extern void cifs_close_all_deferred_files(struct cifs_tcon *cifs_tcon);
|
||||||
|
|
||||||
extern void cifs_close_deferred_file_under_dentry(struct cifs_tcon *cifs_tcon,
|
void cifs_close_deferred_file_under_dentry(struct cifs_tcon *cifs_tcon,
|
||||||
const char *path);
|
struct dentry *dentry);
|
||||||
|
|
||||||
extern void cifs_mark_open_handles_for_deleted_file(struct inode *inode,
|
extern void cifs_mark_open_handles_for_deleted_file(struct inode *inode,
|
||||||
const char *path);
|
const char *path);
|
||||||
|
|||||||
@ -680,7 +680,10 @@ int cifs_open(struct inode *inode, struct file *file)
|
|||||||
|
|
||||||
/* Get the cached handle as SMB2 close is deferred */
|
/* Get the cached handle as SMB2 close is deferred */
|
||||||
if (OPEN_FMODE(file->f_flags) & FMODE_WRITE) {
|
if (OPEN_FMODE(file->f_flags) & FMODE_WRITE) {
|
||||||
rc = cifs_get_writable_path(tcon, full_path, FIND_WR_FSUID_ONLY, &cfile);
|
rc = cifs_get_writable_path(tcon, full_path,
|
||||||
|
FIND_WR_FSUID_ONLY |
|
||||||
|
FIND_WR_NO_PENDING_DELETE,
|
||||||
|
&cfile);
|
||||||
} else {
|
} else {
|
||||||
rc = cifs_get_readable_path(tcon, full_path, &cfile);
|
rc = cifs_get_readable_path(tcon, full_path, &cfile);
|
||||||
}
|
}
|
||||||
@ -2285,6 +2288,9 @@ refind_writable:
|
|||||||
continue;
|
continue;
|
||||||
if (with_delete && !(open_file->fid.access & DELETE))
|
if (with_delete && !(open_file->fid.access & DELETE))
|
||||||
continue;
|
continue;
|
||||||
|
if ((flags & FIND_WR_NO_PENDING_DELETE) &&
|
||||||
|
open_file->status_file_deleted)
|
||||||
|
continue;
|
||||||
if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
|
if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
|
||||||
if (!open_file->invalidHandle) {
|
if (!open_file->invalidHandle) {
|
||||||
/* found a good writable file */
|
/* found a good writable file */
|
||||||
@ -2402,6 +2408,16 @@ cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,
|
|||||||
spin_unlock(&tcon->open_file_lock);
|
spin_unlock(&tcon->open_file_lock);
|
||||||
free_dentry_path(page);
|
free_dentry_path(page);
|
||||||
*ret_file = find_readable_file(cinode, 0);
|
*ret_file = find_readable_file(cinode, 0);
|
||||||
|
if (*ret_file) {
|
||||||
|
spin_lock(&cinode->open_file_lock);
|
||||||
|
if ((*ret_file)->status_file_deleted) {
|
||||||
|
spin_unlock(&cinode->open_file_lock);
|
||||||
|
cifsFileInfo_put(*ret_file);
|
||||||
|
*ret_file = NULL;
|
||||||
|
} else {
|
||||||
|
spin_unlock(&cinode->open_file_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
return *ret_file ? 0 : -ENOENT;
|
return *ret_file ? 0 : -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1890,7 +1890,7 @@ cifs_drop_nlink(struct inode *inode)
|
|||||||
* but will return the EACCES to the caller. Note that the VFS does not call
|
* but will return the EACCES to the caller. Note that the VFS does not call
|
||||||
* unlink on negative dentries currently.
|
* unlink on negative dentries currently.
|
||||||
*/
|
*/
|
||||||
int cifs_unlink(struct inode *dir, struct dentry *dentry)
|
static int __cifs_unlink(struct inode *dir, struct dentry *dentry, bool sillyrename)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
unsigned int xid;
|
unsigned int xid;
|
||||||
@ -1942,7 +1942,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
|
|||||||
goto unlink_out;
|
goto unlink_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
cifs_close_deferred_file_under_dentry(tcon, full_path);
|
cifs_close_deferred_file_under_dentry(tcon, dentry);
|
||||||
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
|
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
|
||||||
if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
|
if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
|
||||||
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
|
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
|
||||||
@ -1961,7 +1961,24 @@ retry_std_delete:
|
|||||||
goto psx_del_no_retry;
|
goto psx_del_no_retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = server->ops->unlink(xid, tcon, full_path, cifs_sb, dentry);
|
/* For SMB2+, if the file is open, we always perform a silly rename.
|
||||||
|
*
|
||||||
|
* We check for d_count() right after calling
|
||||||
|
* cifs_close_deferred_file_under_dentry() to make sure that the
|
||||||
|
* dentry's refcount gets dropped in case the file had any deferred
|
||||||
|
* close.
|
||||||
|
*/
|
||||||
|
if (!sillyrename && server->vals->protocol_id > SMB10_PROT_ID) {
|
||||||
|
spin_lock(&dentry->d_lock);
|
||||||
|
if (d_count(dentry) > 1)
|
||||||
|
sillyrename = true;
|
||||||
|
spin_unlock(&dentry->d_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sillyrename)
|
||||||
|
rc = -EBUSY;
|
||||||
|
else
|
||||||
|
rc = server->ops->unlink(xid, tcon, full_path, cifs_sb, dentry);
|
||||||
|
|
||||||
psx_del_no_retry:
|
psx_del_no_retry:
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
@ -2029,6 +2046,11 @@ unlink_out:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cifs_unlink(struct inode *dir, struct dentry *dentry)
|
||||||
|
{
|
||||||
|
return __cifs_unlink(dir, dentry, false);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode,
|
cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode,
|
||||||
const char *full_path, struct cifs_sb_info *cifs_sb,
|
const char *full_path, struct cifs_sb_info *cifs_sb,
|
||||||
@ -2316,14 +2338,16 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
|
|||||||
rc = server->ops->rmdir(xid, tcon, full_path, cifs_sb);
|
rc = server->ops->rmdir(xid, tcon, full_path, cifs_sb);
|
||||||
cifs_put_tlink(tlink);
|
cifs_put_tlink(tlink);
|
||||||
|
|
||||||
|
cifsInode = CIFS_I(d_inode(direntry));
|
||||||
|
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
|
set_bit(CIFS_INO_DELETE_PENDING, &cifsInode->flags);
|
||||||
spin_lock(&d_inode(direntry)->i_lock);
|
spin_lock(&d_inode(direntry)->i_lock);
|
||||||
i_size_write(d_inode(direntry), 0);
|
i_size_write(d_inode(direntry), 0);
|
||||||
clear_nlink(d_inode(direntry));
|
clear_nlink(d_inode(direntry));
|
||||||
spin_unlock(&d_inode(direntry)->i_lock);
|
spin_unlock(&d_inode(direntry)->i_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
cifsInode = CIFS_I(d_inode(direntry));
|
|
||||||
/* force revalidate to go get info when needed */
|
/* force revalidate to go get info when needed */
|
||||||
cifsInode->time = 0;
|
cifsInode->time = 0;
|
||||||
|
|
||||||
@ -2416,8 +2440,11 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry,
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
|
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
|
||||||
do_rename_exit:
|
do_rename_exit:
|
||||||
if (rc == 0)
|
if (rc == 0) {
|
||||||
d_move(from_dentry, to_dentry);
|
d_move(from_dentry, to_dentry);
|
||||||
|
/* Force a new lookup */
|
||||||
|
d_drop(from_dentry);
|
||||||
|
}
|
||||||
cifs_put_tlink(tlink);
|
cifs_put_tlink(tlink);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -2428,6 +2455,7 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode *source_dir,
|
|||||||
struct dentry *target_dentry, unsigned int flags)
|
struct dentry *target_dentry, unsigned int flags)
|
||||||
{
|
{
|
||||||
const char *from_name, *to_name;
|
const char *from_name, *to_name;
|
||||||
|
struct TCP_Server_Info *server;
|
||||||
void *page1, *page2;
|
void *page1, *page2;
|
||||||
struct cifs_sb_info *cifs_sb;
|
struct cifs_sb_info *cifs_sb;
|
||||||
struct tcon_link *tlink;
|
struct tcon_link *tlink;
|
||||||
@ -2463,6 +2491,7 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode *source_dir,
|
|||||||
if (IS_ERR(tlink))
|
if (IS_ERR(tlink))
|
||||||
return PTR_ERR(tlink);
|
return PTR_ERR(tlink);
|
||||||
tcon = tlink_tcon(tlink);
|
tcon = tlink_tcon(tlink);
|
||||||
|
server = tcon->ses->server;
|
||||||
|
|
||||||
page1 = alloc_dentry_path();
|
page1 = alloc_dentry_path();
|
||||||
page2 = alloc_dentry_path();
|
page2 = alloc_dentry_path();
|
||||||
@ -2480,9 +2509,9 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode *source_dir,
|
|||||||
goto cifs_rename_exit;
|
goto cifs_rename_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
cifs_close_deferred_file_under_dentry(tcon, from_name);
|
cifs_close_deferred_file_under_dentry(tcon, source_dentry);
|
||||||
if (d_inode(target_dentry) != NULL)
|
if (d_inode(target_dentry) != NULL)
|
||||||
cifs_close_deferred_file_under_dentry(tcon, to_name);
|
cifs_close_deferred_file_under_dentry(tcon, target_dentry);
|
||||||
|
|
||||||
rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry,
|
rc = cifs_do_rename(xid, source_dentry, from_name, target_dentry,
|
||||||
to_name);
|
to_name);
|
||||||
@ -2547,19 +2576,52 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode *source_dir,
|
|||||||
|
|
||||||
unlink_target:
|
unlink_target:
|
||||||
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
|
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
|
||||||
|
if (d_really_is_positive(target_dentry)) {
|
||||||
/* Try unlinking the target dentry if it's not negative */
|
if (!rc) {
|
||||||
if (d_really_is_positive(target_dentry) && (rc == -EACCES || rc == -EEXIST)) {
|
struct inode *inode = d_inode(target_dentry);
|
||||||
if (d_is_dir(target_dentry))
|
/*
|
||||||
tmprc = cifs_rmdir(target_dir, target_dentry);
|
* Samba and ksmbd servers allow renaming a target
|
||||||
else
|
* directory that is open, so make sure to update
|
||||||
tmprc = cifs_unlink(target_dir, target_dentry);
|
* ->i_nlink and then mark it as delete pending.
|
||||||
if (tmprc)
|
*/
|
||||||
goto cifs_rename_exit;
|
if (S_ISDIR(inode->i_mode)) {
|
||||||
rc = cifs_do_rename(xid, source_dentry, from_name,
|
drop_cached_dir_by_name(xid, tcon, to_name, cifs_sb);
|
||||||
target_dentry, to_name);
|
spin_lock(&inode->i_lock);
|
||||||
if (!rc)
|
i_size_write(inode, 0);
|
||||||
rehash = false;
|
clear_nlink(inode);
|
||||||
|
spin_unlock(&inode->i_lock);
|
||||||
|
set_bit(CIFS_INO_DELETE_PENDING, &CIFS_I(inode)->flags);
|
||||||
|
CIFS_I(inode)->time = 0; /* force reval */
|
||||||
|
inode->i_mtime = inode_set_ctime_current(inode);
|
||||||
|
}
|
||||||
|
} else if (rc == -EACCES || rc == -EEXIST) {
|
||||||
|
/*
|
||||||
|
* Rename failed, possibly due to a busy target.
|
||||||
|
* Retry it by unliking the target first.
|
||||||
|
*/
|
||||||
|
if (d_is_dir(target_dentry)) {
|
||||||
|
tmprc = cifs_rmdir(target_dir, target_dentry);
|
||||||
|
} else {
|
||||||
|
tmprc = __cifs_unlink(target_dir, target_dentry,
|
||||||
|
server->vals->protocol_id > SMB10_PROT_ID);
|
||||||
|
}
|
||||||
|
if (tmprc) {
|
||||||
|
/*
|
||||||
|
* Some servers will return STATUS_ACCESS_DENIED
|
||||||
|
* or STATUS_DIRECTORY_NOT_EMPTY when failing to
|
||||||
|
* rename a non-empty directory. Make sure to
|
||||||
|
* propagate the appropriate error back to
|
||||||
|
* userspace.
|
||||||
|
*/
|
||||||
|
if (tmprc == -EEXIST || tmprc == -ENOTEMPTY)
|
||||||
|
rc = tmprc;
|
||||||
|
goto cifs_rename_exit;
|
||||||
|
}
|
||||||
|
rc = cifs_do_rename(xid, source_dentry, from_name,
|
||||||
|
target_dentry, to_name);
|
||||||
|
if (!rc)
|
||||||
|
rehash = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* force revalidate to go get info when needed */
|
/* force revalidate to go get info when needed */
|
||||||
@ -2588,6 +2650,8 @@ cifs_dentry_needs_reval(struct dentry *dentry)
|
|||||||
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
|
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
|
||||||
struct cached_fid *cfid = NULL;
|
struct cached_fid *cfid = NULL;
|
||||||
|
|
||||||
|
if (test_bit(CIFS_INO_DELETE_PENDING, &cifs_i->flags))
|
||||||
|
return false;
|
||||||
if (cifs_i->time == 0)
|
if (cifs_i->time == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|||||||
@ -816,33 +816,28 @@ cifs_close_all_deferred_files(struct cifs_tcon *tcon)
|
|||||||
kfree(tmp_list);
|
kfree(tmp_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void
|
|
||||||
cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path)
|
void cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon,
|
||||||
|
struct dentry *dentry)
|
||||||
{
|
{
|
||||||
struct cifsFileInfo *cfile;
|
|
||||||
struct file_list *tmp_list, *tmp_next_list;
|
struct file_list *tmp_list, *tmp_next_list;
|
||||||
void *page;
|
struct cifsFileInfo *cfile;
|
||||||
const char *full_path;
|
|
||||||
LIST_HEAD(file_head);
|
LIST_HEAD(file_head);
|
||||||
|
|
||||||
page = alloc_dentry_path();
|
|
||||||
spin_lock(&tcon->open_file_lock);
|
spin_lock(&tcon->open_file_lock);
|
||||||
list_for_each_entry(cfile, &tcon->openFileList, tlist) {
|
list_for_each_entry(cfile, &tcon->openFileList, tlist) {
|
||||||
full_path = build_path_from_dentry(cfile->dentry, page);
|
if ((cfile->dentry == dentry) &&
|
||||||
if (strstr(full_path, path)) {
|
delayed_work_pending(&cfile->deferred) &&
|
||||||
if (delayed_work_pending(&cfile->deferred)) {
|
cancel_delayed_work(&cfile->deferred)) {
|
||||||
if (cancel_delayed_work(&cfile->deferred)) {
|
spin_lock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
|
||||||
spin_lock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
|
cifs_del_deferred_close(cfile);
|
||||||
cifs_del_deferred_close(cfile);
|
spin_unlock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
|
||||||
spin_unlock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock);
|
|
||||||
|
|
||||||
tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
|
tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC);
|
||||||
if (tmp_list == NULL)
|
if (tmp_list == NULL)
|
||||||
break;
|
break;
|
||||||
tmp_list->cfile = cfile;
|
tmp_list->cfile = cfile;
|
||||||
list_add_tail(&tmp_list->list, &file_head);
|
list_add_tail(&tmp_list->list, &file_head);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock(&tcon->open_file_lock);
|
spin_unlock(&tcon->open_file_lock);
|
||||||
@ -852,7 +847,6 @@ cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, const char *path)
|
|||||||
list_del(&tmp_list->list);
|
list_del(&tmp_list->list);
|
||||||
kfree(tmp_list);
|
kfree(tmp_list);
|
||||||
}
|
}
|
||||||
free_dentry_path(page);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -30,10 +30,9 @@ enum smb2_compound_ops {
|
|||||||
SMB2_OP_QUERY_DIR,
|
SMB2_OP_QUERY_DIR,
|
||||||
SMB2_OP_MKDIR,
|
SMB2_OP_MKDIR,
|
||||||
SMB2_OP_RENAME,
|
SMB2_OP_RENAME,
|
||||||
SMB2_OP_DELETE,
|
|
||||||
SMB2_OP_HARDLINK,
|
SMB2_OP_HARDLINK,
|
||||||
SMB2_OP_SET_EOF,
|
SMB2_OP_SET_EOF,
|
||||||
SMB2_OP_RMDIR,
|
SMB2_OP_UNLINK,
|
||||||
SMB2_OP_POSIX_QUERY_INFO,
|
SMB2_OP_POSIX_QUERY_INFO,
|
||||||
SMB2_OP_SET_REPARSE,
|
SMB2_OP_SET_REPARSE,
|
||||||
SMB2_OP_GET_REPARSE,
|
SMB2_OP_GET_REPARSE,
|
||||||
|
|||||||
@ -206,8 +206,10 @@ replay_again:
|
|||||||
server = cifs_pick_channel(ses);
|
server = cifs_pick_channel(ses);
|
||||||
|
|
||||||
vars = kzalloc(sizeof(*vars), GFP_ATOMIC);
|
vars = kzalloc(sizeof(*vars), GFP_ATOMIC);
|
||||||
if (vars == NULL)
|
if (vars == NULL) {
|
||||||
return -ENOMEM;
|
rc = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
rqst = &vars->rqst[0];
|
rqst = &vars->rqst[0];
|
||||||
rsp_iov = &vars->rsp_iov[0];
|
rsp_iov = &vars->rsp_iov[0];
|
||||||
|
|
||||||
@ -337,9 +339,6 @@ replay_again:
|
|||||||
trace_smb3_posix_query_info_compound_enter(xid, tcon->tid,
|
trace_smb3_posix_query_info_compound_enter(xid, tcon->tid,
|
||||||
ses->Suid, full_path);
|
ses->Suid, full_path);
|
||||||
break;
|
break;
|
||||||
case SMB2_OP_DELETE:
|
|
||||||
trace_smb3_delete_enter(xid, tcon->tid, ses->Suid, full_path);
|
|
||||||
break;
|
|
||||||
case SMB2_OP_MKDIR:
|
case SMB2_OP_MKDIR:
|
||||||
/*
|
/*
|
||||||
* Directories are created through parameters in the
|
* Directories are created through parameters in the
|
||||||
@ -347,23 +346,40 @@ replay_again:
|
|||||||
*/
|
*/
|
||||||
trace_smb3_mkdir_enter(xid, tcon->tid, ses->Suid, full_path);
|
trace_smb3_mkdir_enter(xid, tcon->tid, ses->Suid, full_path);
|
||||||
break;
|
break;
|
||||||
case SMB2_OP_RMDIR:
|
case SMB2_OP_UNLINK:
|
||||||
rqst[num_rqst].rq_iov = &vars->si_iov[0];
|
rqst[num_rqst].rq_iov = vars->unlink_iov;
|
||||||
rqst[num_rqst].rq_nvec = 1;
|
rqst[num_rqst].rq_nvec = 1;
|
||||||
|
|
||||||
size[0] = 1; /* sizeof __u8 See MS-FSCC section 2.4.11 */
|
size[0] = 1; /* sizeof __u8 See MS-FSCC section 2.4.11 */
|
||||||
data[0] = &delete_pending[0];
|
data[0] = &delete_pending[0];
|
||||||
|
|
||||||
rc = SMB2_set_info_init(tcon, server,
|
if (cfile) {
|
||||||
&rqst[num_rqst], COMPOUND_FID,
|
rc = SMB2_set_info_init(tcon, server,
|
||||||
COMPOUND_FID, current->tgid,
|
&rqst[num_rqst],
|
||||||
FILE_DISPOSITION_INFORMATION,
|
cfile->fid.persistent_fid,
|
||||||
SMB2_O_INFO_FILE, 0, data, size);
|
cfile->fid.volatile_fid,
|
||||||
if (rc)
|
current->tgid,
|
||||||
|
FILE_DISPOSITION_INFORMATION,
|
||||||
|
SMB2_O_INFO_FILE, 0,
|
||||||
|
data, size);
|
||||||
|
} else {
|
||||||
|
rc = SMB2_set_info_init(tcon, server,
|
||||||
|
&rqst[num_rqst],
|
||||||
|
COMPOUND_FID,
|
||||||
|
COMPOUND_FID,
|
||||||
|
current->tgid,
|
||||||
|
FILE_DISPOSITION_INFORMATION,
|
||||||
|
SMB2_O_INFO_FILE, 0,
|
||||||
|
data, size);
|
||||||
|
}
|
||||||
|
if (!rc && (!cfile || num_rqst > 1)) {
|
||||||
|
smb2_set_next_command(tcon, &rqst[num_rqst]);
|
||||||
|
smb2_set_related(&rqst[num_rqst]);
|
||||||
|
} else if (rc) {
|
||||||
goto finished;
|
goto finished;
|
||||||
smb2_set_next_command(tcon, &rqst[num_rqst]);
|
}
|
||||||
smb2_set_related(&rqst[num_rqst++]);
|
num_rqst++;
|
||||||
trace_smb3_rmdir_enter(xid, tcon->tid, ses->Suid, full_path);
|
trace_smb3_unlink_enter(xid, tcon->tid, ses->Suid, full_path);
|
||||||
break;
|
break;
|
||||||
case SMB2_OP_SET_EOF:
|
case SMB2_OP_SET_EOF:
|
||||||
rqst[num_rqst].rq_iov = &vars->si_iov[0];
|
rqst[num_rqst].rq_iov = &vars->si_iov[0];
|
||||||
@ -433,7 +449,7 @@ replay_again:
|
|||||||
ses->Suid, full_path);
|
ses->Suid, full_path);
|
||||||
break;
|
break;
|
||||||
case SMB2_OP_RENAME:
|
case SMB2_OP_RENAME:
|
||||||
rqst[num_rqst].rq_iov = &vars->si_iov[0];
|
rqst[num_rqst].rq_iov = vars->rename_iov;
|
||||||
rqst[num_rqst].rq_nvec = 2;
|
rqst[num_rqst].rq_nvec = 2;
|
||||||
|
|
||||||
len = in_iov[i].iov_len;
|
len = in_iov[i].iov_len;
|
||||||
@ -641,7 +657,7 @@ finished:
|
|||||||
|
|
||||||
tmp_rc = rc;
|
tmp_rc = rc;
|
||||||
for (i = 0; i < num_cmds; i++) {
|
for (i = 0; i < num_cmds; i++) {
|
||||||
char *buf = rsp_iov[i + i].iov_base;
|
char *buf = rsp_iov[i + 1].iov_base;
|
||||||
|
|
||||||
if (buf && resp_buftype[i + 1] != CIFS_NO_BUFFER)
|
if (buf && resp_buftype[i + 1] != CIFS_NO_BUFFER)
|
||||||
rc = server->ops->map_error(buf, false);
|
rc = server->ops->map_error(buf, false);
|
||||||
@ -698,19 +714,6 @@ finished:
|
|||||||
trace_smb3_posix_query_info_compound_done(xid, tcon->tid,
|
trace_smb3_posix_query_info_compound_done(xid, tcon->tid,
|
||||||
ses->Suid);
|
ses->Suid);
|
||||||
break;
|
break;
|
||||||
case SMB2_OP_DELETE:
|
|
||||||
if (rc)
|
|
||||||
trace_smb3_delete_err(xid, tcon->tid, ses->Suid, rc);
|
|
||||||
else {
|
|
||||||
/*
|
|
||||||
* If dentry (hence, inode) is NULL, lease break is going to
|
|
||||||
* take care of degrading leases on handles for deleted files.
|
|
||||||
*/
|
|
||||||
if (inode)
|
|
||||||
cifs_mark_open_handles_for_deleted_file(inode, full_path);
|
|
||||||
trace_smb3_delete_done(xid, tcon->tid, ses->Suid);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SMB2_OP_MKDIR:
|
case SMB2_OP_MKDIR:
|
||||||
if (rc)
|
if (rc)
|
||||||
trace_smb3_mkdir_err(xid, tcon->tid, ses->Suid, rc);
|
trace_smb3_mkdir_err(xid, tcon->tid, ses->Suid, rc);
|
||||||
@ -731,11 +734,11 @@ finished:
|
|||||||
trace_smb3_rename_done(xid, tcon->tid, ses->Suid);
|
trace_smb3_rename_done(xid, tcon->tid, ses->Suid);
|
||||||
SMB2_set_info_free(&rqst[num_rqst++]);
|
SMB2_set_info_free(&rqst[num_rqst++]);
|
||||||
break;
|
break;
|
||||||
case SMB2_OP_RMDIR:
|
case SMB2_OP_UNLINK:
|
||||||
if (rc)
|
if (!rc)
|
||||||
trace_smb3_rmdir_err(xid, tcon->tid, ses->Suid, rc);
|
trace_smb3_unlink_done(xid, tcon->tid, ses->Suid);
|
||||||
else
|
else
|
||||||
trace_smb3_rmdir_done(xid, tcon->tid, ses->Suid);
|
trace_smb3_unlink_err(xid, tcon->tid, ses->Suid, rc);
|
||||||
SMB2_set_info_free(&rqst[num_rqst++]);
|
SMB2_set_info_free(&rqst[num_rqst++]);
|
||||||
break;
|
break;
|
||||||
case SMB2_OP_SET_EOF:
|
case SMB2_OP_SET_EOF:
|
||||||
@ -830,6 +833,7 @@ finished:
|
|||||||
smb2_should_replay(tcon, &retries, &cur_sleep))
|
smb2_should_replay(tcon, &retries, &cur_sleep))
|
||||||
goto replay_again;
|
goto replay_again;
|
||||||
|
|
||||||
|
out:
|
||||||
if (cfile)
|
if (cfile)
|
||||||
cifsFileInfo_put(cfile);
|
cifsFileInfo_put(cfile);
|
||||||
|
|
||||||
@ -1091,7 +1095,7 @@ smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
|
|||||||
FILE_OPEN, CREATE_NOT_FILE, ACL_NO_MODE);
|
FILE_OPEN, CREATE_NOT_FILE, ACL_NO_MODE);
|
||||||
return smb2_compound_op(xid, tcon, cifs_sb,
|
return smb2_compound_op(xid, tcon, cifs_sb,
|
||||||
name, &oparms, NULL,
|
name, &oparms, NULL,
|
||||||
&(int){SMB2_OP_RMDIR}, 1,
|
&(int){SMB2_OP_UNLINK}, 1,
|
||||||
NULL, NULL, NULL, NULL);
|
NULL, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1099,21 +1103,107 @@ int
|
|||||||
smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
|
smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
|
||||||
struct cifs_sb_info *cifs_sb, struct dentry *dentry)
|
struct cifs_sb_info *cifs_sb, struct dentry *dentry)
|
||||||
{
|
{
|
||||||
|
struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
|
||||||
|
__le16 *utf16_path __free(kfree) = NULL;
|
||||||
|
int retries = 0, cur_sleep = 1;
|
||||||
|
struct TCP_Server_Info *server;
|
||||||
struct cifs_open_parms oparms;
|
struct cifs_open_parms oparms;
|
||||||
|
struct smb2_create_req *creq;
|
||||||
|
struct inode *inode = NULL;
|
||||||
|
struct smb_rqst rqst[2];
|
||||||
|
struct kvec rsp_iov[2];
|
||||||
|
struct kvec close_iov;
|
||||||
|
int resp_buftype[2];
|
||||||
|
struct cifs_fid fid;
|
||||||
|
int flags = 0;
|
||||||
|
__u8 oplock;
|
||||||
|
int rc;
|
||||||
|
|
||||||
oparms = CIFS_OPARMS(cifs_sb, tcon, name,
|
utf16_path = cifs_convert_path_to_utf16(name, cifs_sb);
|
||||||
DELETE, FILE_OPEN,
|
if (!utf16_path)
|
||||||
CREATE_DELETE_ON_CLOSE | OPEN_REPARSE_POINT,
|
return -ENOMEM;
|
||||||
ACL_NO_MODE);
|
|
||||||
int rc = smb2_compound_op(xid, tcon, cifs_sb, name, &oparms,
|
if (smb3_encryption_required(tcon))
|
||||||
NULL, &(int){SMB2_OP_DELETE}, 1,
|
flags |= CIFS_TRANSFORM_REQ;
|
||||||
NULL, NULL, NULL, dentry);
|
again:
|
||||||
if (rc == -EINVAL) {
|
oplock = SMB2_OPLOCK_LEVEL_NONE;
|
||||||
cifs_dbg(FYI, "invalid lease key, resending request without lease");
|
server = cifs_pick_channel(tcon->ses);
|
||||||
rc = smb2_compound_op(xid, tcon, cifs_sb, name, &oparms,
|
|
||||||
NULL, &(int){SMB2_OP_DELETE}, 1,
|
memset(rqst, 0, sizeof(rqst));
|
||||||
NULL, NULL, NULL, NULL);
|
memset(resp_buftype, 0, sizeof(resp_buftype));
|
||||||
|
memset(rsp_iov, 0, sizeof(rsp_iov));
|
||||||
|
|
||||||
|
rqst[0].rq_iov = open_iov;
|
||||||
|
rqst[0].rq_nvec = ARRAY_SIZE(open_iov);
|
||||||
|
|
||||||
|
oparms = CIFS_OPARMS(cifs_sb, tcon, name, DELETE | FILE_READ_ATTRIBUTES,
|
||||||
|
FILE_OPEN, CREATE_DELETE_ON_CLOSE |
|
||||||
|
OPEN_REPARSE_POINT, ACL_NO_MODE);
|
||||||
|
oparms.fid = &fid;
|
||||||
|
|
||||||
|
if (dentry) {
|
||||||
|
inode = d_inode(dentry);
|
||||||
|
if (CIFS_I(inode)->lease_granted && server->ops->get_lease_key) {
|
||||||
|
oplock = SMB2_OPLOCK_LEVEL_LEASE;
|
||||||
|
server->ops->get_lease_key(inode, &fid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = SMB2_open_init(tcon, server,
|
||||||
|
&rqst[0], &oplock, &oparms, utf16_path);
|
||||||
|
if (rc)
|
||||||
|
goto err_free;
|
||||||
|
smb2_set_next_command(tcon, &rqst[0]);
|
||||||
|
creq = rqst[0].rq_iov[0].iov_base;
|
||||||
|
creq->ShareAccess = FILE_SHARE_DELETE_LE;
|
||||||
|
|
||||||
|
rqst[1].rq_iov = &close_iov;
|
||||||
|
rqst[1].rq_nvec = 1;
|
||||||
|
|
||||||
|
rc = SMB2_close_init(tcon, server, &rqst[1],
|
||||||
|
COMPOUND_FID, COMPOUND_FID, false);
|
||||||
|
smb2_set_related(&rqst[1]);
|
||||||
|
if (rc)
|
||||||
|
goto err_free;
|
||||||
|
|
||||||
|
if (retries) {
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(rqst); i++)
|
||||||
|
smb2_set_replay(server, &rqst[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = compound_send_recv(xid, tcon->ses, server, flags,
|
||||||
|
ARRAY_SIZE(rqst), rqst,
|
||||||
|
resp_buftype, rsp_iov);
|
||||||
|
SMB2_open_free(&rqst[0]);
|
||||||
|
SMB2_close_free(&rqst[1]);
|
||||||
|
free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
|
||||||
|
free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
|
||||||
|
|
||||||
|
if (is_replayable_error(rc) &&
|
||||||
|
smb2_should_replay(tcon, &retries, &cur_sleep))
|
||||||
|
goto again;
|
||||||
|
|
||||||
|
/* Retry compound request without lease */
|
||||||
|
if (rc == -EINVAL && dentry) {
|
||||||
|
dentry = NULL;
|
||||||
|
retries = 0;
|
||||||
|
cur_sleep = 1;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If dentry (hence, inode) is NULL, lease break is going to
|
||||||
|
* take care of degrading leases on handles for deleted files.
|
||||||
|
*/
|
||||||
|
if (!rc && inode)
|
||||||
|
cifs_mark_open_handles_for_deleted_file(inode, name);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
err_free:
|
||||||
|
SMB2_open_free(&rqst[0]);
|
||||||
|
SMB2_close_free(&rqst[1]);
|
||||||
|
free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
|
||||||
|
free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1358,3 +1448,113 @@ out:
|
|||||||
cifs_free_open_info(&data);
|
cifs_free_open_info(&data);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline __le16 *utf16_smb2_path(struct cifs_sb_info *cifs_sb,
|
||||||
|
const char *name, size_t namelen)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (*name == '\\' ||
|
||||||
|
(cifs_sb_master_tlink(cifs_sb) &&
|
||||||
|
cifs_sb_master_tcon(cifs_sb)->posix_extensions && *name == '/'))
|
||||||
|
name++;
|
||||||
|
return cifs_strndup_to_utf16(name, namelen, &len,
|
||||||
|
cifs_sb->local_nls,
|
||||||
|
cifs_remap(cifs_sb));
|
||||||
|
}
|
||||||
|
|
||||||
|
int smb2_rename_pending_delete(const char *full_path,
|
||||||
|
struct dentry *dentry,
|
||||||
|
const unsigned int xid)
|
||||||
|
{
|
||||||
|
struct cifs_sb_info *cifs_sb = CIFS_SB(d_inode(dentry)->i_sb);
|
||||||
|
struct cifsInodeInfo *cinode = CIFS_I(d_inode(dentry));
|
||||||
|
__le16 *utf16_path __free(kfree) = NULL;
|
||||||
|
__u32 co = file_create_options(dentry);
|
||||||
|
int cmds[] = {
|
||||||
|
SMB2_OP_SET_INFO,
|
||||||
|
SMB2_OP_RENAME,
|
||||||
|
SMB2_OP_UNLINK,
|
||||||
|
};
|
||||||
|
const int num_cmds = ARRAY_SIZE(cmds);
|
||||||
|
char *to_name __free(kfree) = NULL;
|
||||||
|
__u32 attrs = cinode->cifsAttrs;
|
||||||
|
struct cifs_open_parms oparms;
|
||||||
|
static atomic_t sillycounter;
|
||||||
|
struct cifsFileInfo *cfile;
|
||||||
|
struct tcon_link *tlink;
|
||||||
|
struct cifs_tcon *tcon;
|
||||||
|
struct kvec iov[2];
|
||||||
|
const char *ppath;
|
||||||
|
void *page;
|
||||||
|
size_t len;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
tlink = cifs_sb_tlink(cifs_sb);
|
||||||
|
if (IS_ERR(tlink))
|
||||||
|
return PTR_ERR(tlink);
|
||||||
|
tcon = tlink_tcon(tlink);
|
||||||
|
|
||||||
|
page = alloc_dentry_path();
|
||||||
|
|
||||||
|
ppath = build_path_from_dentry(dentry->d_parent, page);
|
||||||
|
if (IS_ERR(ppath)) {
|
||||||
|
rc = PTR_ERR(ppath);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen(ppath) + strlen("/.__smb1234") + 1;
|
||||||
|
to_name = kmalloc(len, GFP_KERNEL);
|
||||||
|
if (!to_name) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
scnprintf(to_name, len, "%s%c.__smb%04X", ppath, CIFS_DIR_SEP(cifs_sb),
|
||||||
|
atomic_inc_return(&sillycounter) & 0xffff);
|
||||||
|
|
||||||
|
utf16_path = utf16_smb2_path(cifs_sb, to_name, len);
|
||||||
|
if (!utf16_path) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_cached_dir_by_name(xid, tcon, full_path, cifs_sb);
|
||||||
|
oparms = CIFS_OPARMS(cifs_sb, tcon, full_path,
|
||||||
|
DELETE | FILE_WRITE_ATTRIBUTES,
|
||||||
|
FILE_OPEN, co, ACL_NO_MODE);
|
||||||
|
|
||||||
|
attrs &= ~ATTR_READONLY;
|
||||||
|
if (!attrs)
|
||||||
|
attrs = ATTR_NORMAL;
|
||||||
|
if (d_inode(dentry)->i_nlink <= 1)
|
||||||
|
attrs |= ATTR_HIDDEN;
|
||||||
|
iov[0].iov_base = &(FILE_BASIC_INFO) {
|
||||||
|
.Attributes = cpu_to_le32(attrs),
|
||||||
|
};
|
||||||
|
iov[0].iov_len = sizeof(FILE_BASIC_INFO);
|
||||||
|
iov[1].iov_base = utf16_path;
|
||||||
|
iov[1].iov_len = sizeof(*utf16_path) * UniStrlen((wchar_t *)utf16_path);
|
||||||
|
|
||||||
|
cifs_get_writable_path(tcon, full_path, FIND_WR_WITH_DELETE, &cfile);
|
||||||
|
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, iov,
|
||||||
|
cmds, num_cmds, cfile, NULL, NULL, dentry);
|
||||||
|
if (rc == -EINVAL) {
|
||||||
|
cifs_dbg(FYI, "invalid lease key, resending request without lease\n");
|
||||||
|
cifs_get_writable_path(tcon, full_path,
|
||||||
|
FIND_WR_WITH_DELETE, &cfile);
|
||||||
|
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, iov,
|
||||||
|
cmds, num_cmds, cfile, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
if (!rc) {
|
||||||
|
set_bit(CIFS_INO_DELETE_PENDING, &cinode->flags);
|
||||||
|
} else {
|
||||||
|
cifs_tcon_dbg(FYI, "%s: failed to rename '%s' to '%s': %d\n",
|
||||||
|
__func__, full_path, to_name, rc);
|
||||||
|
rc = -EIO;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
cifs_put_tlink(tlink);
|
||||||
|
free_dentry_path(page);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|||||||
@ -2578,13 +2578,35 @@ smb2_set_next_command(struct cifs_tcon *tcon, struct smb_rqst *rqst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* SMB headers in a compound are 8 byte aligned. */
|
/* SMB headers in a compound are 8 byte aligned. */
|
||||||
if (!IS_ALIGNED(len, 8)) {
|
if (IS_ALIGNED(len, 8))
|
||||||
num_padding = 8 - (len & 7);
|
goto out;
|
||||||
|
|
||||||
|
num_padding = 8 - (len & 7);
|
||||||
|
if (smb3_encryption_required(tcon)) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flatten request into a single buffer with required padding as
|
||||||
|
* the encryption layer can't handle the padding iovs.
|
||||||
|
*/
|
||||||
|
for (i = 1; i < rqst->rq_nvec; i++) {
|
||||||
|
memcpy(rqst->rq_iov[0].iov_base +
|
||||||
|
rqst->rq_iov[0].iov_len,
|
||||||
|
rqst->rq_iov[i].iov_base,
|
||||||
|
rqst->rq_iov[i].iov_len);
|
||||||
|
rqst->rq_iov[0].iov_len += rqst->rq_iov[i].iov_len;
|
||||||
|
}
|
||||||
|
memset(rqst->rq_iov[0].iov_base + rqst->rq_iov[0].iov_len,
|
||||||
|
0, num_padding);
|
||||||
|
rqst->rq_iov[0].iov_len += num_padding;
|
||||||
|
rqst->rq_nvec = 1;
|
||||||
|
} else {
|
||||||
rqst->rq_iov[rqst->rq_nvec].iov_base = smb2_padding;
|
rqst->rq_iov[rqst->rq_nvec].iov_base = smb2_padding;
|
||||||
rqst->rq_iov[rqst->rq_nvec].iov_len = num_padding;
|
rqst->rq_iov[rqst->rq_nvec].iov_len = num_padding;
|
||||||
rqst->rq_nvec++;
|
rqst->rq_nvec++;
|
||||||
len += num_padding;
|
|
||||||
}
|
}
|
||||||
|
len += num_padding;
|
||||||
|
out:
|
||||||
shdr->NextCommand = cpu_to_le32(len);
|
shdr->NextCommand = cpu_to_le32(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5292,6 +5314,7 @@ struct smb_version_operations smb20_operations = {
|
|||||||
.llseek = smb3_llseek,
|
.llseek = smb3_llseek,
|
||||||
.is_status_io_timeout = smb2_is_status_io_timeout,
|
.is_status_io_timeout = smb2_is_status_io_timeout,
|
||||||
.is_network_name_deleted = smb2_is_network_name_deleted,
|
.is_network_name_deleted = smb2_is_network_name_deleted,
|
||||||
|
.rename_pending_delete = smb2_rename_pending_delete,
|
||||||
};
|
};
|
||||||
#endif /* CIFS_ALLOW_INSECURE_LEGACY */
|
#endif /* CIFS_ALLOW_INSECURE_LEGACY */
|
||||||
|
|
||||||
@ -5397,6 +5420,7 @@ struct smb_version_operations smb21_operations = {
|
|||||||
.llseek = smb3_llseek,
|
.llseek = smb3_llseek,
|
||||||
.is_status_io_timeout = smb2_is_status_io_timeout,
|
.is_status_io_timeout = smb2_is_status_io_timeout,
|
||||||
.is_network_name_deleted = smb2_is_network_name_deleted,
|
.is_network_name_deleted = smb2_is_network_name_deleted,
|
||||||
|
.rename_pending_delete = smb2_rename_pending_delete,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct smb_version_operations smb30_operations = {
|
struct smb_version_operations smb30_operations = {
|
||||||
@ -5513,6 +5537,7 @@ struct smb_version_operations smb30_operations = {
|
|||||||
.llseek = smb3_llseek,
|
.llseek = smb3_llseek,
|
||||||
.is_status_io_timeout = smb2_is_status_io_timeout,
|
.is_status_io_timeout = smb2_is_status_io_timeout,
|
||||||
.is_network_name_deleted = smb2_is_network_name_deleted,
|
.is_network_name_deleted = smb2_is_network_name_deleted,
|
||||||
|
.rename_pending_delete = smb2_rename_pending_delete,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct smb_version_operations smb311_operations = {
|
struct smb_version_operations smb311_operations = {
|
||||||
@ -5629,6 +5654,7 @@ struct smb_version_operations smb311_operations = {
|
|||||||
.llseek = smb3_llseek,
|
.llseek = smb3_llseek,
|
||||||
.is_status_io_timeout = smb2_is_status_io_timeout,
|
.is_status_io_timeout = smb2_is_status_io_timeout,
|
||||||
.is_network_name_deleted = smb2_is_network_name_deleted,
|
.is_network_name_deleted = smb2_is_network_name_deleted,
|
||||||
|
.rename_pending_delete = smb2_rename_pending_delete,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
|
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
|
||||||
|
|||||||
@ -324,5 +324,8 @@ int smb2_create_reparse_symlink(const unsigned int xid, struct inode *inode,
|
|||||||
int smb2_make_nfs_node(unsigned int xid, struct inode *inode,
|
int smb2_make_nfs_node(unsigned int xid, struct inode *inode,
|
||||||
struct dentry *dentry, struct cifs_tcon *tcon,
|
struct dentry *dentry, struct cifs_tcon *tcon,
|
||||||
const char *full_path, umode_t mode, dev_t dev);
|
const char *full_path, umode_t mode, dev_t dev);
|
||||||
|
int smb2_rename_pending_delete(const char *full_path,
|
||||||
|
struct dentry *dentry,
|
||||||
|
const unsigned int xid);
|
||||||
|
|
||||||
#endif /* _SMB2PROTO_H */
|
#endif /* _SMB2PROTO_H */
|
||||||
|
|||||||
@ -544,13 +544,12 @@ DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(query_info_compound_enter);
|
|||||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(posix_query_info_compound_enter);
|
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(posix_query_info_compound_enter);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(hardlink_enter);
|
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(hardlink_enter);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(rename_enter);
|
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(rename_enter);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(rmdir_enter);
|
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(unlink_enter);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(set_eof_enter);
|
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(set_eof_enter);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(set_info_compound_enter);
|
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(set_info_compound_enter);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(set_reparse_compound_enter);
|
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(set_reparse_compound_enter);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(get_reparse_compound_enter);
|
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(get_reparse_compound_enter);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(query_wsl_ea_compound_enter);
|
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(query_wsl_ea_compound_enter);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(delete_enter);
|
|
||||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(mkdir_enter);
|
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(mkdir_enter);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(tdis_enter);
|
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(tdis_enter);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(mknod_enter);
|
DEFINE_SMB3_INF_COMPOUND_ENTER_EVENT(mknod_enter);
|
||||||
@ -585,13 +584,12 @@ DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(query_info_compound_done);
|
|||||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(posix_query_info_compound_done);
|
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(posix_query_info_compound_done);
|
||||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(hardlink_done);
|
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(hardlink_done);
|
||||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(rename_done);
|
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(rename_done);
|
||||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(rmdir_done);
|
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(unlink_done);
|
||||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(set_eof_done);
|
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(set_eof_done);
|
||||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(set_info_compound_done);
|
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(set_info_compound_done);
|
||||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(set_reparse_compound_done);
|
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(set_reparse_compound_done);
|
||||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(get_reparse_compound_done);
|
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(get_reparse_compound_done);
|
||||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(query_wsl_ea_compound_done);
|
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(query_wsl_ea_compound_done);
|
||||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(delete_done);
|
|
||||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(mkdir_done);
|
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(mkdir_done);
|
||||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(tdis_done);
|
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(tdis_done);
|
||||||
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(mknod_done);
|
DEFINE_SMB3_INF_COMPOUND_DONE_EVENT(mknod_done);
|
||||||
@ -631,14 +629,13 @@ DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(query_info_compound_err);
|
|||||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(posix_query_info_compound_err);
|
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(posix_query_info_compound_err);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(hardlink_err);
|
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(hardlink_err);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(rename_err);
|
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(rename_err);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(rmdir_err);
|
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(unlink_err);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(set_eof_err);
|
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(set_eof_err);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(set_info_compound_err);
|
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(set_info_compound_err);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(set_reparse_compound_err);
|
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(set_reparse_compound_err);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(get_reparse_compound_err);
|
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(get_reparse_compound_err);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(query_wsl_ea_compound_err);
|
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(query_wsl_ea_compound_err);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(mkdir_err);
|
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(mkdir_err);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(delete_err);
|
|
||||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(tdis_err);
|
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(tdis_err);
|
||||||
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(mknod_err);
|
DEFINE_SMB3_INF_COMPOUND_ERR_EVENT(mknod_err);
|
||||||
|
|
||||||
|
|||||||
@ -1032,11 +1032,12 @@ xfs_log_sb(
|
|||||||
* and hence we don't need have to update it here.
|
* and hence we don't need have to update it here.
|
||||||
*/
|
*/
|
||||||
if (xfs_has_lazysbcount(mp)) {
|
if (xfs_has_lazysbcount(mp)) {
|
||||||
mp->m_sb.sb_icount = percpu_counter_sum(&mp->m_icount);
|
mp->m_sb.sb_icount = percpu_counter_sum_positive(&mp->m_icount);
|
||||||
mp->m_sb.sb_ifree = min_t(uint64_t,
|
mp->m_sb.sb_ifree = min_t(uint64_t,
|
||||||
percpu_counter_sum(&mp->m_ifree),
|
percpu_counter_sum_positive(&mp->m_ifree),
|
||||||
mp->m_sb.sb_icount);
|
mp->m_sb.sb_icount);
|
||||||
mp->m_sb.sb_fdblocks = percpu_counter_sum(&mp->m_fdblocks);
|
mp->m_sb.sb_fdblocks =
|
||||||
|
percpu_counter_sum_positive(&mp->m_fdblocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
xfs_sb_to_disk(bp->b_addr, &mp->m_sb);
|
xfs_sb_to_disk(bp->b_addr, &mp->m_sb);
|
||||||
|
|||||||
@ -142,6 +142,12 @@ struct nfs_inode {
|
|||||||
unsigned long flags; /* atomic bit ops */
|
unsigned long flags; /* atomic bit ops */
|
||||||
unsigned long cache_validity; /* bit mask */
|
unsigned long cache_validity; /* bit mask */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NFS Attributes not included in struct inode
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct timespec64 btime;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* read_cache_jiffies is when we started read-caching this inode.
|
* read_cache_jiffies is when we started read-caching this inode.
|
||||||
* attrtimeo is for how long the cached information is assumed
|
* attrtimeo is for how long the cached information is assumed
|
||||||
@ -298,10 +304,12 @@ struct nfs4_copy_state {
|
|||||||
#define NFS_INO_INVALID_XATTR BIT(15) /* xattrs are invalid */
|
#define NFS_INO_INVALID_XATTR BIT(15) /* xattrs are invalid */
|
||||||
#define NFS_INO_INVALID_NLINK BIT(16) /* cached nlinks is invalid */
|
#define NFS_INO_INVALID_NLINK BIT(16) /* cached nlinks is invalid */
|
||||||
#define NFS_INO_INVALID_MODE BIT(17) /* cached mode is invalid */
|
#define NFS_INO_INVALID_MODE BIT(17) /* cached mode is invalid */
|
||||||
|
#define NFS_INO_INVALID_BTIME BIT(18) /* cached btime is invalid */
|
||||||
|
|
||||||
#define NFS_INO_INVALID_ATTR (NFS_INO_INVALID_CHANGE \
|
#define NFS_INO_INVALID_ATTR (NFS_INO_INVALID_CHANGE \
|
||||||
| NFS_INO_INVALID_CTIME \
|
| NFS_INO_INVALID_CTIME \
|
||||||
| NFS_INO_INVALID_MTIME \
|
| NFS_INO_INVALID_MTIME \
|
||||||
|
| NFS_INO_INVALID_BTIME \
|
||||||
| NFS_INO_INVALID_SIZE \
|
| NFS_INO_INVALID_SIZE \
|
||||||
| NFS_INO_INVALID_NLINK \
|
| NFS_INO_INVALID_NLINK \
|
||||||
| NFS_INO_INVALID_MODE \
|
| NFS_INO_INVALID_MODE \
|
||||||
|
|||||||
@ -159,8 +159,8 @@ struct nfs_server {
|
|||||||
#define NFS_MOUNT_TRUNK_DISCOVERY 0x04000000
|
#define NFS_MOUNT_TRUNK_DISCOVERY 0x04000000
|
||||||
#define NFS_MOUNT_SHUTDOWN 0x08000000
|
#define NFS_MOUNT_SHUTDOWN 0x08000000
|
||||||
|
|
||||||
unsigned int fattr_valid; /* Valid attributes */
|
|
||||||
unsigned int caps; /* server capabilities */
|
unsigned int caps; /* server capabilities */
|
||||||
|
__u64 fattr_valid; /* Valid attributes */
|
||||||
unsigned int rsize; /* read size */
|
unsigned int rsize; /* read size */
|
||||||
unsigned int rpages; /* read size (in pages) */
|
unsigned int rpages; /* read size (in pages) */
|
||||||
unsigned int wsize; /* write size */
|
unsigned int wsize; /* write size */
|
||||||
|
|||||||
@ -45,7 +45,7 @@ struct nfs4_threshold {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct nfs_fattr {
|
struct nfs_fattr {
|
||||||
unsigned int valid; /* which fields are valid */
|
__u64 valid; /* which fields are valid */
|
||||||
umode_t mode;
|
umode_t mode;
|
||||||
__u32 nlink;
|
__u32 nlink;
|
||||||
kuid_t uid;
|
kuid_t uid;
|
||||||
@ -67,6 +67,7 @@ struct nfs_fattr {
|
|||||||
struct timespec64 atime;
|
struct timespec64 atime;
|
||||||
struct timespec64 mtime;
|
struct timespec64 mtime;
|
||||||
struct timespec64 ctime;
|
struct timespec64 ctime;
|
||||||
|
struct timespec64 btime;
|
||||||
__u64 change_attr; /* NFSv4 change attribute */
|
__u64 change_attr; /* NFSv4 change attribute */
|
||||||
__u64 pre_change_attr;/* pre-op NFSv4 change attribute */
|
__u64 pre_change_attr;/* pre-op NFSv4 change attribute */
|
||||||
__u64 pre_size; /* pre_op_attr.size */
|
__u64 pre_size; /* pre_op_attr.size */
|
||||||
@ -80,32 +81,33 @@ struct nfs_fattr {
|
|||||||
struct nfs4_label *label;
|
struct nfs4_label *label;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NFS_ATTR_FATTR_TYPE (1U << 0)
|
#define NFS_ATTR_FATTR_TYPE BIT_ULL(0)
|
||||||
#define NFS_ATTR_FATTR_MODE (1U << 1)
|
#define NFS_ATTR_FATTR_MODE BIT_ULL(1)
|
||||||
#define NFS_ATTR_FATTR_NLINK (1U << 2)
|
#define NFS_ATTR_FATTR_NLINK BIT_ULL(2)
|
||||||
#define NFS_ATTR_FATTR_OWNER (1U << 3)
|
#define NFS_ATTR_FATTR_OWNER BIT_ULL(3)
|
||||||
#define NFS_ATTR_FATTR_GROUP (1U << 4)
|
#define NFS_ATTR_FATTR_GROUP BIT_ULL(4)
|
||||||
#define NFS_ATTR_FATTR_RDEV (1U << 5)
|
#define NFS_ATTR_FATTR_RDEV BIT_ULL(5)
|
||||||
#define NFS_ATTR_FATTR_SIZE (1U << 6)
|
#define NFS_ATTR_FATTR_SIZE BIT_ULL(6)
|
||||||
#define NFS_ATTR_FATTR_PRESIZE (1U << 7)
|
#define NFS_ATTR_FATTR_PRESIZE BIT_ULL(7)
|
||||||
#define NFS_ATTR_FATTR_BLOCKS_USED (1U << 8)
|
#define NFS_ATTR_FATTR_BLOCKS_USED BIT_ULL(8)
|
||||||
#define NFS_ATTR_FATTR_SPACE_USED (1U << 9)
|
#define NFS_ATTR_FATTR_SPACE_USED BIT_ULL(9)
|
||||||
#define NFS_ATTR_FATTR_FSID (1U << 10)
|
#define NFS_ATTR_FATTR_FSID BIT_ULL(10)
|
||||||
#define NFS_ATTR_FATTR_FILEID (1U << 11)
|
#define NFS_ATTR_FATTR_FILEID BIT_ULL(11)
|
||||||
#define NFS_ATTR_FATTR_ATIME (1U << 12)
|
#define NFS_ATTR_FATTR_ATIME BIT_ULL(12)
|
||||||
#define NFS_ATTR_FATTR_MTIME (1U << 13)
|
#define NFS_ATTR_FATTR_MTIME BIT_ULL(13)
|
||||||
#define NFS_ATTR_FATTR_CTIME (1U << 14)
|
#define NFS_ATTR_FATTR_CTIME BIT_ULL(14)
|
||||||
#define NFS_ATTR_FATTR_PREMTIME (1U << 15)
|
#define NFS_ATTR_FATTR_PREMTIME BIT_ULL(15)
|
||||||
#define NFS_ATTR_FATTR_PRECTIME (1U << 16)
|
#define NFS_ATTR_FATTR_PRECTIME BIT_ULL(16)
|
||||||
#define NFS_ATTR_FATTR_CHANGE (1U << 17)
|
#define NFS_ATTR_FATTR_CHANGE BIT_ULL(17)
|
||||||
#define NFS_ATTR_FATTR_PRECHANGE (1U << 18)
|
#define NFS_ATTR_FATTR_PRECHANGE BIT_ULL(18)
|
||||||
#define NFS_ATTR_FATTR_V4_LOCATIONS (1U << 19)
|
#define NFS_ATTR_FATTR_V4_LOCATIONS BIT_ULL(19)
|
||||||
#define NFS_ATTR_FATTR_V4_REFERRAL (1U << 20)
|
#define NFS_ATTR_FATTR_V4_REFERRAL BIT_ULL(20)
|
||||||
#define NFS_ATTR_FATTR_MOUNTPOINT (1U << 21)
|
#define NFS_ATTR_FATTR_MOUNTPOINT BIT_ULL(21)
|
||||||
#define NFS_ATTR_FATTR_MOUNTED_ON_FILEID (1U << 22)
|
#define NFS_ATTR_FATTR_MOUNTED_ON_FILEID BIT_ULL(22)
|
||||||
#define NFS_ATTR_FATTR_OWNER_NAME (1U << 23)
|
#define NFS_ATTR_FATTR_OWNER_NAME BIT_ULL(23)
|
||||||
#define NFS_ATTR_FATTR_GROUP_NAME (1U << 24)
|
#define NFS_ATTR_FATTR_GROUP_NAME BIT_ULL(24)
|
||||||
#define NFS_ATTR_FATTR_V4_SECURITY_LABEL (1U << 25)
|
#define NFS_ATTR_FATTR_V4_SECURITY_LABEL BIT_ULL(25)
|
||||||
|
#define NFS_ATTR_FATTR_BTIME BIT_ULL(26)
|
||||||
|
|
||||||
#define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \
|
#define NFS_ATTR_FATTR (NFS_ATTR_FATTR_TYPE \
|
||||||
| NFS_ATTR_FATTR_MODE \
|
| NFS_ATTR_FATTR_MODE \
|
||||||
@ -126,6 +128,7 @@ struct nfs_fattr {
|
|||||||
| NFS_ATTR_FATTR_SPACE_USED)
|
| NFS_ATTR_FATTR_SPACE_USED)
|
||||||
#define NFS_ATTR_FATTR_V4 (NFS_ATTR_FATTR \
|
#define NFS_ATTR_FATTR_V4 (NFS_ATTR_FATTR \
|
||||||
| NFS_ATTR_FATTR_SPACE_USED \
|
| NFS_ATTR_FATTR_SPACE_USED \
|
||||||
|
| NFS_ATTR_FATTR_BTIME \
|
||||||
| NFS_ATTR_FATTR_V4_SECURITY_LABEL)
|
| NFS_ATTR_FATTR_V4_SECURITY_LABEL)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -582,8 +582,9 @@ static void virtio_transport_rx_work(struct work_struct *work)
|
|||||||
do {
|
do {
|
||||||
virtqueue_disable_cb(vq);
|
virtqueue_disable_cb(vq);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
unsigned int len, payload_len;
|
||||||
|
struct virtio_vsock_hdr *hdr;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
unsigned int len;
|
|
||||||
|
|
||||||
if (!virtio_transport_more_replies(vsock)) {
|
if (!virtio_transport_more_replies(vsock)) {
|
||||||
/* Stop rx until the device processes already
|
/* Stop rx until the device processes already
|
||||||
@ -600,12 +601,19 @@ static void virtio_transport_rx_work(struct work_struct *work)
|
|||||||
vsock->rx_buf_nr--;
|
vsock->rx_buf_nr--;
|
||||||
|
|
||||||
/* Drop short/long packets */
|
/* Drop short/long packets */
|
||||||
if (unlikely(len < sizeof(struct virtio_vsock_hdr) ||
|
if (unlikely(len < sizeof(*hdr) ||
|
||||||
len > virtio_vsock_skb_len(skb))) {
|
len > virtio_vsock_skb_len(skb))) {
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hdr = virtio_vsock_hdr(skb);
|
||||||
|
payload_len = le32_to_cpu(hdr->len);
|
||||||
|
if (unlikely(payload_len > len - sizeof(*hdr))) {
|
||||||
|
kfree_skb(skb);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
virtio_vsock_skb_rx_put(skb);
|
virtio_vsock_skb_rx_put(skb);
|
||||||
virtio_transport_deliver_tap_pkt(skb);
|
virtio_transport_deliver_tap_pkt(skb);
|
||||||
virtio_transport_recv_pkt(&virtio_transport, skb);
|
virtio_transport_recv_pkt(&virtio_transport, skb);
|
||||||
|
|||||||
@ -1,3 +1,30 @@
|
|||||||
|
* Tue Oct 21 2025 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [5.14.0-570.58.1.el9_6]
|
||||||
|
- pstore/ram: Check start of empty przs during init (CKI Backport Bot) [RHEL-122067] {CVE-2023-53331}
|
||||||
|
- vsock/virtio: Validate length in packet header before skb_put() (Jon Maloy) [RHEL-114299] {CVE-2025-39718}
|
||||||
|
Resolves: RHEL-114299, RHEL-122067
|
||||||
|
|
||||||
|
* Mon Oct 20 2025 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [5.14.0-570.57.1.el9_6]
|
||||||
|
- NFSv4/flexfiles: Fix layout merge mirror check. (Benjamin Coddington) [RHEL-118731]
|
||||||
|
- NFS: Fix filehandle bounds checking in nfs_fh_to_dentry() (CKI Backport Bot) [RHEL-113610] {CVE-2025-39730}
|
||||||
|
Resolves: RHEL-113610, RHEL-118731
|
||||||
|
|
||||||
|
* Thu Oct 16 2025 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [5.14.0-570.56.1.el9_6]
|
||||||
|
- NFS: Return the file btime in the statx results when appropriate (Benjamin Coddington) [RHEL-111706]
|
||||||
|
- nfs: Add timecreate to nfs inode (Benjamin Coddington) [RHEL-111706]
|
||||||
|
- Expand the type of nfs_fattr->valid (Benjamin Coddington) [RHEL-111706]
|
||||||
|
- smb: client: fix wrong index reference in smb2_compound_op() (Paulo Alcantara) [RHEL-117879]
|
||||||
|
- smb: client: handle unlink(2) of files open by different clients (Paulo Alcantara) [RHEL-117879]
|
||||||
|
- smb: client: fix file open check in __cifs_unlink() (Paulo Alcantara) [RHEL-117879]
|
||||||
|
- smb: client: fix filename matching of deferred files (Paulo Alcantara) [RHEL-117879]
|
||||||
|
- smb: client: fix data loss due to broken rename(2) (Paulo Alcantara) [RHEL-117879]
|
||||||
|
- smb: client: fix compound alignment with encryption (Paulo Alcantara) [RHEL-117879]
|
||||||
|
- fs/smb: Fix inconsistent refcnt update (Paulo Alcantara) [RHEL-117879] {CVE-2025-39819}
|
||||||
|
- ALSA: hda/ca0132: Fix buffer overflow in add_tuning_control (CKI Backport Bot) [RHEL-114848] {CVE-2025-39751}
|
||||||
|
- NFS: Fixup allocation flags for nfsiod's __GFP_NORETRY (Benjamin Coddington) [RHEL-116232]
|
||||||
|
- xfs: make sure sb_fdblocks is non-negative (CKI Backport Bot) [RHEL-114540]
|
||||||
|
- block: fix adding folio to bio (Ming Lei) [RHEL-96789]
|
||||||
|
Resolves: RHEL-111706, RHEL-114540, RHEL-114848, RHEL-116232, RHEL-117879, RHEL-96789
|
||||||
|
|
||||||
* Tue Oct 14 2025 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [5.14.0-570.55.1.el9_6]
|
* Tue Oct 14 2025 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [5.14.0-570.55.1.el9_6]
|
||||||
- scsi: lpfc: Fix buffer free/clear order in deferred receive path (CKI Backport Bot) [RHEL-119115] {CVE-2025-39841}
|
- scsi: lpfc: Fix buffer free/clear order in deferred receive path (CKI Backport Bot) [RHEL-119115] {CVE-2025-39841}
|
||||||
Resolves: RHEL-119115
|
Resolves: RHEL-119115
|
||||||
|
|||||||
@ -4410,7 +4410,7 @@ static int add_tuning_control(struct hda_codec *codec,
|
|||||||
}
|
}
|
||||||
knew.private_value =
|
knew.private_value =
|
||||||
HDA_COMPOSE_AMP_VAL(nid, 1, 0, type);
|
HDA_COMPOSE_AMP_VAL(nid, 1, 0, type);
|
||||||
sprintf(namestr, "%s %s Volume", name, dirstr[dir]);
|
snprintf(namestr, sizeof(namestr), "%s %s Volume", name, dirstr[dir]);
|
||||||
return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
|
return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user