Added whiteout behavior option. ``-o whiteout=always'' is default mode
(it is established practice) and ``-o whiteout=whenneeded'' is less disk-space using mode especially for resource restricted environments like embedded environments. (Contributed by Ed Schouten. Thanks) Submitted by: Masanori Ozawa <ozawa@ongs.co.jp> (unionfs developer) Reviewed by: jeff, kensmith Approved by: re (kensmith) MFC after: 1 week
This commit is contained in:
parent
524f3f285d
commit
20885def58
@ -98,6 +98,10 @@ For behavior of the
|
||||
mode, see
|
||||
.Sx MASQUERADE MODE
|
||||
below.
|
||||
.It Sm Cm whiteout No = Cm always | whenneeded Sm
|
||||
Specifies whether whiteouts should always be made in the upper layer
|
||||
when removing a file or directory or only when it already exists in the
|
||||
lower layer.
|
||||
.It Cm udir Ns = Ns Ar mode
|
||||
Specifies directory mode bits in octal for
|
||||
.Cm masquerade
|
||||
|
@ -45,11 +45,18 @@ typedef enum _unionfs_copymode {
|
||||
UNIONFS_MASQUERADE
|
||||
} unionfs_copymode;
|
||||
|
||||
/* whiteout policy of upper layer */
|
||||
typedef enum _unionfs_whitemode {
|
||||
UNIONFS_WHITE_ALWAYS = 0,
|
||||
UNIONFS_WHITE_WHENNEEDED
|
||||
} unionfs_whitemode;
|
||||
|
||||
struct unionfs_mount {
|
||||
struct vnode *um_lowervp; /* VREFed once */
|
||||
struct vnode *um_uppervp; /* VREFed once */
|
||||
struct vnode *um_rootvp; /* ROOT vnode */
|
||||
unionfs_copymode um_copymode;
|
||||
unionfs_whitemode um_whitemode;
|
||||
uid_t um_uid;
|
||||
gid_t um_gid;
|
||||
u_short um_udir;
|
||||
|
@ -123,6 +123,7 @@ unionfs_domount(struct mount *mp, struct thread *td)
|
||||
u_short udir;
|
||||
u_short ufile;
|
||||
unionfs_copymode copymode;
|
||||
unionfs_whitemode whitemode;
|
||||
struct componentname fakecn;
|
||||
struct nameidata nd, *ndp;
|
||||
struct vattr va;
|
||||
@ -136,6 +137,7 @@ unionfs_domount(struct mount *mp, struct thread *td)
|
||||
udir = 0;
|
||||
ufile = 0;
|
||||
copymode = UNIONFS_TRANSPARENT; /* default */
|
||||
whitemode = UNIONFS_WHITE_ALWAYS;
|
||||
ndp = &nd;
|
||||
|
||||
if (mp->mnt_flag & MNT_ROOTFS) {
|
||||
@ -237,6 +239,20 @@ unionfs_domount(struct mount *mp, struct thread *td)
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
if (vfs_getopt(mp->mnt_optnew, "whiteout", (void **)&tmp,
|
||||
NULL) == 0) {
|
||||
if (tmp == NULL) {
|
||||
vfs_mount_error(mp, "Invalid whiteout mode");
|
||||
return (EINVAL);
|
||||
} else if (strcasecmp(tmp, "always") == 0)
|
||||
whitemode = UNIONFS_WHITE_ALWAYS;
|
||||
else if (strcasecmp(tmp, "whenneeded") == 0)
|
||||
whitemode = UNIONFS_WHITE_WHENNEEDED;
|
||||
else {
|
||||
vfs_mount_error(mp, "Invalid whiteout mode");
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If copymode is UNIONFS_TRADITIONAL, uid/gid is mounted user. */
|
||||
if (copymode == UNIONFS_TRADITIONAL) {
|
||||
@ -286,6 +302,7 @@ unionfs_domount(struct mount *mp, struct thread *td)
|
||||
ump->um_udir = udir;
|
||||
ump->um_ufile = ufile;
|
||||
ump->um_copymode = copymode;
|
||||
ump->um_whitemode = whitemode;
|
||||
|
||||
MNT_ILOCK(mp);
|
||||
if ((lowerrootvp->v_mount->mnt_kern_flag & MNTK_MPSAFE) &&
|
||||
|
@ -939,6 +939,7 @@ unionfs_remove(struct vop_remove_args *ap)
|
||||
int error;
|
||||
struct unionfs_node *dunp;
|
||||
struct unionfs_node *unp;
|
||||
struct unionfs_mount *ump;
|
||||
struct vnode *udvp;
|
||||
struct vnode *uvp;
|
||||
struct vnode *lvp;
|
||||
@ -960,7 +961,9 @@ unionfs_remove(struct vop_remove_args *ap)
|
||||
return (EROFS);
|
||||
|
||||
if (uvp != NULLVP) {
|
||||
cnp->cn_flags |= DOWHITEOUT;
|
||||
ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
|
||||
if (ump->um_whitemode == UNIONFS_WHITE_ALWAYS || lvp != NULLVP)
|
||||
cnp->cn_flags |= DOWHITEOUT;
|
||||
error = VOP_REMOVE(udvp, uvp, cnp);
|
||||
} else if (lvp != NULLVP)
|
||||
error = unionfs_mkwhiteout(udvp, cnp, td, unp->un_path);
|
||||
@ -1290,6 +1293,7 @@ unionfs_rmdir(struct vop_rmdir_args *ap)
|
||||
int error;
|
||||
struct unionfs_node *dunp;
|
||||
struct unionfs_node *unp;
|
||||
struct unionfs_mount *ump;
|
||||
struct componentname *cnp;
|
||||
struct thread *td;
|
||||
struct vnode *udvp;
|
||||
@ -1319,7 +1323,9 @@ unionfs_rmdir(struct vop_rmdir_args *ap)
|
||||
if (error != 0)
|
||||
return (error);
|
||||
}
|
||||
cnp->cn_flags |= DOWHITEOUT;
|
||||
ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
|
||||
if (ump->um_whitemode == UNIONFS_WHITE_ALWAYS || lvp != NULLVP)
|
||||
cnp->cn_flags |= DOWHITEOUT;
|
||||
error = VOP_RMDIR(udvp, uvp, cnp);
|
||||
}
|
||||
else if (lvp != NULLVP)
|
||||
|
Loading…
Reference in New Issue
Block a user