Lines 71-77
static struct vfsops unionfs_vfsops;
Link Here
|
71 |
static int |
71 |
static int |
72 |
unionfs_domount(struct mount *mp) |
72 |
unionfs_domount(struct mount *mp) |
73 |
{ |
73 |
{ |
74 |
struct mount *lowermp, *uppermp; |
|
|
75 |
struct vnode *lowerrootvp; |
74 |
struct vnode *lowerrootvp; |
76 |
struct vnode *upperrootvp; |
75 |
struct vnode *upperrootvp; |
77 |
struct unionfs_mount *ump; |
76 |
struct unionfs_mount *ump; |
Lines 303-320
unionfs_domount(struct mount *mp)
Link Here
|
303 |
* reused until that happens. We assume the caller holds a reference |
302 |
* reused until that happens. We assume the caller holds a reference |
304 |
* to lowerrootvp as it is the mount's covered vnode. |
303 |
* to lowerrootvp as it is the mount's covered vnode. |
305 |
*/ |
304 |
*/ |
306 |
lowermp = vfs_register_upper_from_vp(ump->um_lowervp, mp, |
305 |
ump->um_lowermp = vfs_register_upper_from_vp(ump->um_lowervp, mp, |
307 |
&ump->um_lower_link); |
306 |
&ump->um_lower_link); |
308 |
uppermp = vfs_register_upper_from_vp(ump->um_uppervp, mp, |
307 |
ump->um_uppermp = vfs_register_upper_from_vp(ump->um_uppervp, mp, |
309 |
&ump->um_upper_link); |
308 |
&ump->um_upper_link); |
310 |
|
309 |
|
311 |
vrele(upperrootvp); |
310 |
vrele(upperrootvp); |
312 |
|
311 |
|
313 |
if (lowermp == NULL || uppermp == NULL) { |
312 |
if (ump->um_lowermp == NULL || ump->um_uppermp == NULL) { |
314 |
if (lowermp != NULL) |
313 |
if (ump->um_lowermp != NULL) |
315 |
vfs_unregister_upper(lowermp, &ump->um_lower_link); |
314 |
vfs_unregister_upper(ump->um_lowermp, &ump->um_lower_link); |
316 |
if (uppermp != NULL) |
315 |
if (ump->um_uppermp != NULL) |
317 |
vfs_unregister_upper(uppermp, &ump->um_upper_link); |
316 |
vfs_unregister_upper(ump->um_uppermp, &ump->um_upper_link); |
318 |
vflush(mp, 1, FORCECLOSE, curthread); |
317 |
vflush(mp, 1, FORCECLOSE, curthread); |
319 |
free(ump, M_UNIONFSMNT); |
318 |
free(ump, M_UNIONFSMNT); |
320 |
mp->mnt_data = NULL; |
319 |
mp->mnt_data = NULL; |
Lines 346-353
unionfs_domount(struct mount *mp)
Link Here
|
346 |
} |
345 |
} |
347 |
|
346 |
|
348 |
MNT_ILOCK(mp); |
347 |
MNT_ILOCK(mp); |
349 |
if ((lowermp->mnt_flag & MNT_LOCAL) != 0 && |
348 |
if ((ump->um_lowermp->mnt_flag & MNT_LOCAL) != 0 && |
350 |
(uppermp->mnt_flag & MNT_LOCAL) != 0) |
349 |
(ump->um_uppermp->mnt_flag & MNT_LOCAL) != 0) |
351 |
mp->mnt_flag |= MNT_LOCAL; |
350 |
mp->mnt_flag |= MNT_LOCAL; |
352 |
mp->mnt_kern_flag |= MNTK_NOMSYNC | MNTK_UNIONFS; |
351 |
mp->mnt_kern_flag |= MNTK_NOMSYNC | MNTK_UNIONFS; |
353 |
MNT_IUNLOCK(mp); |
352 |
MNT_IUNLOCK(mp); |
Lines 400-407
unionfs_unmount(struct mount *mp, int mntflags)
Link Here
|
400 |
vn_lock(mp->mnt_vnodecovered, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE); |
399 |
vn_lock(mp->mnt_vnodecovered, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE); |
401 |
mp->mnt_vnodecovered->v_vflag &= ~VV_CROSSLOCK; |
400 |
mp->mnt_vnodecovered->v_vflag &= ~VV_CROSSLOCK; |
402 |
VOP_UNLOCK(mp->mnt_vnodecovered); |
401 |
VOP_UNLOCK(mp->mnt_vnodecovered); |
403 |
vfs_unregister_upper(ump->um_lowervp->v_mount, &ump->um_lower_link); |
402 |
vfs_unregister_upper(ump->um_lowermp, &ump->um_lower_link); |
404 |
vfs_unregister_upper(ump->um_uppervp->v_mount, &ump->um_upper_link); |
403 |
vfs_unregister_upper(ump->um_uppermp, &ump->um_upper_link); |
405 |
free(ump, M_UNIONFSMNT); |
404 |
free(ump, M_UNIONFSMNT); |
406 |
mp->mnt_data = NULL; |
405 |
mp->mnt_data = NULL; |
407 |
|
406 |
|
Lines 433-445
static int
Link Here
|
433 |
unionfs_quotactl(struct mount *mp, int cmd, uid_t uid, void *arg, |
432 |
unionfs_quotactl(struct mount *mp, int cmd, uid_t uid, void *arg, |
434 |
bool *mp_busy) |
433 |
bool *mp_busy) |
435 |
{ |
434 |
{ |
436 |
struct mount *uppermp; |
|
|
437 |
struct unionfs_mount *ump; |
435 |
struct unionfs_mount *ump; |
438 |
int error; |
436 |
int error; |
439 |
bool unbusy; |
437 |
bool unbusy; |
440 |
|
438 |
|
441 |
ump = MOUNTTOUNIONFSMOUNT(mp); |
439 |
ump = MOUNTTOUNIONFSMOUNT(mp); |
442 |
uppermp = atomic_load_ptr(&ump->um_uppervp->v_mount); |
|
|
443 |
KASSERT(*mp_busy == true, ("upper mount not busy")); |
440 |
KASSERT(*mp_busy == true, ("upper mount not busy")); |
444 |
/* |
441 |
/* |
445 |
* See comment in sys_quotactl() for an explanation of why the |
442 |
* See comment in sys_quotactl() for an explanation of why the |
Lines 452-465
unionfs_quotactl(struct mount *mp, int cmd, uid_t uid, void *arg,
Link Here
|
452 |
vfs_unbusy(mp); |
449 |
vfs_unbusy(mp); |
453 |
*mp_busy = false; |
450 |
*mp_busy = false; |
454 |
unbusy = true; |
451 |
unbusy = true; |
455 |
error = vfs_busy(uppermp, 0); |
452 |
error = vfs_busy(ump->um_uppermp, 0); |
456 |
/* |
453 |
/* |
457 |
* Writing is always performed to upper vnode. |
454 |
* Writing is always performed to upper vnode. |
458 |
*/ |
455 |
*/ |
459 |
if (error == 0) |
456 |
if (error == 0) |
460 |
error = VFS_QUOTACTL(uppermp, cmd, uid, arg, &unbusy); |
457 |
error = VFS_QUOTACTL(ump->um_uppermp, cmd, uid, arg, &unbusy); |
461 |
if (unbusy) |
458 |
if (unbusy) |
462 |
vfs_unbusy(uppermp); |
459 |
vfs_unbusy(ump->um_uppermp); |
463 |
|
460 |
|
464 |
return (error); |
461 |
return (error); |
465 |
} |
462 |
} |
Lines 479-485
unionfs_statfs(struct mount *mp, struct statfs *sbp)
Link Here
|
479 |
|
476 |
|
480 |
mstat = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK | M_ZERO); |
477 |
mstat = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK | M_ZERO); |
481 |
|
478 |
|
482 |
error = VFS_STATFS(ump->um_lowervp->v_mount, mstat); |
479 |
error = VFS_STATFS(ump->um_lowermp, mstat); |
483 |
if (error) { |
480 |
if (error) { |
484 |
free(mstat, M_STATFS); |
481 |
free(mstat, M_STATFS); |
485 |
return (error); |
482 |
return (error); |
Lines 491-497
unionfs_statfs(struct mount *mp, struct statfs *sbp)
Link Here
|
491 |
|
488 |
|
492 |
lbsize = mstat->f_bsize; |
489 |
lbsize = mstat->f_bsize; |
493 |
|
490 |
|
494 |
error = VFS_STATFS(ump->um_uppervp->v_mount, mstat); |
491 |
error = VFS_STATFS(ump->um_uppermp, mstat); |
495 |
if (error) { |
492 |
if (error) { |
496 |
free(mstat, M_STATFS); |
493 |
free(mstat, M_STATFS); |
497 |
return (error); |
494 |
return (error); |
Lines 558-567
unionfs_extattrctl(struct mount *mp, int cmd, struct vnode *filename_vp,
Link Here
|
558 |
unp = VTOUNIONFS(filename_vp); |
555 |
unp = VTOUNIONFS(filename_vp); |
559 |
|
556 |
|
560 |
if (unp->un_uppervp != NULLVP) { |
557 |
if (unp->un_uppervp != NULLVP) { |
561 |
return (VFS_EXTATTRCTL(ump->um_uppervp->v_mount, cmd, |
558 |
return (VFS_EXTATTRCTL(ump->um_uppermp, cmd, |
562 |
unp->un_uppervp, namespace, attrname)); |
559 |
unp->un_uppervp, namespace, attrname)); |
563 |
} else { |
560 |
} else { |
564 |
return (VFS_EXTATTRCTL(ump->um_lowervp->v_mount, cmd, |
561 |
return (VFS_EXTATTRCTL(ump->um_lowermp, cmd, |
565 |
unp->un_lowervp, namespace, attrname)); |
562 |
unp->un_lowervp, namespace, attrname)); |
566 |
} |
563 |
} |
567 |
} |
564 |
} |