union_vnops.c (06be2aaa8320ba839a837d20e35f35c3efdf7587) union_vnops.c (fa288043e2c7d1d75b1bdae82704af2eace72de7)
1/*
2 * Copyright (c) 1992, 1993, 1994, 1995 Jan-Simon Pendry.
3 * Copyright (c) 1992, 1993, 1994, 1995
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Jan-Simon Pendry.
8 *

--- 1210 unchanged lines hidden (view full) ---

1219 }
1220 union_unlock_upper(upperdvp, td);
1221 return (error);
1222}
1223
1224/*
1225 * union_link:
1226 *
1/*
2 * Copyright (c) 1992, 1993, 1994, 1995 Jan-Simon Pendry.
3 * Copyright (c) 1992, 1993, 1994, 1995
4 * The Regents of the University of California. All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * Jan-Simon Pendry.
8 *

--- 1210 unchanged lines hidden (view full) ---

1219 }
1220 union_unlock_upper(upperdvp, td);
1221 return (error);
1222}
1223
1224/*
1225 * union_link:
1226 *
1227 * tdvp will be locked on entry, vp will not be locked on entry.
1228 * tdvp should remain locked on return and vp should remain unlocked
1227 * tdvp and vp will be locked on entry.
1228 * tdvp and vp should remain locked on return.
1229 * on return.
1230 */
1231
1232static int
1233union_link(ap)
1234 struct vop_link_args /* {
1235 struct vnode *a_tdvp;
1236 struct vnode *a_vp;

--- 8 unchanged lines hidden (view full) ---

1245 int error = 0;
1246
1247 if (ap->a_tdvp->v_op != ap->a_vp->v_op) {
1248 vp = ap->a_vp;
1249 } else {
1250 struct union_node *tun = VTOUNION(ap->a_vp);
1251
1252 if (tun->un_uppervp == NULLVP) {
1229 * on return.
1230 */
1231
1232static int
1233union_link(ap)
1234 struct vop_link_args /* {
1235 struct vnode *a_tdvp;
1236 struct vnode *a_vp;

--- 8 unchanged lines hidden (view full) ---

1245 int error = 0;
1246
1247 if (ap->a_tdvp->v_op != ap->a_vp->v_op) {
1248 vp = ap->a_vp;
1249 } else {
1250 struct union_node *tun = VTOUNION(ap->a_vp);
1251
1252 if (tun->un_uppervp == NULLVP) {
1253 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, td);
1254#if 0
1255 if (dun->un_uppervp == tun->un_dirvp) {
1256 if (dun->un_flags & UN_ULOCK) {
1257 dun->un_flags &= ~UN_ULOCK;
1258 VOP_UNLOCK(dun->un_uppervp, 0, td);
1259 }
1260 }
1261#endif
1262 error = union_copyup(tun, 1, cnp->cn_cred, td);
1263#if 0
1264 if (dun->un_uppervp == tun->un_dirvp) {
1265 vn_lock(dun->un_uppervp,
1266 LK_EXCLUSIVE | LK_RETRY, td);
1267 dun->un_flags |= UN_ULOCK;
1268 }
1269#endif
1253#if 0
1254 if (dun->un_uppervp == tun->un_dirvp) {
1255 if (dun->un_flags & UN_ULOCK) {
1256 dun->un_flags &= ~UN_ULOCK;
1257 VOP_UNLOCK(dun->un_uppervp, 0, td);
1258 }
1259 }
1260#endif
1261 error = union_copyup(tun, 1, cnp->cn_cred, td);
1262#if 0
1263 if (dun->un_uppervp == tun->un_dirvp) {
1264 vn_lock(dun->un_uppervp,
1265 LK_EXCLUSIVE | LK_RETRY, td);
1266 dun->un_flags |= UN_ULOCK;
1267 }
1268#endif
1270 VOP_UNLOCK(ap->a_vp, 0, td);
1269 if (error)
1270 return (error);
1271 }
1272 vp = tun->un_uppervp;
1271 }
1272 vp = tun->un_uppervp;
1273 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
1273 }
1274
1274 }
1275
1275 if (error)
1276 return (error);
1277
1278 /*
1279 * Make sure upper is locked, then unlock the union directory we were
1280 * called with to avoid a deadlock while we are calling VOP_LINK on
1281 * the upper (with tdvp locked and vp not locked). Our ap->a_tdvp
1282 * is expected to be locked on return.
1283 */
1284
1285 if ((tdvp = union_lock_upper(dun, td)) == NULLVP)
1286 return (EROFS);
1287
1288 VOP_UNLOCK(ap->a_tdvp, 0, td); /* unlock calling node */
1289 error = VOP_LINK(tdvp, vp, cnp); /* call link on upper */
1290
1291 /*
1276 /*
1277 * Make sure upper is locked, then unlock the union directory we were
1278 * called with to avoid a deadlock while we are calling VOP_LINK on
1279 * the upper (with tdvp locked and vp not locked). Our ap->a_tdvp
1280 * is expected to be locked on return.
1281 */
1282
1283 if ((tdvp = union_lock_upper(dun, td)) == NULLVP)
1284 return (EROFS);
1285
1286 VOP_UNLOCK(ap->a_tdvp, 0, td); /* unlock calling node */
1287 error = VOP_LINK(tdvp, vp, cnp); /* call link on upper */
1288
1289 /*
1290 * Unlock tun->un_uppervp if we locked it above.
1291 */
1292 if (ap->a_tdvp->v_op == ap->a_vp->v_op)
1293 VOP_UNLOCK(vp, 0, td);
1294 /*
1292 * We have to unlock tdvp prior to relocking our calling node in
1295 * We have to unlock tdvp prior to relocking our calling node in
1293 * order to avoid a deadlock.
1296 * order to avoid a deadlock. We also have to unlock ap->a_vp
1297 * before relocking the directory, but then we have to relock
1298 * ap->a_vp as our caller expects.
1294 */
1299 */
1300 VOP_UNLOCK(ap->a_vp, 0, td);
1295 union_unlock_upper(tdvp, td);
1296 vn_lock(ap->a_tdvp, LK_EXCLUSIVE | LK_RETRY, td);
1301 union_unlock_upper(tdvp, td);
1302 vn_lock(ap->a_tdvp, LK_EXCLUSIVE | LK_RETRY, td);
1303 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, td);
1297 return (error);
1298}
1299
1300static int
1301union_rename(ap)
1302 struct vop_rename_args /* {
1303 struct vnode *a_fdvp;
1304 struct vnode *a_fvp;

--- 657 unchanged lines hidden ---
1304 return (error);
1305}
1306
1307static int
1308union_rename(ap)
1309 struct vop_rename_args /* {
1310 struct vnode *a_fdvp;
1311 struct vnode *a_fvp;

--- 657 unchanged lines hidden ---