1086 static int
1087 tmp_remove(
1088 struct vnode *dvp,
1089 char *nm,
1090 struct cred *cred,
1091 caller_context_t *ct,
1092 int flags)
1093 {
1094 struct tmpnode *parent = (struct tmpnode *)VTOTN(dvp);
1095 int error;
1096 struct tmpnode *tp = NULL;
1097
1098 error = tdirlookup(parent, nm, &tp, cred);
1099 if (error)
1100 return (error);
1101
1102 ASSERT(tp);
1103 rw_enter(&parent->tn_rwlock, RW_WRITER);
1104 rw_enter(&tp->tn_rwlock, RW_WRITER);
1105
1106 if (tp->tn_type != VDIR ||
1107 (error = secpolicy_fs_linkdir(cred, dvp->v_vfsp)) == 0)
1108 error = tdirdelete(parent, tp, nm, tp->tn_type == VDIR ?
1109 DR_RMDIR : DR_REMOVE, cred);
1110
1111 rw_exit(&tp->tn_rwlock);
1112 rw_exit(&parent->tn_rwlock);
1113 vnevent_remove(TNTOV(tp), dvp, nm, ct);
1114 tmpnode_rele(tp);
1115
1116 TRACE_3(TR_FAC_TMPFS, TR_TMPFS_REMOVE,
1117 "tmpfs remove:dvp %p nm %s error %d", dvp, nm, error);
1118 return (error);
1119 }
1120
1121 /* ARGSUSED4 */
1122 static int
1123 tmp_link(
1124 struct vnode *dvp,
1125 struct vnode *srcvp,
1126 char *tnm,
1127 struct cred *cred,
1128 caller_context_t *ct,
1129 int flags)
1130 {
1131 struct tmpnode *parent;
1132 struct tmpnode *from;
1133 struct tmount *tm = (struct tmount *)VTOTM(dvp);
1134 int error;
1135 struct tmpnode *found = NULL;
1136 struct vnode *realvp;
1137
1138 if (VOP_REALVP(srcvp, &realvp, ct) == 0)
1139 srcvp = realvp;
1140
1141 parent = (struct tmpnode *)VTOTN(dvp);
1142 from = (struct tmpnode *)VTOTN(srcvp);
1143
1144 if ((srcvp->v_type == VDIR &&
1145 secpolicy_fs_linkdir(cred, dvp->v_vfsp)) ||
1146 (from->tn_uid != crgetuid(cred) && secpolicy_basic_link(cred)))
1147 return (EPERM);
1148
1149 /*
1150 * Make sure link for extended attributes is valid
1151 * We only support hard linking of xattr's in xattrdir to an xattrdir
1152 */
1153 if ((from->tn_flags & ISXATTR) != (parent->tn_flags & ISXATTR))
1154 return (EINVAL);
1155
1156 error = tdirlookup(parent, tnm, &found, cred);
1157 if (error == 0) {
1158 ASSERT(found);
1159 tmpnode_rele(found);
1160 return (EEXIST);
1161 }
1162
1163 if (error != ENOENT)
1164 return (error);
1165
|
1086 static int
1087 tmp_remove(
1088 struct vnode *dvp,
1089 char *nm,
1090 struct cred *cred,
1091 caller_context_t *ct,
1092 int flags)
1093 {
1094 struct tmpnode *parent = (struct tmpnode *)VTOTN(dvp);
1095 int error;
1096 struct tmpnode *tp = NULL;
1097
1098 error = tdirlookup(parent, nm, &tp, cred);
1099 if (error)
1100 return (error);
1101
1102 ASSERT(tp);
1103 rw_enter(&parent->tn_rwlock, RW_WRITER);
1104 rw_enter(&tp->tn_rwlock, RW_WRITER);
1105
1106 error = tp->tn_type == VDIR ? EPERM :
1107 tdirdelete(parent, tp, nm, DR_REMOVE, cred);
1108
1109 rw_exit(&tp->tn_rwlock);
1110 rw_exit(&parent->tn_rwlock);
1111 vnevent_remove(TNTOV(tp), dvp, nm, ct);
1112 tmpnode_rele(tp);
1113
1114 TRACE_3(TR_FAC_TMPFS, TR_TMPFS_REMOVE,
1115 "tmpfs remove:dvp %p nm %s error %d", dvp, nm, error);
1116 return (error);
1117 }
1118
1119 /* ARGSUSED4 */
1120 static int
1121 tmp_link(
1122 struct vnode *dvp,
1123 struct vnode *srcvp,
1124 char *tnm,
1125 struct cred *cred,
1126 caller_context_t *ct,
1127 int flags)
1128 {
1129 struct tmpnode *parent;
1130 struct tmpnode *from;
1131 struct tmount *tm = (struct tmount *)VTOTM(dvp);
1132 int error;
1133 struct tmpnode *found = NULL;
1134 struct vnode *realvp;
1135
1136 if (VOP_REALVP(srcvp, &realvp, ct) == 0)
1137 srcvp = realvp;
1138
1139 parent = (struct tmpnode *)VTOTN(dvp);
1140 from = (struct tmpnode *)VTOTN(srcvp);
1141
1142 if (srcvp->v_type == VDIR ||
1143 (from->tn_uid != crgetuid(cred) && secpolicy_basic_link(cred)))
1144 return (EPERM);
1145
1146 /*
1147 * Make sure link for extended attributes is valid
1148 * We only support hard linking of xattr's in xattrdir to an xattrdir
1149 */
1150 if ((from->tn_flags & ISXATTR) != (parent->tn_flags & ISXATTR))
1151 return (EINVAL);
1152
1153 error = tdirlookup(parent, tnm, &found, cred);
1154 if (error == 0) {
1155 ASSERT(found);
1156 tmpnode_rele(found);
1157 return (EEXIST);
1158 }
1159
1160 if (error != ENOENT)
1161 return (error);
1162
|