Print this page
6785 nfs4_attr_cache deadlock


2558         mutex_enter(&rp->r_statev4_lock);
2559         rp->created_v4 = 0;
2560         mutex_exit(&rp->r_statev4_lock);
2561 
2562         resop = &res.array[2];
2563         osp->open_stateid = resop->nfs_resop4_u.opclose.open_stateid;
2564         osp->os_valid = 0;
2565 
2566         /*
2567          * This removes the reference obtained at OPEN; ie, when the
2568          * open stream structure was created.
2569          *
2570          * We don't have to worry about calling 'open_stream_rele'
2571          * since we our currently holding a reference to the open
2572          * stream which means the count cannot go to 0 with this
2573          * decrement.
2574          */
2575         ASSERT(osp->os_ref_count >= 2);
2576         osp->os_ref_count--;
2577 
2578         if (!ep->error)









2579                 nfs4_attr_cache(vp,
2580                     &res.array[1].nfs_resop4_u.opgetattr.ga_res,
2581                     t, cred_otw, TRUE, NULL);

2582 
2583         NFS4_DEBUG(nfs4_client_state_debug, (CE_NOTE, "nfs4close_otw:"
2584             " returning %d", ep->error));
2585 
2586         (void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
2587 }
2588 
2589 /* ARGSUSED */
2590 static int
2591 nfs4_read(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
2592     caller_context_t *ct)
2593 {
2594         rnode4_t *rp;
2595         u_offset_t off;
2596         offset_t diff;
2597         uint_t on;
2598         uint_t n;
2599         caddr_t base;
2600         uint_t flags;
2601         int error;




2558         mutex_enter(&rp->r_statev4_lock);
2559         rp->created_v4 = 0;
2560         mutex_exit(&rp->r_statev4_lock);
2561 
2562         resop = &res.array[2];
2563         osp->open_stateid = resop->nfs_resop4_u.opclose.open_stateid;
2564         osp->os_valid = 0;
2565 
2566         /*
2567          * This removes the reference obtained at OPEN; ie, when the
2568          * open stream structure was created.
2569          *
2570          * We don't have to worry about calling 'open_stream_rele'
2571          * since we our currently holding a reference to the open
2572          * stream which means the count cannot go to 0 with this
2573          * decrement.
2574          */
2575         ASSERT(osp->os_ref_count >= 2);
2576         osp->os_ref_count--;
2577 
2578         if (ep->error == 0) {
2579                 /*
2580                  * Avoid a deadlock with the r_serial thread waiting for
2581                  * os_sync_lock in nfs4_get_otw_cred_by_osp() which might be
2582                  * held by us. We will wait in nfs4_attr_cache() for the
2583                  * completion of the r_serial thread.
2584                  */
2585                 mutex_exit(&osp->os_sync_lock);
2586                 *have_sync_lockp = 0;
2587 
2588                 nfs4_attr_cache(vp,
2589                     &res.array[1].nfs_resop4_u.opgetattr.ga_res,
2590                     t, cred_otw, TRUE, NULL);
2591         }
2592 
2593         NFS4_DEBUG(nfs4_client_state_debug, (CE_NOTE, "nfs4close_otw:"
2594             " returning %d", ep->error));
2595 
2596         (void) xdr_free(xdr_COMPOUND4res_clnt, (caddr_t)&res);
2597 }
2598 
2599 /* ARGSUSED */
2600 static int
2601 nfs4_read(vnode_t *vp, struct uio *uiop, int ioflag, cred_t *cr,
2602     caller_context_t *ct)
2603 {
2604         rnode4_t *rp;
2605         u_offset_t off;
2606         offset_t diff;
2607         uint_t on;
2608         uint_t n;
2609         caddr_t base;
2610         uint_t flags;
2611         int error;