50 #include "fs/fs_subr.h" |
50 #include "fs/fs_subr.h" |
51 #include <sys/zap.h> |
51 #include <sys/zap.h> |
52 #include <sys/dmu.h> |
52 #include <sys/dmu.h> |
53 #include <sys/atomic.h> |
53 #include <sys/atomic.h> |
54 #include <sys/zfs_ctldir.h> |
54 #include <sys/zfs_ctldir.h> |
|
55 #include <sys/zfs_fuid.h> |
55 #include <sys/dnlc.h> |
56 #include <sys/dnlc.h> |
|
57 #include <sys/extdirent.h> |
|
58 #include <sys/zfs_i18n.h> |
|
59 |
|
60 /* |
|
61 * zfs_match_find() is used by zfs_dirent_lock() to peform zap lookups |
|
62 * of names after deciding which is the appropriate lookup interface. |
|
63 */ |
|
64 static int |
|
65 zfs_match_find(zfsvfs_t *zfsvfs, znode_t *dzp, char *name, boolean_t exact, |
|
66 boolean_t update, int *deflags, pathname_t *rpnp, uint64_t *zoid) |
|
67 { |
|
68 int error; |
|
69 |
|
70 if (zfsvfs->z_norm) { |
|
71 matchtype_t mt = MT_FIRST; |
|
72 boolean_t conflict = B_FALSE; |
|
73 size_t bufsz = 0; |
|
74 char *buf = NULL; |
|
75 |
|
76 if (rpnp) { |
|
77 buf = rpnp->pn_path; |
|
78 bufsz = rpnp->pn_bufsize; |
|
79 } |
|
80 if (exact) |
|
81 mt = MT_EXACT; |
|
82 /* |
|
83 * In the non-mixed case we only expect there would ever |
|
84 * be one match, but we need to use the normalizing lookup. |
|
85 */ |
|
86 error = zap_lookup_norm(zfsvfs->z_os, dzp->z_id, name, 8, 1, |
|
87 zoid, mt, buf, bufsz, &conflict); |
|
88 if (deflags) |
|
89 *deflags = conflict ? ED_CASE_CONFLICT : 0; |
|
90 } else { |
|
91 error = zap_lookup(zfsvfs->z_os, dzp->z_id, name, 8, 1, zoid); |
|
92 } |
|
93 *zoid = ZFS_DIRENT_OBJ(*zoid); |
|
94 |
|
95 if (error == ENOENT && update) |
|
96 dnlc_update(ZTOV(dzp), name, DNLC_NO_VNODE); |
|
97 |
|
98 return (error); |
|
99 } |
56 |
100 |
57 /* |
101 /* |
58 * Lock a directory entry. A dirlock on <dzp, name> protects that name |
102 * Lock a directory entry. A dirlock on <dzp, name> protects that name |
59 * in dzp's directory zap object. As long as you hold a dirlock, you can |
103 * in dzp's directory zap object. As long as you hold a dirlock, you can |
60 * assume two things: (1) dzp cannot be reaped, and (2) no other thread |
104 * assume two things: (1) dzp cannot be reaped, and (2) no other thread |
65 * name - name of entry to lock |
109 * name - name of entry to lock |
66 * flag - ZNEW: if the entry already exists, fail with EEXIST. |
110 * flag - ZNEW: if the entry already exists, fail with EEXIST. |
67 * ZEXISTS: if the entry does not exist, fail with ENOENT. |
111 * ZEXISTS: if the entry does not exist, fail with ENOENT. |
68 * ZSHARED: allow concurrent access with other ZSHARED callers. |
112 * ZSHARED: allow concurrent access with other ZSHARED callers. |
69 * ZXATTR: we want dzp's xattr directory |
113 * ZXATTR: we want dzp's xattr directory |
|
114 * ZCILOOK: On a mixed sensitivity file system, |
|
115 * this lookup should be case-insensitive. |
|
116 * ZCIEXACT: On a purely case-insensitive file system, |
|
117 * this lookup should be case-sensitive. |
|
118 * ZRENAMING: we are locking for renaming, force narrow locks |
70 * |
119 * |
71 * Output arguments: |
120 * Output arguments: |
72 * zpp - pointer to the znode for the entry (NULL if there isn't one) |
121 * zpp - pointer to the znode for the entry (NULL if there isn't one) |
73 * dlpp - pointer to the dirlock for this entry (NULL on error) |
122 * dlpp - pointer to the dirlock for this entry (NULL on error) |
|
123 * direntflags - (case-insensitive lookup only) |
|
124 * flags if multiple case-sensitive matches exist in directory |
|
125 * realpnp - (case-insensitive lookup only) |
|
126 * actual name matched within the directory |
74 * |
127 * |
75 * Return value: 0 on success or errno on failure. |
128 * Return value: 0 on success or errno on failure. |
76 * |
129 * |
77 * NOTE: Always checks for, and rejects, '.' and '..'. |
130 * NOTE: Always checks for, and rejects, '.' and '..'. |
|
131 * NOTE: For case-insensitive file systems we take wide locks (see below), |
|
132 * but return znode pointers to a single match. |
78 */ |
133 */ |
79 int |
134 int |
80 zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp, |
135 zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp, |
81 int flag) |
136 int flag, int *direntflags, pathname_t *realpnp) |
82 { |
137 { |
83 zfsvfs_t *zfsvfs = dzp->z_zfsvfs; |
138 zfsvfs_t *zfsvfs = dzp->z_zfsvfs; |
84 zfs_dirlock_t *dl; |
139 zfs_dirlock_t *dl; |
|
140 boolean_t update; |
|
141 boolean_t exact; |
85 uint64_t zoid; |
142 uint64_t zoid; |
86 int error; |
143 vnode_t *vp = NULL; |
87 vnode_t *vp; |
144 int error = 0; |
|
145 int cmpflags; |
88 |
146 |
89 *zpp = NULL; |
147 *zpp = NULL; |
90 *dlpp = NULL; |
148 *dlpp = NULL; |
91 |
149 |
92 /* |
150 /* |
94 */ |
152 */ |
95 if (name[0] == '.' && |
153 if (name[0] == '.' && |
96 (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')) || |
154 (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')) || |
97 zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) |
155 zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) |
98 return (EEXIST); |
156 return (EEXIST); |
|
157 |
|
158 /* |
|
159 * Case sensitivity and normalization preferences are set when |
|
160 * the file system is created. These are stored in the |
|
161 * zfsvfs->z_case and zfsvfs->z_norm fields. These choices |
|
162 * affect what vnodes can be cached in the DNLC, how we |
|
163 * perform zap lookups, and the "width" of our dirlocks. |
|
164 * |
|
165 * A normal dirlock locks a single name. Note that with |
|
166 * normalization a name can be composed multiple ways, but |
|
167 * when normalized, these names all compare equal. A wide |
|
168 * dirlock locks multiple names. We need these when the file |
|
169 * system is supporting mixed-mode access. It is sometimes |
|
170 * necessary to lock all case permutations of file name at |
|
171 * once so that simultaneous case-insensitive/case-sensitive |
|
172 * behaves as rationally as possible. |
|
173 */ |
|
174 |
|
175 /* |
|
176 * Decide if exact matches should be requested when performing |
|
177 * a zap lookup on file systems supporting case-insensitive |
|
178 * access. |
|
179 */ |
|
180 exact = ((zfsvfs->z_case & ZFS_CI_ONLY) && (flag & ZCIEXACT)) || |
|
181 ((zfsvfs->z_case & ZFS_CI_MIXD) && !(flag & ZCILOOK)); |
|
182 |
|
183 /* |
|
184 * Only look in or update the DNLC if we are looking for the |
|
185 * name on a file system that does not require normalization |
|
186 * or case folding. We can also look there if we happen to be |
|
187 * on a non-normalizing, mixed sensitivity file system IF we |
|
188 * are looking for the exact name. |
|
189 * |
|
190 * Maybe can add TO-UPPERed version of name to dnlc in ci-only |
|
191 * case for performance improvement? |
|
192 */ |
|
193 update = !zfsvfs->z_norm || |
|
194 ((zfsvfs->z_case & ZFS_CI_MIXD) && |
|
195 !(zfsvfs->z_norm & ~U8_TEXTPREP_TOUPPER) && !(flag & ZCILOOK)); |
|
196 |
|
197 /* |
|
198 * ZRENAMING indicates we are in a situation where we should |
|
199 * take narrow locks regardless of the file system's |
|
200 * preferences for normalizing and case folding. This will |
|
201 * prevent us deadlocking trying to grab the same wide lock |
|
202 * twice if the two names happen to be case-insensitive |
|
203 * matches. |
|
204 */ |
|
205 if (flag & ZRENAMING) |
|
206 cmpflags = 0; |
|
207 else |
|
208 cmpflags = zfsvfs->z_norm; |
99 |
209 |
100 /* |
210 /* |
101 * Wait until there are no locks on this name. |
211 * Wait until there are no locks on this name. |
102 */ |
212 */ |
103 rw_enter(&dzp->z_name_lock, RW_READER); |
213 rw_enter(&dzp->z_name_lock, RW_READER); |
106 if (dzp->z_unlinked) { |
216 if (dzp->z_unlinked) { |
107 mutex_exit(&dzp->z_lock); |
217 mutex_exit(&dzp->z_lock); |
108 rw_exit(&dzp->z_name_lock); |
218 rw_exit(&dzp->z_name_lock); |
109 return (ENOENT); |
219 return (ENOENT); |
110 } |
220 } |
111 for (dl = dzp->z_dirlocks; dl != NULL; dl = dl->dl_next) |
221 for (dl = dzp->z_dirlocks; dl != NULL; dl = dl->dl_next) { |
112 if (strcmp(name, dl->dl_name) == 0) |
222 if ((u8_strcmp(name, dl->dl_name, 0, cmpflags, |
|
223 U8_UNICODE_LATEST, &error) == 0) || error != 0) |
113 break; |
224 break; |
|
225 } |
|
226 if (error != 0) { |
|
227 mutex_exit(&dzp->z_lock); |
|
228 rw_exit(&dzp->z_name_lock); |
|
229 return (ENOENT); |
|
230 } |
114 if (dl == NULL) { |
231 if (dl == NULL) { |
115 /* |
232 /* |
116 * Allocate a new dirlock and add it to the list. |
233 * Allocate a new dirlock and add it to the list. |
117 */ |
234 */ |
118 dl = kmem_alloc(sizeof (zfs_dirlock_t), KM_SLEEP); |
235 dl = kmem_alloc(sizeof (zfs_dirlock_t), KM_SLEEP); |
168 } |
286 } |
169 *dlpp = dl; |
287 *dlpp = dl; |
170 *zpp = VTOZ(vp); |
288 *zpp = VTOZ(vp); |
171 return (0); |
289 return (0); |
172 } else { |
290 } else { |
173 error = zap_lookup(zfsvfs->z_os, dzp->z_id, name, |
291 error = zfs_match_find(zfsvfs, dzp, name, exact, |
174 8, 1, &zoid); |
292 update, direntflags, realpnp, &zoid); |
175 zoid = ZFS_DIRENT_OBJ(zoid); |
|
176 if (error == ENOENT) |
|
177 dnlc_update(ZTOV(dzp), name, DNLC_NO_VNODE); |
|
178 } |
293 } |
179 } |
294 } |
180 if (error) { |
295 if (error) { |
181 if (error != ENOENT || (flag & ZEXISTS)) { |
296 if (error != ENOENT || (flag & ZEXISTS)) { |
182 zfs_dirent_unlock(dl); |
297 zfs_dirent_unlock(dl); |
237 * no directory entries are actually stored for them. If this is |
352 * no directory entries are actually stored for them. If this is |
238 * the root of a filesystem, then '.zfs' is also treated as a |
353 * the root of a filesystem, then '.zfs' is also treated as a |
239 * special pseudo-directory. |
354 * special pseudo-directory. |
240 */ |
355 */ |
241 int |
356 int |
242 zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp) |
357 zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp, int flags, |
|
358 int *deflg, pathname_t *rpnp) |
243 { |
359 { |
244 zfs_dirlock_t *dl; |
360 zfs_dirlock_t *dl; |
245 znode_t *zp; |
361 znode_t *zp; |
246 int error = 0; |
362 int error = 0; |
247 |
363 |
255 * the vp for the snapshot directory. |
371 * the vp for the snapshot directory. |
256 */ |
372 */ |
257 if (dzp->z_phys->zp_parent == dzp->z_id && |
373 if (dzp->z_phys->zp_parent == dzp->z_id && |
258 zfsvfs->z_parent != zfsvfs) { |
374 zfsvfs->z_parent != zfsvfs) { |
259 error = zfsctl_root_lookup(zfsvfs->z_parent->z_ctldir, |
375 error = zfsctl_root_lookup(zfsvfs->z_parent->z_ctldir, |
260 "snapshot", vpp, NULL, 0, NULL, kcred); |
376 "snapshot", vpp, NULL, 0, NULL, kcred, |
|
377 NULL, NULL, NULL); |
261 return (error); |
378 return (error); |
262 } |
379 } |
263 rw_enter(&dzp->z_parent_lock, RW_READER); |
380 rw_enter(&dzp->z_parent_lock, RW_READER); |
264 error = zfs_zget(zfsvfs, dzp->z_phys->zp_parent, &zp); |
381 error = zfs_zget(zfsvfs, dzp->z_phys->zp_parent, &zp); |
265 if (error == 0) |
382 if (error == 0) |
266 *vpp = ZTOV(zp); |
383 *vpp = ZTOV(zp); |
267 rw_exit(&dzp->z_parent_lock); |
384 rw_exit(&dzp->z_parent_lock); |
268 } else if (zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) { |
385 } else if (zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) { |
269 *vpp = zfsctl_root(dzp); |
386 *vpp = zfsctl_root(dzp); |
270 } else { |
387 } else { |
271 error = zfs_dirent_lock(&dl, dzp, name, &zp, ZEXISTS | ZSHARED); |
388 int zf; |
|
389 |
|
390 zf = ZEXISTS | ZSHARED; |
|
391 if (flags & FIGNORECASE) |
|
392 zf |= ZCILOOK; |
|
393 |
|
394 error = zfs_dirent_lock(&dl, dzp, name, &zp, zf, deflg, rpnp); |
272 if (error == 0) { |
395 if (error == 0) { |
273 *vpp = ZTOV(zp); |
396 *vpp = ZTOV(zp); |
274 zfs_dirent_unlock(dl); |
397 zfs_dirent_unlock(dl); |
275 dzp->z_zn_prefetch = B_TRUE; /* enable prefetching */ |
398 dzp->z_zn_prefetch = B_TRUE; /* enable prefetching */ |
276 } |
399 } |
277 } |
400 rpnp = NULL; |
|
401 } |
|
402 |
|
403 if ((flags & FIGNORECASE) && rpnp) |
|
404 (void) strlcpy(rpnp->pn_path, name, rpnp->pn_bufsize); |
278 |
405 |
279 return (error); |
406 return (error); |
280 } |
407 } |
281 |
408 |
282 static char * |
409 static char * |
631 dzp->z_phys->zp_size--; /* one dirent removed */ |
758 dzp->z_phys->zp_size--; /* one dirent removed */ |
632 dzp->z_phys->zp_links -= zp_is_dir; /* ".." link from zp */ |
759 dzp->z_phys->zp_links -= zp_is_dir; /* ".." link from zp */ |
633 zfs_time_stamper_locked(dzp, CONTENT_MODIFIED, tx); |
760 zfs_time_stamper_locked(dzp, CONTENT_MODIFIED, tx); |
634 mutex_exit(&dzp->z_lock); |
761 mutex_exit(&dzp->z_lock); |
635 |
762 |
636 error = zap_remove(zp->z_zfsvfs->z_os, dzp->z_id, dl->dl_name, tx); |
763 if (zp->z_zfsvfs->z_norm) { |
|
764 if (((zp->z_zfsvfs->z_case & ZFS_CI_ONLY) && |
|
765 (flag & ZCIEXACT)) || |
|
766 ((zp->z_zfsvfs->z_case & ZFS_CI_MIXD) && |
|
767 !(flag & ZCILOOK))) |
|
768 error = zap_remove_norm(zp->z_zfsvfs->z_os, |
|
769 dzp->z_id, dl->dl_name, MT_EXACT, tx); |
|
770 else |
|
771 error = zap_remove_norm(zp->z_zfsvfs->z_os, |
|
772 dzp->z_id, dl->dl_name, MT_FIRST, tx); |
|
773 } else { |
|
774 error = zap_remove(zp->z_zfsvfs->z_os, |
|
775 dzp->z_id, dl->dl_name, tx); |
|
776 } |
637 ASSERT(error == 0); |
777 ASSERT(error == 0); |
638 |
778 |
639 if (unlinkedp != NULL) |
779 if (unlinkedp != NULL) |
640 *unlinkedp = unlinked; |
780 *unlinkedp = unlinked; |
641 else if (unlinked) |
781 else if (unlinked) |
661 zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
801 zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
662 znode_t *xzp; |
802 znode_t *xzp; |
663 dmu_tx_t *tx; |
803 dmu_tx_t *tx; |
664 uint64_t xoid; |
804 uint64_t xoid; |
665 int error; |
805 int error; |
|
806 zfs_fuid_info_t *fuidp = NULL; |
666 |
807 |
667 *xvpp = NULL; |
808 *xvpp = NULL; |
668 |
809 |
669 if (error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, cr)) |
810 if (error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr)) |
670 return (error); |
811 return (error); |
671 |
812 |
672 tx = dmu_tx_create(zfsvfs->z_os); |
813 tx = dmu_tx_create(zfsvfs->z_os); |
673 dmu_tx_hold_bonus(tx, zp->z_id); |
814 dmu_tx_hold_bonus(tx, zp->z_id); |
674 dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL); |
815 dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL); |
|
816 if (zfsvfs->z_fuid_obj == 0) { |
|
817 dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); |
|
818 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, SPA_MAXBLOCKSIZE); |
|
819 dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, FALSE, NULL); |
|
820 } else { |
|
821 dmu_tx_hold_bonus(tx, zfsvfs->z_fuid_obj); |
|
822 dmu_tx_hold_write(tx, zfsvfs->z_fuid_obj, 0, SPA_MAXBLOCKSIZE); |
|
823 } |
675 error = dmu_tx_assign(tx, zfsvfs->z_assign); |
824 error = dmu_tx_assign(tx, zfsvfs->z_assign); |
676 if (error) { |
825 if (error) { |
677 if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) |
826 if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) |
678 dmu_tx_wait(tx); |
827 dmu_tx_wait(tx); |
679 dmu_tx_abort(tx); |
828 dmu_tx_abort(tx); |
680 return (error); |
829 return (error); |
681 } |
830 } |
682 zfs_mknode(zp, vap, &xoid, tx, cr, IS_XATTR, &xzp, 0); |
831 zfs_mknode(zp, vap, &xoid, tx, cr, IS_XATTR, &xzp, 0, NULL, &fuidp); |
683 ASSERT(xzp->z_id == xoid); |
832 ASSERT(xzp->z_id == xoid); |
684 ASSERT(xzp->z_phys->zp_parent == zp->z_id); |
833 ASSERT(xzp->z_phys->zp_parent == zp->z_id); |
685 dmu_buf_will_dirty(zp->z_dbuf, tx); |
834 dmu_buf_will_dirty(zp->z_dbuf, tx); |
686 zp->z_phys->zp_xattr = xoid; |
835 zp->z_phys->zp_xattr = xoid; |
687 |
836 |
688 (void) zfs_log_create(zfsvfs->z_log, tx, TX_MKXATTR, zp, xzp, ""); |
837 (void) zfs_log_create(zfsvfs->z_log, tx, TX_MKXATTR, zp, |
|
838 xzp, "", NULL, fuidp, vap); |
|
839 if (fuidp) |
|
840 zfs_fuid_info_free(fuidp); |
689 dmu_tx_commit(tx); |
841 dmu_tx_commit(tx); |
690 |
842 |
691 *xvpp = ZTOV(xzp); |
843 *xvpp = ZTOV(xzp); |
692 |
844 |
693 return (0); |
845 return (0); |
748 * is controlled by the permissions on the attribute file. |
900 * is controlled by the permissions on the attribute file. |
749 */ |
901 */ |
750 va.va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID; |
902 va.va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID; |
751 va.va_type = VDIR; |
903 va.va_type = VDIR; |
752 va.va_mode = S_IFDIR | S_ISVTX | 0777; |
904 va.va_mode = S_IFDIR | S_ISVTX | 0777; |
753 va.va_uid = (uid_t)zp->z_phys->zp_uid; |
905 zfs_fuid_map_ids(zp, &va.va_uid, &va.va_gid); |
754 va.va_gid = (gid_t)zp->z_phys->zp_gid; |
|
755 |
906 |
756 error = zfs_make_xattrdir(zp, &va, xvpp, cr); |
907 error = zfs_make_xattrdir(zp, &va, xvpp, cr); |
757 zfs_dirent_unlock(dl); |
908 zfs_dirent_unlock(dl); |
758 |
909 |
759 if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) { |
910 if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) { |
779 */ |
930 */ |
780 int |
931 int |
781 zfs_sticky_remove_access(znode_t *zdp, znode_t *zp, cred_t *cr) |
932 zfs_sticky_remove_access(znode_t *zdp, znode_t *zp, cred_t *cr) |
782 { |
933 { |
783 uid_t uid; |
934 uid_t uid; |
|
935 uid_t downer; |
|
936 uid_t fowner; |
|
937 zfsvfs_t *zfsvfs = zdp->z_zfsvfs; |
784 |
938 |
785 if (zdp->z_zfsvfs->z_assign >= TXG_INITIAL) /* ZIL replay */ |
939 if (zdp->z_zfsvfs->z_assign >= TXG_INITIAL) /* ZIL replay */ |
786 return (0); |
940 return (0); |
787 |
941 |
788 if ((zdp->z_phys->zp_mode & S_ISVTX) == 0 || |
942 if ((zdp->z_phys->zp_mode & S_ISVTX) == 0) |
789 (uid = crgetuid(cr)) == zdp->z_phys->zp_uid || |
943 return (0); |
790 uid == zp->z_phys->zp_uid || |
944 |
|
945 zfs_fuid_map_id(zfsvfs, zdp->z_phys->zp_uid, ZFS_OWNER, &downer); |
|
946 zfs_fuid_map_id(zfsvfs, zp->z_phys->zp_uid, ZFS_OWNER, &fowner); |
|
947 |
|
948 if ((uid = crgetuid(cr)) == downer || uid == fowner || |
791 (ZTOV(zp)->v_type == VREG && |
949 (ZTOV(zp)->v_type == VREG && |
792 zfs_zaccess(zp, ACE_WRITE_DATA, cr) == 0)) |
950 zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr) == 0)) |
793 return (0); |
951 return (0); |
794 else |
952 else |
795 return (secpolicy_vnode_remove(cr)); |
953 return (secpolicy_vnode_remove(cr)); |
796 } |
954 } |