public inbox for linux-nfs@vger.kernel.org
 help / color / mirror / Atom feed
* [bug report] NFSv4: Deal more correctly with duplicate delegations
@ 2021-03-22 13:40 Dan Carpenter
  0 siblings, 0 replies; only message in thread
From: Dan Carpenter @ 2021-03-22 13:40 UTC (permalink / raw)
  To: Trond Myklebust; +Cc: linux-nfs

Hello Trond Myklebust,

The patch 57bfa89171e5: "NFSv4: Deal more correctly with duplicate
delegations" from Jan 25, 2008, leads to the following static checker
warning:

	fs/nfs/delegation.c:482 nfs_inode_set_delegation()
	warn: missing error code here? 'nfs_detach_delegation_locked()' failed. 'status' = '0'

fs/nfs/delegation.c
   421  int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
   422                                    fmode_t type,
   423                                    const nfs4_stateid *stateid,
   424                                    unsigned long pagemod_limit)
   425  {
   426          struct nfs_server *server = NFS_SERVER(inode);
   427          struct nfs_client *clp = server->nfs_client;
   428          struct nfs_inode *nfsi = NFS_I(inode);
   429          struct nfs_delegation *delegation, *old_delegation;
   430          struct nfs_delegation *freeme = NULL;
   431          int status = 0;
                    ^^^^^^^^^^
"status" is always success.

   432  
   433          delegation = kmalloc(sizeof(*delegation), GFP_NOFS);
   434          if (delegation == NULL)
   435                  return -ENOMEM;
   436          nfs4_stateid_copy(&delegation->stateid, stateid);
   437          refcount_set(&delegation->refcount, 1);
   438          delegation->type = type;
   439          delegation->pagemod_limit = pagemod_limit;
   440          delegation->change_attr = inode_peek_iversion_raw(inode);
   441          delegation->cred = get_cred(cred);
   442          delegation->inode = inode;
   443          delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
   444          spin_lock_init(&delegation->lock);
   445  
   446          spin_lock(&clp->cl_lock);
   447          old_delegation = rcu_dereference_protected(nfsi->delegation,
   448                                          lockdep_is_held(&clp->cl_lock));
   449          if (old_delegation == NULL)
   450                  goto add_new;
   451          /* Is this an update of the existing delegation? */
   452          if (nfs4_stateid_match_other(&old_delegation->stateid,
   453                                  &delegation->stateid)) {
   454                  spin_lock(&old_delegation->lock);
   455                  nfs_update_inplace_delegation(old_delegation,
   456                                  delegation);
   457                  spin_unlock(&old_delegation->lock);
   458                  goto out;

I think these used to return -EIO back in the day.

   459          }
   460          if (!test_bit(NFS_DELEGATION_REVOKED, &old_delegation->flags)) {
   461                  /*
   462                   * Deal with broken servers that hand out two
   463                   * delegations for the same file.
   464                   * Allow for upgrades to a WRITE delegation, but
   465                   * nothing else.
   466                   */
   467                  dfprintk(FILE, "%s: server %s handed out "
   468                                  "a duplicate delegation!\n",
   469                                  __func__, clp->cl_hostname);
   470                  if (delegation->type == old_delegation->type ||
   471                      !(delegation->type & FMODE_WRITE)) {
   472                          freeme = delegation;
   473                          delegation = NULL;
   474                          goto out;
   475                  }
   476                  if (test_and_set_bit(NFS_DELEGATION_RETURNING,
   477                                          &old_delegation->flags))
   478                          goto out;
   479          }
   480          freeme = nfs_detach_delegation_locked(nfsi, old_delegation, clp);
   481          if (freeme == NULL)
   482                  goto out;

status isn't set

   483  add_new:
   484          list_add_tail_rcu(&delegation->super_list, &server->delegations);
   485          rcu_assign_pointer(nfsi->delegation, delegation);
   486          delegation = NULL;
   487  
   488          atomic_long_inc(&nfs_active_delegations);
   489  
   490          trace_nfs4_set_delegation(inode, type);
   491  
   492          spin_lock(&inode->i_lock);
   493          if (NFS_I(inode)->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME))
   494                  NFS_I(inode)->cache_validity |= NFS_INO_REVAL_FORCED;
   495          spin_unlock(&inode->i_lock);
   496  out:
   497          spin_unlock(&clp->cl_lock);
   498          if (delegation != NULL)
   499                  __nfs_free_delegation(delegation);
   500          if (freeme != NULL) {
   501                  nfs_do_return_delegation(inode, freeme, 0);
   502                  nfs_free_delegation(freeme);
   503          }
   504          return status;
   505  }

regards,
dan carpenter

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-03-22 13:41 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-03-22 13:40 [bug report] NFSv4: Deal more correctly with duplicate delegations Dan Carpenter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox