447 int mtime_changed = 0;
448 int ctime_changed = 0;
449 vsecattr_t *vsp;
450 int was_serial, set_time_cache_inval, recov;
451 vattr_t *vap = &garp->n4g_va;
452 mntinfo4_t *mi = VTOMI4(vp);
453 len_t preattr_rsize;
454 boolean_t writemodify_set = B_FALSE;
455 boolean_t cachepurge_set = B_FALSE;
456
457 ASSERT(mi->mi_vfsp->vfs_dev == garp->n4g_va.va_fsid);
458
459 /* Is curthread the recovery thread? */
460 mutex_enter(&mi->mi_lock);
461 recov = (VTOMI4(vp)->mi_recovthread == curthread);
462 mutex_exit(&mi->mi_lock);
463
464 rp = VTOR4(vp);
465 mutex_enter(&rp->r_statelock);
466 was_serial = (rp->r_serial == curthread);
467 if (rp->r_serial && !was_serial) {
468 klwp_t *lwp = ttolwp(curthread);
469
470 /*
471 * If we're the recovery thread, then purge current attrs
472 * and bail out to avoid potential deadlock between another
473 * thread caching attrs (r_serial thread), recov thread,
474 * and an async writer thread.
475 */
476 if (recov) {
477 PURGE_ATTRCACHE4_LOCKED(rp);
478 mutex_exit(&rp->r_statelock);
479 return;
480 }
481
482 if (lwp != NULL)
483 lwp->lwp_nostop++;
484 while (rp->r_serial != NULL) {
485 if (!cv_wait_sig(&rp->r_cv, &rp->r_statelock)) {
486 mutex_exit(&rp->r_statelock);
487 if (lwp != NULL)
488 lwp->lwp_nostop--;
489 return;
490 }
491 }
492 if (lwp != NULL)
493 lwp->lwp_nostop--;
494 }
495
496 /*
497 * If there is a page flush thread, the current thread needs to
498 * bail out, to prevent a possible deadlock between the current
499 * thread (which might be in a start_op/end_op region), the
500 * recovery thread, and the page flush thread. Expire the
501 * attribute cache, so that any attributes the current thread was
502 * going to set are not lost.
503 */
504 if ((rp->r_flags & R4PGFLUSH) && rp->r_pgflush != curthread) {
505 PURGE_ATTRCACHE4_LOCKED(rp);
506 mutex_exit(&rp->r_statelock);
507 return;
508 }
509
510 if (rp->r_time_attr_saved > t) {
511 /*
512 * Attributes have been cached since these attributes were
513 * probably made. If there is an inconsistency in what is
514 * cached, mark them invalid. If not, don't act on them.
515 */
|
447 int mtime_changed = 0;
448 int ctime_changed = 0;
449 vsecattr_t *vsp;
450 int was_serial, set_time_cache_inval, recov;
451 vattr_t *vap = &garp->n4g_va;
452 mntinfo4_t *mi = VTOMI4(vp);
453 len_t preattr_rsize;
454 boolean_t writemodify_set = B_FALSE;
455 boolean_t cachepurge_set = B_FALSE;
456
457 ASSERT(mi->mi_vfsp->vfs_dev == garp->n4g_va.va_fsid);
458
459 /* Is curthread the recovery thread? */
460 mutex_enter(&mi->mi_lock);
461 recov = (VTOMI4(vp)->mi_recovthread == curthread);
462 mutex_exit(&mi->mi_lock);
463
464 rp = VTOR4(vp);
465 mutex_enter(&rp->r_statelock);
466 was_serial = (rp->r_serial == curthread);
467 if (rp->r_serial != NULL && !was_serial) {
468 /*
469 * Purge current attrs and bail out to avoid potential deadlock
470 * between another thread caching attrs (r_serial thread), this
471 * thread, and a thread trying to read or write pages.
472 */
473 PURGE_ATTRCACHE4_LOCKED(rp);
474 mutex_exit(&rp->r_statelock);
475 return;
476 }
477
478 /*
479 * If there is a page flush thread, the current thread needs to
480 * bail out, to prevent a possible deadlock between the current
481 * thread (which might be in a start_op/end_op region), the
482 * recovery thread, and the page flush thread. Expire the
483 * attribute cache, so that any attributes the current thread was
484 * going to set are not lost.
485 */
486 if ((rp->r_flags & R4PGFLUSH) && rp->r_pgflush != curthread) {
487 PURGE_ATTRCACHE4_LOCKED(rp);
488 mutex_exit(&rp->r_statelock);
489 return;
490 }
491
492 if (rp->r_time_attr_saved > t) {
493 /*
494 * Attributes have been cached since these attributes were
495 * probably made. If there is an inconsistency in what is
496 * cached, mark them invalid. If not, don't act on them.
497 */
|