Commit f74e3ea3 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'nfs-for-6.6-4' of git://git.linux-nfs.org/projects/anna/linux-nfs

Pull NFS client fixes from Anna Schumaker:
 "Stable Fix:
   - Fix a pNFS hang in nfs4_evict_inode()

  Fixes:
   - Force update of suid/sgid bits after an NFS v4.2 ALLOCATE op
   - Fix a potential oops in nfs_inode_remove_request()
   - Check the validity of the layout pointer in ff_layout_mirror_prepare_stats()
   - Fix incorrectly marking the pNFS MDS with USE_PNFS_DS in some cases"

* tag 'nfs-for-6.6-4' of git://git.linux-nfs.org/projects/anna/linux-nfs:
  NFSv4.1: fixup use EXCHGID4_FLAG_USE_PNFS_DS for DS server
  pNFS/flexfiles: Check the layout validity in ff_layout_mirror_prepare_stats
  pNFS: Fix a hang in nfs4_evict_inode()
  NFS: Fix potential oops in nfs_inode_remove_request()
  nfs42: client needs to strip file mode's suid/sgid bit after ALLOCATE op
parents 0e97fd29 379e4adf
......@@ -2520,9 +2520,9 @@ ff_layout_mirror_prepare_stats(struct pnfs_layout_hdr *lo,
return i;
}
static int
ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args)
static int ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args)
{
struct pnfs_layout_hdr *lo;
struct nfs4_flexfile_layout *ff_layout;
const int dev_count = PNFS_LAYOUTSTATS_MAXDEV;
......@@ -2533,11 +2533,14 @@ ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args)
return -ENOMEM;
spin_lock(&args->inode->i_lock);
ff_layout = FF_LAYOUT_FROM_HDR(NFS_I(args->inode)->layout);
args->num_dev = ff_layout_mirror_prepare_stats(&ff_layout->generic_hdr,
&args->devinfo[0],
dev_count,
NFS4_FF_OP_LAYOUTSTATS);
lo = NFS_I(args->inode)->layout;
if (lo && pnfs_layout_is_valid(lo)) {
ff_layout = FF_LAYOUT_FROM_HDR(lo);
args->num_dev = ff_layout_mirror_prepare_stats(
&ff_layout->generic_hdr, &args->devinfo[0], dev_count,
NFS4_FF_OP_LAYOUTSTATS);
} else
args->num_dev = 0;
spin_unlock(&args->inode->i_lock);
if (!args->num_dev) {
kfree(args->devinfo);
......
......@@ -81,7 +81,8 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
if (status == 0) {
if (nfs_should_remove_suid(inode)) {
spin_lock(&inode->i_lock);
nfs_set_cache_invalid(inode, NFS_INO_INVALID_MODE);
nfs_set_cache_invalid(inode,
NFS_INO_REVAL_FORCED | NFS_INO_INVALID_MODE);
spin_unlock(&inode->i_lock);
}
status = nfs_post_op_update_inode_force_wcc(inode,
......
......@@ -8870,8 +8870,6 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cre
/* Save the EXCHANGE_ID verifier session trunk tests */
memcpy(clp->cl_confirm.data, argp->verifier.data,
sizeof(clp->cl_confirm.data));
if (resp->flags & EXCHGID4_FLAG_USE_PNFS_DS)
set_bit(NFS_CS_DS, &clp->cl_flags);
out:
trace_nfs4_exchange_id(clp, status);
rpc_put_task(task);
......
......@@ -2634,31 +2634,44 @@ pnfs_should_return_unused_layout(struct pnfs_layout_hdr *lo,
return mode == 0;
}
static int
pnfs_layout_return_unused_byserver(struct nfs_server *server, void *data)
static int pnfs_layout_return_unused_byserver(struct nfs_server *server,
void *data)
{
const struct pnfs_layout_range *range = data;
const struct cred *cred;
struct pnfs_layout_hdr *lo;
struct inode *inode;
nfs4_stateid stateid;
enum pnfs_iomode iomode;
restart:
rcu_read_lock();
list_for_each_entry_rcu(lo, &server->layouts, plh_layouts) {
if (!pnfs_layout_can_be_returned(lo) ||
inode = lo->plh_inode;
if (!inode || !pnfs_layout_can_be_returned(lo) ||
test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags))
continue;
inode = lo->plh_inode;
spin_lock(&inode->i_lock);
if (!pnfs_should_return_unused_layout(lo, range)) {
if (!lo->plh_inode ||
!pnfs_should_return_unused_layout(lo, range)) {
spin_unlock(&inode->i_lock);
continue;
}
pnfs_get_layout_hdr(lo);
pnfs_set_plh_return_info(lo, range->iomode, 0);
if (pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs,
range, 0) != 0 ||
!pnfs_prepare_layoutreturn(lo, &stateid, &cred, &iomode)) {
spin_unlock(&inode->i_lock);
rcu_read_unlock();
pnfs_put_layout_hdr(lo);
cond_resched();
goto restart;
}
spin_unlock(&inode->i_lock);
inode = pnfs_grab_inode_layout_hdr(lo);
if (!inode)
continue;
rcu_read_unlock();
pnfs_mark_layout_for_return(inode, range);
iput(inode);
pnfs_send_layoutreturn(lo, &stateid, &cred, iomode, false);
pnfs_put_layout_hdr(lo);
cond_resched();
goto restart;
}
......
......@@ -788,6 +788,8 @@ static void nfs_inode_add_request(struct nfs_page *req)
*/
static void nfs_inode_remove_request(struct nfs_page *req)
{
struct nfs_inode *nfsi = NFS_I(nfs_page_to_inode(req));
if (nfs_page_group_sync_on_bit(req, PG_REMOVE)) {
struct folio *folio = nfs_page_to_folio(req->wb_head);
struct address_space *mapping = folio_file_mapping(folio);
......@@ -802,7 +804,7 @@ static void nfs_inode_remove_request(struct nfs_page *req)
}
if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) {
atomic_long_dec(&NFS_I(nfs_page_to_inode(req))->nrequests);
atomic_long_dec(&nfsi->nrequests);
nfs_release_request(req);
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment