* Scan all active processes and prisons to see if any of them have a current * or root directory of `olddp'. If so, replace them with the new mount point. */
| 4066 | * or root directory of `olddp'. If so, replace them with the new mount point. |
| 4067 | */ |
| 4068 | void |
| 4069 | mountcheckdirs(struct vnode *olddp, struct vnode *newdp) |
| 4070 | { |
| 4071 | struct pwddesc *pdp; |
| 4072 | struct pwd *newpwd, *oldpwd; |
| 4073 | struct prison *pr; |
| 4074 | struct proc *p; |
| 4075 | int nrele; |
| 4076 | |
| 4077 | if (vrefcnt(olddp) == 1) |
| 4078 | return; |
| 4079 | nrele = 0; |
| 4080 | newpwd = pwd_alloc(); |
| 4081 | sx_slock(&allproc_lock); |
| 4082 | FOREACH_PROC_IN_SYSTEM(p) { |
| 4083 | PROC_LOCK(p); |
| 4084 | pdp = pdhold(p); |
| 4085 | PROC_UNLOCK(p); |
| 4086 | if (pdp == NULL) |
| 4087 | continue; |
| 4088 | PWDDESC_XLOCK(pdp); |
| 4089 | #pragma GCC diagnostic ignored "-Wcast-qual" |
| 4090 | oldpwd = PWDDESC_XLOCKED_LOAD_PWD(pdp); |
| 4091 | #pragma GCC diagnostic error "-Wcast-qual" |
| 4092 | if (oldpwd == NULL || |
| 4093 | (oldpwd->pwd_cdir != olddp && |
| 4094 | oldpwd->pwd_rdir != olddp && |
| 4095 | oldpwd->pwd_jdir != olddp)) { |
| 4096 | PWDDESC_XUNLOCK(pdp); |
| 4097 | pddrop(pdp); |
| 4098 | continue; |
| 4099 | } |
| 4100 | if (oldpwd->pwd_cdir == olddp) { |
| 4101 | vrefact(newdp); |
| 4102 | newpwd->pwd_cdir = newdp; |
| 4103 | } |
| 4104 | if (oldpwd->pwd_rdir == olddp) { |
| 4105 | vrefact(newdp); |
| 4106 | newpwd->pwd_rdir = newdp; |
| 4107 | } |
| 4108 | if (oldpwd->pwd_jdir == olddp) { |
| 4109 | vrefact(newdp); |
| 4110 | newpwd->pwd_jdir = newdp; |
| 4111 | } |
| 4112 | pwd_fill(oldpwd, newpwd); |
| 4113 | pwd_set(pdp, newpwd); |
| 4114 | PWDDESC_XUNLOCK(pdp); |
| 4115 | pwd_drop(oldpwd); |
| 4116 | pddrop(pdp); |
| 4117 | newpwd = pwd_alloc(); |
| 4118 | } |
| 4119 | sx_sunlock(&allproc_lock); |
| 4120 | pwd_drop(newpwd); |
| 4121 | if (rootvnode == olddp) { |
| 4122 | vrefact(newdp); |
| 4123 | rootvnode = newdp; |
| 4124 | nrele++; |
| 4125 | } |