Merge branches 'pnp', 'pm-cpuidle' and 'pm-cpufreq'
[firefly-linux-kernel-4.4.55.git] / fs / nfs / nfs4state.c
index 5194933ed419c140d6d5089406def6657683785e..5ad908e9ce9c332696ed52a85a5c4324a45d8b02 100644 (file)
@@ -1003,11 +1003,11 @@ struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_m
        struct nfs_seqid *new;
 
        new = kmalloc(sizeof(*new), gfp_mask);
-       if (new != NULL) {
-               new->sequence = counter;
-               INIT_LIST_HEAD(&new->list);
-               new->task = NULL;
-       }
+       if (new == NULL)
+               return ERR_PTR(-ENOMEM);
+       new->sequence = counter;
+       INIT_LIST_HEAD(&new->list);
+       new->task = NULL;
        return new;
 }
 
@@ -1015,7 +1015,7 @@ void nfs_release_seqid(struct nfs_seqid *seqid)
 {
        struct nfs_seqid_counter *sequence;
 
-       if (list_empty(&seqid->list))
+       if (seqid == NULL || list_empty(&seqid->list))
                return;
        sequence = seqid->sequence;
        spin_lock(&sequence->lock);
@@ -1071,13 +1071,15 @@ static void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
 
 void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid)
 {
-       struct nfs4_state_owner *sp = container_of(seqid->sequence,
-                                       struct nfs4_state_owner, so_seqid);
-       struct nfs_server *server = sp->so_server;
+       struct nfs4_state_owner *sp;
+
+       if (seqid == NULL)
+               return;
 
+       sp = container_of(seqid->sequence, struct nfs4_state_owner, so_seqid);
        if (status == -NFS4ERR_BAD_SEQID)
                nfs4_drop_state_owner(sp);
-       if (!nfs4_has_session(server->nfs_client))
+       if (!nfs4_has_session(sp->so_server->nfs_client))
                nfs_increment_seqid(status, seqid);
 }
 
@@ -1088,14 +1090,18 @@ void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid)
  */
 void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid)
 {
-       nfs_increment_seqid(status, seqid);
+       if (seqid != NULL)
+               nfs_increment_seqid(status, seqid);
 }
 
 int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
 {
-       struct nfs_seqid_counter *sequence = seqid->sequence;
+       struct nfs_seqid_counter *sequence;
        int status = 0;
 
+       if (seqid == NULL)
+               goto out;
+       sequence = seqid->sequence;
        spin_lock(&sequence->lock);
        seqid->task = task;
        if (list_empty(&seqid->list))
@@ -1106,6 +1112,7 @@ int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
        status = -EAGAIN;
 unlock:
        spin_unlock(&sequence->lock);
+out:
        return status;
 }
 
@@ -1366,49 +1373,55 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
        struct nfs_inode *nfsi = NFS_I(inode);
        struct file_lock *fl;
        int status = 0;
+       struct file_lock_context *flctx = inode->i_flctx;
+       struct list_head *list;
 
-       if (inode->i_flock == NULL)
+       if (flctx == NULL)
                return 0;
 
+       list = &flctx->flc_posix;
+
        /* Guard against delegation returns and new lock/unlock calls */
        down_write(&nfsi->rwsem);
-       /* Protect inode->i_flock using the BKL */
-       spin_lock(&inode->i_lock);
-       for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
-               if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
-                       continue;
+       spin_lock(&flctx->flc_lock);
+restart:
+       list_for_each_entry(fl, list, fl_list) {
                if (nfs_file_open_context(fl->fl_file)->state != state)
                        continue;
-               spin_unlock(&inode->i_lock);
+               spin_unlock(&flctx->flc_lock);
                status = ops->recover_lock(state, fl);
                switch (status) {
-                       case 0:
-                               break;
-                       case -ESTALE:
-                       case -NFS4ERR_ADMIN_REVOKED:
-                       case -NFS4ERR_STALE_STATEID:
-                       case -NFS4ERR_BAD_STATEID:
-                       case -NFS4ERR_EXPIRED:
-                       case -NFS4ERR_NO_GRACE:
-                       case -NFS4ERR_STALE_CLIENTID:
-                       case -NFS4ERR_BADSESSION:
-                       case -NFS4ERR_BADSLOT:
-                       case -NFS4ERR_BAD_HIGH_SLOT:
-                       case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
-                               goto out;
-                       default:
-                               printk(KERN_ERR "NFS: %s: unhandled error %d\n",
-                                        __func__, status);
-                       case -ENOMEM:
-                       case -NFS4ERR_DENIED:
-                       case -NFS4ERR_RECLAIM_BAD:
-                       case -NFS4ERR_RECLAIM_CONFLICT:
-                               /* kill_proc(fl->fl_pid, SIGLOST, 1); */
-                               status = 0;
+               case 0:
+                       break;
+               case -ESTALE:
+               case -NFS4ERR_ADMIN_REVOKED:
+               case -NFS4ERR_STALE_STATEID:
+               case -NFS4ERR_BAD_STATEID:
+               case -NFS4ERR_EXPIRED:
+               case -NFS4ERR_NO_GRACE:
+               case -NFS4ERR_STALE_CLIENTID:
+               case -NFS4ERR_BADSESSION:
+               case -NFS4ERR_BADSLOT:
+               case -NFS4ERR_BAD_HIGH_SLOT:
+               case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
+                       goto out;
+               default:
+                       pr_err("NFS: %s: unhandled error %d\n",
+                                       __func__, status);
+               case -ENOMEM:
+               case -NFS4ERR_DENIED:
+               case -NFS4ERR_RECLAIM_BAD:
+               case -NFS4ERR_RECLAIM_CONFLICT:
+                       /* kill_proc(fl->fl_pid, SIGLOST, 1); */
+                       status = 0;
                }
-               spin_lock(&inode->i_lock);
+               spin_lock(&flctx->flc_lock);
        }
-       spin_unlock(&inode->i_lock);
+       if (list == &flctx->flc_posix) {
+               list = &flctx->flc_flock;
+               goto restart;
+       }
+       spin_unlock(&flctx->flc_lock);
 out:
        up_write(&nfsi->rwsem);
        return status;