View | Details | Raw Unified | Return to bug 251433 | Differences between
and this patch

Collapse All | Expand All

(-)union.h (working copy) (+7 lines)
Lines 40-45 Link Here
40
#ifdef _KERNEL
40
#ifdef _KERNEL
41
/* copy policy from lower to upper layer */
42
typedef enum _unionfs_copypolicy {
43
        UNIONFS_COPY_ON_WRITE = 0,
44
        UNIONFS_COPY_ALWAYS
45
} unionfs_copypolicy;
46
41
/* copy method of attr from lower to upper */
47
/* copy method of attr from lower to upper */
42
typedef enum _unionfs_copymode {
48
typedef enum _unionfs_copymode {
43
       UNIONFS_TRADITIONAL = 0,
49
       UNIONFS_TRADITIONAL = 0,
Lines 57-62 Link Here
57
       struct vnode   *um_lowervp;     /* VREFed once */
63
       struct vnode   *um_lowervp;     /* VREFed once */
58
       struct vnode   *um_uppervp;     /* VREFed once */
64
       struct vnode   *um_uppervp;     /* VREFed once */
59
       struct vnode   *um_rootvp;      /* ROOT vnode */
65
       struct vnode   *um_rootvp;      /* ROOT vnode */
66
        unionfs_copypolicy um_copypolicy;
60
       unionfs_copymode um_copymode;
67
       unionfs_copymode um_copymode;
61
       unionfs_whitemode um_whitemode;
68
       unionfs_whitemode um_whitemode;
62
       uid_t           um_uid;
69
       uid_t           um_uid;
(-)union_subr.c (working copy) (-16 / +28 lines)
Lines 892-903 Link Here
892
static int
892
static int
893
unionfs_vn_create_on_upper(struct vnode **vpp, struct vnode *udvp,
893
unionfs_vn_create_on_upper(struct vnode **vpp, struct vnode *udvp,
894
                          struct unionfs_node *unp, struct vattr *uvap,
894
                          struct unionfs_node *unp, struct vattr *uvap,
895
                          struct thread *td)
895
                          struct ucred *cred, struct thread *td)
896
{
896
{
897
       struct unionfs_mount *ump;
897
       struct unionfs_mount *ump;
898
       struct vnode   *vp;
898
       struct vnode   *vp;
899
       struct vnode   *lvp;
899
       struct vnode   *lvp;
900
       struct ucred   *cred;
901
       struct vattr    lva;
900
       struct vattr    lva;
902
       int             fmode;
901
       int             fmode;
903
       int             error;
902
       int             error;
Lines 906-912 Link Here
906
       ump = MOUNTTOUNIONFSMOUNT(UNIONFSTOV(unp)->v_mount);
905
       ump = MOUNTTOUNIONFSMOUNT(UNIONFSTOV(unp)->v_mount);
907
       vp = NULLVP;
906
       vp = NULLVP;
908
       lvp = unp->un_lowervp;
907
       lvp = unp->un_lowervp;
909
       cred = td->td_ucred;
908
       if (unp->un_path == NULL)
909
               panic("unionfs: un_path is null");
910
910
       fmode = FFLAGS(O_WRONLY | O_CREAT | O_TRUNC | O_EXCL);
911
       fmode = FFLAGS(O_WRONLY | O_CREAT | O_TRUNC | O_EXCL);
911
       error = 0;
912
       error = 0;
Lines 914-922 Link Here
914
               return (error);
915
               return (error);
915
       unionfs_create_uppervattr_core(ump, &lva, uvap, td);
916
       unionfs_create_uppervattr_core(ump, &lva, uvap, td);
916
       if (unp->un_path == NULL)
917
               panic("unionfs: un_path is null");
918
919
       cn.cn_namelen = strlen(unp->un_path);
917
       cn.cn_namelen = strlen(unp->un_path);
920
       cn.cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK);
918
       cn.cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK);
921
       bcopy(unp->un_path, cn.cn_pnbuf, cn.cn_namelen + 1);
919
       bcopy(unp->un_path, cn.cn_pnbuf, cn.cn_namelen + 1);
Lines 1053-1058 Link Here
1053
       struct vnode   *lvp;
1051
       struct vnode   *lvp;
1054
       struct vnode   *uvp;
1052
       struct vnode   *uvp;
1055
       struct vattr    uva;
1053
       struct vattr    uva;
1054
       struct uidinfo *rootinfo;
1056
       lvp = unp->un_lowervp;
1055
       lvp = unp->un_lowervp;
1057
       uvp = NULLVP;
1056
       uvp = NULLVP;
Lines 1069-1084 Link Here
1069
       if ((udvp->v_mount->mnt_flag & MNT_RDONLY))
1068
       if ((udvp->v_mount->mnt_flag & MNT_RDONLY))
1070
               return (EROFS);
1069
               return (EROFS);
1070
       /* Authority change to root */
1071
       rootinfo = uifind((uid_t)0);
1072
       cred = crdup(cred);
1073
       /*
1074
        * The calls to chgproccnt() are needed to compensate for change_ruid()
1075
        * calling chgproccnt().
1076
        */
1077
       chgproccnt(cred->cr_ruidinfo, 1, 0);
1078
       change_euid(cred, rootinfo);
1079
       change_ruid(cred, rootinfo);
1080
       change_svuid(cred, (uid_t)0);
1081
       uifree(rootinfo);
1082
1083
       /* we changed to root here, so no need to check again
1071
       error = VOP_ACCESS(lvp, VREAD, cred, td);
1084
       error = VOP_ACCESS(lvp, VREAD, cred, td);
1072
       if (error != 0)
1085
       if (error != 0)
1073
               return (error);
1086
               goto unionfs_copyfile_abort;
1087
       */
1074
       if ((error = vn_start_write(udvp, &mp, V_WAIT | PCATCH)) != 0)
1088
       if ((error = vn_start_write(udvp, &mp, V_WAIT | PCATCH)) != 0)
1075
               return (error);
1089
               goto unionfs_copyfile_abort;
1076
       error = unionfs_vn_create_on_upper(&uvp, udvp, unp, &uva, td);
1090
       error = unionfs_vn_create_on_upper(&uvp, udvp, unp, &uva, cred, td);
1077
       if (error != 0) {
1091
       if (error != 0) {
1078
               vn_finished_write(mp);
1092
               vn_finished_write(mp);
1079
               return (error);
1093
               goto unionfs_copyfile_abort;
1080
       }
1094
       }
1081
       if (docopy != 0) {
1095
       if (docopy != 0) {
Lines 1095-1108 Link Here
1095
       vn_finished_write(mp);
1109
       vn_finished_write(mp);
1096
       if (error == 0) {
1097
               /* Reset the attributes. Ignore errors. */
1098
               uva.va_type = VNON;
1099
               VOP_SETATTR(uvp, &uva, cred);
1100
       }
1101
1102
       unionfs_node_update(unp, uvp, td);
1110
       unionfs_node_update(unp, uvp, td);
1111
 unionfs_copyfile_abort:
1112
       chgproccnt(cred->cr_ruidinfo, -1, 0);
1113
       crfree(cred);
1114
1103
       return (error);
1115
       return (error);
1104
}
1116
}
(-)union_vfsops.c (working copy) (-1 / +18 lines)
Lines 89-94 Link Here
89
       gid_t           gid;
89
       gid_t           gid;
90
       u_short         udir;
90
       u_short         udir;
91
       u_short         ufile;
91
       u_short         ufile;
92
       unionfs_copypolicy copypolicy;
92
       unionfs_copymode copymode;
93
       unionfs_copymode copymode;
93
       unionfs_whitemode whitemode;
94
       unionfs_whitemode whitemode;
94
       struct nameidata nd, *ndp;
95
       struct nameidata nd, *ndp;
Lines 102-107 Link Here
102
       gid = 0;
103
       gid = 0;
103
       udir = 0;
104
       udir = 0;
104
       ufile = 0;
105
       ufile = 0;
106
       copypolicy = UNIONFS_COPY_ON_WRITE;
105
       copymode = UNIONFS_TRANSPARENT; /* default */
107
       copymode = UNIONFS_TRANSPARENT; /* default */
106
       whitemode = UNIONFS_WHITE_ALWAYS;
108
       whitemode = UNIONFS_WHITE_ALWAYS;
107
       ndp = &nd;
109
       ndp = &nd;
Lines 190-195 Link Here
190
                               return (EINVAL);
192
                               return (EINVAL);
191
                       }
193
                       }
192
               }
194
               }
195
               if (vfs_getopt(mp->mnt_optnew, "copypolicy", (void **)&tmp,
196
                              NULL) == 0) {
197
                 if (tmp == NULL) {
198
                   vfs_mount_error(mp, "Invalid copy policy");
199
                   return (EINVAL);
200
                 } else if (strcasecmp(tmp, "always") == 0)
201
                   copypolicy = UNIONFS_COPY_ALWAYS;
202
                 else if (strcasecmp(tmp, "onwrite") == 0)
203
                   copypolicy = UNIONFS_COPY_ON_WRITE;
204
                 else {
205
                   vfs_mount_error(mp, "Invalid copy policy");
206
                   return (EINVAL);
207
                 }
208
               }
193
               if (vfs_getopt(mp->mnt_optnew, "copymode", (void **)&tmp,
209
               if (vfs_getopt(mp->mnt_optnew, "copymode", (void **)&tmp,
194
                   NULL) == 0) {
210
                   NULL) == 0) {
195
                       if (tmp == NULL) {
211
                       if (tmp == NULL) {
Lines 229-235 Link Here
229
       UNIONFSDEBUG("unionfs_mount: uid=%d, gid=%d\n", uid, gid);
245
       UNIONFSDEBUG("unionfs_mount: uid=%d, gid=%d\n", uid, gid);
230
       UNIONFSDEBUG("unionfs_mount: udir=0%03o, ufile=0%03o\n", udir, ufile);
246
       UNIONFSDEBUG("unionfs_mount: udir=0%03o, ufile=0%03o\n", udir, ufile);
231
       UNIONFSDEBUG("unionfs_mount: copymode=%d\n", copymode);
247
       UNIONFSDEBUG("unionfs_mount: copypolicy=%d, copymode=%d, whitemode=%d\n", copypolicy, copymode, whitemode);
232
       /*
248
       /*
233
        * Find upper node
249
        * Find upper node
Lines 265-270 Link Here
265
       ump->um_gid = gid;
281
       ump->um_gid = gid;
266
       ump->um_udir = udir;
282
       ump->um_udir = udir;
267
       ump->um_ufile = ufile;
283
       ump->um_ufile = ufile;
284
       ump->um_copypolicy = copypolicy;
268
       ump->um_copymode = copymode;
285
       ump->um_copymode = copymode;
269
       ump->um_whitemode = whitemode;
286
       ump->um_whitemode = whitemode;
(-)union_vnops.c (working copy) (-1 / +6 lines)
Lines 464-469 Link Here
464
{
464
{
465
       int             error;
465
       int             error;
466
       struct unionfs_node *unp;
466
       struct unionfs_node *unp;
467
       struct unionfs_mount *ump;
467
       struct unionfs_node_status *unsp;
468
       struct unionfs_node_status *unsp;
468
       struct vnode   *uvp;
469
       struct vnode   *uvp;
469
       struct vnode   *lvp;
470
       struct vnode   *lvp;
Lines 477-482 Link Here
477
       error = 0;
478
       error = 0;
478
       unp = VTOUNIONFS(ap->a_vp);
479
       unp = VTOUNIONFS(ap->a_vp);
480
       ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
479
       uvp = unp->un_uppervp;
481
       uvp = unp->un_uppervp;
480
       lvp = unp->un_lowervp;
482
       lvp = unp->un_lowervp;
481
       targetvp = NULLVP;
483
       targetvp = NULLVP;
Lines 498-504 Link Here
498
       }
500
       }
499
       if (targetvp == NULLVP) {
501
       if (targetvp == NULLVP) {
500
               if (uvp == NULLVP) {
502
               if (uvp == NULLVP) {
501
                       if ((ap->a_mode & FWRITE) && lvp->v_type == VREG) {
503
                       if (((ap->a_mode & FWRITE) || (ump->um_copypolicy == UNIONFS_COPY_ALWAYS)) && lvp->v_type == VREG) {
504
                               error = VOP_ACCESS(lvp, ap->a_mode & (VREAD|VWRITE|VEXEC), cred, td);
505
                               if (error != 0)
506
                                       goto unionfs_open_abort;
502
                               error = unionfs_copyfile(unp,
507
                               error = unionfs_copyfile(unp,
503
                                   !(ap->a_mode & O_TRUNC), cred, td);
508
                                   !(ap->a_mode & O_TRUNC), cred, td);
504
                               if (error != 0)
509
                               if (error != 0)

Return to bug 251433